mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-11 06:20:23 +02:00
add support for variable transformers: settable identifier syntax
* module/ice-9/psyntax.scm (set!): Handle variable transformers; though, they cannot produce definitions. (make-variable-transformer): New procedure. (identifier-syntax): Allow the R6RS form that makes variable transformers. * module/ice-9/psyntax-pp.scm: Regenerated. * doc/ref/r6rs.texi (R6RS Incompatibilities): Remove letrec* item, and add set! restriction.
This commit is contained in:
parent
7034da249b
commit
bfccdcd530
3 changed files with 8296 additions and 7755 deletions
|
@ -24,10 +24,6 @@ intentional, some of them are bugs, and some are simply unimplemented features.
|
||||||
Please let the Guile developers know if you find one that is not on this list.
|
Please let the Guile developers know if you find one that is not on this list.
|
||||||
|
|
||||||
@itemize
|
@itemize
|
||||||
@item
|
|
||||||
In the R6RS, internal definitions expand to @code{letrec*}, not @code{letrec}.
|
|
||||||
Guile does not support @code{letrec*}, though that would be nice.
|
|
||||||
|
|
||||||
@item
|
@item
|
||||||
The R6RS specifies many situations in which a conforming implementation must
|
The R6RS specifies many situations in which a conforming implementation must
|
||||||
signal a specific error. Guile doesn't really care about that too much -- if a
|
signal a specific error. Guile doesn't really care about that too much -- if a
|
||||||
|
@ -37,8 +33,12 @@ correct R6RS program would not hit that error, we don't bother checking for it.
|
||||||
Multiple @code{library} forms in one file are not yet supported. This is because
|
Multiple @code{library} forms in one file are not yet supported. This is because
|
||||||
the expansion of @code{library} sets the current module, but does not restore
|
the expansion of @code{library} sets the current module, but does not restore
|
||||||
it. This is a bug.
|
it. This is a bug.
|
||||||
@end itemize
|
|
||||||
|
|
||||||
|
@item
|
||||||
|
A @code{set!} to a variable transformer may only expand to an expression, not a
|
||||||
|
definition -- even if the original @code{set!} expression was in definition
|
||||||
|
context.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
@node R6RS Standard Libraries
|
@node R6RS Standard Libraries
|
||||||
@subsection R6RS Standard Libraries
|
@subsection R6RS Standard Libraries
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1327,7 +1327,6 @@
|
||||||
;; possible.
|
;; possible.
|
||||||
(define chi-macro
|
(define chi-macro
|
||||||
(lambda (p e r w s rib mod)
|
(lambda (p e r w s rib mod)
|
||||||
;; p := (procedure . module-name)
|
|
||||||
(define rebuild-macro-output
|
(define rebuild-macro-output
|
||||||
(lambda (x m)
|
(lambda (x m)
|
||||||
(cond ((pair? x)
|
(cond ((pair? x)
|
||||||
|
@ -2138,16 +2137,23 @@
|
||||||
(syntax-case e ()
|
(syntax-case e ()
|
||||||
((_ id val)
|
((_ id val)
|
||||||
(id? #'id)
|
(id? #'id)
|
||||||
(let ((val (chi #'val r w mod))
|
(let ((n (id-var-name #'id w)))
|
||||||
(n (id-var-name #'id w)))
|
|
||||||
(let ((b (lookup n r mod)))
|
(let ((b (lookup n r mod)))
|
||||||
(case (binding-type b)
|
(case (binding-type b)
|
||||||
((lexical)
|
((lexical)
|
||||||
(build-lexical-assignment s
|
(build-lexical-assignment s
|
||||||
(syntax->datum #'id)
|
(syntax->datum #'id)
|
||||||
(binding-value b)
|
(binding-value b)
|
||||||
val))
|
(chi #'val r w mod)))
|
||||||
((global) (build-global-assignment s n val mod))
|
((global)
|
||||||
|
(build-global-assignment s n (chi #'val r w mod) mod))
|
||||||
|
((macro)
|
||||||
|
(let ((p (binding-value b)))
|
||||||
|
(if (procedure-property p 'variable-transformer)
|
||||||
|
(chi (chi-macro p e r w s #f mod) r w mod)
|
||||||
|
(syntax-violation 'set! "not a variable transformer"
|
||||||
|
(wrap e w mod)
|
||||||
|
(wrap #'id w mod)))))
|
||||||
((displaced-lexical)
|
((displaced-lexical)
|
||||||
(syntax-violation 'set! "identifier out of context"
|
(syntax-violation 'set! "identifier out of context"
|
||||||
(wrap #'id w mod)))
|
(wrap #'id w mod)))
|
||||||
|
@ -2826,9 +2832,18 @@
|
||||||
clause))))))))
|
clause))))))))
|
||||||
#'(let ((t e)) body))))))
|
#'(let ((t e)) body))))))
|
||||||
|
|
||||||
|
(define (make-variable-transformer proc)
|
||||||
|
(if (procedure? proc)
|
||||||
|
(let ((trans (lambda (x)
|
||||||
|
#((macro-type . variable-transformer))
|
||||||
|
(proc x))))
|
||||||
|
(set-procedure-property! trans 'variable-transformer #t)
|
||||||
|
trans)
|
||||||
|
(error "variable transformer not a procedure" proc)))
|
||||||
|
|
||||||
(define-syntax identifier-syntax
|
(define-syntax identifier-syntax
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
(syntax-case x ()
|
(syntax-case x (set!)
|
||||||
((_ e)
|
((_ e)
|
||||||
#'(lambda (x)
|
#'(lambda (x)
|
||||||
#((macro-type . identifier-syntax))
|
#((macro-type . identifier-syntax))
|
||||||
|
@ -2837,7 +2852,16 @@
|
||||||
(identifier? #'id)
|
(identifier? #'id)
|
||||||
#'e)
|
#'e)
|
||||||
((_ x (... ...))
|
((_ x (... ...))
|
||||||
#'(e x (... ...)))))))))
|
#'(e x (... ...))))))
|
||||||
|
((_ (id exp1) ((set! var val) exp2))
|
||||||
|
(and (identifier? #'id) (identifier? #'var))
|
||||||
|
#'(make-variable-transformer
|
||||||
|
(lambda (x)
|
||||||
|
#((macro-type . variable-transformer))
|
||||||
|
(syntax-case x (set!)
|
||||||
|
((set! var val) #'exp2)
|
||||||
|
((id x (... ...)) #'(exp1 x (... ...)))
|
||||||
|
(id (identifier? #'id) #'exp1))))))))
|
||||||
|
|
||||||
(define-syntax define*
|
(define-syntax define*
|
||||||
(lambda (x)
|
(lambda (x)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue