Ticket #394: ir-macros.patch

File ir-macros.patch, 5.6 KB (added by sjamaan, 14 years ago)

Add Implicit Renaming macros to Chicken Core (includes testsuite)

  • chicken.import.scm

    diff --git a/chicken.import.scm b/chicken.import.scm
    index 07cf416..acb2b41 100644
    a b  
    226226   warning
    227227   eval-handler
    228228   er-macro-transformer
     229   ir-macro-transformer
    229230   dynamic-load-libraries
    230231   with-exception-handler)
    231232 ##sys#chicken-macro-environment)       ;*** incorrect - won't work in compiled executable that does expansion
  • expand.scm

    diff --git a/expand.scm b/expand.scm
    index 52de4cf..0ada41f 100644
    a b  
    748748
    749749;;; explicit-renaming transformer
    750750
    751 (define (er-macro-transformer x) x)
    752 
    753 (define ((##sys#er-transformer handler) form se dse)
     751(define ((make-er/ir-transformer handler explicit-renaming?) form se dse)
    754752  (let ((renv '()))                     ; keep rename-environment for this expansion
    755753    (define (rename sym)
    756754      (cond ((pair? sym)
     
    820818                r)
    821819            ")")
    822820        r))
    823     (handler form rename compare) ) )
     821    (define (mirror-rename sym)
     822      (cond ((pair? sym)
     823             (cons (mirror-rename (car sym)) (mirror-rename (cdr sym))))
     824            ((vector? sym)
     825             (list->vector (mirror-rename (vector->list sym))))
     826            ((not (symbol? sym)) sym)
     827            (else                       ; Code stolen from ##sys#strip-syntax
     828             (let ((renamed (lookup sym se) ) )
     829               (cond ((getp sym '##core#real-name) =>
     830                      (lambda (name)
     831                        (dd "STRIP SYNTAX ON " sym " ---> " name)
     832                        name))
     833                     ((not renamed)
     834                      (dd "IMPLICITLY RENAMED: " sym) (rename sym))
     835                     ((pair? renamed)
     836                      (dd "MACRO: " sym) (rename sym))
     837                     (else (dd "BUILTIN ALIAS:" renamed) renamed))))))
     838    (if explicit-renaming?
     839        ;; Let the user handle renaming
     840        (handler form rename compare)
     841        ;; Implicit renaming:
     842        ;; Rename everything in the input first, feed it to the transformer
     843        ;; and then swap out all renamed identifiers by their non-renamed
     844        ;; versions, and vice versa.  User can decide when to inject code
     845        ;; unhygienically this way.
     846        (mirror-rename (handler (rename form) rename compare)) ) ) )
     847
     848(define (##sys#er-transformer handler) (make-er/ir-transformer handler #t))
     849(define (##sys#ir-transformer handler) (make-er/ir-transformer handler #f))
    824850
     851(define (er-macro-transformer x) x)
     852(define ir-macro-transformer ##sys#ir-transformer)
    825853
    826854;;; Macro definitions:
    827855
  • tests/syntax-tests.scm

    diff --git a/tests/syntax-tests.scm b/tests/syntax-tests.scm
    index cf35236..6524253 100644
    a b  
    402402(let-syntax ((s1 (syntax-rules () ((_ x) x))))
    403403  (assert (equal? '#((99)) (s2 99))))
    404404
     405;; IR macros
     406
     407(define-syntax loop2
     408  (ir-macro-transformer
     409   (lambda (x i c)
     410     (let ((body (cdr x)))
     411       `(call/cc
     412         (lambda (,(i 'exit))
     413           (let f () ,@body (f))))))))
     414
     415(let ((n 10))
     416  (loop2
     417   (print* n " ")
     418   (set! n (sub1 n))
     419   (when (zero? n) (exit #f)))
     420  (newline))
     421
     422(define-syntax while20
     423  (syntax-rules ()
     424    ((_ t b ...)
     425     (loop2 (if (not t) (exit #f))
     426            b ...))))
     427
     428(f (while20 #f (print "no.")))
     429
     430(define-syntax while2
     431  (ir-macro-transformer
     432   (lambda (x i c)
     433     `(loop
     434       (if (not ,(cadr x)) (,(i 'exit) #f))
     435       ,@(cddr x)))))
     436
     437(let ((n 10))
     438  (while2 (not (zero? n))
     439          (print* n " ")
     440          (set! n (- n 1)) )
     441  (newline))
     442
     443(module m2 (s3 s4)
     444
     445  (import chicken scheme)
     446
     447  (define-syntax s3 (syntax-rules () ((_ x) (list x))))
     448
     449  (define-syntax s4
     450    (ir-macro-transformer
     451     (lambda (x r c)
     452       `(vector (s3 ,(cadr x)))))) ) ; without implicit renaming the local version
     453                                     ; of `s3' below would be captured
     454
     455(import m2)
     456
     457(let-syntax ((s3 (syntax-rules () ((_ x) x))))
     458  (t '#((99)) (s4 99)))
     459
     460(let ((vector list))
     461  (t '#((one)) (s4 'one)))
     462
     463(define-syntax nest-me
     464  (ir-macro-transformer
     465   (lambda (x i c)
     466     `(let ((,(i 'captured) 1))
     467        ,@(cdr x)))))
     468
     469(t '(1 #(1 #(1)))
     470   (nest-me (list captured
     471                  (let ((captured 2)
     472                        (let 'not-captured)
     473                        (list vector))
     474                    (nest-me (list captured
     475                                   (nest-me (list captured))))))))
     476
     477(define-syntax cond-test
     478  (ir-macro-transformer
     479   (lambda (x i c)
     480     (let lp ((exprs (cdr x)))
     481       (cond
     482        ((null? exprs) '(void))
     483        ((c (caar exprs) 'else)
     484         `(begin ,@(cdar exprs)))
     485        ((c (cadar exprs) '=>)
     486         `(let ((tmp ,(caar exprs)))
     487            (if tmp
     488                (,(caddar exprs) tmp)
     489                ,(lp (cdr exprs)))))
     490        ((c (cadar exprs) (i '==>)) ;; ==> is an Unhygienic variant of =>
     491         `(let ((tmp ,(caar exprs)))
     492            (if tmp
     493                (,(caddar exprs) tmp)
     494                ,(lp (cdr exprs)))))
     495        (else
     496         `(if ,(caar exprs)
     497              (begin ,@(cdar exprs))
     498              ,(lp (cdr exprs)))))))))
     499
     500(t 'yep
     501   (cond-test
     502    (#f 'false)
     503    (else 'yep)))
     504
     505(t 1
     506   (cond-test
     507    (#f 'false)
     508    (1 => (lambda (x) x))
     509    (else 'yep)))
     510
     511(let ((=> #f))
     512  (t 'a-procedure
     513     (cond-test
     514      (#f 'false)
     515      (1 => 'a-procedure)
     516      (else 'yep))))
     517
     518(let ((else #f))
     519  (t (void)
     520     (cond-test
     521      (#f 'false)
     522      (else 'nope))))
     523
     524(t 1
     525   (cond-test
     526    (#f 'false)
     527    (1 ==> (lambda (x) x))
     528    (else 'yep)))
     529
     530(let ((==> #f))
     531  (t 1
     532     (cond-test
     533      (#f 'false)
     534      (1 ==> (lambda (x) x))
     535      (else 'yep))))
     536
    405537
    406538;;; local definitions
    407539