~ chicken-r7rs (master) 8e32b4ab01f198384579c4301115f820a942228a


commit 8e32b4ab01f198384579c4301115f820a942228a
Author:     Evan Hanson <evhan@foldling.org>
AuthorDate: Tue Jan 7 01:54:45 2014 +0000
Commit:     Evan Hanson <evhan@foldling.org>
CommitDate: Tue Jan 7 01:54:45 2014 +0000

    import/library loading, scheme.eval, scheme.r5rs, a bunch of other hacking

diff --git a/r7rs-compile-time-module.scm b/r7rs-compile-time-module.scm
index 172a7f9..0ff9be8 100644
--- a/r7rs-compile-time-module.scm
+++ b/r7rs-compile-time-module.scm
@@ -1,9 +1,10 @@
 (module r7rs-compile-time (parse-library-definition
+			   define-extended-arity-comparator
 			   process-cond-expand
 			   fixup-import/export-spec
 			   parse-library-name
+			   import-transformer
 			   read-forms
-			   current-source-filename
 			   register-r7rs-module
 			   locate-library)
 
diff --git a/r7rs-compile-time.scm b/r7rs-compile-time.scm
index 12543d3..5a74cfa 100644
--- a/r7rs-compile-time.scm
+++ b/r7rs-compile-time.scm
@@ -68,15 +68,41 @@
     ((? symbol? spec) spec)
     (_ (syntax-error loc "invalid import/export specifier" spec))))
 
