Another rewrite, this time to treat programs as anonymous libraries.
authorChris Hanson <org/chris-hanson/cph>
Sat, 6 Oct 2018 23:28:42 +0000 (16:28 -0700)
committerChris Hanson <org/chris-hanson/cph>
Sat, 6 Oct 2018 23:28:42 +0000 (16:28 -0700)
This change simplifies handling programs since they can now use the machinery
developed for libraries.  So now r7rs-source is just a combination of some
libraries and an optional program.

Also added property 'imports-environment to get the environment prior to
evaluation.

src/runtime/library-database.scm
src/runtime/library-loader.scm
src/runtime/library-parser.scm
src/runtime/runtime.pkg
tests/check.scm
tests/runtime/test-library-data/support-code.scm
tests/runtime/test-library-loader.scm [new file with mode: 0644]
tests/runtime/test-library-parser.scm

index 241b585f897d17daff5f33d40e5ecbaf61a7c0cd..2b43e94041346cc4ce4082000df0ce1e5eeb823f 100644 (file)
@@ -42,11 +42,13 @@ USA.
       (if (and (library 'has? 'db)
               (not (eq? (library 'get 'db) this)))
          (error "Can't use library in multiple databases:" library))
+      (library 'put! 'db this)
       (let ((name (library 'get 'name)))
-       (if (has? name)
-           (warn "Overwriting library:" name))
-       (library 'put! 'db this)
-       (hash-table-set! table name library)))
+       (if name
+           (begin
+             (if (has? name)
+                 (warn "Overwriting library:" name))
+             (hash-table-set! table name library)))))
 
     (define (get-names)
       (hash-table-keys table))
