mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-23 12:00:21 +02:00
Merge remote-tracking branch 'origin/stable-2.0'
Conflicts: libguile/debug.h module/ice-9/psyntax-pp.scm module/ice-9/psyntax.scm module/language/tree-il/peval.scm module/language/tree-il/primitives.scm
This commit is contained in:
commit
dfadcf85cb
45 changed files with 20479 additions and 19006 deletions
|
@ -389,8 +389,6 @@ If there is no handler at all, Guile prints an error and then exits."
|
|||
(define generate-temporaries #f)
|
||||
(define bound-identifier=? #f)
|
||||
(define free-identifier=? #f)
|
||||
(define syntax-local-binding #f)
|
||||
(define syntax-locally-bound-identifiers #f)
|
||||
|
||||
;; $sc-dispatch is an implementation detail of psyntax. It is used by
|
||||
;; expanded macros, to dispatch an input against a set of patterns.
|
||||
|
@ -3821,12 +3819,44 @@ module '(ice-9 q) '(make-q q-length))}."
|
|||
|
||||
|
||||
|
||||
;;; Place the user in the guile-user module.
|
||||
;;; SRFI-4 in the default environment. FIXME: we should figure out how
|
||||
;;; to deprecate this.
|
||||
;;;
|
||||
|
||||
;; FIXME:
|
||||
(module-use! the-scm-module (resolve-interface '(srfi srfi-4)))
|
||||
|
||||
|
||||
|
||||
;;; A few identifiers that need to be defined in this file are really
|
||||
;;; internal implementation details. We shove them off into internal
|
||||
;;; modules, removing them from the (guile) module.
|
||||
;;;
|
||||
|
||||
(define-module (system syntax))
|
||||
|
||||
(let ()
|
||||
(define (steal-bindings! from to ids)
|
||||
(for-each
|
||||
(lambda (sym)
|
||||
(let ((v (module-local-variable from sym)))
|
||||
(module-remove! from sym)
|
||||
(module-add! to sym v)))
|
||||
ids)
|
||||
(module-export! to ids))
|
||||
|
||||
(steal-bindings! the-root-module (resolve-module '(system syntax))
|
||||
'(syntax-local-binding
|
||||
syntax-module
|
||||
syntax-locally-bound-identifiers
|
||||
syntax-session-id)))
|
||||
|
||||
|
||||
|
||||
|
||||
;;; Place the user in the guile-user module.
|
||||
;;;
|
||||
|
||||
;; Set filename to #f to prevent reload.
|
||||
(define-module (guile-user)
|
||||
#:autoload (system base compile) (compile compile-file)
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
;;; -*- mode: scheme; coding: utf-8; -*-
|
||||
;;;
|
||||
;;; Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
|
||||
;;; Copyright (C) 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
|
||||
;;;
|
||||
;;; This library is free software; you can redistribute it and/or
|
||||
;;; modify it under the terms of the GNU Lesser General Public
|
||||
|
@ -19,7 +19,12 @@
|
|||
(use-modules (language tree-il)
|
||||
(language tree-il optimize)
|
||||
(language tree-il canonicalize)
|
||||
(ice-9 pretty-print))
|
||||
(ice-9 pretty-print)
|
||||
(system syntax))
|
||||
|
||||
;; Avoid gratuitous churn in psyntax-pp.scm due to the marks and labels
|
||||
;; changing session identifiers.
|
||||
(set! syntax-session-id (lambda () "*"))
|
||||
|
||||
(let ((source (list-ref (command-line) 1))
|
||||
(target (list-ref (command-line) 2)))
|
||||
|
|
|
@ -425,7 +425,8 @@
|
|||
(let ((x (eval x env)))
|
||||
(if (and (procedure? x) (not (procedure-property x 'name)))
|
||||
(set-procedure-property! x 'name name))
|
||||
(define! name x)))
|
||||
(define! name x)
|
||||
(if #f #f)))
|
||||
|
||||
(('toplevel-set! (var-or-sym . x))
|
||||
(variable-set!
|
||||
|
|
251
module/ice-9/local-eval.scm
Normal file
251
module/ice-9/local-eval.scm
Normal file
|
@ -0,0 +1,251 @@
|
|||
;;; -*- mode: scheme; coding: utf-8; -*-
|
||||
;;;
|
||||
;;; Copyright (C) 2012 Free Software Foundation, Inc.
|
||||
;;;
|
||||
;;; This library is free software; you can redistribute it and/or
|
||||
;;; modify it under the terms of the GNU Lesser General Public
|
||||
;;; License as published by the Free Software Foundation; either
|
||||
;;; version 3 of the License, or (at your option) any later version.
|
||||
;;;
|
||||
;;; This library 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
|
||||
;;; Lesser General Public License for more details.
|
||||
;;;
|
||||
;;; You should have received a copy of the GNU Lesser General Public
|
||||
;;; License along with this library; if not, write to the Free Software
|
||||
;;; Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
|
||||
(define-module (ice-9 local-eval)
|
||||
#:use-module (ice-9 format)
|
||||
#:use-module (srfi srfi-9)
|
||||
#:use-module (srfi srfi-9 gnu)
|
||||
#:use-module (system base compile)
|
||||
#:use-module (system syntax)
|
||||
#:export (the-environment local-eval local-compile))
|
||||
|
||||
(define-record-type lexical-environment-type
|
||||
(make-lexical-environment scope wrapper boxes patterns)
|
||||
lexical-environment?
|
||||
(scope lexenv-scope)
|
||||
(wrapper lexenv-wrapper)
|
||||
(boxes lexenv-boxes)
|
||||
(patterns lexenv-patterns))
|
||||
|
||||
(set-record-type-printer!
|
||||
lexical-environment-type
|
||||
(lambda (e port)
|
||||
(format port "#<lexical-environment ~S (~S bindings)>"
|
||||
(syntax-module (lexenv-scope e))
|
||||
(+ (length (lexenv-boxes e)) (length (lexenv-patterns e))))))
|
||||
|
||||
(define-syntax syntax-object-of
|
||||
(lambda (form)
|
||||
(syntax-case form ()
|
||||
((_ x) #`(quote #,(datum->syntax #'x #'x))))))
|
||||
|
||||
(define-syntax-rule (make-box v)
|
||||
(case-lambda
|
||||
(() v)
|
||||
((x) (set! v x))))
|
||||
|
||||
(define (make-transformer-from-box id trans)
|
||||
(set-procedure-property! trans 'identifier-syntax-box id)
|
||||
trans)
|
||||
|
||||
(define-syntax-rule (identifier-syntax-from-box box)
|
||||
(make-transformer-from-box
|
||||
(syntax-object-of box)
|
||||
(identifier-syntax (id (box))
|
||||
((set! id x) (box x)))))
|
||||
|
||||
(define (unsupported-binding name)
|
||||
(make-variable-transformer
|
||||
(lambda (x)
|
||||
(syntax-violation
|
||||
'local-eval
|
||||
"unsupported binding captured by (the-environment)"
|
||||
x))))
|
||||
|
||||
(define (within-nested-ellipses id lvl)
|
||||
(let loop ((s id) (n lvl))
|
||||
(if (zero? n)
|
||||
s
|
||||
(loop #`(#,s (... ...)) (- n 1)))))
|
||||
|
||||
;; Analyze the set of bound identifiers IDS. Return four values:
|
||||
;;
|
||||
;; capture: A list of forms that will be emitted in the expansion of
|
||||
;; `the-environment' to capture lexical variables.
|
||||
;;
|
||||
;; formals: Corresponding formal parameters for use in the lambda that
|
||||
;; re-introduces those variables. These are temporary identifiers, and
|
||||
;; as such if we have a nested `the-environment', there is no need to
|
||||
;; capture them. (See the notes on nested `the-environment' and
|
||||
;; proxies, below.)
|
||||
;;
|
||||
;; wrappers: A list of procedures of type SYNTAX -> SYNTAX, used to wrap
|
||||
;; the expression to be evaluated in forms that re-introduce the
|
||||
;; variable. The forms will be nested so that the variable shadowing
|
||||
;; semantics of the original form are maintained.
|
||||
;;
|
||||
;; patterns: A terrible hack. The issue is that for pattern variables,
|
||||
;; we can't emit lexically nested with-syntax forms, like:
|
||||
;;
|
||||
;; (with-syntax ((foo 1)) (the-environment))
|
||||
;; => (with-syntax ((foo 1))
|
||||
;; ... #'(with-syntax ((foo ...)) ... exp) ...)
|
||||
;;
|
||||
;; The reason is that the outer "foo" substitutes into the inner "foo",
|
||||
;; yielding something like:
|
||||
;;
|
||||
;; (with-syntax ((foo 1))
|
||||
;; ... (with-syntax ((1 ...)) ...)
|
||||
;;
|
||||
;; Which ain't what we want. So we hide the information needed to
|
||||
;; re-make the inner pattern binding form in the lexical environment
|
||||
;; object, and then introduce those identifiers via another with-syntax.
|
||||
;;
|
||||
;;
|
||||
;; There are four different kinds of lexical bindings: normal lexicals,
|
||||
;; macros, displaced lexicals, and pattern variables. See the
|
||||
;; documentation of syntax-local-binding for more info on these.
|
||||
;;
|
||||
;; We capture normal lexicals via `make-box', which creates a
|
||||
;; case-lambda that can reference or set a variable. These get
|
||||
;; re-introduced with an identifier-syntax.
|
||||
;;
|
||||
;; We can't capture macros currently. However we do recognize our own
|
||||
;; macros that are actually proxying lexicals, so that nested
|
||||
;; `the-environment' forms are possible. In that case we drill down to
|
||||
;; the identifier for the already-existing box, and just capture that
|
||||
;; box.
|
||||
;;
|
||||
;; And that's it: we skip displaced lexicals, and the pattern variables
|
||||
;; are discussed above.
|
||||
;;
|
||||
(define (analyze-identifiers ids)
|
||||
(define (mktmp)
|
||||
(datum->syntax #'here (gensym "t ")))
|
||||
(let lp ((ids ids) (capture '()) (formals '()) (wrappers '()) (patterns '()))
|
||||
(cond
|
||||
((null? ids)
|
||||
(values capture formals wrappers patterns))
|
||||
(else
|
||||
(let ((id (car ids)) (ids (cdr ids)))
|
||||
(call-with-values (lambda () (syntax-local-binding id))
|
||||
(lambda (type val)
|
||||
(case type
|
||||
((lexical)
|
||||
(if (or-map (lambda (x) (bound-identifier=? x id)) formals)
|
||||
(lp ids capture formals wrappers patterns)
|
||||
(let ((t (mktmp)))
|
||||
(lp ids
|
||||
(cons #`(make-box #,id) capture)
|
||||
(cons t formals)
|
||||
(cons (lambda (x)
|
||||
#`(let-syntax ((#,id (identifier-syntax-from-box #,t)))
|
||||
#,x))
|
||||
wrappers)
|
||||
patterns))))
|
||||
((displaced-lexical)
|
||||
(lp ids capture formals wrappers patterns))
|
||||
((macro)
|
||||
(let ((b (procedure-property val 'identifier-syntax-box)))
|
||||
(if b
|
||||
(lp ids (cons b capture) (cons b formals)
|
||||
(cons (lambda (x)
|
||||
#`(let-syntax ((#,id (identifier-syntax-from-box #,b)))
|
||||
#,x))
|
||||
wrappers)
|
||||
patterns)
|
||||
(lp ids capture formals
|
||||
(cons (lambda (x)
|
||||
#`(let-syntax ((#,id (unsupported-binding '#,id)))
|
||||
#,x))
|
||||
wrappers)
|
||||
patterns))))
|
||||
((pattern-variable)
|
||||
(let ((t (datum->syntax id (gensym "p ")))
|
||||
(nested (within-nested-ellipses id (cdr val))))
|
||||
(lp ids capture formals
|
||||
(cons (lambda (x)
|
||||
#`(with-syntax ((#,t '#,nested))
|
||||
#,x))
|
||||
wrappers)
|
||||
;; This dance is to hide these pattern variables
|
||||
;; from the expander.
|
||||
(cons (list (datum->syntax #'here (syntax->datum id))
|
||||
(cdr val)
|
||||
t)
|
||||
patterns))))
|
||||
(else
|
||||
(error "what" type val))))))))))
|
||||
|
||||
(define-syntax the-environment
|
||||
(lambda (x)
|
||||
(syntax-case x ()
|
||||
((the-environment)
|
||||
#'(the-environment the-environment))
|
||||
((the-environment scope)
|
||||
(call-with-values (lambda ()
|
||||
(analyze-identifiers
|
||||
(syntax-locally-bound-identifiers #'scope)))
|
||||
(lambda (capture formals wrappers patterns)
|
||||
(define (wrap-expression x)
|
||||
(let lp ((x x) (wrappers wrappers))
|
||||
(if (null? wrappers)
|
||||
x
|
||||
(lp ((car wrappers) x) (cdr wrappers)))))
|
||||
(with-syntax (((f ...) formals)
|
||||
((c ...) capture)
|
||||
(((pname plvl pformal) ...) patterns)
|
||||
(wrapped (wrap-expression #'(begin #f exp))))
|
||||
#'(make-lexical-environment
|
||||
#'scope
|
||||
(lambda (exp pformal ...)
|
||||
(with-syntax ((exp exp)
|
||||
(pformal pformal)
|
||||
...)
|
||||
#'(lambda (f ...)
|
||||
wrapped)))
|
||||
(list c ...)
|
||||
(list (list 'pname plvl #'pformal) ...)))))))))
|
||||
|
||||
(define (env-module e)
|
||||
(cond
|
||||
((lexical-environment? e) (resolve-module (syntax-module (lexenv-scope e))))
|
||||
((module? e) e)
|
||||
(else (error "invalid lexical environment" e))))
|
||||
|
||||
(define (env-boxes e)
|
||||
(cond
|
||||
((lexical-environment? e) (lexenv-boxes e))
|
||||
((module? e) '())
|
||||
(else (error "invalid lexical environment" e))))
|
||||
|
||||
(define (local-wrap x e)
|
||||
(cond
|
||||
((lexical-environment? e)
|
||||
(apply (lexenv-wrapper e)
|
||||
(datum->syntax (lexenv-scope e) x)
|
||||
(map (lambda (l)
|
||||
(let ((name (car l))
|
||||
(lvl (cadr l))
|
||||
(scope (caddr l)))
|
||||
(within-nested-ellipses (datum->syntax scope name) lvl)))
|
||||
(lexenv-patterns e))))
|
||||
((module? e) #`(lambda () #f #,x))
|
||||
(else (error "invalid lexical environment" e))))
|
||||
|
||||
(define (local-eval x e)
|
||||
"Evaluate the expression @var{x} within the lexical environment @var{e}."
|
||||
(apply (eval (local-wrap x e) (env-module e))
|
||||
(env-boxes e)))
|
||||
|
||||
(define* (local-compile x e #:key (opts '()))
|
||||
"Compile and evaluate the expression @var{x} within the lexical
|
||||
environment @var{e}."
|
||||
(apply (compile (local-wrap x e) #:env (env-module e)
|
||||
#:from 'scheme #:opts opts)
|
||||
(env-boxes e)))
|
File diff suppressed because it is too large
Load diff
|
@ -273,8 +273,11 @@
|
|||
(lambda (x mod)
|
||||
(primitive-eval x)))
|
||||
|
||||
(define-syntax-rule (gensym-hook)
|
||||
(gensym))
|
||||
;; Capture syntax-session-id before we shove it off into a module.
|
||||
(define session-id
|
||||
(let ((v (module-variable (current-module) 'syntax-session-id)))
|
||||
(lambda ()
|
||||
((variable-ref v)))))
|
||||
|
||||
(define put-global-definition-hook
|
||||
(lambda (symbol type val)
|
||||
|
@ -452,7 +455,7 @@
|
|||
|
||||
;; FIXME: use a faster gensym
|
||||
(define-syntax-rule (build-lexical-var src id)
|
||||
(gensym (string-append (symbol->string id) " ")))
|
||||
(gensym (string-append (symbol->string id) "-")))
|
||||
|
||||
(define-structure (syntax-object expression wrap module))
|
||||
|
||||
|
@ -626,13 +629,8 @@
|
|||
|
||||
;; labels must be comparable with "eq?", have read-write invariance,
|
||||
;; and distinct from symbols.
|
||||
(define gen-label
|
||||
(let ((i 0))
|
||||
(lambda ()
|
||||
(let ((n i))
|
||||
;; FIXME: Use atomic ops.
|
||||
(set! i (1+ n))
|
||||
(number->string n 36)))))
|
||||
(define (gen-label)
|
||||
(string-append "l-" (session-id) (symbol->string (gensym "-"))))
|
||||
|
||||
(define gen-labels
|
||||
(lambda (ls)
|
||||
|
@ -661,7 +659,7 @@
|
|||
(cons 'shift (wrap-subst w)))))
|
||||
|
||||
(define-syntax-rule (new-mark)
|
||||
(gensym "m"))
|
||||
(gensym (string-append "m-" (session-id) "-")))
|
||||
|
||||
;; make-empty-ribcage and extend-ribcage maintain list-based ribcages for
|
||||
;; internal definitions, in which the ribcages are built incrementally
|
||||
|
@ -1079,7 +1077,7 @@
|
|||
(call-with-values
|
||||
(lambda ()
|
||||
(syntax-type x r w (source-annotation x) ribcage mod #f))
|
||||
(lambda (type value e w s mod)
|
||||
(lambda (type value form e w s mod)
|
||||
(case type
|
||||
((define-form)
|
||||
(let* ((id (wrap value w mod))
|
||||
|
@ -1171,11 +1169,11 @@
|
|||
(else
|
||||
(list
|
||||
(if (eq? m 'c&e)
|
||||
(let ((x (expand-expr type value e r w s mod)))
|
||||
(let ((x (expand-expr type value form e r w s mod)))
|
||||
(top-level-eval-hook x mod)
|
||||
(lambda () x))
|
||||
(lambda ()
|
||||
(expand-expr type value e r w s mod)))))))))
|
||||
(expand-expr type value form e r w s mod)))))))))
|
||||
(let ((exps (map (lambda (x) (x))
|
||||
(reverse (parse body r w s m esew mod)))))
|
||||
(if (null? exps)
|
||||
|
@ -1214,8 +1212,8 @@
|
|||
(syntax-violation 'eval-when "invalid situation" e
|
||||
(car l))))))))
|
||||
|
||||
;; syntax-type returns six values: type, value, e, w, s, and mod. The
|
||||
;; first two are described in the table below.
|
||||
;; syntax-type returns seven values: type, value, form, e, w, s, and
|
||||
;; mod. The first two are described in the table below.
|
||||
;;
|
||||
;; type value explanation
|
||||
;; -------------------------------------------------------------------
|
||||
|
@ -1244,10 +1242,11 @@
|
|||
;; constant none self-evaluating datum
|
||||
;; other none anything else
|
||||
;;
|
||||
;; For definition forms (define-form, define-syntax-parameter-form,
|
||||
;; and define-syntax-form), e is the rhs expression. For all
|
||||
;; others, e is the entire form. w is the wrap for e. s is the
|
||||
;; source for the entire form. mod is the module for e.
|
||||
;; form is the entire form. For definition forms (define-form,
|
||||
;; define-syntax-form, and define-syntax-parameter-form), e is the
|
||||
;; rhs expression. For all others, e is the entire form. w is the
|
||||
;; wrap for both form and e. s is the source for the entire form.
|
||||
;; mod is the module for both form and e.
|
||||
;;
|
||||
;; syntax-type expands macros and unwraps as necessary to get to one
|
||||
;; of the forms above. It also parses definition forms, although
|
||||
|
@ -1262,28 +1261,28 @@
|
|||
(case type
|
||||
((macro)
|
||||
(if for-car?
|
||||
(values type value e w s mod)
|
||||
(values type value e e w s mod)
|
||||
(syntax-type (expand-macro value e r w s rib mod)
|
||||
r empty-wrap s rib mod #f)))
|
||||
((global)
|
||||
;; Toplevel definitions may resolve to bindings with
|
||||
;; different names or in different modules.
|
||||
(values type value value w s mod*))
|
||||
(else (values type value e w s mod))))))
|
||||
(values type value e value w s mod*))
|
||||
(else (values type value e e w s mod))))))
|
||||
((pair? e)
|
||||
(let ((first (car e)))
|
||||
(call-with-values
|
||||
(lambda () (syntax-type first r w s rib mod #t))
|
||||
(lambda (ftype fval fe fw fs fmod)
|
||||
(lambda (ftype fval fform fe fw fs fmod)
|
||||
(case ftype
|
||||
((lexical)
|
||||
(values 'lexical-call fval e w s mod))
|
||||
(values 'lexical-call fval e e w s mod))
|
||||
((global)
|
||||
;; If we got here via an (@@ ...) expansion, we need to
|
||||
;; make sure the fmod information is propagated back
|
||||
;; correctly -- hence this consing.
|
||||
(values 'global-call (make-syntax-object fval w fmod)
|
||||
e w s mod))
|
||||
e e w s mod))
|
||||
((macro)
|
||||
(syntax-type (expand-macro fval e r w s rib mod)
|
||||
r empty-wrap s rib mod for-car?))
|
||||
|
@ -1292,23 +1291,24 @@
|
|||
(lambda (e r w s mod)
|
||||
(syntax-type e r w s rib mod for-car?))))
|
||||
((core)
|
||||
(values 'core-form fval e w s mod))
|
||||
(values 'core-form fval e e w s mod))
|
||||
((local-syntax)
|
||||
(values 'local-syntax-form fval e w s mod))
|
||||
(values 'local-syntax-form fval e e w s mod))
|
||||
((begin)
|
||||
(values 'begin-form #f e w s mod))
|
||||
(values 'begin-form #f e e w s mod))
|
||||
((eval-when)
|
||||
(values 'eval-when-form #f e w s mod))
|
||||
(values 'eval-when-form #f e e w s mod))
|
||||
((define)
|
||||
(syntax-case e ()
|
||||
((_ name val)
|
||||
(id? #'name)
|
||||
(values 'define-form #'name #'val w s mod))
|
||||
(values 'define-form #'name e #'val w s mod))
|
||||
((_ (name . args) e1 e2 ...)
|
||||
(and (id? #'name)
|
||||
(valid-bound-ids? (lambda-var-list #'args)))
|
||||
;; need lambda here...
|
||||
(values 'define-form (wrap #'name w mod)
|
||||
(wrap e w mod)
|
||||
(decorate-source
|
||||
(cons #'lambda (wrap #'(args e1 e2 ...) w mod))
|
||||
s)
|
||||
|
@ -1316,38 +1316,39 @@
|
|||
((_ name)
|
||||
(id? #'name)
|
||||
(values 'define-form (wrap #'name w mod)
|
||||
(wrap e w mod)
|
||||
#'(if #f #f)
|
||||
empty-wrap s mod))))
|
||||
((define-syntax)
|
||||
(syntax-case e ()
|
||||
((_ name val)
|
||||
(id? #'name)
|
||||
(values 'define-syntax-form #'name #'val w s mod))))
|
||||
(values 'define-syntax-form #'name e #'val w s mod))))
|
||||
((define-syntax-parameter)
|
||||
(syntax-case e ()
|
||||
((_ name val)
|
||||
(id? #'name)
|
||||
(values 'define-syntax-parameter-form #'name #'val w s mod))))
|
||||
(values 'define-syntax-parameter-form #'name e #'val w s mod))))
|
||||
(else
|
||||
(values 'call #f e w s mod)))))))
|
||||
(values 'call #f e e w s mod)))))))
|
||||
((syntax-object? e)
|
||||
(syntax-type (syntax-object-expression e)
|
||||
r
|
||||
(join-wraps w (syntax-object-wrap e))
|
||||
(or (source-annotation e) s) rib
|
||||
(or (syntax-object-module e) mod) for-car?))
|
||||
((self-evaluating? e) (values 'constant #f e w s mod))
|
||||
(else (values 'other #f e w s mod)))))
|
||||
((self-evaluating? e) (values 'constant #f e e w s mod))
|
||||
(else (values 'other #f e e w s mod)))))
|
||||
|
||||
(define expand
|
||||
(lambda (e r w mod)
|
||||
(call-with-values
|
||||
(lambda () (syntax-type e r w (source-annotation e) #f mod #f))
|
||||
(lambda (type value e w s mod)
|
||||
(expand-expr type value e r w s mod)))))
|
||||
(lambda (type value form e w s mod)
|
||||
(expand-expr type value form e r w s mod)))))
|
||||
|
||||
(define expand-expr
|
||||
(lambda (type value e r w s mod)
|
||||
(lambda (type value form e r w s mod)
|
||||
(case type
|
||||
((lexical)
|
||||
(build-lexical-reference 'value s e value))
|
||||
|
@ -1396,8 +1397,8 @@
|
|||
(expand-sequence #'(e1 e2 ...) r w s mod)
|
||||
(expand-void))))))
|
||||
((define-form define-syntax-form define-syntax-parameter-form)
|
||||
(syntax-violation #f "definition in expression context"
|
||||
e (wrap value w mod)))
|
||||
(syntax-violation #f "definition in expression context, where definitions are not allowed,"
|
||||
(source-wrap form w s mod)))
|
||||
((syntax)
|
||||
(syntax-violation #f "reference to pattern variable outside syntax form"
|
||||
(source-wrap e w s mod)))
|
||||
|
@ -1541,7 +1542,7 @@
|
|||
(let ((e (cdar body)) (er (caar body)))
|
||||
(call-with-values
|
||||
(lambda () (syntax-type e er empty-wrap (source-annotation er) ribcage mod #f))
|
||||
(lambda (type value e w s mod)
|
||||
(lambda (type value form e w s mod)
|
||||
(case type
|
||||
((define-form)
|
||||
(let ((id (wrap value w mod)) (label (gen-label)))
|
||||
|
@ -2307,7 +2308,7 @@
|
|||
((_ (head tail ...) val)
|
||||
(call-with-values
|
||||
(lambda () (syntax-type #'head r empty-wrap no-source #f mod #t))
|
||||
(lambda (type value ee ww ss modmod)
|
||||
(lambda (type value ee* ee ww ss modmod)
|
||||
(case type
|
||||
((module-ref)
|
||||
(let ((val (expand #'val r w mod)))
|
||||
|
@ -2605,47 +2606,11 @@
|
|||
(set! syntax-source
|
||||
(lambda (x) (source-annotation x)))
|
||||
|
||||
(set! syntax-local-binding
|
||||
(lambda (id)
|
||||
(arg-check nonsymbol-id? id 'syntax-local-binding)
|
||||
(with-transformer-environment
|
||||
(lambda (e r w s rib mod)
|
||||
(define (strip-anti-mark w)
|
||||
(let ((ms (wrap-marks w)) (s (wrap-subst w)))
|
||||
(if (and (pair? ms) (eq? (car ms) the-anti-mark))
|
||||
;; output is from original text
|
||||
(make-wrap (cdr ms) (if rib (cons rib (cdr s)) (cdr s)))
|
||||
;; output introduced by macro
|
||||
(make-wrap ms (if rib (cons rib s) s)))))
|
||||
(call-with-values (lambda ()
|
||||
(resolve-identifier
|
||||
(syntax-object-expression id)
|
||||
(strip-anti-mark (syntax-object-wrap id))
|
||||
r
|
||||
(syntax-object-module id)
|
||||
;; FIXME: come up with a better policy for
|
||||
;; resolve-syntax-parameters
|
||||
#t))
|
||||
(lambda (type value mod)
|
||||
(case type
|
||||
((lexical) (values 'lexical value))
|
||||
((macro) (values 'macro value))
|
||||
((syntax) (values 'pattern-variable value))
|
||||
((displaced-lexical) (values 'displaced-lexical #f))
|
||||
((global) (values 'global (cons value (cdr mod))))
|
||||
(else (values 'other #f)))))))))
|
||||
|
||||
(set! syntax-locally-bound-identifiers
|
||||
(lambda (x)
|
||||
(arg-check nonsymbol-id? x 'syntax-locally-bound-identifiers)
|
||||
(locally-bound-identifiers (syntax-object-wrap x)
|
||||
(syntax-object-module x))))
|
||||
|
||||
(set! generate-temporaries
|
||||
(lambda (ls)
|
||||
(arg-check list? ls 'generate-temporaries)
|
||||
(let ((mod (cons 'hygiene (module-name (current-module)))))
|
||||
(map (lambda (x) (wrap (gensym-hook) top-wrap mod)) ls))))
|
||||
(map (lambda (x) (wrap (gensym "t-") top-wrap mod)) ls))))
|
||||
|
||||
(set! free-identifier=?
|
||||
(lambda (x y)
|
||||
|
@ -2669,6 +2634,53 @@
|
|||
(strip form empty-wrap)
|
||||
(and subform (strip subform empty-wrap)))))
|
||||
|
||||
(let ()
|
||||
(define (syntax-module id)
|
||||
(arg-check nonsymbol-id? id 'syntax-module)
|
||||
(cdr (syntax-object-module id)))
|
||||
|
||||
(define (syntax-local-binding id)
|
||||
(arg-check nonsymbol-id? id 'syntax-local-binding)
|
||||
(with-transformer-environment
|
||||
(lambda (e r w s rib mod)
|
||||
(define (strip-anti-mark w)
|
||||
(let ((ms (wrap-marks w)) (s (wrap-subst w)))
|
||||
(if (and (pair? ms) (eq? (car ms) the-anti-mark))
|
||||
;; output is from original text
|
||||
(make-wrap (cdr ms) (if rib (cons rib (cdr s)) (cdr s)))
|
||||
;; output introduced by macro
|
||||
(make-wrap ms (if rib (cons rib s) s)))))
|
||||
(call-with-values (lambda ()
|
||||
(resolve-identifier
|
||||
(syntax-object-expression id)
|
||||
(strip-anti-mark (syntax-object-wrap id))
|
||||
r
|
||||
(syntax-object-module id)
|
||||
;; FIXME: come up with a better policy for
|
||||
;; resolve-syntax-parameters
|
||||
#t))
|
||||
(lambda (type value mod)
|
||||
(case type
|
||||
((lexical) (values 'lexical value))
|
||||
((macro) (values 'macro value))
|
||||
((syntax) (values 'pattern-variable value))
|
||||
((displaced-lexical) (values 'displaced-lexical #f))
|
||||
((global) (values 'global (cons value (cdr mod))))
|
||||
(else (values 'other #f))))))))
|
||||
|
||||
(define (syntax-locally-bound-identifiers id)
|
||||
(arg-check nonsymbol-id? id 'syntax-locally-bound-identifiers)
|
||||
(locally-bound-identifiers (syntax-object-wrap id)
|
||||
(syntax-object-module id)))
|
||||
|
||||
;; Using define! instead of set! to avoid warnings at
|
||||
;; compile-time, after the variables are stolen away into (system
|
||||
;; syntax). See the end of boot-9.scm.
|
||||
;;
|
||||
(define! 'syntax-module syntax-module)
|
||||
(define! 'syntax-local-binding syntax-local-binding)
|
||||
(define! 'syntax-locally-bound-identifiers syntax-locally-bound-identifiers))
|
||||
|
||||
;; $sc-dispatch expects an expression and a pattern. If the expression
|
||||
;; matches the pattern a list of the matching expressions for each
|
||||
;; "any" is returned. Otherwise, #f is returned. (This use of #f will
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue