Also, a bunch of small changes, mostly cleanups and simplification.
(RUNTIME UNSYNTAXER)
(RUNTIME PRETTY-PRINTER)
(RUNTIME EXTENDED-SCODE-EVAL)
+ (runtime syntax compile)
(RUNTIME SYNTAX DEFINITIONS)
(runtime syntax rename)
;; REP Loops
(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))))
(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)
(files "syntax")
(parent (runtime syntax))
(export ()
- <syntactic-closure>
capture-syntactic-environment
close-syntax
identifier->symbol
(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
expander-item/expander
expander-item?
expression-item/compiler
+ expression-item?
+ extract-declarations-from-body
flatten-body-items
item->list
keyword-item?
(export (runtime syntax)
classify/body
classify/expression
- classify/form
- extract-declarations-from-body))
+ classify/form))
(define-package (runtime syntax compile)
(files "syntax-compile")
compile-body-item/top-level
compile-body-items
compile-item/expression
- compile-item/expression
define-item-compiler))
(define-package (runtime syntax rename)
(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
(if (keyword-value-item? item)
(keyword-value-item/item item)
item))
-\f
+
(define (classify/expression expression environment)
(classify/form expression environment))
(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
(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))))
(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
(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.
(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)
(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.
(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.
(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).
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))
(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.
(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
|#
-;;;; Syntaxer Output Interface
+;;;; Syntaxer output interface
;;; package: (runtime syntax output)
(declare (usual-integrations))
(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
\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?
(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)
(loop (syntactic-closure-form object))
object)))
object))
-
-(define (close-syntax form environment)
- (make-syntactic-closure environment '() form))
\f
;;;; Identifiers
;; 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)
(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))
(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