(spar-push spar-arg:ctx)
(spar-subform
(spar-match identifier? spar-arg:form)
- (spar-funcall reserve-identifier spar-arg:form spar-arg:senv)
+ (spar-funcall reserve-keyword spar-arg:form spar-arg:senv)
(spar-push spar-arg:form))
(spar-subform
spar-push-classified
(spar-subform)
(spar-push spar-arg:ctx)
(spar-push-subform-if mit-lambda-list? spar-arg:form)
- (spar-push-body)))))
+ (spar-push-body make-internal-senv)))))
(define $named-lambda
(spar-classifier->runtime
(spar-subform
(spar-push-subform-if identifier? spar-arg:form)
(spar-push-form-if mit-lambda-list? spar-arg:form))
- (spar-push-body)))))
+ (spar-push-body make-internal-senv)))))
(define (assemble-lambda-item ctx name bvl body)
(let ((frame-senv (make-internal-senv (serror-ctx-senv ctx))))
(receive (body-ctx body-items) (body frame-senv)
(body-item body-ctx body-items))))))
-(define (spar-push-body)
+(define (spar-push-body make-senv)
(spar-call-with-values
(lambda (ctx . elts)
(lambda (frame-senv)
- (let ((body-senv (make-internal-senv frame-senv)))
+ (let ((body-senv (make-senv frame-senv)))
(values (serror-ctx (serror-ctx-form ctx)
body-senv
(serror-ctx-hist ctx))
(delay
(spar-call-with-values
(lambda (ctx bindings body)
- (let ((frame-senv (make-internal-senv (serror-ctx-senv ctx))))
+ (let ((frame-senv (make-keyword-internal-senv (serror-ctx-senv ctx))))
(for-each (lambda (binding)
(bind-keyword (car binding) frame-senv (cdr binding)))
bindings)
(spar-subform spar-push-classified)
(spar-match-null)))))
(spar-match-null))
- (spar-push-body))))
+ (spar-push-body make-keyword-internal-senv))))
(define $let-syntax
(spar-classifier->runtime spar-promise:let-syntax))
(delay
(spar-call-with-values
(lambda (ctx bindings body)
- (let ((frame-senv (make-internal-senv (serror-ctx-senv ctx)))
+ (let ((frame-senv
+ (make-keyword-internal-senv (serror-ctx-senv ctx)))
(ids (map car bindings)))
(for-each (lambda (id)
- (reserve-identifier id frame-senv))
+ (reserve-keyword id frame-senv))
ids)
(for-each (lambda (id item)
(bind-keyword id frame-senv item))
(spar-subform spar-push-open-classified)
(spar-match-null)))))
(spar-match-null))
- (spar-push-body)))))
+ (spar-push-body make-keyword-internal-senv)))))
\f
;;;; Pseudo keywords
(syntactic-closure-senv id))
(var-item id)))))
-(define (reserve-identifier identifier senv)
- (guarantee identifier? identifier 'reserve-identifier)
- ((senv-store senv) identifier (reserved-name-item)))
+(define (reserve-keyword identifier senv)
+ (guarantee identifier? identifier 'reserve-keyword)
+ ((senv-store senv) identifier #t (reserved-name-item)))
(define (bind-keyword identifier senv item)
(guarantee identifier? identifier 'bind-keyword)
(guarantee keyword-item? item 'bind-keyword)
- ((senv-store senv) identifier item))
+ ((senv-store senv) identifier #t item))
(define (bind-variable identifier senv)
(guarantee identifier? identifier 'bind-variable)
- (let ((rename ((senv-rename senv) identifier)))
- ((senv-store senv) identifier (var-item rename))
- rename))
+ (let ((rename ((senv-rename senv) identifier)))
+ ((senv-store senv) identifier #f (var-item rename))
+ rename))
(define-record-type <syntactic-environment>
(make-senv get-type get-runtime lookup store rename describe)
(cdr binding)
(runtime-lookup identifier env))))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
(let ((binding (assq identifier bound)))
(if binding
(set-cdr! binding item)
(define (lookup identifier)
(runtime-lookup identifier env))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
(error "Can't bind in non-top-level runtime environment:" identifier item))
(define (rename identifier)
(and (eq? name identifier)
item))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
(error "Can't bind in keyword environment:" identifier item))
(define (rename identifier)
(set! free (cons (cons identifier item) free))
item))))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
(cond ((assq identifier bound)
=> (lambda (binding)
(set-cdr! binding item)))
(make-senv get-type get-runtime lookup store rename describe)))
\f
+;;; Internal keyword syntactic environments represent environments created by
+;;; syntactic scopes, such as let-syntax.
+
+(define (make-keyword-internal-senv parent)
+ (guarantee syntactic-environment? parent 'make-keyword-internal-senv)
+ (let ((bound '())
+ (free '())
+ (get-runtime (senv-get-runtime parent))
+ (rename (senv-rename parent)))
+
+ (define (get-type)
+ 'keyword-internal)
+
+ (define (lookup identifier)
+ (let ((binding
+ (or (assq identifier bound)
+ (assq identifier free))))
+ (if binding
+ (cdr binding)
+ (let ((item ((senv-lookup parent) identifier)))
+ (set! free (cons (cons identifier item) free))
+ item))))
+
+ (define (store identifier keyword? item)
+ (if keyword?
+ (cond ((assq identifier bound)
+ => (lambda (binding)
+ (set-cdr! binding item)))
+ ((assq identifier free)
+ (error "Can't define name; already free:" identifier))
+ (else
+ (set! bound (cons (cons identifier item) bound))
+ unspecific))
+ ((senv-store parent) identifier keyword? item)))
+
+ (define (describe)
+ `((bound ,bound)
+ (free ,free)
+ (parent ,parent)))
+
+ (make-senv get-type get-runtime lookup store rename describe)))
+\f
;;; Partial syntactic environments are used to implement syntactic
;;; closures that have free names.
(define (lookup identifier)
((senv-lookup (select-env identifier)) identifier))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
;; **** Shouldn't this be a syntax error? It can happen as the
;; result of a misplaced definition. ****
(error "Can't bind identifier in partial syntactic environment:"
(set! free (cons (cons identifier item) free))
item))))
- (define (store identifier item)
+ (define (store identifier keyword? item)
+ (declare (ignore keyword?))
(cond ((assq identifier bound)
=> (lambda (binding)
(set-cdr! binding item)))