Changeset 38671 in project


Ignore:
Timestamp:
05/01/20 19:44:04 (7 months ago)
Author:
juergen
Message:

procedural-macros 3.0 docu

File:
1 edited

Legend:

Unmodified
Added
Removed
  • wiki/eggref/5/procedural-macros

    r38190 r38671  
    2727
    2828This library provides the means for this to happen. In particular,
    29 you'll find a variant of good old define-macro and a macro, macro-rules,
    30 which looks much like syntax-rules.
     29you'll find variants of good old define-macro. And macro-rules are
     30implemented, which looks much like syntax-rules but doesn't have its
     31limitations.
    3132
    3233
    3334=== Module procedural-macros
    3435
    35 ==== macro-rules
    36 
    37 <macro>(macro-rules sym ... (key ...) (pat tpl) ....)</macro>
    38 
    39 like syntax-rules, but the templates are usually quasiquote-expressions.
    40 Moreover, the symbols sym ... are injected, if there are any.
    41 
    42 Note, that non-symbol literals are accepted in each pat and considered a
    43 match if they are equal to the corresponding expression in the
    44 macro-code. The keys are transformed to keyword literals behind the
    45 scene.
    46 
    47 macro-rules must be imported for syntax if used in the preprocessing
    48 phase of a macro evaluation.
     36==== define-er-macro
     37
     38<macro>(define-er-macro (name . args) (where . fenders) prefix xpr . xprs)</macro>
     39<macro>(define-er-macro (name . args) prefix xpr . xprs)</macro>
     40<macro>(define-er-macro name (pat (where . fenders) prefix xpr . xprs) . others)</macro>
     41<macro>(define-er-macro name (pat prefix xpr . xprs) . others)</macro>
     42
     43where fenders are of the form (key? sym) most of the time, to check for keywords.
     44A version of good old define-macro, where symbols prefixed with prefix are
     45automatically renamed.
     46
     47==== define-ir-macro
     48
     49<macro>(define-ir-macro (name . args) (where . fenders) prefix xpr . xprs)</macro>
     50<macro>(define-ir-macro (name . args) prefix xpr . xprs)</macro>
     51<macro>(define-ir-macro name (pat (where . fenders) prefix xpr . xprs) . others)</macro>
     52<macro>(define-ir-macro name (pat prefix xpr . xprs) . others)</macro>
     53
     54where fenders are of the form (key? sym) most of the time, to check for keywords.
     55A version of good old define-macro, where symbols prefixed with prefix
     56are automatically injected.
    4957
    5058==== define-macro
     
    6472The last form is implicit-renaming without injections and keys.
    6573
     74==== macro-rules
     75
     76<macro>(macro-rules sym ... (key ...) (pat tpl) ....)</macro>
     77
     78like syntax-rules, but the templates are usually quasiquote-expressions.
     79Moreover, the symbols sym ... are injected, if there are any.
     80
     81Note, that non-symbol literals are accepted in each pat and considered a
     82match if they are equal to the corresponding expression in the
     83macro-code. The keys are transformed to keyword literals behind the
     84scene.
     85
     86macro-rules must be imported for syntax if used in the preprocessing
     87phase of a macro evaluation.
     88
    6689==== macro-let
    6790
     
    134157(import procedural-macros)
    135158(import-for-syntax
    136   (only checks >>)
     159  (only checks <<)
    137160  (only bindings bind bind-case)
    138161  (only procedural-macros macro-rules with-renamed-symbols once-only))
     162
     163;; NUMERIC AND VERBOSE IF AS ER-MACRO
     164
     165(define-er-macro (er-nif xpr pos zer neg)
     166  %
     167  `(,%let ((,%result ,xpr))
     168     (,%cond
     169       ((,%positive? ,%result) ,pos)
     170       ((,%negative? ,%result) ,neg)
     171       (,%else ,zer))))
     172
     173(define-er-macro er-vif
     174  ((_ test (then . xprs) (else . yprs))
     175   (where (key? then) (key? else))
     176   %
     177   `(,%if ,test (,%begin ,@xprs) (,%begin ,@yprs))))
     178
     179;; COND AND CASE AS ER- OR IR-MACRO
     180
     181(define-er-macro er-cond
     182  ((_ (else xpr . xprs))
     183   (where (key? else))
     184   %
     185   `(,%begin ,xpr ,@xprs))
     186  ((_ (test => xpr))
     187   (where (key? =>))
     188   %
     189   `(,%let ((,%tmp ,test))
     190      (,%if ,%tmp (,xpr ,%tmp))))
     191  ((_ (test => xpr) . clauses)
     192   (where (key? =>))
     193   %
     194   `(,%let ((,%tmp ,test))
     195      (,%if ,%tmp
     196        (,xpr ,%tmp)
     197        (,%er-cond ,@clauses))))
     198  ((_ (test))
     199   %
     200   ;`(if #f #f))
     201   test)
     202  ((_ (test) . clauses)
     203   %
     204   `(,%let ((,%tmp ,test))
     205      (,%if ,%tmp
     206        ,%tmp
     207        (,%er-cond ,@clauses))))
     208  ((_ (test xpr . xprs))
     209   %
     210   `(,%if ,test (,%begin ,xpr ,@xprs)))
     211  ((_ (test xpr . xprs) . clauses)
     212   %
     213   `(,%if ,test
     214      (,%begin ,xpr ,@xprs)
     215      (,%er-cond ,@clauses)))
     216  )
     217
     218(define-ir-macro ir-case* ; helper
     219  ((_ key (else result . results))
     220   (where (key? else))
     221   %
     222   `(begin ,result ,@results))
     223  ((_ key (keys result . results))
     224   %
     225   `(if (memv ,key ',keys)
     226      (begin ,result ,@results)))
     227  ((_ key (keys result . results) clause . clauses)
     228   %
     229   `(if (memv ,key ',keys)
     230      (begin ,result ,@results)
     231      (ir-case* ,key ,clause ,@clauses)))
     232  )
     233
     234(define-ir-macro (ir-case key clause . clauses)
     235  %
     236  ;`(let ((tmp ,key)) ; ok
     237  ;   (ir-case* tmp ,clause ,@clauses)))
     238  (let ((tmp key)) ; ok
     239    `(ir-case* ,tmp ,clause ,@clauses)))
     240
     241;; ALAMBDA AS ER- AND IR-MACRO
     242
     243(define-ir-macro (ir-alambda args xpr . xprs)
     244  %
     245  `(letrec ((,%self (lambda ,args ,xpr ,@xprs)))
     246     ,%self))
     247
     248(define-er-macro (er-alambda args xpr . xprs)
     249  %
     250  `(,%letrec ((self (,%lambda ,args ,xpr ,@xprs)))
     251     self))
    139252
    140253;; TWO ANAPHORIC MACROS
     
    153266     `(letrec ((,self (lambda ,args ,xpr ,@xprs)))
    154267        ,self))))
     268
     269;; VERBOSE IF
     270(define-er-macro % (vvif test (then . xprs) (else . yprs))
     271  (lambda (compare?)
     272    (if (and (compare? then %then) (compare? else %else))
     273      `(,%if ,test (,%begin ,@xprs) (,%begin ,@yprs))
     274      `(,%error 'vvif "wrong keys" then else))))
    155275
    156276;; EFFICIENT MEMBERSHIP TESTING
     
    213333;; PROCEDURAL VERSION OF LETREC
    214334(define-macro (my-letrec pairs xpr . xprs)
    215   (>> pairs (list-of? pair?))
     335  (<< pairs (list-of? pair?))
    216336  (let ((vars (map car pairs))
    217337        (vals (map cadr pairs))
     
    228348    ((_ #f x) `(list 'false))
    229349    ((_ #f x) 'false)
    230     ((_ a b) (>> a string?) `(list ,a ,b))
    231     ((_ a b) (>> a odd?) `(list ,a ,b))
     350    ((_ a b) (<< a string?) `(list ,a ,b))
     351    ((_ a b) (<< a odd?) `(list ,a ,b))
    232352    ((_ a b) a)))
    233353
     
    235355(macro-let (
    236356  ((first lst)
    237    `(begin
    238       (>> ,lst list?)
    239       (car ,lst)))
     357   `(car (<< ,lst list?)))
    240358  ((rest lst)
    241    `(begin
    242       (>> ,lst list?)
    243       (cdr ,lst)))
     359   `(cdr (<< ,lst list?)))
    244360  )
    245361  (first (rest '(1 2 3))))
     
    255371== Last update
    256372
    257 Feb 21, 2020
     373May 01, 2020
    258374
    259375== Author
     
    294410== Version History
    295411
     412; 3.0 : define-er-macro and define-ir-macro added
    296413; 2.1 : bug in macro-let and macro-letrec fixed
    297414; 2.0 : simplyfied and streamlined rewrite. Only one module remains.
Note: See TracChangeset for help on using the changeset viewer.