Changeset 15038 in project for chicken/trunk


Ignore:
Timestamp:
06/20/09 16:07:53 (10 years ago)
Author:
felix winkelmann
Message:
  • `er-macro-transformer' is not officially required anymore and moved from the scheme module into the chicken module
  • internal support or compiler macros
  • locating import-library does start in repo, as it used to be (otherwise you'll get runtime linker errors during build)
Location:
chicken/trunk
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • chicken/trunk/NEWS

    r14236 r15038  
    1 4.0.1
    2 
    3 - Added `er-macro-transformer'; Low-level syntax definitions should use
    4   this procedure to generate transformers from now on
    5 
    614.0.0
    72
  • chicken/trunk/chicken.import.scm

    r15001 r15038  
    204204   warning
    205205   eval-handler
     206   er-macro-transformer
    206207   dynamic-load-libraries
    207208   with-exception-handler)
    208  ##sys#chicken-macro-environment)       ;*** incorrect - won't work in compiled executable
     209 ##sys#chicken-macro-environment)       ;*** incorrect - won't work in compiled executable that does expansion
  • chicken/trunk/compiler.scm

    r15037 r15038  
    546546             (let* ((name0 (lookup (car x) se))
    547547                    (name (or (and (symbol? name0) (##sys#get name0 '##core#primitive)) name0))
    548                     (xexpanded (##sys#expand x se)))
     548                    (xexpanded (##sys#expand x se #t)))
    549549               (cond ((not (eq? x xexpanded))
    550550                      (walk xexpanded e se dest))
     
    620620                                                            (##sys#canonicalize-extension-path
    621621                                                             id 'require-extension)
    622                                                             #f #t)) ) )
     622                                                            #f)) ) )
    623623                                        (compiler-warning
    624624                                         'ext "extension `~A' is currently not installed" id))
     
    637637                                     (list alias (walk (cadr b) e se (car b))) )
    638638                                   aliases bindings)
    639                              ,(walk (##sys#canonicalize-body (cddr x) se2)
     639                             ,(walk (##sys#canonicalize-body (cddr x) se2 #t)
    640640                                    (append aliases e)
    641641                                    se2 dest) ) ) )
     
    670670                              (let* ((aliases (map gensym vars))
    671671                                     (se2 (append (map cons vars aliases) se))
    672                                      (body0 (##sys#canonicalize-body obody se2))
     672                                     (body0 (##sys#canonicalize-body obody se2 #t))
    673673                                     (body (walk body0 (append aliases e) se2 #f))
    674674                                     (llist2
     
    714714                                     se) ) )
    715715                           (walk
    716                             (##sys#canonicalize-body (cddr x) se2)
     716                            (##sys#canonicalize-body (cddr x) se2 #t)
    717717                            e se2
    718718                            dest) ) )
     
    733733                           ms)
    734734                          (walk
    735                            (##sys#canonicalize-body (cddr x) se2)
     735                           (##sys#canonicalize-body (cddr x) se2 #t)
    736736                           e se2 dest)))
    737737                               
     
    885885                               [body
    886886                                (walk
    887                                  (##sys#canonicalize-body obody se2)
     887                                 (##sys#canonicalize-body obody se2 #t)
    888888                                 (append aliases e)
    889889                                 se2 #f) ] )
  • chicken/trunk/eval.scm

    r15001 r15038  
    327327              [(symbol? (##sys#slot x 0))
    328328               (emit-syntax-trace-info tf x cntr)
    329                (let ((x2 (##sys#expand x se)))
     329               (let ((x2 (##sys#expand x se #f)))
    330330                 (d `(EVAL/EXPANDED: ,x2))
    331331                 (if (not (eq? x2 x))
     
    426426                                 (se2 (append (map cons vars aliases) se))
    427427                                 [body (##sys#compile-to-closure
    428                                         (##sys#canonicalize-body (cddr x) se2)
     428                                        (##sys#canonicalize-body (cddr x) se2 #f)
    429429                                        e2
    430430                                        se2
     
    502502                                      (body
    503503                                       (##sys#compile-to-closure
    504                                         (##sys#canonicalize-body body se2)
     504                                        (##sys#canonicalize-body body se2 #f)
    505505                                        e2
    506506                                        se2
     
    591591                                      se) ) )
    592592                            (compile
    593                              (##sys#canonicalize-body (cddr x) se2)
     593                             (##sys#canonicalize-body (cddr x) se2 #f)
    594594                             e #f tf cntr se2)))
    595595                               
     
    609609                             ms)
    610610                            (compile
    611                              (##sys#canonicalize-body (cddr x) se2)
     611                             (##sys#canonicalize-body (cddr x) se2 #f)
    612612                             e #f tf cntr se2)))
    613613                               
     
    10891089  (let ((file-exists? file-exists?)
    10901090        (string-append string-append) )
    1091     (lambda (p inc? here-first?)
     1091    (lambda (p inc?)
    10921092      (let ((rp (##sys#repository-path)))
    10931093        (define (check path)
     
    11001100                 p0) ) )
    11011101          (let loop ((paths (##sys#append
    1102                              (if here-first? '(".") '())
    11031102                             (if rp (list rp) '())
    11041103                             (if inc? ##sys#include-pathnames '())
    1105                              (if here-first? '() '("."))) ) )
     1104                             '("."))) )
    11061105            (and (pair? paths)
    11071106                 (let ((pa (##sys#slot paths 0)))
     
    11211120               (##sys#load-library id #f) )
    11221121              (else
    1123                (let ([id2 (##sys#find-extension p #t #f)])
     1122               (let ([id2 (##sys#find-extension p #t)])
    11241123                 (cond (id2
    11251124                        (##sys#load id2 #f #f)
  • chicken/trunk/expand.scm

    r15037 r15038  
    3131  (hide match-expression
    3232        macro-alias module-indirect-exports
    33         d dd dm map-se merge-se
     33        d dd dm dc map-se merge-se
    3434        lookup check-for-redef) )
    3535
     
    4646(define dd d)
    4747(define dm d)
     48(define dc d)
    4849
    4950(cond-expand
     
    5455 (else))
    5556
    56 (define-syntax dd (syntax-rules () ((_ . _) (void))))
    57 (define-syntax dm (syntax-rules () ((_ . _) (void))))
     57(begin
     58  (define-syntax dd (syntax-rules () ((_ . _) (void))))
     59  (define-syntax dm (syntax-rules () ((_ . _) (void))))
     60  (define-syntax dc (syntax-rules () ((_ . _) (void)))) )
    5861
    5962
     
    228231;; The basic macro-expander
    229232
    230 (define (##sys#expand-0 exp dse)
    231   (define (call-handler name handler exp se)
     233(define (##sys#expand-0 exp dse cs?)
     234  (define (call-handler name handler exp se cs)
    232235    (dd "invoking macro: " name)
    233236    (dd `(STATIC-SE: ,@(map-se se)))
     
    260263             ex) )
    261264      (let ((exp2 (handler exp se dse)))
    262         (when (eq? exp exp2)
     265        (when (and (not cs) (eq? exp exp2))
    263266          (##sys#syntax-error-hook
    264267           (string-append
    265268            "syntax transformer for `" (symbol->string name)
    266             "' returns original form, which would result in non-termination")
     269            "' returns original form, which would result in endless expansion")
    267270           exp))
    268271        (dd `(,name --> ,exp2))
     
    283286           (values
    284287            ;; force ref. opaqueness by passing dynamic se  [what is this comment meaning? I forgot]
    285             (call-handler head (cadr mdef) exp (car mdef))
     288            (call-handler head (cadr mdef) exp (car mdef) #f)
    286289            #t))
    287290          (else (values exp #f)) ) )
    288   (if (pair? exp)
     291  (let loop ((exp exp))
     292    (if (pair? exp)
    289293      (let ((head (car exp))
    290294            (body (cdr exp)) )
     
    317321                                (cdr body) )
    318322                        #t) ) ]
     323                    ((and cs? (symbol? head2) (##sys#get head2 '##compiler#compiler-syntax)) =>
     324                     (lambda (cs)
     325                       (dc "applying compiler syntax for `" head2 "' ...")
     326                       (let ((result (call-handler head (car cs) exp (cdr cs) #t)))
     327                         (if (eq? result exp)
     328                             (expand head exp head2)
     329                             (loop result)))))
    319330                    [else (expand head exp head2)] ) )
    320331            (values exp #f) ) )
    321       (values exp #f) ) )
     332      (values exp #f) ) ) )
    322333
    323334(define ##sys#enable-runtime-macros #f)
     
    358369;;; User-level macroexpansion
    359370
    360 (define (##sys#expand exp #!optional (se (##sys#current-environment)))
     371(define (##sys#expand exp #!optional (se (##sys#current-environment)) cs?)
    361372  (let loop ((exp exp))
    362     (let-values (((exp2 m) (##sys#expand-0 exp se)))
     373    (let-values (((exp2 m) (##sys#expand-0 exp se cs?)))
    363374      (if m
    364375          (loop exp2)
     
    488499  (let ([reverse reverse]
    489500        [map map] )
    490     (lambda (body #!optional (se (##sys#current-environment)))
     501    (lambda (body #!optional (se (##sys#current-environment)) cs?)
    491502      (define (fini vars vals mvars mvals body)
    492503        (if (and (null? vars) (null? mvars))
     
    592603                       (fini vars vals mvars mvals body))
    593604                      [else
    594                        (let ([x2 (##sys#expand-0 x se)])
     605                       (let ([x2 (##sys#expand-0 x se cs?)])
    595606                         (if (eq? x x2)
    596607                             (fini vars vals mvars mvals body)
     
    820831          (let ((il (##sys#find-extension
    821832                     (string-append (symbol->string mname) ".import")
    822                      #t #t)))
     833                     #t)))
    823834            (cond (il (parameterize ((##sys#current-module #f)
    824835                                     (##sys#current-environment '())
  • chicken/trunk/manual/Modules and macros

    r14556 r15038  
    1818Defines a macro named {{IDENTIFIER}} that will transform an expression
    1919with {{IDENTIFIER}} in operator position according to {{TRANSFORMER}}.
    20 The transformer expression must be an instance of
    21 {{er-macro-transformer}}, called with a procedure of three arguments,
    22 or a {{syntax-rules}} form. If {{syntax-rules}} is used, the usual
    23 R5RS semantics apply. If {{TRANSFORMER}} is an instance of
    24 {{er-macro-transformer}}, then it will be called on expansion with the
    25 complete s-expression of the macro invocation, a rename procedure that
    26 hygienically renames identifiers and a comparison procedure that
    27 compares (possibly renamed) identifiers.
     20The transformer expression must be a procedure with three arguments or
     21a {{syntax-rules}} form. If {{syntax-rules}} is used, the usual R5RS
     22semantics apply. If {{TRANSFORMER}} is a procedure, then it will
     23be called on expansion with the complete s-expression of the macro
     24invocation, a rename procedure that hygienically renames identifiers
     25and a comparison procedure that compares (possibly renamed) identifiers.
    2826
    2927{{define-syntax}} may be used to define local macros that are visible
     
    4745argument to the {{syntax-rules}} form.
    4846
    49 The alternative syntax
    50 
    51   (define-syntax (foo . LAMBDALIST) BODY ...)
    52 
    53 is also allowed and is equivalent to
    54 
    55   (define-syntax foo
    56     (er-macro-transformer
    57       (lambda LAMBDALIST BODY ...)))
    58 
    59 ==== er-macro-transformer
    60 
    61   [procedure] (er-macro-transformer PROCEDURE)
    62 
    63 Takes a low-level transformer procedure and returns an explicit renaming
    64 syntax transformer. The canonical method of defining a low-level macro is
    65 
    66   (define-syntax foo
    67     (er-macro-transformer
    68       (lambda (exp rename compare)
    69         ...)))
    7047
    7148==== define-compiled-syntax
     
    9673
    9774The low-level macro facility that CHICKEN provides is called "explicit
    98 renaming" and allows writing hygienic or non-hygienic macros
    99 procedurally.  When given a macro-transformer returned by
    100 {{er-macro-transformer}} instead of a {{syntax-rules}} form,
    101 {{define-syntax}} evaluates the procedure given to it in a distinct
    102 expansion environment (initially having access to the exported
    103 identifiers of the {{scheme}} module). The procedure takes an
    104 expression and two other arguments and returns a transformed
    105 expression.
    106 
    107 For example, the transformation procedure for a {{call}} macro such
    108 that {{(call proc arg ...)}} expands into {{(proc arg ...)}} can be
    109 written as
     75renaming" and allows writing hygienic or non-hygienic macros procedurally.
     76When given a lambda-expression instead of a {{syntax-rules}} form,
     77{{define-syntax}} evaluates the procedure in a distinct expansion
     78environment (initially having access to the exported identifiers
     79of the {{scheme}} module). The procedure takes an expression and two
     80other arguments and returns a transformed expression.
     81
     82For example, the transformation
     83procedure for a {{call}} macro such that
     84{{(call proc arg ...)}} expands
     85into {{(proc arg ...)}} can be written as
    11086
    11187  (lambda (exp rename compare)
    11288    (cdr exp))
    11389
    114 Expressions are represented as lists in the traditional manner, except
    115 that identifiers are represented as special uninterned symbols.
    116 
    117 The second argument to a transformation procedure is a renaming
    118 procedure that takes the representation of an identifier as its
    119 argument and returns the representation of a fresh identifier that
    120 occurs nowhere else in the program.  For example, the transformation
    121 procedure for a simplified version of the {{let}} macro might be
    122 written as
     90Expressions are represented as lists in the traditional manner,
     91except that identifiers are represented as special uninterned symbols.
     92
     93The second argument to a transformation procedure is a renaming procedure that
     94takes the representation of an identifier as its argument and returns the
     95representation of a fresh identifier that occurs nowhere else in the
     96program.  For example, the transformation procedure for a simplified
     97version of the {{let}} macro might be written as
    12398
    12499  (lambda (exp rename compare)
     
    184159thing in the syntactic environment of the expression being transformed
    185160as {{else}} denotes in the syntactic environment in which the {{cond}}
    186 macro was defined.  If {{else}} were not renamed before being passed
    187 to the comparison predicate, then it would match a local variable that
     161macro was defined.  If {{else}} were not renamed before being passed to
     162the comparison predicate, then it would match a local variable that
    188163happened to be named {{else}}, and the macro would not be hygienic.
    189164
    190 Some macros are non-hygienic by design.  For example, the following
    191 defines a {{loop}} macro that implicitly binds {{exit}} to an escape
    192 procedure.  The binding of {{exit}} is intended to capture free
     165Some macros are non-hygienic by design.  For example, the
     166following defines a {{loop}} macro that implicitly binds {{exit}} to an
     167escape procedure.  The binding of {{exit}} is intended to capture free
    193168references to {{exit}} in the body of the loop, so {{exit}} is not
    194169renamed.
    195170
    196171  (define-syntax loop
    197     (er-macro-transformer
    198       (lambda (x r c)
    199         (let ((body (cdr x)))
    200           `(,(r 'call-with-current-continuation)
    201             (,(r 'lambda) (exit)
    202              (,(r 'let) ,(r 'f) () ,@body (,(r 'f)))))))))
     172     (lambda (x r c)
     173       (let ((body (cdr x)))
     174         `(,(r 'call-with-current-continuation)
     175           (,(r 'lambda) (exit)
     176            (,(r 'let) ,(r 'f) () ,@body (,(r 'f))))))))
    203177
    204178Suppose a {{while}} macro is implemented using {{loop}}, with the intent
     
    207181
    208182  (define-syntax while
    209     (er-macro-transformer
    210       (syntax-rules ()
    211         ((while test body ...)
    212          (loop (if (not test) (exit #f))
    213                body ...)))))
     183    (syntax-rules ()
     184      ((while test body ...)
     185       (loop (if (not test) (exit #f))
     186             body ...))))
    214187
    215188because the reference to {{exit}} that is inserted by the {{while}} macro
     
    219192
    220193  (define-syntax while
    221     (er-macro-transformer
    222       (lambda (x r c)
    223         (let ((test (cadr x))
    224               (body (cddr x)))
    225           `(,(r 'loop)
    226             (,(r 'if) (,(r 'not) ,test) (exit #f))
    227             ,@body)))))
     194     (lambda (x r c)
     195       (let ((test (cadr x))
     196             (body (cddr x)))
     197         `(,(r 'loop)
     198           (,(r 'if) (,(r 'not) ,test) (exit #f))
     199           ,@body))))
    228200
    229201
  • chicken/trunk/manual/Unit expand

    r13710 r15038  
    3434{{error}}.
    3535
     36
     37==== er-macro-transformer
     38
     39  [procedure] (er-macro-transformer TRANSFORMER)
     40
     41This procedure does nothing and is available for writing low-level
     42macros in a more portable fashion, without hard-coding the signature
     43of a transformer procedure.
     44
     45
    3646---
    3747Previous: [[Unit library]]
  • chicken/trunk/private-namespace.scm

    r14236 r15038  
    2929 (hygienic-macros
    3030  (define-syntax private
    31     ;;XXX use er-macro-transformer
    3231    (lambda (form r c)
    3332      (let ((namespace (cadr form))
  • chicken/trunk/scheme.import.scm

    r14236 r15038  
    5454       with-output-to-file dynamic-wind values call-with-values eval
    5555       char-ready? imag-part real-part magnitude numerator denominator
    56        scheme-report-environment null-environment interaction-environment
    57        er-macro-transformer)
     56       scheme-report-environment null-environment interaction-environment)
    5857 ##sys#default-macro-environment)
  • chicken/trunk/setup-api.scm

    r15000 r15038  
    400400
    401401(define-syntax make
    402   ;;XXX use er-macro-transformer
    403402  (lambda (form r c)
    404403    (##sys#check-syntax 'make form '(_ _ . #(_ 0 1)))
  • chicken/trunk/srfi-13.scm

    r14236 r15038  
    206206 (else
    207207  (define-syntax let-string-start+end
    208     ;;XXX use er-macro-transformer
    209208    (lambda (form r c)
    210209      (##sys#check-syntax 'let-string-start+end form '(_ _ _ _ _ . _))
  • chicken/trunk/srfi-69.scm

    r14806 r15038  
    144144
    145145(define-syntax $flonum-hash
    146   ;;XXX use er-macro-transformer
    147146  (lambda (form r c)
    148147    (let ( (flo (cadr form))
  • chicken/trunk/tests/srfi-18-tests.scm

    r14236 r15038  
    44(define-for-syntax count 0)
    55(define-syntax trail
    6   (er-macro-transformer
    76  (lambda (form r c)                    ; doesn't bother much with renaming
    87    (let ((loc (cadr form))
     
    1312        (let ((xxx ,expr))
    1413          (print "  (" ,count ") " ,loc ": " ',expr ": get: " (##sys#slot get-mutex 5) ", put: " (##sys#slot put-mutex 5))
    15           xxx) ) )))))
     14          xxx) ) ))))
    1615(else (define-syntax trail (syntax-rules () ((_ loc expr) expr)))))
    1716
  • chicken/trunk/tests/syntax-tests.scm

    r15020 r15038  
    212212
    213213(define-syntax loop
    214   (er-macro-transformer
    215    (lambda (x r c)
    216      (let ((body (cdr x)))
    217        `(,(r 'call/cc)
    218          (,(r 'lambda) (exit)
    219           (,(r 'let) ,(r 'f) () ,@body (,(r 'f)))))))))
     214  (lambda (x r c)
     215    (let ((body (cdr x)))
     216      `(,(r 'call/cc)
     217        (,(r 'lambda) (exit)
     218         (,(r 'let) ,(r 'f) () ,@body (,(r 'f))))))))
    220219
    221220(let ((n 10))
     
    235234
    236235(define-syntax while
    237   (er-macro-transformer
    238    (lambda (x r c)
    239      `(,(r 'loop)
    240        (,(r 'if) (,(r 'not) ,(cadr x)) (exit #f))
    241        ,@(cddr x)))))
     236  (lambda (x r c)
     237    `(,(r 'loop)
     238      (,(r 'if) (,(r 'not) ,(cadr x)) (exit #f))
     239      ,@(cddr x))))
    242240
    243241(let ((n 10))
Note: See TracChangeset for help on using the changeset viewer.