2007-04-28 20:54:02 -04:00
|
|
|
|
2007-05-08 05:47:30 -04:00
|
|
|
;;; FIXME: teach the compiler about (apply append ls) since I
|
|
|
|
;;; used it a zillion times in this file.
|
|
|
|
;;; other primitives that are usually apply'd include the
|
|
|
|
;;; arithmetic operations (+, =, min, max, ...).
|
|
|
|
;;; (apply (lambda ---) ls) is also common in this file.
|
|
|
|
|
2007-05-01 05:16:32 -04:00
|
|
|
(library (ikarus syntax)
|
2007-05-11 21:06:31 -04:00
|
|
|
(export identifier? syntax-dispatch environment environment?
|
2007-09-11 13:32:14 -04:00
|
|
|
eval expand generate-temporaries free-identifier=?
|
2007-05-11 22:50:02 -04:00
|
|
|
bound-identifier=? syntax-error datum->syntax
|
2007-09-02 02:03:29 -04:00
|
|
|
syntax->datum make-variable-transformer
|
2007-09-02 03:09:29 -04:00
|
|
|
eval-r6rs-top-level boot-library-expand eval-top-level
|
|
|
|
null-environment)
|
2007-05-08 06:56:20 -04:00
|
|
|
(import
|
2007-05-09 12:54:57 -04:00
|
|
|
(r6rs)
|
2007-05-09 11:12:27 -04:00
|
|
|
(except (ikarus library-manager) installed-libraries)
|
2007-05-15 08:56:22 -04:00
|
|
|
(only (ikarus system $bootstrap) eval-core)
|
2007-05-09 11:12:27 -04:00
|
|
|
(chez modules)
|
2007-05-09 11:17:54 -04:00
|
|
|
(ikarus symbols)
|
2007-05-09 12:54:57 -04:00
|
|
|
(ikarus parameters)
|
2007-09-09 23:41:12 -04:00
|
|
|
(only (ikarus) error printf ormap andmap cons* format
|
2007-09-02 01:16:14 -04:00
|
|
|
make-record-type void set-rtd-printer! type-descriptor
|
|
|
|
pretty-print)
|
2007-05-09 12:54:57 -04:00
|
|
|
(only (r6rs syntax-case) syntax-case syntax with-syntax)
|
|
|
|
(prefix (r6rs syntax-case) sys:))
|
2007-05-03 01:25:09 -04:00
|
|
|
(define who 'expander)
|
2007-05-08 06:56:20 -04:00
|
|
|
(define-syntax no-source
|
2007-05-01 05:12:32 -04:00
|
|
|
(lambda (x) #f))
|
2007-05-08 06:56:20 -04:00
|
|
|
(begin ;;; builders
|
2007-05-01 05:12:32 -04:00
|
|
|
(define-syntax build-application
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ ae fun-exp arg-exps)
|
|
|
|
`(,fun-exp . ,arg-exps))))
|
|
|
|
(define-syntax build-conditional
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ ae test-exp then-exp else-exp)
|
|
|
|
`(if ,test-exp ,then-exp ,else-exp))))
|
|
|
|
(define-syntax build-lexical-reference
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ ae var) var)
|
|
|
|
((_ type ae var) var)))
|
|
|
|
(define-syntax build-lexical-assignment
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ ae var exp) `(set! ,var ,exp))))
|
|
|
|
(define-syntax build-global-reference
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ae var) `(top-level-value ',var)]))
|
|
|
|
(define-syntax build-global-assignment
|
|
|
|
(syntax-rules ()
|
2007-05-02 01:52:11 -04:00
|
|
|
[(_ ae var exp) `(#%set-top-level-value! ',var ,exp)]))
|
2007-05-01 05:12:32 -04:00
|
|
|
(define-syntax build-global-definition
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ae var exp) (build-global-assignment ae var exp)]))
|
|
|
|
(define-syntax build-lambda
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ae vars exp) `(case-lambda [,vars ,exp])]))
|
|
|
|
(define build-case-lambda
|
|
|
|
(lambda (ae vars* exp*)
|
|
|
|
`(case-lambda . ,(map list vars* exp*))))
|
|
|
|
(define build-let
|
|
|
|
(lambda (ae lhs* rhs* body)
|
|
|
|
`((case-lambda [,lhs* ,body]) . ,rhs*)))
|
|
|
|
(define-syntax build-primref
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ae name) (build-primref ae 1 name)]
|
|
|
|
[(_ ae level name) `(|#primitive| ,name)]))
|
|
|
|
(define-syntax build-foreign-call
|
|
|
|
(syntax-rules ()
|
|
|
|
[(_ ae name arg*) `(foreign-call ,name . ,arg*)]))
|
|
|
|
(define-syntax build-data
|
|
|
|
(syntax-rules ()
|
|
|
|
((_ ae exp) `',exp)))
|
|
|
|
(define build-sequence
|
|
|
|
(lambda (ae exps)
|
|
|
|
(let loop ((exps exps))
|
|
|
|
(if (null? (cdr exps))
|
|
|
|
(car exps)
|
|
|
|
(if (equal? (car exps) '(#%void))
|
|
|
|
(loop (cdr exps))
|
|
|
|
`(begin ,@exps))))))
|
|
|
|
(define build-void
|
|
|
|
(lambda () '(#%void)))
|
|
|
|
(define build-letrec
|
|
|
|
(lambda (ae vars val-exps body-exp)
|
2007-05-09 06:09:37 -04:00
|
|
|
(if (null? vars) body-exp `(letrec ,(map list vars val-exps) ,body-exp))))
|
|
|
|
(define build-letrec*
|
|
|
|
(lambda (ae vars val-exps body-exp)
|
|
|
|
(if (null? vars) body-exp `(letrec* ,(map list vars val-exps) ,body-exp)))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define top-mark* '(top))
|
|
|
|
(define top-marked?
|
|
|
|
(lambda (m*) (memq 'top m*)))
|
2007-05-08 06:56:20 -04:00
|
|
|
(define gen-lexical
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (sym)
|
|
|
|
(cond
|
2007-05-08 06:56:20 -04:00
|
|
|
[(symbol? sym)
|
2007-04-30 04:51:37 -04:00
|
|
|
(gensym (symbol->string sym))]
|
|
|
|
[(stx? sym) (gen-lexical (id->sym sym))]
|
|
|
|
[else (error 'gen-lexical "invalid arg ~s" sym)])))
|
2007-05-09 23:42:32 -04:00
|
|
|
(define (gen-global x) (gen-lexical x))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define gen-label
|
|
|
|
(lambda (_) (gensym)))
|
2007-05-07 00:44:28 -04:00
|
|
|
(define-record rib (sym* mark** label* sealed/freq))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define make-full-rib
|
|
|
|
(lambda (id* label*)
|
2007-05-07 00:44:28 -04:00
|
|
|
(make-rib (map id->sym id*) (map stx-mark* id*) label* #f)))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define make-empty-rib
|
|
|
|
(lambda ()
|
2007-05-07 00:44:28 -04:00
|
|
|
(make-rib '() '() '() #f)))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define extend-rib!
|
|
|
|
(lambda (rib id label)
|
|
|
|
(if (rib? rib)
|
|
|
|
(let ([sym (id->sym id)] [mark* (stx-mark* id)])
|
2007-05-07 00:44:28 -04:00
|
|
|
(when (rib-sealed/freq rib)
|
|
|
|
(error 'extend-rib! "rib ~s is sealed" rib))
|
2007-05-07 00:25:21 -04:00
|
|
|
(set-rib-sym*! rib (cons sym (rib-sym* rib)))
|
|
|
|
(set-rib-mark**! rib (cons mark* (rib-mark** rib)))
|
|
|
|
(set-rib-label*! rib (cons label (rib-label* rib))))
|
2007-05-07 00:44:28 -04:00
|
|
|
(error 'extend-rib! "~s is not a rib" rib))))
|
2007-05-08 01:42:19 -04:00
|
|
|
(define (extend-rib/check! rib id label)
|
|
|
|
(cond
|
|
|
|
[(rib? rib)
|
|
|
|
(when (rib-sealed/freq rib)
|
|
|
|
(error 'extend-rib/check! "rib ~s is sealed" rib))
|
|
|
|
(let ([sym (id->sym id)] [mark* (stx-mark* id)])
|
|
|
|
(let ([sym* (rib-sym* rib)])
|
|
|
|
(when (and (memq sym (rib-sym* rib))
|
|
|
|
(bound-id=? id
|
|
|
|
(stx sym mark* (list rib))))
|
|
|
|
(stx-error id "cannot redefine"))
|
|
|
|
(set-rib-sym*! rib (cons sym sym*))
|
|
|
|
(set-rib-mark**! rib (cons mark* (rib-mark** rib)))
|
|
|
|
(set-rib-label*! rib (cons label (rib-label* rib)))))]
|
|
|
|
[else (error 'extend-rib/check! "~s is not a rib" rib)]))
|
2007-05-01 16:41:36 -04:00
|
|
|
(module (make-stx stx? stx-expr stx-mark* stx-subst*)
|
2007-05-15 10:18:58 -04:00
|
|
|
(define-record stx (expr mark* subst*))
|
|
|
|
(set-rtd-printer! (type-descriptor stx)
|
|
|
|
(lambda (x p)
|
|
|
|
(display "#<syntax " p)
|
2007-09-02 02:03:29 -04:00
|
|
|
(write (stx->datum x) p)
|
2007-05-15 10:18:58 -04:00
|
|
|
(display ">" p))))
|
2007-05-07 02:17:39 -04:00
|
|
|
(define (seal-rib! rib)
|
|
|
|
(let ([sym* (rib-sym* rib)])
|
|
|
|
(unless (null? sym*)
|
|
|
|
;;; only seal if rib is not empty.
|
|
|
|
(let ([sym* (list->vector sym*)])
|
|
|
|
(set-rib-sym*! rib sym*)
|
2007-05-08 06:56:20 -04:00
|
|
|
(set-rib-mark**! rib
|
2007-05-07 02:17:39 -04:00
|
|
|
(list->vector (rib-mark** rib)))
|
2007-05-08 06:56:20 -04:00
|
|
|
(set-rib-label*! rib
|
2007-05-07 02:17:39 -04:00
|
|
|
(list->vector (rib-label* rib)))
|
|
|
|
(set-rib-sealed/freq! rib
|
|
|
|
(make-vector (vector-length sym*) 0))))))
|
2007-05-07 02:48:23 -04:00
|
|
|
(define (unseal-rib! rib)
|
|
|
|
(when (rib-sealed/freq rib)
|
|
|
|
(set-rib-sealed/freq! rib #f)
|
|
|
|
(set-rib-sym*! rib (vector->list (rib-sym* rib)))
|
|
|
|
(set-rib-mark**! rib (vector->list (rib-mark** rib)))
|
|
|
|
(set-rib-label*! rib (vector->list (rib-label* rib)))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define datum->stx
|
|
|
|
(lambda (id datum)
|
|
|
|
(make-stx datum (stx-mark* id) (stx-subst* id))))
|
|
|
|
(define join-wraps
|
|
|
|
(lambda (m1* s1* e)
|
2007-05-08 06:56:20 -04:00
|
|
|
(define cancel
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (ls1 ls2)
|
|
|
|
(let f ((x (car ls1)) (ls1 (cdr ls1)))
|
|
|
|
(if (null? ls1)
|
|
|
|
(cdr ls2)
|
|
|
|
(cons x (f (car ls1) (cdr ls1)))))))
|
|
|
|
(let ((m2* (stx-mark* e)) (s2* (stx-subst* e)))
|
|
|
|
(if (and (not (null? m1*))
|
|
|
|
(not (null? m2*))
|
|
|
|
(eq? (car m2*) anti-mark))
|
|
|
|
; cancel mark, anti-mark, and corresponding shifts
|
|
|
|
(values (cancel m1* m2*) (cancel s1* s2*))
|
|
|
|
(values (append m1* m2*) (append s1* s2*))))))
|
|
|
|
(define stx
|
|
|
|
(lambda (e m* s*)
|
|
|
|
(if (stx? e)
|
|
|
|
(let-values ([(m* s*) (join-wraps m* s* e)])
|
|
|
|
(make-stx (stx-expr e) m* s*))
|
|
|
|
(make-stx e m* s*))))
|
|
|
|
(define add-subst
|
|
|
|
(lambda (subst e)
|
|
|
|
(if subst
|
|
|
|
(stx e '() (list subst))
|
|
|
|
e)))
|
|
|
|
(define gen-mark
|
|
|
|
(lambda () (string #\m)))
|
|
|
|
(define add-mark
|
|
|
|
(lambda (m e)
|
|
|
|
(stx e (list m) '(shift))))
|
|
|
|
(define anti-mark #f)
|
2007-05-08 06:56:20 -04:00
|
|
|
(define syntax-kind?
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (x p?)
|
|
|
|
(if (stx? x)
|
|
|
|
(syntax-kind? (stx-expr x) p?)
|
|
|
|
(p? x))))
|
2007-05-01 04:36:53 -04:00
|
|
|
(define syntax-vector->list
|
|
|
|
(lambda (x)
|
|
|
|
(cond
|
2007-05-08 06:56:20 -04:00
|
|
|
[(stx? x)
|
2007-05-01 04:36:53 -04:00
|
|
|
(let ([ls (syntax-vector->list (stx-expr x))]
|
|
|
|
[m* (stx-mark* x)] [s* (stx-subst* x)])
|
|
|
|
(map (lambda (x) (stx x m* s*)) ls))]
|
|
|
|
[(vector? x) (vector->list x)]
|
|
|
|
[else (error 'syntax-vector->list "not a syntax vector ~s" x)])))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define syntax-pair?
|
|
|
|
(lambda (x) (syntax-kind? x pair?)))
|
2007-05-08 06:56:20 -04:00
|
|
|
(define syntax-vector?
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (x) (syntax-kind? x vector?)))
|
|
|
|
(define syntax-null?
|
|
|
|
(lambda (x) (syntax-kind? x null?)))
|
|
|
|
(define syntax-list?
|
|
|
|
(lambda (x)
|
|
|
|
(or (syntax-null? x)
|
|
|
|
(and (syntax-pair? x) (syntax-list? (syntax-cdr x))))))
|
|
|
|
(define syntax-car
|
|
|
|
(lambda (x)
|
|
|
|
(if (stx? x)
|
|
|
|
(stx (syntax-car (stx-expr x)) (stx-mark* x) (stx-subst* x))
|
|
|
|
(if (pair? x)
|
|
|
|
(car x)
|
|
|
|
(error 'syntax-car "~s is not a pair" x)))))
|
|
|
|
(define syntax->list
|
|
|
|
(lambda (x)
|
|
|
|
(if (syntax-pair? x)
|
|
|
|
(cons (syntax-car x) (syntax->list (syntax-cdr x)))
|
|
|
|
(if (syntax-null? x)
|
|
|
|
'()
|
|
|
|
(error 'syntax->list "invalid ~s" x)))))
|
|
|
|
(define syntax-cdr
|
|
|
|
(lambda (x)
|
|
|
|
(if (stx? x)
|
|
|
|
(stx (syntax-cdr (stx-expr x)) (stx-mark* x) (stx-subst* x))
|
|
|
|
(if (pair? x)
|
|
|
|
(cdr x)
|
2007-05-08 06:56:20 -04:00
|
|
|
(error 'syntax-cdr "~s is not a pair" x)))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define id?
|
|
|
|
(lambda (x) (syntax-kind? x symbol?)))
|
|
|
|
(define id->sym
|
|
|
|
(lambda (x)
|
|
|
|
(if (stx? x)
|
|
|
|
(id->sym (stx-expr x))
|
|
|
|
(if (symbol? x)
|
|
|
|
x
|
|
|
|
(error 'id->sym "~s is not an id" x)))))
|
|
|
|
(define same-marks?
|
|
|
|
(lambda (x y)
|
|
|
|
(or (eq? x y)
|
|
|
|
(and (pair? x) (pair? y)
|
|
|
|
(eq? (car x) (car y))
|
|
|
|
(same-marks? (cdr x) (cdr y))))))
|
|
|
|
(define bound-id=?
|
|
|
|
(lambda (x y)
|
|
|
|
(and (eq? (id->sym x) (id->sym y))
|
|
|
|
(same-marks? (stx-mark* x) (stx-mark* y)))))
|
|
|
|
(define free-id=?
|
|
|
|
(lambda (i j)
|
|
|
|
(let ((t0 (id->label i)) (t1 (id->label j)))
|
|
|
|
(if (or t0 t1)
|
|
|
|
(eq? t0 t1)
|
|
|
|
(eq? (id->sym i) (id->sym j))))))
|
|
|
|
(define valid-bound-ids?
|
|
|
|
(lambda (id*)
|
|
|
|
(and (andmap id? id*)
|
|
|
|
(distinct-bound-ids? id*))))
|
|
|
|
(define distinct-bound-ids?
|
|
|
|
(lambda (id*)
|
|
|
|
(or (null? id*)
|
|
|
|
(and (not (bound-id-member? (car id*) (cdr id*)))
|
|
|
|
(distinct-bound-ids? (cdr id*))))))
|
2007-05-01 16:41:36 -04:00
|
|
|
(define bound-id-member?
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (id id*)
|
|
|
|
(and (pair? id*)
|
|
|
|
(or (bound-id=? id (car id*))
|
2007-05-01 16:41:36 -04:00
|
|
|
(bound-id-member? id (cdr id*))))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define self-evaluating?
|
2007-05-08 06:56:20 -04:00
|
|
|
(lambda (x)
|
2007-04-30 04:51:37 -04:00
|
|
|
(or (number? x) (string? x) (char? x) (boolean? x))))
|
|
|
|
(define stx->datum
|
|
|
|
(lambda (x)
|
|
|
|
(strip x '())))
|
|
|
|
(define extend-env
|
2007-05-08 06:56:20 -04:00
|
|
|
(lambda (lab b r)
|
2007-04-30 04:51:37 -04:00
|
|
|
(cons (cons lab b) r)))
|
2007-05-08 06:56:20 -04:00
|
|
|
(define extend-env*
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (lab* b* r)
|
|
|
|
(append (map cons lab* b*) r)))
|
2007-04-30 23:46:31 -04:00
|
|
|
(define cons-id
|
|
|
|
(lambda (kwd kwd*)
|
|
|
|
(if (id? kwd)
|
|
|
|
(cons kwd kwd*)
|
|
|
|
kwd*)))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define strip
|
|
|
|
(lambda (x m*)
|
2007-05-08 06:56:20 -04:00
|
|
|
(if (top-marked? m*)
|
2007-04-30 04:51:37 -04:00
|
|
|
x
|
|
|
|
(let f ([x x])
|
2007-04-28 20:54:02 -04:00
|
|
|
(cond
|
2007-04-30 04:51:37 -04:00
|
|
|
[(stx? x) (strip (stx-expr x) (stx-mark* x))]
|
|
|
|
[(pair? x)
|
|
|
|
(let ([a (f (car x))] [d (f (cdr x))])
|
|
|
|
(if (and (eq? a (car x)) (eq? d (cdr x)))
|
|
|
|
x
|
|
|
|
(cons a d)))]
|
|
|
|
[(vector? x)
|
|
|
|
(let ([old (vector->list x)])
|
|
|
|
(let ([new (map f old)])
|
2007-05-08 06:56:20 -04:00
|
|
|
(if (andmap eq? old new)
|
|
|
|
x
|
2007-04-30 04:51:37 -04:00
|
|
|
(list->vector new))))]
|
|
|
|
[else x])))))
|
2007-05-07 02:17:39 -04:00
|
|
|
(define (increment-rib-frequency! rib idx)
|
|
|
|
(let ([freq* (rib-sealed/freq rib)])
|
|
|
|
(let ([freq (vector-ref freq* idx)])
|
|
|
|
(let ([i
|
|
|
|
(let f ([i idx])
|
|
|
|
(cond
|
2007-05-09 11:26:26 -04:00
|
|
|
[(zero? i) 0]
|
2007-05-08 06:56:20 -04:00
|
|
|
[else
|
2007-05-09 11:26:26 -04:00
|
|
|
(let ([j (- i 1)])
|
2007-05-07 02:17:39 -04:00
|
|
|
(cond
|
2007-05-09 11:26:26 -04:00
|
|
|
[(= freq (vector-ref freq* j)) (f j)]
|
2007-05-07 02:17:39 -04:00
|
|
|
[else i]))]))])
|
2007-05-09 11:26:26 -04:00
|
|
|
(vector-set! freq* i (+ freq 1))
|
|
|
|
(unless (= i idx)
|
2007-05-08 06:56:20 -04:00
|
|
|
(let ([sym* (rib-sym* rib)]
|
2007-05-07 02:17:39 -04:00
|
|
|
[mark** (rib-mark** rib)]
|
|
|
|
[label* (rib-label* rib)])
|
|
|
|
(let ([sym (vector-ref sym* idx)])
|
|
|
|
(vector-set! sym* idx (vector-ref sym* i))
|
|
|
|
(vector-set! sym* i sym))
|
|
|
|
(let ([mark* (vector-ref mark** idx)])
|
|
|
|
(vector-set! mark** idx (vector-ref mark** i))
|
|
|
|
(vector-set! mark** i mark*))
|
|
|
|
(let ([label (vector-ref label* idx)])
|
|
|
|
(vector-set! label* idx (vector-ref label* i))
|
|
|
|
(vector-set! label* i label))))))))
|
2007-05-09 23:42:32 -04:00
|
|
|
(define interaction-library
|
|
|
|
(make-parameter #f))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define id->label
|
|
|
|
(lambda (id)
|
|
|
|
(let ([sym (id->sym id)])
|
|
|
|
(let search ([subst* (stx-subst* id)] [mark* (stx-mark* id)])
|
|
|
|
(cond
|
2007-05-09 23:42:32 -04:00
|
|
|
[(null? subst*)
|
|
|
|
(cond
|
|
|
|
[(interaction-library) =>
|
|
|
|
(lambda (lib)
|
|
|
|
(cond
|
|
|
|
[(assq sym (library-subst lib)) => cdr]
|
|
|
|
[else
|
|
|
|
(let ([subst (library-subst
|
|
|
|
(find-library-by-name '(ikarus)))])
|
|
|
|
(cond
|
|
|
|
[(assq sym subst) =>
|
|
|
|
(lambda (sym/lab)
|
|
|
|
(let ([label (cdr sym/lab)])
|
|
|
|
(extend-library-subst! lib sym label)
|
|
|
|
label))]
|
|
|
|
[else
|
|
|
|
(let ([label (gen-label sym)])
|
|
|
|
(extend-library-subst! lib sym label)
|
|
|
|
(extend-library-env! lib label
|
|
|
|
(cons 'global (cons lib (gen-global sym))))
|
|
|
|
label)]))]))]
|
|
|
|
[else #f])]
|
2007-05-08 06:56:20 -04:00
|
|
|
[(eq? (car subst*) 'shift)
|
2007-04-30 04:51:37 -04:00
|
|
|
(search (cdr subst*) (cdr mark*))]
|
|
|
|
[else
|
|
|
|
(let ([rib (car subst*)])
|
2007-05-07 02:17:39 -04:00
|
|
|
(cond
|
2007-05-08 06:56:20 -04:00
|
|
|
[(rib-sealed/freq rib)
|
2007-05-07 02:17:39 -04:00
|
|
|
(let ([sym* (rib-sym* rib)])
|
2007-05-09 11:26:26 -04:00
|
|
|
(let f ([i 0] [n (- (vector-length sym*) 1)])
|
2007-05-07 02:17:39 -04:00
|
|
|
(cond
|
|
|
|
[(and (eq? (vector-ref sym* i) sym)
|
|
|
|
(same-marks? mark*
|
|
|
|
(vector-ref (rib-mark** rib) i)))
|
|
|
|
(let ([label (vector-ref (rib-label* rib) i)])
|
|
|
|
(increment-rib-frequency! rib i)
|
|
|
|
label)]
|
2007-05-09 11:26:26 -04:00
|
|
|
[(= i n) (search (cdr subst*) mark*)]
|
|
|
|
[else (f (+ i 1) n)])))]
|
2007-05-07 02:17:39 -04:00
|
|
|
[else
|
2007-05-08 06:56:20 -04:00
|
|
|
(let f ([sym* (rib-sym* rib)]
|
2007-05-07 02:17:39 -04:00
|
|
|
[mark** (rib-mark** rib)]
|
|
|
|
[label* (rib-label* rib)])
|
|
|
|
(cond
|
|
|
|
[(null? sym*) (search (cdr subst*) mark*)]
|
|
|
|
[(and (eq? (car sym*) sym)
|
|
|
|
(same-marks? (car mark**) mark*))
|
|
|
|
(car label*)]
|
|
|
|
[else (f (cdr sym*) (cdr mark**) (cdr label*))]))]))])))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define label->binding
|
|
|
|
(lambda (x r)
|
|
|
|
(cond
|
2007-05-02 18:16:25 -04:00
|
|
|
[(imported-label->binding x)]
|
2007-05-07 00:25:21 -04:00
|
|
|
[(assq x r) => cdr]
|
2007-04-30 04:51:37 -04:00
|
|
|
[else (cons 'displaced-lexical #f)])))
|
2007-04-30 22:00:04 -04:00
|
|
|
(define make-binding cons)
|
|
|
|
(define binding-type car)
|
|
|
|
(define binding-value cdr)
|
2007-05-07 20:02:29 -04:00
|
|
|
(define local-binding-value cadr)
|
2007-05-07 20:32:36 -04:00
|
|
|
(define local-macro-src cddr)
|
2007-04-30 04:51:37 -04:00
|
|
|
(define syntax-type
|
|
|
|
(lambda (e r)
|
|
|
|
(cond
|
2007-05-08 06:56:20 -04:00
|
|
|
[(id? e)
|
2007-04-30 04:51:37 -04:00
|
|
|
(let ([id e])
|
|
|
|
(let* ([label (id->label id)]
|
|
|
|
[b (label->binding label r)]
|
|
|
|
[type (binding-type b)])
|
2007-05-08 06:56:20 -04:00
|
|
|
(unless label
|
2007-04-30 04:51:37 -04:00
|
|
|
(stx-error e "unbound identifier"))
|
|
|
|
(case type
|
2007-05-08 10:04:00 -04:00
|
|
|
[(lexical core-prim macro global local-macro
|
2007-06-01 22:59:55 -04:00
|
|
|
global-macro displaced-lexical syntax import
|
|
|
|
$module)
|
2007-04-30 04:51:37 -04:00
|
|
|
(values type (binding-value b) id)]
|
|
|
|
[else (values 'other #f #f)])))]
|
|
|
|
[(syntax-pair? e)
|
|
|
|
(let ([id (syntax-car e)])
|
2007-05-08 06:56:20 -04:00
|
|
|
(if (id? id)
|
2007-04-30 04:51:37 -04:00
|
|
|
(let* ([label (id->label id)]
|
|
|
|
[b (label->binding label r)]
|
|
|
|
[type (binding-type b)])
|
|
|
|
(case type
|
2007-05-07 20:58:12 -04:00
|
|
|
[(define define-syntax core-macro begin macro
|
2007-05-22 19:59:30 -04:00
|
|
|
local-macro global-macro module set!
|
2007-06-01 22:43:24 -04:00
|
|
|
let-syntax letrec-syntax import)
|
2007-04-30 04:51:37 -04:00
|
|
|
(values type (binding-value b) id)]
|
2007-05-08 06:56:20 -04:00
|
|
|
[else
|
2007-04-30 04:51:37 -04:00
|
|
|
(values 'call #f #f)]))
|
|
|
|
(values 'call #f #f)))]
|
|
|
|
[else (let ([d (strip e '())])
|
|
|
|
(if (self-evaluating? d)
|
|
|
|
(values 'constant d #f)
|
|
|
|
(values 'other #f #f)))])))
|
2007-05-08 06:56:20 -04:00
|
|
|
(define-syntax stx-error
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (x)
|
|
|
|
(syntax-case x ()
|
2007-05-22 20:21:22 -04:00
|
|
|
[(_ stx) #'(error #f "invalid syntax ~s" (strip stx '()))]
|
2007-09-02 02:03:29 -04:00
|
|
|
[(_ stx msg) #'(error #f "~a ~s" msg (strip stx '()))])))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define sanitize-binding
|
2007-05-07 20:02:29 -04:00
|
|
|
(lambda (x src)
|
2007-04-30 04:51:37 -04:00
|
|
|
(cond
|
2007-09-09 23:41:12 -04:00
|
|
|
[(procedure? x) (cons* 'local-macro x src)]
|
2007-04-30 04:51:37 -04:00
|
|
|
[(and (pair? x) (eq? (car x) 'macro!) (procedure? (cdr x)))
|
2007-09-09 23:41:12 -04:00
|
|
|
(cons* 'local-macro! (cdr x) src)]
|
2007-05-07 22:18:46 -04:00
|
|
|
[(and (pair? x) (eq? (car x) '$rtd)) x]
|
2007-04-30 04:51:37 -04:00
|
|
|
[else (error 'expand "invalid transformer ~s" x)])))
|
2007-09-02 02:03:29 -04:00
|
|
|
(define make-variable-transformer
|
|
|
|
(lambda (x)
|
|
|
|
(if (procedure? x)
|
|
|
|
(cons 'macro! x)
|
|
|
|
(error 'make-variable-transformer
|
|
|
|
"~s is not a procedure" x))))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define make-eval-transformer
|
|
|
|
(lambda (x)
|
2007-05-07 20:02:29 -04:00
|
|
|
(sanitize-binding (eval-core x) x)))
|
2007-05-08 05:10:37 -04:00
|
|
|
(define-syntax syntax-match
|
|
|
|
(lambda (ctx)
|
|
|
|
(define dots?
|
|
|
|
(lambda (x)
|
2007-05-08 06:56:20 -04:00
|
|
|
(and (sys:identifier? x)
|
2007-05-08 05:10:37 -04:00
|
|
|
(sys:free-identifier=? x #'(... ...)))))
|
|
|
|
(define free-identifier-member?
|
|
|
|
(lambda (x ls)
|
|
|
|
(and (ormap (lambda (y) (sys:free-identifier=? x y)) ls) #t)))
|
|
|
|
(define (parse-clause lits cls)
|
|
|
|
(define (parse-pat pat)
|
|
|
|
(syntax-case pat ()
|
2007-05-08 06:56:20 -04:00
|
|
|
[id (sys:identifier? #'id)
|
2007-05-08 05:15:30 -04:00
|
|
|
(cond
|
|
|
|
[(free-identifier-member? #'id lits)
|
2007-05-08 06:56:20 -04:00
|
|
|
(values '()
|
|
|
|
#'(lambda (x)
|
2007-05-08 05:15:30 -04:00
|
|
|
(and (id? x)
|
2007-05-08 05:31:04 -04:00
|
|
|
(free-id=? x (scheme-stx 'id))
|
|
|
|
'())))]
|
|
|
|
[(sys:free-identifier=? #'id #'_)
|
2007-05-08 05:15:30 -04:00
|
|
|
(values '() #'(lambda (x) '()))]
|
|
|
|
[else
|
|
|
|
(values (list #'id) #'(lambda (x) (list x)))])]
|
2007-05-08 05:10:37 -04:00
|
|
|
[(pat dots) (dots? #'dots)
|
|
|
|
(let-values ([(pvars decon) (parse-pat #'pat)])
|
|
|
|
(with-syntax ([(v* ...) pvars] [decon decon])
|
|
|
|
(values pvars
|
|
|
|
#'(letrec ([f (lambda (x)
|
|
|
|
(cond
|
|
|
|
[(syntax-pair? x)
|
|
|
|
(let ([cars/f (decon (syntax-car x))])
|
|
|
|
(and cars/f
|
|
|
|
(let ([cdrs/f (f (syntax-cdr x))])
|
|
|
|
(and cdrs/f
|
|
|
|
(map cons cars/f cdrs/f)))))]
|
2007-05-08 06:56:20 -04:00
|
|
|
[(syntax-null? x)
|
2007-05-08 05:10:37 -04:00
|
|
|
(list (begin 'v* '()) ...)]
|
|
|
|
[else #f]))])
|
|
|
|
f))))]
|
|
|
|
[(pat dots . last) (dots? #'dots)
|
|
|
|
(let-values ([(p1 d1) (parse-pat #'pat)]
|
|
|
|
[(p2 d2) (parse-pat #'last)])
|
|
|
|
(with-syntax ([(v* ...) (append p1 p2)]
|
|
|
|
[(v1* ...) p1]
|
|
|
|
[(v2* ...) p2]
|
|
|
|
[d1 d1] [d2 d2])
|
|
|
|
(values (append p1 p2)
|
|
|
|
#'(letrec ([f (lambda (x)
|
|
|
|
(cond
|
|
|
|
[(syntax-pair? x)
|
|
|
|
(let ([cars/f (d1 (syntax-car x))])
|
2007-05-08 06:56:20 -04:00
|
|
|
(and cars/f
|
2007-05-08 05:10:37 -04:00
|
|
|
(let ([d/f (f (syntax-cdr x))])
|
|
|
|
(and d/f
|
|
|
|
(cons (map cons cars/f (car d/f))
|
|
|
|
(cdr d/f))))))]
|
|
|
|
[else
|
|
|
|
(let ([d (d2 x)])
|
2007-05-08 06:56:20 -04:00
|
|
|
(and d
|
2007-05-08 05:10:37 -04:00
|
|
|
(cons (list (begin 'v1* '()) ...)
|
|
|
|
d)))]))])
|
|
|
|
(lambda (x)
|
|
|
|
(let ([x (f x)])
|
|
|
|
(and x (append (car x) (cdr x)))))))))]
|
2007-05-08 06:56:20 -04:00
|
|
|
[(pat1 . pat2)
|
2007-05-08 05:10:37 -04:00
|
|
|
(let-values ([(p1 d1) (parse-pat #'pat1)]
|
|
|
|
[(p2 d2) (parse-pat #'pat2)])
|
|
|
|
(with-syntax ([d1 d1] [d2 d2])
|
|
|
|
(values (append p1 p2)
|
|
|
|
#'(lambda (x)
|
|
|
|
(and (syntax-pair? x)
|
|
|
|
(let ([q (d1 (syntax-car x))])
|
2007-05-08 06:56:20 -04:00
|
|
|
(and q
|
2007-05-08 05:10:37 -04:00
|
|
|
(let ([r (d2 (syntax-cdr x))])
|
|
|
|
(and r (append q r))))))))))]
|
|
|
|
[#(pats ...)
|
|
|
|
(let-values ([(pvars d) (parse-pat #'(pats ...))])
|
|
|
|
(with-syntax ([d d])
|
|
|
|
(values pvars
|
|
|
|
#'(lambda (x)
|
|
|
|
(and (syntax-vector? x)
|
|
|
|
(d (syntax-vector->list x)))))))]
|
2007-05-08 06:56:20 -04:00
|
|
|
[datum
|
2007-05-08 05:10:37 -04:00
|
|
|
(values '()
|
2007-05-08 06:56:20 -04:00
|
|
|
#'(lambda (x)
|
2007-05-08 05:10:37 -04:00
|
|
|
(and (equal? (strip x '()) 'datum) '())))]))
|
|
|
|
(syntax-case cls ()
|
|
|
|
[(pat body)
|
|
|
|
(let-values ([(pvars decon) (parse-pat #'pat)])
|
|
|
|
(with-syntax ([(v* ...) pvars])
|
2007-05-08 06:56:20 -04:00
|
|
|
(values decon
|
2007-05-08 05:10:37 -04:00
|
|
|
#'(lambda (v* ...) #t)
|
2007-05-08 05:15:30 -04:00
|
|
|
#'(lambda (v* ...) body))))]
|
|
|
|
[(pat guard body)
|
|
|
|
(let-values ([(pvars decon) (parse-pat #'pat)])
|
|
|
|
(with-syntax ([(v* ...) pvars])
|
|
|
|
(values decon
|
|
|
|
#'(lambda (v* ...) guard)
|
2007-05-08 05:10:37 -04:00
|
|
|
#'(lambda (v* ...) body))))]))
|
|
|
|
(syntax-case ctx ()
|
|
|
|
[(_ expr (lits ...)) (andmap sys:identifier? #'(lits ...))
|
|
|
|
#'(stx-error expr "invalid syntax")]
|
|
|
|
[(_ expr (lits ...) cls cls* ...) (andmap sys:identifier? #'(lits ...))
|
|
|
|
(let-values ([(decon guard body)
|
|
|
|
(parse-clause #'(lits ...) #'cls)])
|
2007-05-08 05:31:04 -04:00
|
|
|
(with-syntax ([decon decon] [guard guard] [body body])
|
2007-05-08 05:10:37 -04:00
|
|
|
#'(let ([t expr])
|
|
|
|
(let ([ls/false (decon t)])
|
|
|
|
(if (and ls/false (apply guard ls/false))
|
|
|
|
(apply body ls/false)
|
|
|
|
(syntax-match t (lits ...) cls* ...))))))])))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define parse-define
|
|
|
|
(lambda (x)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match x ()
|
2007-05-08 05:31:04 -04:00
|
|
|
[(_ (id . fmls) b b* ...) (id? id)
|
|
|
|
(values id (cons 'defun (cons fmls (cons b b*))))]
|
|
|
|
[(_ id val) (id? id)
|
|
|
|
(values id (cons 'expr val))])))
|
2007-04-30 04:51:37 -04:00
|
|
|
(define parse-define-syntax
|
|
|
|
(lambda (x)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match x ()
|
2007-05-08 05:31:04 -04:00
|
|
|
[(_ id val) (id? id) (values id val)])))
|
2007-05-01 04:36:53 -04:00
|
|
|
(define scheme-stx
|
|
|
|
(lambda (sym)
|
2007-05-08 06:56:20 -04:00
|
|
|
(let ([subst
|
|
|
|
(library-subst
|
2007-05-07 03:55:51 -04:00
|
|
|
(find-library-by-name '(ikarus system $all)))])
|
2007-05-02 17:13:16 -04:00
|
|
|
(cond
|
|
|
|
[(assq sym subst) =>
|
|
|
|
(lambda (x)
|
|
|
|
(let ([name (car x)] [label (cdr x)])
|
2007-05-08 06:56:20 -04:00
|
|
|
(add-subst
|
2007-05-07 00:44:28 -04:00
|
|
|
(make-rib (list name) (list top-mark*) (list label) #f)
|
2007-05-02 17:13:16 -04:00
|
|
|
(stx sym top-mark* '()))))]
|
|
|
|
[else (stx sym top-mark* '())]))))
|
2007-04-30 04:51:37 -04:00
|
|
|
;;; macros
|
2007-05-07 03:22:42 -04:00
|
|
|
(define add-lexical
|
|
|
|
(lambda (lab lex r)
|
2007-09-09 23:41:12 -04:00
|
|
|
(cons (cons* lab 'lexical lex) r)))
|
2007-05-07 03:22:42 -04:00
|
|
|
;;;
|
2007-04-30 04:51:37 -04:00
|
|
|
(define add-lexicals
|
|
|
|
(lambda (lab* lex* r)
|
2007-05-07 03:22:42 -04:00
|
|
|
(cond
|
|
|
|
[(null? lab*) r]
|
2007-05-08 06:56:20 -04:00
|
|
|
[else
|
2007-05-07 03:22:42 -04:00
|
|
|
(add-lexicals (cdr lab*) (cdr lex*)
|
|
|
|
(add-lexical (car lab*) (car lex*) r))])))
|
|
|
|
;;;
|
2007-05-01 16:41:36 -04:00
|
|
|
(define let-values-transformer ;;; go away
|
2007-05-08 06:56:20 -04:00
|
|
|
(lambda (e r mr)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match e ()
|
2007-04-30 04:51:37 -04:00
|
|
|
[(_ ([(fml** ...) rhs*] ...) b b* ...)
|
|
|
|
(let ([rhs* (chi-expr* rhs* r mr)])
|
|
|
|
(let ([lex** (map (lambda (ls) (map gen-lexical ls)) fml**)]
|
|
|
|
[lab** (map (lambda (ls) (map gen-label ls)) fml**)])
|
|
|
|
(let ([fml* (apply append fml**)]
|
|
|
|
[lab* (apply append lab**)]
|
|
|
|
[lex* (apply append lex**)])
|
|
|
|
(let f ([lex** lex**] [rhs* rhs*])
|
2007-04-28 20:54:02 -04:00
|
|
|
(cond
|
2007-05-08 06:56:20 -04:00
|
|
|
[(null? lex**)
|
|
|
|
(chi-internal
|
|
|
|
(add-subst
|
2007-04-30 04:51:37 -04:00
|
|
|
(make-full-rib fml* lab*)
|
|
|
|
(cons b b*))
|
|
|
|
(add-lexicals lab* lex* r)
|
|
|
|
mr)]
|
2007-04-28 20:54:02 -04:00
|
|
|
[else
|
2007-05-08 06:56:20 -04:00
|
|
|
(build-application no-source
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-primref no-source 'call-with-values)
|
2007-05-08 06:56:20 -04:00
|
|
|
(list
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-lambda no-source '() (car rhs*))
|
2007-05-08 06:56:20 -04:00
|
|
|
(build-lambda no-source (car lex**)
|
2007-04-30 04:51:37 -04:00
|
|
|
(f (cdr lex**) (cdr rhs*)))))])))))])))
|
2007-05-09 06:09:37 -04:00
|
|
|
(module (letrec-transformer letrec*-transformer)
|
|
|
|
(define helper
|
|
|
|
(lambda (e r mr letrec?)
|
|
|
|
(syntax-match e ()
|
|
|
|
[(_ ([lhs* rhs*] ...) b b* ...)
|
|
|
|
(if (not (valid-bound-ids? lhs*))
|
2007-09-02 02:03:29 -04:00
|
|
|
(stx-error e "invalid identifiers")
|
2007-05-09 06:09:37 -04:00
|
|
|
(let ([lex* (map gen-lexical lhs*)]
|
|
|
|
[lab* (map gen-label lhs*)])
|
|
|
|
(let ([rib (make-full-rib lhs* lab*)]
|
|
|
|
[r (add-lexicals lab* lex* r)])
|
|
|
|
(let ([body (chi-internal
|
|
|
|
(add-subst rib (cons b b*))
|
|
|
|
r mr)]
|
|
|
|
[rhs* (chi-expr*
|
|
|
|
(map (lambda (x)
|
|
|
|
(add-subst rib x))
|
|
|
|
rhs*)
|
|
|
|
r mr)])
|
|
|
|
((if letrec? build-letrec build-letrec*)
|
|
|
|
no-source lex* rhs* body)))))])))
|
|
|
|
(define letrec-transformer
|
|
|
|
(lambda (e r mr) (helper e r mr #t)))
|
|
|
|
(define letrec*-transformer
|
|
|
|
(lambda (e r mr) (helper e r mr #f))))
|
2007-05-01 04:36:53 -04:00
|
|
|
(define type-descriptor-transformer
|
|
|
|
(lambda (e r mr)
|
|
|
|
(syntax-match e ()
|
2007-05-08 05:31:04 -04:00
|
|
|
[(_ id) (id? id)
|
|
|
|
(let* ([lab (id->label id)]
|
|
|
|
[b (label->binding lab r)]
|
|
|
|
[type (binding-type b)])
|
|
|
|
(unless lab (stx-error e "unbound identifier"))
|
|
|
|
(case type
|
|
|
|
[($rtd)
|
|
|
|
(build-data no-source (binding-value b))]
|
|
|
|
[else (stx-error e "invalid type")]))])))
|
2007-05-01 16:41:36 -04:00
|
|
|
(define when-transformer ;;; go away
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (e r mr)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match e ()
|
2007-05-08 06:56:20 -04:00
|
|
|
[(_ test e e* ...)
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-conditional no-source
|
|
|
|
(chi-expr test r mr)
|
|
|
|
(build-sequence no-source
|
|
|
|
(chi-expr* (cons e e*) r mr))
|
2007-05-01 05:12:32 -04:00
|
|
|
(build-void))])))
|
2007-05-01 16:41:36 -04:00
|
|
|
(define unless-transformer ;;; go away
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (e r mr)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match e ()
|
2007-05-08 06:56:20 -04:00
|
|
|
[(_ test e e* ...)
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-conditional no-source
|
|
|
|
(chi-expr test r mr)
|
2007-05-08 06:56:20 -04:00
|
|
|
(build-void)
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-sequence no-source
|
|
|
|
(chi-expr* (cons e e*) r mr)))])))
|
|
|
|
(define if-transformer
|
|
|
|
(lambda (e r mr)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match e ()
|
2007-04-30 04:51:37 -04:00
|
|
|
[(_ e0 e1 e2)
|
|
|
|
(build-conditional no-source
|
|
|
|
(chi-expr e0 r mr)
|
|
|
|
(chi-expr e1 r mr)
|
|
|
|
(chi-expr e2 r mr))]
|
|
|
|
[(_ e0 e1)
|
|
|
|
(build-conditional no-source
|
|
|
|
(chi-expr e0 r mr)
|
|
|
|
(chi-expr e1 r mr)
|
2007-05-01 05:12:32 -04:00
|
|
|
(build-void))])))
|
2007-05-01 16:41:36 -04:00
|
|
|
(define case-transformer ;;; go away
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (e r mr)
|
2007-05-08 06:56:20 -04:00
|
|
|
(define build-one
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (t cls rest)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match cls ()
|
2007-04-30 04:51:37 -04:00
|
|
|
[((d* ...) e e* ...)
|
|
|
|
(build-conditional no-source
|
|
|
|
(build-application no-source
|
|
|
|
(build-primref no-source 'memv)
|
|
|
|
(list t (build-data no-source (strip d* '()))))
|
|
|
|
(build-sequence no-source
|
|
|
|
(chi-expr* (cons e e*) r mr))
|
|
|
|
rest)]
|
|
|
|
[else (stx-error e)])))
|
2007-05-08 06:56:20 -04:00
|
|
|
(define build-last
|
2007-04-30 04:51:37 -04:00
|
|
|
(lambda (t cls)
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match cls ()
|
2007-04-30 04:51:37 -04:00
|
|
|
[((d* ...) e e* ...)
|
2007-05-01 05:12:32 -04:00
|
|
|
(build-one t cls (build-void))]
|
2007-04-30 04:51:37 -04:00
|
|
|
[(else-kwd x x* ...)
|
|
|
|
(if (and (id? else-kwd)
|
2007-05-01 04:36:53 -04:00
|
|
|
(free-id=? else-kwd (scheme-stx 'else)))
|
2007-04-30 04:51:37 -04:00
|
|
|
(build-sequence no-source
|
|
|
|
(chi-expr* (cons x x*) r mr))
|
|
|
|
(stx-error e))]
|
|
|
|
[else (stx-error e)])))
|
2007-04-30 22:00:04 -04:00
|
|
|
(syntax-match e ()
|
2007-05-08 06:56:20 -04:00
|
|
|