This wouldn't work correctly in some weird edge cases. Specifically, it was
trying to detect the 'else and '=> keywords, but comparing them in the syntactic
environment outside of the DO, not the one inside of it. Fixed by rewriting the
macro to defer the cond-clause processing until the interior environment was
available.
(delay
(scons-rule
`((subform (* (subform (list id any (? any)))))
- ,cond-clause-pattern
+ (subform (+ any))
(* any))
(lambda (bindings test-clause actions)
(let ((loop-name (new-identifier 'do-loop)))
(list (car binding)
(cadr binding)))
bindings)
- (expand-cond-clause test-clause
- (scons-begin
- (apply scons-begin actions)
- (apply scons-call
- loop-name
- (map (lambda (binding)
- (if (pair? (cddr binding))
- (caddr binding)
- (car binding)))
- bindings)))))))))))
+ (scons-cond test-clause
+ (list (scons-close 'else)
+ (apply scons-begin actions)
+ (apply scons-call
+ loop-name
+ (map (lambda (binding)
+ (if (pair? (cddr binding))
+ (caddr binding)
+ (car binding)))
+ bindings)))))))))))
\f
(define $case
(spar-transformer->runtime
scons-begin
scons-call
scons-close
+ scons-cond
scons-declare
scons-define
scons-delay
(cons (close-part close operator)
(close-parts close operands)))))
+(define (scons-cond . clauses)
+ (make-open-expr
+ (lambda (close)
+ (cons (close 'cond)
+ (map (lambda (clause)
+ (close-parts close clause))
+ clauses)))))
+
(define (scons-declare . decls)
(make-open-expr
(lambda (close)
(lambda (close)
(list (close 'delay)
(close-part close expr)))))
-
+\f
(define (scons-if predicate consequent alternative)
(make-open-expr
(lambda (close)
(close-part close predicate)
(close-part close consequent)
(close-part close alternative)))))
-\f
+
(define (scons-lambda bvl . body-forms)
(make-open-expr
(lambda (close)