Change compile-item/expression to be a predicate dispatcher.
authorChris Hanson <org/chris-hanson/cph>
Fri, 26 Jan 2018 07:14:31 +0000 (23:14 -0800)
committerChris Hanson <org/chris-hanson/cph>
Fri, 26 Jan 2018 07:14:31 +0000 (23:14 -0800)
Also, a bunch of small changes, mostly cleanups and simplification.

src/runtime/make.scm
src/runtime/mit-syntax.scm
src/runtime/runtime.pkg
src/runtime/syntax-classify.scm
src/runtime/syntax-compile.scm
src/runtime/syntax-environment.scm
src/runtime/syntax-items.scm
src/runtime/syntax-output.scm
src/runtime/syntax.scm

index 16fc336ba1669f042d22df1b0b6810bd428b2ced..00b04a266e0c800ca904def75df680d49d555638 100644 (file)
@@ -530,6 +530,7 @@ USA.
    (RUNTIME UNSYNTAXER)
    (RUNTIME PRETTY-PRINTER)
    (RUNTIME EXTENDED-SCODE-EVAL)
+   (runtime syntax compile)
    (RUNTIME SYNTAX DEFINITIONS)
    (runtime syntax rename)
    ;; REP Loops
index ba8b33b2e6388eee712c0514380959c9000d278d..519a2b2a5917394fe8e866c57803a3a27efc3b34 100644 (file)
@@ -86,8 +86,7 @@ USA.
               (classify/body body environment))))))
 
 (define (compile-body-item item)
-  (receive (declaration-items items)
-      (extract-declarations-from-body (body-item/components item))
+  (receive (declaration-items items) (extract-declarations-from-body item)
     (output/body (map declaration-item/text declaration-items)
                 (compile-body-items items))))
 
@@ -256,7 +255,7 @@ USA.
      (make-access-item (cadr form)
                       (classify/expression (caddr form) environment)))))
 
-(define-item-compiler <access-item>
+(define-item-compiler access-item?
   (lambda (item)
     (output/access-reference
      (access-item/name item)
index 96a2a3ded74c7b9b37899be739a26e217443935b..0faf0a036fdf1f6d940bb0e109935eb5f94233c8 100644 (file)
@@ -4384,7 +4384,6 @@ USA.
   (files "syntax")
   (parent (runtime syntax))
   (export ()
-         <syntactic-closure>
          capture-syntactic-environment
          close-syntax
          identifier->symbol
@@ -4412,20 +4411,11 @@ USA.
   (files "syntax-items")
   (parent (runtime syntax))
   (export (runtime syntax)
-         <binding-item>
-         <body-item>
-         <classifier-item>
-         <compiler-item>
-         <declaration-item>
-         <expander-item>
-         <expression-item>
-         <keyword-value-item>
-         <reserved-name-item>
-         <variable-item>
          binding-item/name
          binding-item/value
          binding-item?
          body-item/components
+         body-item?
          classifier-item/classifier
          classifier-item?
          compiler-item/compiler
@@ -4435,6 +4425,8 @@ USA.
          expander-item/expander
          expander-item?
          expression-item/compiler
+         expression-item?
+         extract-declarations-from-body
          flatten-body-items
          item->list
          keyword-item?
@@ -4490,8 +4482,7 @@ USA.
   (export (runtime syntax)
          classify/body
          classify/expression
-         classify/form
-         extract-declarations-from-body))
+         classify/form))
 
 (define-package (runtime syntax compile)
   (files "syntax-compile")
@@ -4500,7 +4491,6 @@ USA.
          compile-body-item/top-level
          compile-body-items
          compile-item/expression
-         compile-item/expression
          define-item-compiler))
 
 (define-package (runtime syntax rename)
index 2705307b48d66739ad6dfc1b52d91e40f6e0bd37..47204699e36b19badbf08fd79581c1cac443143e 100644 (file)
@@ -38,18 +38,16 @@ USA.
                 (let ((name (identifier->symbol form)))
                   (lambda ()
                     (output/combination
-                     (output/runtime-reference 'SYNTACTIC-KEYWORD->ITEM)
+                     (output/runtime-reference 'syntactic-keyword->item)
                      (list (output/constant name)
                            (output/the-environment)))))))
               item)))
        ((syntactic-closure? form)
-        (let ((form (syntactic-closure-form form))
-              (free-names (syntactic-closure-free form))
-              (closing-env (syntactic-closure-senv form)))
-          (classify/form form
-                         (make-partial-syntactic-environment free-names
-                                                             environment
-                                                             closing-env))))
+        (classify/form
+         (syntactic-closure-form form)
+         (make-partial-syntactic-environment (syntactic-closure-free form)
+                                             environment
+                                             (syntactic-closure-senv form))))
        ((pair? form)
         (let ((item
                (strip-keyword-value-item
@@ -81,7 +79,7 @@ USA.
   (if (keyword-value-item? item)
       (keyword-value-item/item item)
       item))
-\f
+
 (define (classify/expression expression environment)
   (classify/form expression environment))
 
@@ -99,16 +97,4 @@ USA.
         (loop (cdr forms)
               (reverse* (item->list (classify/form (car forms) environment))
                         body-items))
-        (reverse! body-items)))))
-
-(define (extract-declarations-from-body items)
-  (let loop ((items items) (declarations '()) (items* '()))
-    (if (pair? items)
-       (if (declaration-item? (car items))
-           (loop (cdr items)
-                 (cons (car items) declarations)
-                 items*)
-           (loop (cdr items)
-                 declarations
-                 (cons (car items) items*)))
-       (values (reverse! declarations) (reverse! items*)))))
\ No newline at end of file
+        (reverse! body-items)))))
\ No newline at end of file
index e76cc72b254a68e1e684a38855923a098bc6f2ef..4b3cf490832576b4256f483f6cc2cfdc4c528e20 100644 (file)
@@ -43,7 +43,7 @@ USA.
 
 (define (compile-body-item/top-level body-item)
   (receive (declaration-items body-items)
-      (extract-declarations-from-body (body-item/components body-item))
+      (extract-declarations-from-body body-item)
     (output/top-level-sequence (map declaration-item/text declaration-items)
                               (map compile-item/top-level body-items))))
 