@@ -75,6 +77,8 @@ USA.
   (make-library-db 'host))
 \f
 (define (make-library name . keylist)
+  (if name
+      (guarantee library-name? name 'make-library))
   (let ((alist
         (cons* 'library
                (cons 'name name)
@@ -93,7 +97,7 @@ USA.
            (cdr p)
            (let ((auto (automatic-property key)))
              (if (not auto)
-                 (error "Unknown library property:" key))
+                 (error "Unknown property:" key))
              (if (not (auto-runnable? auto this))
                  (error "Auto property not ready:" auto))
              (let ((value (run-auto auto this)))
@@ -102,11 +106,11 @@ USA.
 
     (define (put! key value)
       (if (automatic-property? key)
-         (error "Can't overwrite automatic property:" key))
+         (warn "Overwriting automatic property:" key))
       (let ((p (assq key (cdr alist))))
        (if p
            (begin
-             (warn "Overwriting library property:" key name)
+             (warn "Overwriting property:" key)
              (set-cdr! p value))
            (set-cdr! alist (cons (cons key value) (cdr alist))))))
 
@@ -122,7 +126,9 @@ USA.
       (set-cdr! alist (del-assq! key (cdr alist))))
 
     (define (summarize-self)
-      (list name))
+      (if name
+         (list name)
+         '()))
 
     (define (describe-self)
       (map (lambda (p)
@@ -282,11 +288,13 @@ USA.
   (lambda (library)
     (library 'get key)))
 
+(define library-contents (library-accessor 'contents))
 (define library-environment (library-accessor 'environment))
 (define library-exporter (library-accessor 'exporter))
 (define library-exports (library-accessor 'exports))
 (define library-filename (library-accessor 'filename))
 (define library-imports (library-accessor 'imports))
+(define library-imports-environment (library-accessor 'imports-environment))
 (define library-name (library-accessor 'name))
 (define library-parsed-contents (library-accessor 'parsed-contents))
 (define library-parsed-imports (library-accessor 'parsed-imports))
index d28a7e83e3aba86fb530a48c0de07dd018e59358..19413bdd09bc0ae6bc40f8b86f69e29cc6f3d707 100644 (file)
@@ -41,13 +41,12 @@ USA.
                (exports ,(map library-export->list exports))))
      (make-scode-quotation contents))))
 
-(define-automatic-property 'evaluable-contents
-    '(parsed-contents imports exports db)
+(define-automatic-property 'contents
+    '(parsed-contents imports exports imports-environment)
   #f
-  (lambda (contents imports exports db)
+  (lambda (contents imports exports env)
     (receive (body bound free)
-       (syntax-library-forms (expand-contents contents)
-                             (imports->environment imports db))
+       (syntax-library-forms (expand-contents contents) env)
       (let ((exports-from (map library-export-from exports)))
        (if (not (lset<= eq? exports-from (lset-union eq? bound free)))
            (warn "Library export refers to unbound identifiers:"
@@ -117,14 +116,15 @@ USA.
              imports)
     env))
 
-(define-automatic-property 'environment '(imports evaluable-contents db)
-  (lambda (imports contents db)
-    (declare (ignore contents))
-    (import-environments-available? imports db))
-  (lambda (imports contents db)
-    (let ((env (make-environment-from-imports imports db)))
-      (scode-eval contents env)
-      env)))
+(define-automatic-property 'imports-environment '(imports db)
+  import-environments-available?
+  make-environment-from-imports)
+
+(define-automatic-property 'environment '(imports-environment contents)
+  #f
+  (lambda (env contents)
+    (scode-eval contents env)
+    env))
 
 (define (environment . import-sets)
   (let ((parsed (map parse-import-set import-sets)))
index abe35169489f2e1e63edc05c81d4249b5073ed4e..6a6a7cef0062d7e41cc85710ccc5d90b39b277a2 100644 (file)
@@ -41,7 +41,7 @@ USA.
        (define (read-libs libs)
          (let ((form (read port)))
            (cond ((eof-object? form)
-                  (done (reverse libs) '() #f))
+                  (make-r7rs-source (reverse libs) #f))
                  ((r7rs-library? form)
                   (read-libs
                    (cons (parse-define-library-form form pathname)
@@ -60,19 +60,22 @@ USA.
                (error "Can't mix libraries and imports:" form))
            (if (r7rs-import? form)
                (read-imports (cons (parse-import-form form) imports) libs)
-               (done libs
-                     (append-map cdr (reverse imports))
-                     (read-body (list form))))))
+               (make-r7rs-source
+                libs
+                ;; A program is simply an anonymous library.
+                (make-library #f
+                              'parsed-imports (append-map cdr
+                                                          (reverse imports))
+                              'exports '()
+                              'parsed-contents (read-body (list form))
+                              'filename (->namestring pathname))))))
 
        (define (read-body forms)
          (let ((form (read port)))
            (if (eof-object? form)
-               (reverse forms)
+               `((begin ,@(reverse forms)))
                (read-body (cons form forms)))))
 
-       (define (done libs imports body)
-         (make-r7rs-source libs imports body (->namestring pathname)))
-
        (read-libs '())))))
 
 (define (r7rs-library? object)
@@ -84,17 +87,17 @@ USA.
        (eq? 'import (car object))))
 
 (define-record-type <r7rs-source>
-    (make-r7rs-source parsed-libraries imports body filename)
+    (make-r7rs-source libraries program)
     r7rs-source?
-  (parsed-libraries r7rs-source-parsed-libraries)
-  (imports r7rs-source-imports)
-  (body r7rs-source-body)
-  (filename r7rs-source-filename))
-
-(define-print-method r7rs-source?
-  (standard-print-method 'r7rs-source
-    (lambda (source)
-      (list (r7rs-source-filename source)))))
+  (libraries r7rs-source-libraries)
+  (program r7rs-source-program))
+
+(define (register-r7rs-source! source db)
+  (register-libraries! (r7rs-source-libraries source) db)
+  (let ((program (r7rs-source-program source)))
+    (if program
+       (register-library! program db))
+    program))
 \f
 (define (parse-define-library-form form #!optional pathname)
   (let ((directory
index 8b541309a2172e342887536fcd378885ec244256..16bc6ec0c07a17710741beb6b761773e080f8990 100644 (file)
@@ -5839,6 +5839,7 @@ USA.
   (export (runtime library)
          define-automatic-property
          host-library-db
+         library-contents
          library-db?
          library-environment
          library-exporter
@@ -5857,6 +5858,7 @@ USA.
          library-import=?
          library-import?
          library-imports
+         library-imports-environment
          library-name
          library-parsed-contents
          library-parsed-imports
@@ -5884,14 +5886,11 @@ USA.
          parse-define-library-form
          parse-import-form
          parse-import-set
-         r7rs-source-body
-         r7rs-source-filename
-         r7rs-source-imports
-         r7rs-source-parsed-libraries
+         r7rs-source-program
+         r7rs-source-libraries
          r7rs-source?
-         read-r7rs-source)
-  (export (runtime load)
-         read-r7rs-source))
+         read-r7rs-source
+         register-r7rs-source!))
 
 (define-package (runtime library standard)
   (files "library-standard")
index ed766d51f0ef86b371175df512297dc42bc68280..4bc61a656fe75f19a3a2eeaf2becc65054286264 100644 (file)
@@ -66,6 +66,7 @@ USA.
     ("runtime/test-library-parser" (runtime library))
     ("runtime/test-library-standard" (runtime library))
     ("runtime/test-library-imports" (runtime library))
+    ("runtime/test-library-loader" (runtime library))
     "runtime/test-md5"
     "runtime/test-mime-codec"
     ("runtime/test-parametric-predicate" (runtime parametric-predicate))
index d0db663fe8588440e0c08eb16a7cb49be194e202..c647bafb1bed953658283ea2852a546f71435df7 100644 (file)
@@ -116,8 +116,7 @@ USA.
      ,@ex1-contents))
 
 (define (read-dependencies)
-  (r7rs-source-parsed-libraries
-   (read-r7rs-source dependencies-filename)))
+  (r7rs-source-libraries (read-r7rs-source dependencies-filename)))
 
 (define dependencies-filename
   (->namestring
diff --git a/tests/runtime/test-library-loader.scm b/tests/runtime/test-library-loader.scm
new file mode 100644 (file)
index 0000000..19a285a
--- /dev/null
@@ -0,0 +1,52 @@
+#| -*-Scheme-*-
+
+Copyright (C) 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993, 1994,
+    1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
+    2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016,
+    2017, 2018 Massachusetts Institute of Technology
+
+This file is part of MIT/GNU Scheme.
+
+MIT/GNU Scheme is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation; either version 2 of the License, or (at
+your option) any later version.
+
+MIT/GNU Scheme is distributed in the hope that it will be useful, but
+WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with MIT/GNU Scheme; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301,
+USA.
+
+|#
+
+;;;; Tests for library loader
+
+(declare (usual-integrations))
+\f
+(include "test-library-data/support-code.scm")
+
+(define-test 'read-r7rs-source:r7rs-example
+  (lambda ()
+    (let ((source (read-r7rs-source r7rs-example-filename))
+         (db (make-library-db 'test)))
+      (add-standard-libraries! db)
+      (let ((program (register-r7rs-source! source db)))
+       (assert-equal (unsyntax (library-contents program))
+                     '(begin
+                        (define grid (make-grid 24 24))
+                        (grid-set! grid 1 1 #t)
+                        (grid-set! grid 2 2 #t)
+                        (grid-set! grid 3 0 #t)
+                        (grid-set! grid 3 1 #t)
+                        (grid-set! grid 3 2 #t)
+                        (life grid 80)))
+       (let ((env (library-imports-environment program)))
+         (assert-lset= eq?
+                       (environment-bound-names env)
+                       (map library-import-to
+                            (library-imports program))))))))
\ No newline at end of file
index 6b94af3ff4264cda52dbdd3e6a929d50b156f2ef..3f7d5b94ef5b7c6599b21a6aa986f832dbc04c88 100644 (file)
@@ -82,7 +82,7 @@ USA.
 (define-test 'read-r7rs-source:dependencies
   (lambda ()
     (let ((source (read-r7rs-source dependencies-filename)))
-      (let ((libraries (r7rs-source-parsed-libraries source)))
+      (let ((libraries (r7rs-source-libraries source)))
        (assert-true (list? libraries))
        (assert-= (length libraries) 4)
        (assert-list= equal?
@@ -91,33 +91,32 @@ USA.
                        (foo bletch)
                        (foo grumble)
                        (foo quux))))
-      (assert-null (r7rs-source-imports source))
-      (assert-false (r7rs-source-body source))
-      (assert-string= (r7rs-source-filename source)
-                     dependencies-filename))))
+      (assert-false (r7rs-source-program source)))))
 
 (define-test 'read-r7rs-source:r7rs-example
   (lambda ()
     (let ((source (read-r7rs-source r7rs-example-filename)))
-      (let ((libraries (r7rs-source-parsed-libraries source)))
+      (let ((libraries (r7rs-source-libraries source)))
        (assert-true (list? libraries))
        (assert-= (length libraries) 2)
        (assert-list= equal?
                      (map library-name libraries)
                      '((example grid)
                        (example life))))
-      (assert-equal (r7rs-source-imports source)
-                   '((library (scheme base))
-                     (only (library (example life)) life)
-                     (rename (prefix (library (example grid)) grid-)
-                             (grid-make . make-grid))))
-      (assert-equal (r7rs-source-body source)
-                   '((define grid (make-grid 24 24))
-                     (grid-set! grid 1 1 #t)
-                     (grid-set! grid 2 2 #t)
-                     (grid-set! grid 3 0 #t)
-                     (grid-set! grid 3 1 #t)
-                     (grid-set! grid 3 2 #t)
-                     (life grid 80)))
-      (assert-string= (r7rs-source-filename source)
-                     r7rs-example-filename))))
\ No newline at end of file
+      (let ((program (r7rs-source-program source)))
+       (assert-equal (library-parsed-imports program)
+                     '((library (scheme base))
+                       (only (library (example life)) life)
+                       (rename (prefix (library (example grid)) grid-)
+                               (grid-make . make-grid))))
+       (assert-equal (library-parsed-contents program)
+                     '((begin
+                         (define grid (make-grid 24 24))
+                         (grid-set! grid 1 1 #t)
+                         (grid-set! grid 2 2 #t)
+                         (grid-set! grid 3 0 #t)
+                         (grid-set! grid 3 1 #t)
+                         (grid-set! grid 3 2 #t)
+                         (life grid 80))))
+       (assert-string= (library-filename program)
+                       r7rs-example-filename)))))
\ No newline at end of file