March 23th Friday (三月  二十三日 金曜日)

  Quasiquote forms may be nested. Substitutions are made only for unquoted components appearing at the
same nesting level as the outermost quasiquote. The nesting level increases by one inside each
successive quasiquotation, and decreases by one inside each unquotation.

`(a `(b ,(+ 1 2) ,(foo ,(+ 1 3) d) e) f)
=> (a `(b ,(+ 1 2) ,(foo 4 d) e) f)

(let ((name1 ’x)
  (name2 ’y))
   `(a `(b ,,name1 ,’,name2 d) e))
=> (a `(b ,x ,’y d) e)


  Macro Transformer

  (syntax-rules (hliterali ...) hsyntax rulei ...)

  Each <literal> must be an identifier.  Each <syntax rule> must have the following form:

 (<srpattern> <template>)

  An <srpattern> is a restricted form of <pattern>, namely, a nonempty hpatterni in one of four
parenthesized forms below whose first subform is an identifier or an underscore.  A <pattern> is
an identifier, constant, or one of the following.

(<pattern> ...)
(<pattern> <pattern> ... . <pattern>)
(<pattern> ... <pattern> <ellipsis> <pattern> ...)
(<pattern> ... <pattern> <ellipsis> <pattern> ... . <pattern>)
#(<pattern> ...)
#(<pattern> ... <pattern> <ellipsis> <pattern> ...)

  An <ellipsis> is the identifier “...” (three periods).  A <template> is a pattern variable,
an identifier that is not a pattern variable, a pattern datum, or one of the following.

(<subtemplate> ...)
(<subtemplate> ... . <template>)
#(<subtemplate> ...)

  A <subtemplate> is a <template> followed by zero or more ellipses. 

  An instance of "syntax-rules" evaluates, at macro-expansion time, to a new macro transformer by
specifying a sequence of hygienic rewrite rules.  A use of a macro whose keyword is associated
with a transformer specified by "syntax-rules" is matched against the patterns contained in the
<syntax rule>s, beginning with the leftmost <syntax rule>.  When a match is found, the macro use
is transcribed hygienically according to the template. It is a syntax violation when no match is
found. 

  An identifier appearing within a hpatterni may be an underscore (_), a literal identifier
 listed in the list of literals (<literal> ...), or an ellipsis (...).  All other identifiers
appearing within a <pattern> are pattern variables.  It is a syntax violation if an ellipsis or
underscore appears in (<literal> ...). 

  While the first subform of <srpattern> may be an identifier, the identifier is not involved in
the matching and is not considered a pattern variable or literal identifier.

  (identifier-syntax <template>)
  (identifier-syntax (<id1> <template1>)
                     ((set! <id2> <pattern>) <template2>))

  The <id>s must be identifiers.  When a keyword is bound to a transformer produced by the first
form of identifier-syntax, references to the keyword within the scope of the binding are replaced
by <template>.

  (The identifier is most often the keyword used to identify the macro.  The scope of the keyword
is determined by the binding form or syntax definition that binds it to the associated macro
transformer.  If the keyword were a pattern variable or literal identifier, then the template
that follows the pattern would be within its scope regardless of whether the keyword were bound
by "let-syntax", "letrec-syntax", or "define-syntax".)

  Pattern variables match arbitrary input subforms and are used to refer to elements of the input.  It is a syntax violation if the same pattern variable appears more than once in a <pattern>.

  Underscores also match arbitrary input subforms but are not pattern variables and so cannot be
used to refer to those elements.  Multiple underscores may appear in a <pattern>.

  A literal identifier matches an input subform if and only if the input subform is an identifier and either both its occurrence in the input expression and its occurrence in the list of literals
have the same lexical binding, or the two identifiers have the same name and both have no lexical
binding.

  A subpattern followed by an ellipsis can match zero or more elements of the input.

  More formally, an input form F matches a pattern P if and only if one of the following holds:

  * P is an underscore (_).
  * P is a pattern variable.
  * P is a literal identifier and F is an identifier such that both P and F would refer to the
same binding if both were to appear in the output of the macro outside of any bindings inserted
into the output of the macro.  (If neither of two like-named identifiers refers to any binding,
i.e., both are undefined, they are considered to refer to the same binding.)
  * P is of the form (P1 ... Pn) and F is a list of n elements that match P1 through Pn.
  * P is of the form (P1 ... Pn . Px) and F is a list or improper list of n or more elements
whose first n elements match P1 through Pn and whose nth cdr matches Px.
  * P is of the form (P1 ... Pk Pe hellipsisi Pm+1 ... Pn), where hellipsisi is the identifier
... and F is a proper list of n elements whose first k elements match P1 through Pk, whose next
m?k elements each match Pe, and whose remaining n?m elements match Pm+1 through Pn.
  * P is of the form (P1 ... Pk Pe hellipsisi Pm+1 ... Pn . Px), where hellipsisi is the
identifier ... and F is a list or improper list of n elements whose first k elements match P1
through Pk, whose next m ? k elements each match Pe, whose next n ? m elements match Pm+1 through
Pn, and whose nth and final cdr matches Px.
  * P is of the form #(P1 ... Pn) and F is a vector of n elements that match P1 through Pn.
  * P is of the form #(P1 ... Pk Pe hellipsisi Pm+1 ... Pn), where hellipsisi is the identifier
... and F is a vector of n or more elements whose first k elements match P1 through Pk, whose
next m?k elements each match Pe, and whose remaining n?m elements match Pm+1 through Pn.
  * P is a pattern datum (any nonlist, nonvector, nonsymbol datum) and F is equal to P in the
sense of the "equal?" procedure.

  When a macro use is transcribed according to the template of the matching hsyntax rulei,
pattern variables that occur in the template are replaced by the subforms they match in the
input.

  Pattern data and identifiers that are not pattern variables or ellipses are copied directly
into the output.  A subtemplate followed by an ellipsis expands into zero or more occurrences
of the subtemplate.  Pattern variables that occur in subpatterns followed by one or more ellipses
may occur only in subtemplates that are followed by (at least) as many ellipses.  These pattern
variables are replaced in the output by the input subforms to which they are bound, distributed
as specified.  If a pattern variable is followed by more ellipses in the subtemplate than in the
associated subpattern, the input form is replicated as necessary.  The subtemplate must contain
at least one pattern variable from a subpattern followed by an ellipsis, and for at least one
such pattern variable, the subtemplate must be followed by exactly as many ellipses as the
 subpattern in which the pattern variable appears.  (Otherwise, the expander would not be able to
determine how many times the subform should be repeated in the output.)  It is a syntax violation
if the constraints of this paragraph are not met.

  A template of the form (<ellipsis> <template>) is identical to htemplatei, except that ellipses
within the template have no special meaning.  That is, any ellipses contained within <template>
are treated as ordinary identifiers.  In particular, the template (... ...) produces a single
ellipsis, .... This allows syntactic abstractions to expand into forms containing ellipses.

  (define p (cons 4 5))
  (define-syntax p.car (identifier-syntax (car p)))
  p.car => 4
  (set! p.car 15) => &syntax exception

  The second, more general, form of "identifier-syntax" permits the transformer to determine what
happens when "set!" is used.  In this case, uses of the identifier by itself are replaced by
<template1>, and uses of set! with the identifier are replaced by <template2>.

  (define p (cons 4 5))
  (define-syntax p.car
    (identifier-syntax
 (_ (car p))
 ((set! _ e) (set-car! p e))))
    (set! p.car 15)

  p.car => 15
  p => (15 5) 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值