diff --git a/module/ice-9/psyntax.scm b/module/ice-9/psyntax.scm index b1c09f86c..5d3291388 100644 --- a/module/ice-9/psyntax.scm +++ b/module/ice-9/psyntax.scm @@ -239,393 +239,393 @@ args)))))) (syntax-case x () ((_ (name id1 ...)) - (and-map identifier? (syntax (name id1 ...))) + (and-map identifier? #'(name id1 ...)) (with-syntax - ((constructor (construct-name (syntax name) "make-" (syntax name))) - (predicate (construct-name (syntax name) (syntax name) "?")) - ((access ...) - (map (lambda (x) (construct-name x (syntax name) "-" x)) - (syntax (id1 ...)))) - ((assign ...) - (map (lambda (x) - (construct-name x "set-" (syntax name) "-" x "!")) - (syntax (id1 ...)))) - (structure-length - (+ (length (syntax (id1 ...))) 1)) - ((index ...) - (let f ((i 1) (ids (syntax (id1 ...)))) - (if (null? ids) - '() - (cons i (f (+ i 1) (cdr ids))))))) - (syntax (begin - (define constructor - (lambda (id1 ...) - (vector 'name id1 ... ))) - (define predicate - (lambda (x) - (and (vector? x) - (= (vector-length x) structure-length) - (eq? (vector-ref x 0) 'name)))) - (define access - (lambda (x) - (vector-ref x index))) - ... - (define assign - (lambda (x update) - (vector-set! x index update))) - ...))))))) + ((constructor (construct-name #'name "make-" #'name)) + (predicate (construct-name #'name #'name "?")) + ((access ...) + (map (lambda (x) (construct-name x #'name "-" x)) + #'(id1 ...))) + ((assign ...) + (map (lambda (x) + (construct-name x "set-" #'name "-" x "!")) + #'(id1 ...))) + (structure-length + (+ (length #'(id1 ...)) 1)) + ((index ...) + (let f ((i 1) (ids #'(id1 ...))) + (if (null? ids) + '() + (cons i (f (+ i 1) (cdr ids))))))) + #'(begin + (define constructor + (lambda (id1 ...) + (vector 'name id1 ... ))) + (define predicate + (lambda (x) + (and (vector? x) + (= (vector-length x) structure-length) + (eq? (vector-ref x 0) 'name)))) + (define access + (lambda (x) + (vector-ref x index))) + ... + (define assign + (lambda (x update) + (vector-set! x index update))) + ...)))))) (let () -(define noexpand "noexpand") -(define *mode* (make-fluid)) + (define noexpand "noexpand") + (define *mode* (make-fluid)) ;;; hooks to nonportable run-time helpers -(begin -(define fx+ +) -(define fx- -) -(define fx= =) -(define fx< <) + (begin + (define fx+ +) + (define fx- -) + (define fx= =) + (define fx< <) -(define top-level-eval-hook - (lambda (x mod) - (primitive-eval - `(,noexpand - ,(case (fluid-ref *mode*) - ((c) ((@ (language tree-il) tree-il->scheme) x)) - (else x)))))) + (define top-level-eval-hook + (lambda (x mod) + (primitive-eval + `(,noexpand + ,(case (fluid-ref *mode*) + ((c) ((@ (language tree-il) tree-il->scheme) x)) + (else x)))))) -(define local-eval-hook - (lambda (x mod) - (primitive-eval - `(,noexpand - ,(case (fluid-ref *mode*) - ((c) ((@ (language tree-il) tree-il->scheme) x)) - (else x)))))) + (define local-eval-hook + (lambda (x mod) + (primitive-eval + `(,noexpand + ,(case (fluid-ref *mode*) + ((c) ((@ (language tree-il) tree-il->scheme) x)) + (else x)))))) -(define-syntax gensym-hook - (syntax-rules () - ((_) (gensym)))) + (define-syntax gensym-hook + (syntax-rules () + ((_) (gensym)))) -(define put-global-definition-hook - (lambda (symbol type val) - (let ((existing (let ((v (module-variable (current-module) symbol))) - (and v (variable-bound? v) - (let ((val (variable-ref v))) - (and (macro? val) - (not (syncase-macro-type val)) - val)))))) - (module-define! (current-module) - symbol - (if existing - (make-extended-syncase-macro existing type val) - (make-syncase-macro type val)))))) + (define put-global-definition-hook + (lambda (symbol type val) + (let ((existing (let ((v (module-variable (current-module) symbol))) + (and v (variable-bound? v) + (let ((val (variable-ref v))) + (and (macro? val) + (not (syncase-macro-type val)) + val)))))) + (module-define! (current-module) + symbol + (if existing + (make-extended-syncase-macro existing type val) + (make-syncase-macro type val)))))) -(define get-global-definition-hook - (lambda (symbol module) - (if (and (not module) (current-module)) - (warn "module system is booted, we should have a module" symbol)) - (let ((v (module-variable (if module - (resolve-module (cdr module)) - (current-module)) - symbol))) - (and v (variable-bound? v) - (let ((val (variable-ref v))) - (and (macro? val) (syncase-macro-type val) - (cons (syncase-macro-type val) - (syncase-macro-binding val)))))))) + (define get-global-definition-hook + (lambda (symbol module) + (if (and (not module) (current-module)) + (warn "module system is booted, we should have a module" symbol)) + (let ((v (module-variable (if module + (resolve-module (cdr module)) + (current-module)) + symbol))) + (and v (variable-bound? v) + (let ((val (variable-ref v))) + (and (macro? val) (syncase-macro-type val) + (cons (syncase-macro-type val) + (syncase-macro-binding val)))))))) -) + ) -(define (decorate-source e s) - (if (and (pair? e) s) - (set-source-properties! e s)) - e) + (define (decorate-source e s) + (if (and (pair? e) s) + (set-source-properties! e s)) + e) ;;; output constructors -(define build-void - (lambda (source) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-void) source)) - (else (decorate-source '(if #f #f) source))))) + (define build-void + (lambda (source) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-void) source)) + (else (decorate-source '(if #f #f) source))))) -(define build-application - (lambda (source fun-exp arg-exps) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-application) source fun-exp arg-exps)) - (else (decorate-source `(,fun-exp . ,arg-exps) source))))) + (define build-application + (lambda (source fun-exp arg-exps) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-application) source fun-exp arg-exps)) + (else (decorate-source `(,fun-exp . ,arg-exps) source))))) -(define build-conditional - (lambda (source test-exp then-exp else-exp) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-conditional) - source test-exp then-exp else-exp)) - (else (decorate-source - (if (equal? else-exp '(if #f #f)) - `(if ,test-exp ,then-exp) - `(if ,test-exp ,then-exp ,else-exp)) - source))))) + (define build-conditional + (lambda (source test-exp then-exp else-exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-conditional) + source test-exp then-exp else-exp)) + (else (decorate-source + (if (equal? else-exp '(if #f #f)) + `(if ,test-exp ,then-exp) + `(if ,test-exp ,then-exp ,else-exp)) + source))))) -(define build-lexical-reference - (lambda (type source name var) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-lexical-ref) source name var)) - (else (decorate-source var source))))) + (define build-lexical-reference + (lambda (type source name var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lexical-ref) source name var)) + (else (decorate-source var source))))) -(define build-lexical-assignment - (lambda (source name var exp) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-lexical-set) source name var exp)) - (else (decorate-source `(set! ,var ,exp) source))))) + (define build-lexical-assignment + (lambda (source name var exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lexical-set) source name var exp)) + (else (decorate-source `(set! ,var ,exp) source))))) -;; Before modules are booted, we can't expand into data structures from -;; (language tree-il) -- we need to give the evaluator the -;; s-expressions that it understands natively. Actually the real truth -;; of the matter is that the evaluator doesn't understand tree-il -;; structures at all. So until we fix the evaluator, if ever, the -;; conflation that we should use tree-il iff we are compiling -;; holds true. -;; -(define (analyze-variable mod var modref-cont bare-cont) - (if (not mod) - (bare-cont var) - (let ((kind (car mod)) - (mod (cdr mod))) - (case kind - ((public) (modref-cont mod var #t)) - ((private) (if (not (equal? mod (module-name (current-module)))) - (modref-cont mod var #f) - (bare-cont var))) - ((bare) (bare-cont var)) - ((hygiene) (if (and (not (equal? mod (module-name (current-module)))) - (module-variable (resolve-module mod) var)) - (modref-cont mod var #f) - (bare-cont var))) - (else (syntax-violation #f "bad module kind" var mod)))))) + ;; Before modules are booted, we can't expand into data structures from + ;; (language tree-il) -- we need to give the evaluator the + ;; s-expressions that it understands natively. Actually the real truth + ;; of the matter is that the evaluator doesn't understand tree-il + ;; structures at all. So until we fix the evaluator, if ever, the + ;; conflation that we should use tree-il iff we are compiling + ;; holds true. + ;; + (define (analyze-variable mod var modref-cont bare-cont) + (if (not mod) + (bare-cont var) + (let ((kind (car mod)) + (mod (cdr mod))) + (case kind + ((public) (modref-cont mod var #t)) + ((private) (if (not (equal? mod (module-name (current-module)))) + (modref-cont mod var #f) + (bare-cont var))) + ((bare) (bare-cont var)) + ((hygiene) (if (and (not (equal? mod (module-name (current-module)))) + (module-variable (resolve-module mod) var)) + (modref-cont mod var #f) + (bare-cont var))) + (else (syntax-violation #f "bad module kind" var mod)))))) -(define build-global-reference - (lambda (source var mod) - (analyze-variable - mod var - (lambda (mod var public?) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-module-ref) source mod var public?)) - (else (decorate-source (list (if public? '@ '@@) mod var) source)))) - (lambda (var) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-toplevel-ref) source var)) - (else (decorate-source var source))))))) + (define build-global-reference + (lambda (source var mod) + (analyze-variable + mod var + (lambda (mod var public?) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-ref) source mod var public?)) + (else (decorate-source (list (if public? '@ '@@) mod var) source)))) + (lambda (var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-ref) source var)) + (else (decorate-source var source))))))) -(define build-global-assignment - (lambda (source var exp mod) - (analyze-variable - mod var - (lambda (mod var public?) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-module-set) source mod var public? exp)) - (else (decorate-source `(set! ,(list (if public? '@ '@@) mod var) ,exp) source)))) - (lambda (var) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-toplevel-set) source var exp)) - (else (decorate-source `(set! ,var ,exp) source))))))) + (define build-global-assignment + (lambda (source var exp mod) + (analyze-variable + mod var + (lambda (mod var public?) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-set) source mod var public? exp)) + (else (decorate-source `(set! ,(list (if public? '@ '@@) mod var) ,exp) source)))) + (lambda (var) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-set) source var exp)) + (else (decorate-source `(set! ,var ,exp) source))))))) -;; FIXME: there is a bug that prevents (set! ((@ (foo) bar) baz) quz) -;; from working. Hack around it. -(define (maybe-name-value! name val) - (cond - (((@ (language tree-il) lambda?) val) - (let ((meta ((@ (language tree-il) lambda-meta) val))) - (if (not (assq 'name meta)) - ((setter (@ (language tree-il) lambda-meta)) - val - (acons 'name name meta))))))) + ;; FIXME: there is a bug that prevents (set! ((@ (foo) bar) baz) quz) + ;; from working. Hack around it. + (define (maybe-name-value! name val) + (cond + (((@ (language tree-il) lambda?) val) + (let ((meta ((@ (language tree-il) lambda-meta) val))) + (if (not (assq 'name meta)) + ((setter (@ (language tree-il) lambda-meta)) + val + (acons 'name name meta))))))) -(define build-global-definition - (lambda (source var exp) - (case (fluid-ref *mode*) - ((c) - (maybe-name-value! var exp) - ((@ (language tree-il) make-toplevel-define) source var exp)) - (else (decorate-source `(define ,var ,exp) source))))) - -;; Ideally we would have all lambdas be case lambdas, but that would -;; need special support in the interpreter for the full capabilities of -;; case-lambda, with optional and keyword args, predicates, and else -;; clauses. This will come with the new interpreter, but for now we -;; separate the cases. -(define build-simple-lambda - (lambda (src req rest vars docstring exp) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-lambda) src - (if docstring `((documentation . ,docstring)) '()) - ;; hah, a case in which kwargs would be nice. - ((@ (language tree-il) make-lambda-case) - ;; src req opt rest kw inits vars predicate body else - src req #f rest #f '() vars #f exp #f))) - (else (decorate-source - `(lambda ,(if rest (apply cons* vars) vars) - ,@(if docstring (list docstring) '()) - ,exp) - src))))) - -(define build-case-lambda - (lambda (src docstring body) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-lambda) src - (if docstring `((documentation . ,docstring)) '()) - body)) - (else (decorate-source - ;; really gross hack - `(lambda %%args - ,@(if docstring (list docstring) '()) - (cond ,@body)) - src))))) - -(define build-lambda-case - ;; req := (name ...) - ;; opt := (name ...) | #f - ;; rest := name | #f - ;; kw := (allow-other-keys? (keyword name var [init]) ...) | #f - ;; inits: (init ...) - ;; vars: (sym ...) - ;; vars map to named arguments in the following order: - ;; required, optional (positional), rest, keyword. - ;; predicate: something you can stuff in a (lambda ,vars ,pred), already expanded - ;; the body of a lambda: anything, already expanded - ;; else: lambda-case | #f - (lambda (src req opt rest kw inits vars predicate body else-case) - (case (fluid-ref *mode*) - ((c) - ((@ (language tree-il) make-lambda-case) - src req opt rest kw inits vars predicate body else-case)) - (else - ;; Very much like the logic of (language tree-il compile-glil). - (let* ((nreq (length req)) - (nopt (if opt (length opt) 0)) - (rest-idx (and rest (+ nreq nopt))) - (allow-other-keys? (if kw (car kw) #f)) - (kw-indices (map (lambda (x) - ;; (,key ,name ,var) - (cons (car x) (list-index vars (caddr x)))) - (if kw (cdr kw) '()))) - (nargs (apply max (+ nreq nopt (if rest 1 0)) - (map 1+ (map cdr kw-indices))))) - (or (= nargs - (length vars) - (+ nreq (length inits) (if rest 1 0))) - (error "something went wrong" - req opt rest kw inits vars nreq nopt kw-indices nargs)) - (decorate-source - `((((@@ (ice-9 optargs) parse-lambda-case) - '(,nreq ,nopt ,rest-idx ,nargs ,allow-other-keys? ,kw-indices) - (list ,@(map (lambda (i) `(lambda ,vars ,i)) inits)) - ,(if predicate `(lambda ,vars ,predicate) #f) - %%args) - ;; FIXME: This _ is here to work around a bug in the - ;; memoizer. The %%% makes it different from %%, also a - ;; memoizer workaround. See the "interesting bug" mail from - ;; 23 oct 2009. As soon as we change the evaluator, this - ;; can be removed. - => (lambda (%%%args . _) (apply (lambda ,vars ,body) %%%args))) - ,@(or else-case - `((%%args (error "wrong number of arguments" %%args))))) - src)))))) - -(define build-primref - (lambda (src name) - (if (equal? (module-name (current-module)) '(guile)) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-toplevel-ref) src name)) - (else (decorate-source name src))) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-module-ref) src '(guile) name #f)) - (else (decorate-source `(@@ (guile) ,name) src)))))) - -(define (build-data src exp) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-const) src exp)) - (else (decorate-source - (if (and (self-evaluating? exp) (not (vector? exp))) - exp - (list 'quote exp)) - src)))) - -(define build-sequence - (lambda (src exps) - (if (null? (cdr exps)) - (car exps) - (case (fluid-ref *mode*) - ((c) ((@ (language tree-il) make-sequence) src exps)) - (else (decorate-source `(begin ,@exps) src)))))) - -(define build-let - (lambda (src ids vars val-exps body-exp) - (if (null? vars) - body-exp - (case (fluid-ref *mode*) - ((c) - (for-each maybe-name-value! ids val-exps) - ((@ (language tree-il) make-let) src ids vars val-exps body-exp)) - (else (decorate-source - `(let ,(map list vars val-exps) ,body-exp) - src)))))) - -(define build-named-let - (lambda (src ids vars val-exps body-exp) - (let ((f (car vars)) - (f-name (car ids)) - (vars (cdr vars)) - (ids (cdr ids))) + (define build-global-definition + (lambda (source var exp) (case (fluid-ref *mode*) ((c) - (let ((proc (build-simple-lambda src ids #f vars #f body-exp))) - (maybe-name-value! f-name proc) - (for-each maybe-name-value! ids val-exps) - ((@ (language tree-il) make-letrec) src - (list f-name) (list f) (list proc) - (build-application src (build-lexical-reference 'fun src f-name f) - val-exps)))) - (else (decorate-source - `(let ,f ,(map list vars val-exps) ,body-exp) - src)))))) + (maybe-name-value! var exp) + ((@ (language tree-il) make-toplevel-define) source var exp)) + (else (decorate-source `(define ,var ,exp) source))))) -(define build-letrec - (lambda (src ids vars val-exps body-exp) - (if (null? vars) - body-exp + ;; Ideally we would have all lambdas be case lambdas, but that would + ;; need special support in the interpreter for the full capabilities of + ;; case-lambda, with optional and keyword args, predicates, and else + ;; clauses. This will come with the new interpreter, but for now we + ;; separate the cases. + (define build-simple-lambda + (lambda (src req rest vars docstring exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lambda) src + (if docstring `((documentation . ,docstring)) '()) + ;; hah, a case in which kwargs would be nice. + ((@ (language tree-il) make-lambda-case) + ;; src req opt rest kw inits vars predicate body else + src req #f rest #f '() vars #f exp #f))) + (else (decorate-source + `(lambda ,(if rest (apply cons* vars) vars) + ,@(if docstring (list docstring) '()) + ,exp) + src))))) + + (define build-case-lambda + (lambda (src docstring body) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-lambda) src + (if docstring `((documentation . ,docstring)) '()) + body)) + (else (decorate-source + ;; really gross hack + `(lambda %%args + ,@(if docstring (list docstring) '()) + (cond ,@body)) + src))))) + + (define build-lambda-case + ;; req := (name ...) + ;; opt := (name ...) | #f + ;; rest := name | #f + ;; kw := (allow-other-keys? (keyword name var [init]) ...) | #f + ;; inits: (init ...) + ;; vars: (sym ...) + ;; vars map to named arguments in the following order: + ;; required, optional (positional), rest, keyword. + ;; predicate: something you can stuff in a (lambda ,vars ,pred), already expanded + ;; the body of a lambda: anything, already expanded + ;; else: lambda-case | #f + (lambda (src req opt rest kw inits vars predicate body else-case) + (case (fluid-ref *mode*) + ((c) + ((@ (language tree-il) make-lambda-case) + src req opt rest kw inits vars predicate body else-case)) + (else + ;; Very much like the logic of (language tree-il compile-glil). + (let* ((nreq (length req)) + (nopt (if opt (length opt) 0)) + (rest-idx (and rest (+ nreq nopt))) + (allow-other-keys? (if kw (car kw) #f)) + (kw-indices (map (lambda (x) + ;; (,key ,name ,var) + (cons (car x) (list-index vars (caddr x)))) + (if kw (cdr kw) '()))) + (nargs (apply max (+ nreq nopt (if rest 1 0)) + (map 1+ (map cdr kw-indices))))) + (or (= nargs + (length vars) + (+ nreq (length inits) (if rest 1 0))) + (error "something went wrong" + req opt rest kw inits vars nreq nopt kw-indices nargs)) + (decorate-source + `((((@@ (ice-9 optargs) parse-lambda-case) + '(,nreq ,nopt ,rest-idx ,nargs ,allow-other-keys? ,kw-indices) + (list ,@(map (lambda (i) `(lambda ,vars ,i)) inits)) + ,(if predicate `(lambda ,vars ,predicate) #f) + %%args) + ;; FIXME: This _ is here to work around a bug in the + ;; memoizer. The %%% makes it different from %%, also a + ;; memoizer workaround. See the "interesting bug" mail from + ;; 23 oct 2009. As soon as we change the evaluator, this + ;; can be removed. + => (lambda (%%%args . _) (apply (lambda ,vars ,body) %%%args))) + ,@(or else-case + `((%%args (error "wrong number of arguments" %%args))))) + src)))))) + + (define build-primref + (lambda (src name) + (if (equal? (module-name (current-module)) '(guile)) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-toplevel-ref) src name)) + (else (decorate-source name src))) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-module-ref) src '(guile) name #f)) + (else (decorate-source `(@@ (guile) ,name) src)))))) + + (define (build-data src exp) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-const) src exp)) + (else (decorate-source + (if (and (self-evaluating? exp) (not (vector? exp))) + exp + (list 'quote exp)) + src)))) + + (define build-sequence + (lambda (src exps) + (if (null? (cdr exps)) + (car exps) + (case (fluid-ref *mode*) + ((c) ((@ (language tree-il) make-sequence) src exps)) + (else (decorate-source `(begin ,@exps) src)))))) + + (define build-let + (lambda (src ids vars val-exps body-exp) + (if (null? vars) + body-exp + (case (fluid-ref *mode*) + ((c) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-let) src ids vars val-exps body-exp)) + (else (decorate-source + `(let ,(map list vars val-exps) ,body-exp) + src)))))) + + (define build-named-let + (lambda (src ids vars val-exps body-exp) + (let ((f (car vars)) + (f-name (car ids)) + (vars (cdr vars)) + (ids (cdr ids))) (case (fluid-ref *mode*) ((c) - (for-each maybe-name-value! ids val-exps) - ((@ (language tree-il) make-letrec) src ids vars val-exps body-exp)) + (let ((proc (build-simple-lambda src ids #f vars #f body-exp))) + (maybe-name-value! f-name proc) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-letrec) src + (list f-name) (list f) (list proc) + (build-application src (build-lexical-reference 'fun src f-name f) + val-exps)))) (else (decorate-source - `(letrec ,(map list vars val-exps) ,body-exp) + `(let ,f ,(map list vars val-exps) ,body-exp) src)))))) -;; FIXME: use a faster gensym -(define-syntax build-lexical-var - (syntax-rules () - ((_ src id) (gensym (string-append (symbol->string id) " "))))) + (define build-letrec + (lambda (src ids vars val-exps body-exp) + (if (null? vars) + body-exp + (case (fluid-ref *mode*) + ((c) + (for-each maybe-name-value! ids val-exps) + ((@ (language tree-il) make-letrec) src ids vars val-exps body-exp)) + (else (decorate-source + `(letrec ,(map list vars val-exps) ,body-exp) + src)))))) -(define-structure (syntax-object expression wrap module)) + ;; FIXME: use a faster gensym + (define-syntax build-lexical-var + (syntax-rules () + ((_ src id) (gensym (string-append (symbol->string id) " "))))) -(define-syntax no-source (identifier-syntax #f)) + (define-structure (syntax-object expression wrap module)) -(define source-annotation - (lambda (x) - (cond - ((syntax-object? x) - (source-annotation (syntax-object-expression x))) - ((pair? x) (let ((props (source-properties x))) - (if (pair? props) - props - #f))) - (else #f)))) + (define-syntax no-source (identifier-syntax #f)) -(define-syntax arg-check - (syntax-rules () - ((_ pred? e who) - (let ((x e)) - (if (not (pred? x)) (syntax-violation who "invalid argument" x)))))) + (define source-annotation + (lambda (x) + (cond + ((syntax-object? x) + (source-annotation (syntax-object-expression x))) + ((pair? x) (let ((props (source-properties x))) + (if (pair? props) + props + #f))) + (else #f)))) + + (define-syntax arg-check + (syntax-rules () + ((_ pred? e who) + (let ((x e)) + (if (not (pred? x)) (syntax-violation who "invalid argument" x)))))) ;;; compile-time environments @@ -655,7 +655,7 @@ ;;; (define-syntax) define-syntax ;;; (local-syntax . rec?) let-syntax/letrec-syntax ;;; (eval-when) eval-when -;;; (syntax . ( . )) pattern variables +;;; #'. ( . ) pattern variables ;;; (global) assumed global variable ;;; (lexical . ) lexical variables ;;; (displaced-lexical) displaced lexicals @@ -683,58 +683,58 @@ ;;; keyword is referenced on the rhs of one of the letrec-syntax clauses. ;;; a displaced lexical should never occur with properly written macros. -(define-syntax make-binding - (syntax-rules (quote) - ((_ type value) (cons type value)) - ((_ 'type) '(type)) - ((_ type) (cons type '())))) -(define binding-type car) -(define binding-value cdr) + (define-syntax make-binding + (syntax-rules (quote) + ((_ type value) (cons type value)) + ((_ 'type) '(type)) + ((_ type) (cons type '())))) + (define binding-type car) + (define binding-value cdr) -(define-syntax null-env (identifier-syntax '())) + (define-syntax null-env (identifier-syntax '())) -(define extend-env - (lambda (labels bindings r) - (if (null? labels) - r - (extend-env (cdr labels) (cdr bindings) - (cons (cons (car labels) (car bindings)) r))))) + (define extend-env + (lambda (labels bindings r) + (if (null? labels) + r + (extend-env (cdr labels) (cdr bindings) + (cons (cons (car labels) (car bindings)) r))))) -(define extend-var-env - ; variant of extend-env that forms "lexical" binding - (lambda (labels vars r) - (if (null? labels) - r - (extend-var-env (cdr labels) (cdr vars) - (cons (cons (car labels) (make-binding 'lexical (car vars))) r))))) + (define extend-var-env + ; variant of extend-env that forms "lexical" binding + (lambda (labels vars r) + (if (null? labels) + r + (extend-var-env (cdr labels) (cdr vars) + (cons (cons (car labels) (make-binding 'lexical (car vars))) r))))) ;;; we use a "macros only" environment in expansion of local macro ;;; definitions so that their definitions can use local macros without ;;; attempting to use other lexical identifiers. -(define macros-only-env - (lambda (r) - (if (null? r) - '() - (let ((a (car r))) - (if (eq? (cadr a) 'macro) - (cons a (macros-only-env (cdr r))) - (macros-only-env (cdr r))))))) + (define macros-only-env + (lambda (r) + (if (null? r) + '() + (let ((a (car r))) + (if (eq? (cadr a) 'macro) + (cons a (macros-only-env (cdr r))) + (macros-only-env (cdr r))))))) -(define lookup - ; x may be a label or a symbol - ; although symbols are usually global, we check the environment first - ; anyway because a temporary binding may have been established by - ; fluid-let-syntax - (lambda (x r mod) - (cond - ((assq x r) => cdr) - ((symbol? x) - (or (get-global-definition-hook x mod) (make-binding 'global))) - (else (make-binding 'displaced-lexical))))) + (define lookup + ; x may be a label or a symbol + ; although symbols are usually global, we check the environment first + ; anyway because a temporary binding may have been established by + ; fluid-let-syntax + (lambda (x r mod) + (cond + ((assq x r) => cdr) + ((symbol? x) + (or (get-global-definition-hook x mod) (make-binding 'global))) + (else (make-binding 'displaced-lexical))))) -(define global-extend - (lambda (type sym val) - (put-global-definition-hook sym type val))) + (define global-extend + (lambda (type sym val) + (put-global-definition-hook sym type val))) ;;; Conceptually, identifiers are always syntax objects. Internally, @@ -742,33 +742,33 @@ ;;; efficiency and confusion), so that symbols are also considered ;;; identifiers by id?. Externally, they are always wrapped. -(define nonsymbol-id? - (lambda (x) - (and (syntax-object? x) - (symbol? (syntax-object-expression x))))) + (define nonsymbol-id? + (lambda (x) + (and (syntax-object? x) + (symbol? (syntax-object-expression x))))) -(define id? - (lambda (x) - (cond - ((symbol? x) #t) - ((syntax-object? x) (symbol? (syntax-object-expression x))) - (else #f)))) + (define id? + (lambda (x) + (cond + ((symbol? x) #t) + ((syntax-object? x) (symbol? (syntax-object-expression x))) + (else #f)))) -(define-syntax id-sym-name - (syntax-rules () - ((_ e) - (let ((x e)) - (if (syntax-object? x) + (define-syntax id-sym-name + (syntax-rules () + ((_ e) + (let ((x e)) + (if (syntax-object? x) + (syntax-object-expression x) + x))))) + + (define id-sym-name&marks + (lambda (x w) + (if (syntax-object? x) + (values (syntax-object-expression x) - x))))) - -(define id-sym-name&marks - (lambda (x w) - (if (syntax-object? x) - (values - (syntax-object-expression x) - (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x)))) - (values x (wrap-marks w))))) + (join-marks (wrap-marks w) (wrap-marks (syntax-object-wrap x)))) + (values x (wrap-marks w))))) ;;; syntax object wraps @@ -777,86 +777,86 @@ ;;; ::= #(