-(define (current-source-filename)
-  (or (and (feature? #:compiling) ##compiler#source-filename)
-      ##sys#current-source-filename))
+;; Dig e.g. foo.bar out of (only (foo bar) ...) ...
+(define (import/export-spec-feature-name spec loc)
+  (match spec
+    ((? symbol? spec) spec)
+    (((or 'only 'except 'rename 'prefix) name . more)
+     (import/export-spec-feature-name name loc))
+    ((name ...)
+     (parse-library-name name loc))
+    (else
+     (syntax-error loc "invalid import/export specifier" spec))))
+
+(define (import-transformer type)
+  (er-macro-transformer
+   (let ((%import (caddr (assq type (##sys#macro-environment))))) ; XXX safe?
+     (lambda (x r c)
+       `(##core#begin
+	 ,@(map (lambda (spec)
+		  (let ((spec (fixup-import/export-spec spec type))
+			(name (import/export-spec-feature-name spec type)))
+		    (%import (list type spec) '() (##sys#current-environment))
+		    (if (memq name '(scheme foreign)) ; XXX others?
+			'(##core#undefined)
+			`(##core#require-extension (,name) #f))))
+		(strip-syntax (cdr x))))))))
+
+(define (current-source-directory)
+  (pathname-directory
+   (or (and (feature? #:compiling) ##compiler#source-filename)
+       ##sys#current-source-filename)))
 
 (define (read-forms filename ci?)
   (read-file 
    (if (absolute-pathname? filename)
        filename
-       (make-pathname (current-source-filename) filename))
+       (make-pathname (current-source-directory) filename))
    (lambda (port)
      (parameterize ((case-sensitive ci?))
        (read port)))))
@@ -98,10 +124,8 @@
 	      specs))
        (define (parse-imports specs)
 	 ;; What R7RS calls IMPORT, we call USE (it imports *and* loads code)
-         ;; XXX TODO: Should be import-for-syntax'ed as well?
-	 `(##core#require-extension
-	   ,(map (lambda (s) (fixup-import/export-spec s 'import)) specs)
-	   #t))
+	 ;; XXX TODO: Should be import-for-syntax'ed as well?
+	 `(import ,@specs)) ; NOTE this is the r7rs module's IMPORT!
        (define (process-includes fnames ci?)
 	 `(##core#begin
 	   ,@(map (match-lambda
@@ -136,7 +160,7 @@
 	      ,(parse-decls more)))
 	   ((('cond-expand decls ...) . more)
 	    `(##core#begin
-	      ,(parse-decls (process-cond-expand decls))
+	      ,@(process-cond-expand decls)
 	      ,(parse-decls more)))
 	   ((('begin code ...) . more)
 	    `(##core#begin 
@@ -144,15 +168,15 @@
 	      ,(parse-decls more)))
 	   (decl (syntax-error 'define-library "invalid library declaration" decl))))
        `(##core#begin
-         (##core#module
-          ,real-name ((,dummy-export))
-          ;; gruesome hack: we add a dummy export for adding indirect exports
-          (import (rename scheme (define-syntax hidden:define-syntax)))
-          (import (only scheme.base import export)) ; overwrites existing "import"
-          ;; Another gruesome hack: register feature so "use" works properly
-          (import (rename chicken (register-feature! hidden:register-feature!)))
-          (hidden:register-feature! (##core#quote ,real-name))
-          (hidden:define-syntax ,dummy-export (lambda () #f))
+	 (##core#module
+	  ,real-name ((,dummy-export))
+	  ;; gruesome hack: we add a dummy export for adding indirect exports
+	  (##core#define-syntax ,dummy-export (##core#lambda () #f))
+	  ;; Another gruesome hack: provide feature so "use" works properly
+	  (##sys#provide (##core#quote ,real-name))
+	  ;; Set up an R7RS environment for the module's body.
+	  (import-for-syntax r7rs) ; overwrites "syntax-rules"
+	  (import r7rs) ; overwrites existing "import" and "import-for-syntax"
           ,(parse-decls decls)))))
     (_ (syntax-error 'define-library "invalid library definition" form))))
 
@@ -173,3 +197,16 @@
 		     (lambda (dummylist)
 		       (set-cdr! dummylist (cons sym (cdr dummylist))))))))
 	  (register-export sym mod))))))
+
+(define-syntax define-extended-arity-comparator
+  (syntax-rules ()
+    ((_ name comparator check-type)
+     (define name
+       (let ((c comparator))
+	 (lambda (o1 o2 . os)
+	   (check-type o1 'name)
+	   (let lp ((o1 o1) (o2 o2) (os os) (eq #t))
+	     (check-type o2 'name)
+	     (if (null? os)
+		 (and eq (c o1 o2))
+		 (lp o2 (car os) (cdr os) (and eq (c o1 o2)))))))))))
diff --git a/r7rs.scm b/r7rs.scm
index b423eec..54c7ac3 100644
--- a/r7rs.scm
+++ b/r7rs.scm
@@ -1,20 +1,38 @@
-(module r7rs (define-library)
+(module r7rs (define-library import import-for-syntax export syntax-rules)
 
-  (import (except scheme syntax-rules))		;XXX except ...
-  (import chicken)			;XXX except ...
-  (import numbers)
-  (import scheme.base)
-  (include "scheme.base-interface.scm")
+  (import (except scheme syntax-rules))	;XXX except ...
+  (import (only chicken include))	;XXX except ...
 
-  (begin-for-syntax
-   (require-library r7rs-compile-time numbers))
+  ;; For syntax definition helpers.
   (import-for-syntax r7rs-compile-time matchable)
+  (begin-for-syntax (require-library r7rs-compile-time))
 
-(require-library scheme.base)
+  ;; For extended number literals.
+  (require-library numbers)
+
+  ;; For #u8(...) syntax.
+  (require-extension srfi-4)
 
 (let ((old-hook ##sys#user-read-hook))
+  ;; XXX Read syntax for "#false" and srfi-4's "#f32(...)" and friends
+  ;; don't play nicely together, so we have to copy some of srfi-4.scm's
+  ;; read hook here, to fall back on when we hit a vector of floats.
+  (define read-srfi-4-vector
+    (let ([consers (list 'u8 list->u8vector
+			 's8 list->s8vector
+			 'u16 list->u16vector
+			 's16 list->s16vector
+			 'u32 list->u32vector
+			 's32 list->s32vector
+			 'f32 list->f32vector
+			 'f64 list->f64vector)])
+      (lambda (tag port)
+	(let* ([x (read port)])
+	  (cond [(or (eq? tag 'f) (eq? tag 'F)) #f]
+		[(memq tag consers) => (lambda (c) ((##sys#slot (##sys#slot c 1) 0) (read port)))]
+		[else (##sys#read-error port "illegal bytevector syntax" tag)])))))
   (set! ##sys#user-read-hook
-        (lambda (char port)
+	(lambda (char port)
 	  (define (fail tok)
 	    (##sys#read-error port "invalid boolean literal syntax" tok))
           (case char
@@ -25,9 +43,21 @@
 		   (let ((str (symbol->string sym)))
 		     (cond ((or (string-ci=? "t" str) (string-ci=? "true" str)) #t)
 			   ((or (string-ci=? "f" str) (string-ci=? "false" str)) #f)
-			   (else (fail sym)))))))
+			   (else (read-srfi-4-vector sym port)))))))
             (else (old-hook char port))))))
 
+;;;
+;;; 5.2. Import declarations
+;;;
+
+(define-syntax import (import-transformer 'import))
+(define-syntax import-for-syntax (import-transformer 'import-for-syntax))
+
+;;;
+;;; 5.4. Syntax definitions
+;;;
+(include "synrules.scm")
+
 ;;;
 ;;; 5.6.1. Libraries
 ;;;
@@ -39,7 +69,4 @@
        ((_ name decls ...)
 	(let ((dummy (register-r7rs-module (parse-library-name name 'define-library))))
 	  (parse-library-definition x dummy)))
-       (_ (syntax-error 'define-library "invalid library definition" x))))))
-
-
-)
+       (_ (syntax-error 'define-library "invalid library definition" x)))))))
diff --git a/r7rs.setup b/r7rs.setup
index 59224d0..13c8073 100644
--- a/r7rs.setup
+++ b/r7rs.setup
@@ -4,13 +4,12 @@
 (use make srfi-1)
 
 (define scheme-modules
-  '("case-lambda" "char" "complex" "cxr" "eval" "file" "inexact" "load" "process-context" "read")) ;XXX
+  '("case-lambda" "char" "complex" "cxr" "eval" "file" "inexact" "load" "process-context" "r5rs" "read" "write")) ;XXX
 
 (make (("r7rs-compile-time.so" ("r7rs-compile-time.scm" "r7rs-compile-time-module.scm")
 	(compile -s -O3 -d1 r7rs-compile-time-module.scm -J -o r7rs-compile-time.so)
 	(compile -s -O3 -d0 r7rs-compile-time.import.scm))
-       ("scheme.base.so" ("scheme.base.scm" "scheme.base-interface.scm"
-                          "synrules.scm")
+       ("scheme.base.so" ("scheme.base.scm" "scheme.base-interface.scm")
 	(compile -s -O3 -d1 scheme.base.scm -J -emit-type-file scheme.base.types)
 	(compile -s -O3 -d0 scheme.base.import.scm)))
   '("r7rs-compile-time.so" "scheme.base.so"))
@@ -27,7 +26,7 @@
 		(list so))))
  scheme-modules)
 
-(make (("r7rs.so" ("r7rs.scm" "scheme.base-interface.scm")
+(make (("r7rs.so" ("r7rs.scm" "synrules.scm")
 	(compile -s -O3 -d0 r7rs.scm -J)
 	(compile -s -O3 -d0 r7rs.import.scm))))
 
diff --git a/scheme.base-interface.scm b/scheme.base-interface.scm
index 83879aa..380047a 100644
--- a/scheme.base-interface.scm
+++ b/scheme.base-interface.scm
@@ -1,17 +1,13 @@
 (export
-  #|
   * + - /
   <= < >= = >
   abs 
   and
-  |#
   append
-  #|
   apply
-  |#
   assoc assq assv
-  #|
   begin
+  #|
   binary-port?
   |#
   boolean? boolean=?
@@ -22,51 +18,35 @@
   bytevector?
   car cdr
   caar cadr cdar cddr
-  #|
   call-with-current-continuation call/cc
-  |#
   call-with-port 
-  #|
   call-with-values
   case
   ceiling
   char-ready?
   char->integer integer->char
-  |#
   char=? char<? char>? char<=? char>=?
-  #|
   char?
   close-input-port close-output-port
-  |#
   close-port
-  #|
   complex?
   cond
-  |#
   cond-expand
   cons
-  #|
   current-input-port current-output-port current-error-port
   define
-  define-record-type
-  |#
+  define-record-type ; TODO
   define-syntax
-  #|
-  define-values
+  define-values ; TODO
   denominator numerator
   do
   dynamic-wind
-  else
-  |#
   eof-object
-  #|
   eof-object?
   eq? eqv? equal?
   error
-  |#
   error-object-irritants error-object-message
   error-object?
-  #|
   even? odd?
   exact inexact
   exact-integer-sqrt
@@ -74,40 +54,34 @@
   exact? inexact?
   expt
   features
-  |#
   file-error?
-  #|
   floor
-  |#
   floor/ floor-quotient floor-remainder
-  #|
   flush-output-port
   for-each
   gcd lcm
+  #|
   get-output-bytevector
-  get-output-string
   |#
+  get-output-string
   guard
-  #|
   if
+  #|
+  import ; provided by the "r7rs" module
+  import-for-syntax ; XXX should we?  Probably not, it's not in r7rs...
   |#
-  import
+  include 
   #|
-  ;; import-for-syntax   XXX should we?  Probably not, it's not in r7rs...
-  include include-ci
+  include-ci
   |#
   input-port-open? output-port-open?
-  #|
   input-port? output-port?
   integer?
   lambda
-  |#
   length
-  #|
   let let*
   letrec letrec*
   let-values let*-values
-  |#
   let-syntax letrec-syntax
   #|
   library                    ; for "cond-expand"
@@ -115,107 +89,117 @@
   list list-copy list-ref list-set! list-tail list?
   make-bytevector
   make-list
-  #|
   make-parameter
   make-string
   make-vector
   map
   max min
-  |#
   member memq memv
-  #|
   modulo remainder
   negative? positive?
   newline
-  |#
   not
   null?
-  #|
   number->string string->number
   number?
+  #|
   open-input-bytevector open-output-bytevector
-  open-input-string open-output-string
   |#
+  open-input-string open-output-string
+  or
   pair?
-  #|
   parameterize
   peek-char
+  #|
   peek-u8
+  |#
   port?
   procedure?
   quasiquote
   quote
-  |#
   quotient remainder
   raise raise-continuable
-  #|
   rational?
   rationalize
+  #|
   read-bytevector read-bytevector!
-  read-char
   |#
+  read-char
   read-error?
   #|
   read-line
   read-string
   read-u8
-  real?
   |#
+  real?
   reverse
-  #|
   round
   set!
-  |#
   set-car! set-cdr!
-  #|
   square
   string
   string->list list->string
+  #|
   string->utf8 utf8->string
+  |#
   string->symbol symbol->string
+  #|
   string->vector
+  |#
   string-append
-  string-copy string-copy!
+  string-copy
+  #|
+  string-copy!
+  |#
   string-fill!
+  #|
   string-for-each
+  |#
   string-length
+  #|
   string-map
-  string-ref string-set!
   |#
+  string-ref string-set!
   string=? string<? string>? string<=? string>=?
-  #|
   string?
+  #|
   substring
   symbol=?
+  |#
   symbol?
   syntax-error
-  |#
-  syntax-rules
   #|
+  syntax-rules
   textual-port?
-  truncate
   |#
+  truncate
   truncate/ truncate-quotient truncate-remainder
   #|
   u8-ready?
+  |#
   unless
+  #|
   unquote unquote-splicing
+  |#
   values
   vector
+  #|
   vector-append
   vector-copy vector-copy!
   vector-for-each
   vector-length
   vector-map
+  |#
   vector-ref vector-set!
   when
-  |#
   with-exception-handler
   #|
   write-bytevector 
+  |#
   write-char
+  #|
   write-string
   write-u8
-  zero?
   |#
+  zero?
   )
diff --git a/scheme.base.scm b/scheme.base.scm
index 7020311..ec4e8f0 100644
--- a/scheme.base.scm
+++ b/scheme.base.scm
@@ -1,13 +1,14 @@
 (module scheme.base ()
 
-(import (except scheme syntax-rules cond-expand
+(import (except scheme syntax-rules cond-expand include
                        assoc list-set! list-tail member
                        char=? char<? char>? char<=? char>=?
                        string=? string<? string>? string<=? string>=?))
 (import (prefix (only scheme char=? char<? char>? char<=? char>=?
                              string=? string<? string>? string<=? string>=?)
                 %))
-(import (except chicken with-exception-handler raise quotient remainder modulo))
+(import (except chicken with-exception-handler raise include quotient remainder modulo))
+(import (rename (only chicken include) (include %include)))
 (import (rename (only srfi-4 ; TODO: utf8<->string
                              make-u8vector subu8vector u8vector u8vector?
                              u8vector-length u8vector-ref u8vector-set!)
@@ -17,28 +18,26 @@
                 (u8vector-length bytevector-length)
                 (u8vector-ref bytevector-u8-ref)
                 (u8vector-set! bytevector-u8-set!)))
-(import numbers)
-
-(include "scheme.base-interface.scm")
 
-(require-library srfi-4)
+(%include "scheme.base-interface.scm")
 
 (begin-for-syntax (require-library r7rs-compile-time))
 (import-for-syntax r7rs-compile-time)
+(import r7rs-compile-time)
+(import numbers)
 
+;;;
+;;; 4.1.7. Inclusion
+;;;
 
-(define-syntax import
-  (er-macro-transformer
-   (lambda (x r c)
-     (##sys#expand-import 
-      (cons (car x)
-	    (map (lambda (spec)
-		   (fixup-import/export-spec (strip-syntax spec) 'import))
-		 (cdr x)))
-      r c
-      ##sys#current-environment ##sys#macro-environment
-      #f #f 'import) ) ) )
-
+(define-syntax include
+  (syntax-rules ()
+    ((_ str)
+     (%include str))
+    ((_ str . rest)
+     (begin
+       (%include str)
+       (include . rest)))))
 
 ;;;
 ;;; 4.2.1. Conditionals
@@ -115,10 +114,12 @@
                     (apply values args))))))))))))))
 
 ;;;
-;;; 5.4. Syntax definitions
+;;; 6.2.6 Numerical operations
 ;;;
-(include "synrules.scm")
 
+(: square (number --> number))
+
+(define (square n) (* n n))
 
 ;;;
 ;;; 6.3 Booleans
@@ -243,19 +244,6 @@
 ;;; 6.6 Characters
 ;;;
 
-(define-syntax define-extended-arity-comparator
-  (syntax-rules ()
-    ((_ name comparator check-type)
-     (define name
-       (let ((cmp comparator))
-         (lambda (o1 o2 . os)
-           (check-type o1 'name)
-           (let lp ((o1 o1) (o2 o2) (os os) (eq #t))
-             (check-type o2 'name)
-             (if (null? os)
-                 (and eq (cmp o1 o2))
-                 (lp o2 (car os) (cdr os) (and eq (cmp o1 o2)))))))))))
-
 (: char=? (char char #!rest char -> boolean))
 (: char<? (char char #!rest char -> boolean))
 (: char>? (char char #!rest char -> boolean))
@@ -452,4 +440,6 @@
 
 (define (eof-object) #!eof)
 
+(define flush-output-port flush-output)
+
 )
diff --git a/scheme.char.scm b/scheme.char.scm
index 3c1db5d..e66e19d 100644
--- a/scheme.char.scm
+++ b/scheme.char.scm
@@ -12,20 +12,7 @@
     %))
 
 (import chicken)
-
-;; Copy-pasta from scheme.base.scm.
-(define-syntax define-extended-arity-comparator
-  (syntax-rules ()
-    ((_ name comparator check-type)
-     (define name
-       (let ((c comparator))
-         (lambda (o1 o2 . os)
-           (check-type o1 'name)
-           (let lp ((o1 o1) (o2 o2) (os os) (eq #t))
-             (check-type o2 'name)
-             (if (null? os)
-                 (and eq (c o1 o2))
-                 (lp o2 (car os) (cdr os) (and eq (c o1 o2)))))))))))
+(require-extension r7rs-compile-time)
 
 (: char-ci=? (char char #!rest char -> boolean))
 (: char-ci<? (char char #!rest char -> boolean))
diff --git a/scheme.eval.scm b/scheme.eval.scm
index c25b0cc..b96a9d7 100644
--- a/scheme.eval.scm
+++ b/scheme.eval.scm
@@ -1,25 +1,33 @@
 (module scheme.eval (eval
 		     environment)
 
-  (import scheme chicken)
-  (use r7rs-compile-time)
+  (import (rename scheme (eval %eval)) chicken)
+  (import r7rs-compile-time)
 
 ;;;
 ;;; 6.12. Environments and evaluation
 ;;;
 
+  (: eval (* (struct environment) -> *))
+
+  (define (eval expr env) (%eval expr env))
+
   (: environment (list -> (struct environment)))
 
   (define (environment . specs)
     (let ((name (gensym "environment-module-")))
       ;; create module...
-      (eval `(module ,name ()
-	       ,@(map (lambda (spec)
-			`(import ,(fixup-import/export-spec spec 'environment)))
-		      specs)))
-      (let ((env (module-environment name)))
+      (%eval `(module ,name ()
+		,@(map (lambda (spec)
+			 `(import ,(fixup-import/export-spec spec 'environment)))
+		       specs)))
+      (let ((mod (##sys#find-module name)))
 	;; ...and remove it right away
-	(set! ##sys#module-table (##sys#delq (assq name ##sys#module-table) ##sys#module-table))
-	env)))
+	(set! ##sys#module-table (##sys#delq mod ##sys#module-table))
+	(##sys#make-structure 'environment
+	 name
+	 (let ((env (##sys#slot mod 13)))
+	   (append (car env) (cdr env))) ; combine env and syntax bindings
+	 #t))))
 
 )
diff --git a/scheme.r5rs.scm b/scheme.r5rs.scm
new file mode 100644
index 0000000..d5b8d8b
--- /dev/null
+++ b/scheme.r5rs.scm
@@ -0,0 +1,43 @@
+(module scheme.r5rs ()
+
+  (import chicken)
+  (import
+   (rename scheme
+	   (null-environment %null-environment)
+	   (scheme-report-environment %scheme-report-environment)))
+
+  (import numbers)
+  (export angle make-polar make-rectangular rationalize)
+
+  (require-extension scheme.eval)
+  (export null-environment scheme-report-environment)
+
+  (reexport
+   (except scheme
+	   null-environment scheme-report-environment eval
+	   and begin begin-for-syntax case cond cond-expand define
+	   define-syntax delay delay-force do else export if lambda let
+	   let* let-syntax letrec letrec* letrec-syntax module or
+	   quasiquote quote reexport require-extension
+	   require-extension-for-syntax require-library set! syntax))
+
+  (define-constant null-environment-identifiers
+    '(and begin case cond cond-expand define define-syntax delay
+      delay-force do if lambda let let* let-syntax letrec letrec*
+      letrec-syntax or quasiquote quote set! syntax-rules))
+
+  (: null-environment (fixnum -> (struct environment)))
+
+  (define (null-environment version)
+    (case version
+      ((7)  (environment `(only (scheme base) ,@null-environment-identifiers)))
+      ((5)  (environment `(only (scheme r5rs) ,@null-environment-identifiers)))
+      (else (%null-environment version))))
+
+  (: scheme-report-environment (fixnum -> (struct environment)))
+
+  (define (scheme-report-environment version)
+    (case version
+      ((7)  (environment '(scheme base)))
+      ((5)  (environment '(scheme r5rs)))
+      (else (%scheme-report-environment version)))))
diff --git a/scheme.write.scm b/scheme.write.scm
new file mode 100644
index 0000000..63cd99a
--- /dev/null
+++ b/scheme.write.scm
@@ -0,0 +1,6 @@
+(module scheme.write (display
+		      write
+		      ; write-shared
+		      write-simple)
+  (import scheme)
+  (define write-simple write))
diff --git a/tests/run.scm b/tests/run.scm
index 6149b47..1032672 100644
--- a/tests/run.scm
+++ b/tests/run.scm
@@ -1,9 +1,19 @@
-(use r7rs test)
+(use r7rs)
 
 ;; XXX: This seems to be necessary in order to get the syntax-rules
 ;; from r7rs rather than the built-in CHICKEN one.  I'm not sure if
 ;; that's correct or not...
-(import-for-syntax r7rs)
+(import-for-syntax (r7rs))
+
+(import (chicken)
+        (test)
+        (ports)
+        (scheme base)
+        (scheme char)
+        (scheme eval)
+        (scheme file)
+        (scheme read)
+        (scheme write))
 
 (define (read-from-string s)
   (with-input-from-string s read))
@@ -304,6 +314,8 @@
     (test-error "arity" (char=? #\a))
     (test-error "type check" (char=? #\a #\a 1))
     (test-error "no shortcutting" (char=? #\a #\b 1))
+    (test #f (char? 1))
+    (test #t (char? #\a))
     (test #t (char=? #\a #\a))
     (test #f (char=? #\a #\b))
     (test #t (char=? #\a #\a #\a))
@@ -326,6 +338,8 @@
     (test-error "arity" (string=? "a"))
     (test-error "type check" (string=? "a" "a" 1))
     (test-error "no shortcutting" (string=? "a" "b" 1))
+    (test #f (string? 1))
+    (test #t (string? "a"))
     (test #t (string=? "a" "a"))
     (test #f (string=? "a" "b"))
     (test #t (string=? "a" "a" "a"))
@@ -762,6 +776,12 @@
          (test "DSSSL keyword arguments aren't renamed (not R7RS)"
                "hello, XXX" (bar who: "XXX")))))
 
+(test-group "define-library"
+  (test-assert "R7RS libraries use the numbers extension"
+               (define-library (foo)
+                 (import (scheme base))
+                 (begin (eq? numbers#+ +)))))
+
 (test-end "r7rs tests")
 
 (test-exit)
Trap