@@ -63,55 +63,45 @@ USA.
            (list (compile-item/expression item))))
       items))))
 
-(define (compile-item/expression item)
-  (let ((compiler (get-item-compiler item)))
-    (if (not compiler)
-       (error:bad-range-argument item 'COMPILE-ITEM/EXPRESSION))
-    (compiler item)))
-
-(define (get-item-compiler item)
-  (let ((entry (assq (record-type-descriptor item) item-compilers)))
-    (and entry
-        (cdr entry))))
-
-(define (define-item-compiler rtd compiler)
-  (let ((entry (assq rtd item-compilers)))
-    (if entry
-       (set-cdr! entry compiler)
-       (begin
-         (set! item-compilers (cons (cons rtd compiler) item-compilers))
-         unspecific))))
-
-(define item-compilers '())
-\f
-(define (illegal-expression-compiler description)
-  (lambda (item)
-    (syntax-error (string description " may not be used as an expression:")
-                 item)))
-
-(define-item-compiler <reserved-name-item>
-  (illegal-expression-compiler "Reserved name"))
-
-(let ((compiler (illegal-expression-compiler "Syntactic keyword")))
-  (define-item-compiler <classifier-item> compiler)
-  (define-item-compiler <compiler-item> compiler)
-  (define-item-compiler <expander-item> compiler)
-  (define-item-compiler <keyword-value-item> compiler))
-
-(define-item-compiler <variable-item>
+(define compile-item/expression)
+(add-boot-init!
+ (lambda ()
+   (set! compile-item/expression
+        (standard-predicate-dispatcher 'compile-item/expression 1))
+   (run-deferred-boot-actions 'define-item-compiler)))
+
+(define (define-item-compiler predicate compiler)
+  (defer-boot-action 'define-item-compiler
+    (lambda ()
+      (define-predicate-dispatch-handler compile-item/expression
+       (list predicate)
+       compiler))))
+
+(define-item-compiler variable-item?
   (lambda (item)
     (output/variable (variable-item/name item))))
 
-(define-item-compiler <expression-item>
+(define-item-compiler expression-item?
   (lambda (item)
     ((expression-item/compiler item))))
 
-(define-item-compiler <body-item>
+(define-item-compiler body-item?
   (lambda (item)
     (compile-body-items (body-item/components item))))
 
-(define-item-compiler <declaration-item>
+(define (illegal-expression-compiler description)
+  (lambda (item)
+    (syntax-error (string description " may not be used as an expression:")
+                 item)))
+
+(define-item-compiler reserved-name-item?
+  (illegal-expression-compiler "Reserved name"))
+
+(define-item-compiler keyword-item?
+  (illegal-expression-compiler "Syntactic keyword"))
+
+(define-item-compiler declaration-item?
   (illegal-expression-compiler "Declaration"))
 
-(define-item-compiler <binding-item>
+(define-item-compiler binding-item?
   (illegal-expression-compiler "Definition"))
\ No newline at end of file
index 89b63ef0b35975e9b032acb4ed65585247e750fd..a34eaa53ac1372797bc9e98ccacbf0b05813c90e 100644 (file)
@@ -71,6 +71,30 @@ USA.
   (cond ((syntactic-environment? object) object)
        ((environment? object) (%make-runtime-syntactic-environment object))
        (else (error "Unable to convert to a syntactic environment:" object))))
+
+;;; Runtime syntactic environments are wrappers around runtime environments.
+;;; They maintain their own bindings, but can defer lookups of syntactic
+;;; keywords to the given runtime environment.
+
+(define (%make-runtime-syntactic-environment env)
+
+  (define (get-type)
+    (if (interpreter-environment? env) 'runtime-top-level 'runtime))
+
+  (define (get-runtime)
+    env)
+
+  (define (lookup identifier)
+    (and (symbol? identifier)
+        (environment-lookup-macro env identifier)))
+
+  (define (store identifier item)
+    (environment-define-macro env identifier item))
+
+  (define (rename identifier)
+    (rename-top-level-identifier identifier))
+
+  (make-senv get-type get-runtime lookup store rename))
 \f
 ;;; Null environments are used only for synthetic identifiers.
 
@@ -93,7 +117,7 @@ USA.
       (error "Can't rename in null environment:" identifier))
 
     (make-senv get-type get-runtime lookup store rename)))
-
+\f
 ;;; Keyword environments are used to make keywords that represent items.
 
 (define (make-keyword-syntactic-environment name item)
@@ -114,30 +138,8 @@ USA.
   (define (rename identifier)
     (error "Can't rename in keyword environment:" identifier))
 
-  (make-senv get-type get-runtime lookup store rename))
-\f
-;;; Runtime syntactic environments are wrappers around runtime environments.
-;;; They maintain their own bindings, but can defer lookups of syntactic
-;;; keywords to the given runtime environment.
-
-(define (%make-runtime-syntactic-environment env)
-
-  (define (get-type)
-    (if (interpreter-environment? env) 'runtime-top-level 'runtime))
-
-  (define (get-runtime)
-    env)
-
-  (define (lookup identifier)
-    (and (symbol? identifier)
-        (environment-lookup-macro env identifier)))
-
-  (define (store identifier item)
-    (environment-define-macro env identifier item))
-
-  (define (rename identifier)
-    (rename-top-level-identifier identifier))
-
+  (guarantee identifier? name 'make-keyword-environment)
+  (guarantee keyword-item? item 'make-keyword-environment)
   (make-senv get-type get-runtime lookup store rename))
 
 ;;; Top-level syntactic environments represent top-level environments.
index 83b9ff7b519c036a46ab5b5ffc1be1eaaf4b293b..20648205fb8211d56aac179185650fb4a2a4543b 100644 (file)
@@ -28,16 +28,7 @@ USA.
 
 (declare (usual-integrations))
 \f
-;;; Reserved name items do not represent any form, but instead are
-;;; used to reserve a particular name in a syntactic environment.  If
-;;; the classifier refers to a reserved name, a syntax error is
-;;; signalled.  This is used in the implementation of LETREC-SYNTAX
-;;; to signal a meaningful error when one of the <init>s refers to
-;;; one of the names being bound.
-
-(define-record-type <reserved-name-item>
-    (make-reserved-name-item)
-    reserved-name-item?)
+;;; These items can be stored in a syntactic environment.
 
 ;;; Keyword items represent macro keywords.  There are several flavors
 ;;; of keyword item.
@@ -63,31 +54,71 @@ USA.
   (item keyword-value-item/item)
   (expression keyword-value-item/expression))
 
-(define (keyword-item? item)
-  (or (classifier-item? item)
-      (compiler-item? item)
-      (expander-item? item)
-      (keyword-value-item? item)))
+(define (keyword-item? object)
+  (or (classifier-item? object)
+      (compiler-item? object)
+      (expander-item? object)
+      (keyword-value-item? object)))
+
+(register-predicate! keyword-item? 'keyword-item)
+(set-predicate<=! classifier-item? keyword-item?)
+(set-predicate<=! compiler-item? keyword-item?)
+(set-predicate<=! expander-item? keyword-item?)
+(set-predicate<=! keyword-value-item? keyword-item?)
 
 ;;; Variable items represent run-time variables.
 
+(define (make-variable-item name)
+  (guarantee identifier? name 'make-variable-item)
+  (%make-variable-item name))
+
 (define-record-type <variable-item>
-    (make-variable-item name)
+    (%make-variable-item name)
     variable-item?
   (name variable-item/name))
 
 (define-unparser-method variable-item?
-  (simple-unparser-method 'variable-item?
+  (simple-unparser-method 'variable-item
     (lambda (item)
       (list (variable-item/name item)))))
+
+;;; Reserved name items do not represent any form, but instead are
+;;; used to reserve a particular name in a syntactic environment.  If
+;;; the classifier refers to a reserved name, a syntax error is
+;;; signalled.  This is used in the implementation of LETREC-SYNTAX
+;;; to signal a meaningful error when one of the <init>s refers to
+;;; one of the names being bound.
+
+(define-record-type <reserved-name-item>
+    (make-reserved-name-item)
+    reserved-name-item?)
 \f
-;;; Expression items represent any kind of expression other than a
-;;; run-time variable or a sequence.
+;;; These items can't be stored in a syntactic environment.
 
-(define-record-type <expression-item>
-    (make-expression-item compiler)
-    expression-item?
-  (compiler expression-item/compiler))
+;;; Binding items represent definitions, whether top-level or internal, keyword
+;;; or variable.
+
+(define (make-binding-item name value)
+  (guarantee identifier? name 'make-binding-item)
+  (guarantee binding-item-value? value 'make-binding-item)
+  (%make-binding-item name value))
+
+(define (binding-item-value? object)
+  (not (or (reserved-name-item? object)
+          (declaration-item? object))))
+(register-predicate! binding-item-value? 'binding-item-value)
+
+(define-record-type <binding-item>
+    (%make-binding-item name value)
+    binding-item?
+  (name binding-item/name)
+  (value binding-item/value))
+
+(define-unparser-method binding-item?
+  (simple-unparser-method 'binding-item
+    (lambda (item)
+      (list (binding-item/name item)
+           (binding-item/value item)))))
 
 ;;; Body items represent sequences (e.g. BEGIN).
 
@@ -96,6 +127,9 @@ USA.
     body-item?
   (components body-item/components))
 
+(define (extract-declarations-from-body body-item)
+  (partition declaration-item? (body-item/components body-item)))
+
 (define (flatten-body-items items)
   (append-map item->list items))
 
@@ -104,6 +138,14 @@ USA.
       (flatten-body-items (body-item/components item))
       (list item)))
 
+;;; Expression items represent any kind of expression other than a
+;;; run-time variable or a sequence.
+
+(define-record-type <expression-item>
+    (make-expression-item compiler)
+    expression-item?
+  (compiler expression-item/compiler))
+
 ;;; Declaration items represent block-scoped declarations that are to
 ;;; be passed through to the compiler.
 
@@ -113,13 +155,4 @@ USA.
   (get-text declaration-item/get-text))
 
 (define (declaration-item/text item)
-  ((declaration-item/get-text item)))
-
-;;; Binding items represent definitions, whether top-level or internal, keyword
-;;; or variable.
-
-(define-record-type <binding-item>
-    (make-binding-item name value)
-    binding-item?
-  (name binding-item/name)
-  (value binding-item/value))
\ No newline at end of file
+  ((declaration-item/get-text item)))
\ No newline at end of file
index 0cf48c549eff68fb66de0756bb0195e168e35466..261bf8053f396696db42df78783dca8374f8f376 100644 (file)
@@ -24,7 +24,7 @@ USA.
 
 |#
 
-;;;; Syntaxer Output Interface
+;;;; Syntaxer output interface
 ;;; package: (runtime syntax output)
 
 (declare (usual-integrations))
@@ -90,10 +90,12 @@ USA.
   (output/combination (output/named-lambda lambda-tag:let names body) values))
 
 (define (output/letrec names values body)
-  (let ((temps (map (lambda (name)
-                     (string->uninterned-symbol
-                      (string-append (symbol->string (identifier->symbol name))
-                                     "-value"))) names)))
+  (let ((temps
+        (map (lambda (name)
+               (string->uninterned-symbol
+                (string-append (symbol->string (identifier->symbol name))
+                               "-value")))
+             names)))
     (output/let
      names (map (lambda (name) name (output/unassigned)) names)
      (make-scode-sequence
index dbe842c296de9b5ef9d5554c9a992a94a7b066fe..41228ab4589c8136f8964a825fd712fb7bbf1a43 100644 (file)
@@ -66,6 +66,25 @@ USA.
 \f
 ;;;; Syntactic closures
 
+(define (close-syntax form senv)
+  (make-syntactic-closure senv '() form))
+
+(define (make-syntactic-closure senv free form)
+  (let ((senv (->syntactic-environment senv 'make-syntactic-closure)))
+    (guarantee-list-of identifier? free 'make-syntactic-closure)
+    (if (or (memq form free)   ;LOOKUP-IDENTIFIER assumes this.
+           (constant-form? form)
+           (and (syntactic-closure? form)
+                (null? (syntactic-closure-free form))
+                (not (identifier? (syntactic-closure-form form)))))
+       form
+       (%make-syntactic-closure senv free form))))
+
+(define (constant-form? form)
+  (not (or (syntactic-closure? form)
+          (pair? form)
+          (identifier? form))))
+
 (define-record-type <syntactic-closure>
     (%make-syntactic-closure senv free form)
     syntactic-closure?
@@ -73,20 +92,6 @@ USA.
   (free syntactic-closure-free)
   (form syntactic-closure-form))
 
-(define (make-syntactic-closure environment free-names form)
-  (let ((senv (->syntactic-environment environment 'MAKE-SYNTACTIC-CLOSURE)))
-    (guarantee-list-of-type free-names identifier?
-                           "list of identifiers" 'MAKE-SYNTACTIC-CLOSURE)
-    (if (or (memq form free-names)     ;LOOKUP-IDENTIFIER assumes this.
-           (and (syntactic-closure? form)
-                (null? (syntactic-closure-free form))
-                (not (identifier? (syntactic-closure-form form))))
-           (not (or (syntactic-closure? form)
-                    (pair? form)
-                    (symbol? form))))
-       form
-       (%make-syntactic-closure senv free-names form))))
-
 (define (strip-syntactic-closures object)
   (if (let loop ((object object))
        (if (pair? object)
@@ -101,9 +106,6 @@ USA.
                (loop (syntactic-closure-form object))
                object)))
       object))
-
-(define (close-syntax form environment)
-  (make-syntactic-closure environment '() form))
 \f
 ;;;; Identifiers
 
@@ -112,6 +114,7 @@ USA.
           ;; This makes `:keyword' objects be self-evaluating.
           (not (keyword? object)))
       (synthetic-identifier? object)))
+(register-predicate! identifier? 'identifier)
 
 (define (synthetic-identifier? object)
   (and (syntactic-closure? object)
@@ -126,7 +129,7 @@ USA.
            (loop (syntactic-closure-form identifier))
            (and (symbol? identifier)
                 identifier)))
-      (error:not-a identifier? identifier 'IDENTIFIER->SYMBOL)))
+      (error:not-a identifier? identifier 'identifier->symbol)))
 
 (define (identifier=? environment-1 identifier-1 environment-2 identifier-2)
   (let ((item-1 (lookup-identifier identifier-1 environment-1))
@@ -154,7 +157,7 @@ USA.
           (lookup-identifier (syntactic-closure-form identifier)
                              (syntactic-closure-senv identifier)))
          (else
-          (error:not-a identifier? identifier 'LOOKUP-IDENTIFIER)))))
+          (error:not-a identifier? identifier 'lookup-identifier)))))
 \f
 ;;;; Utilities