mark multi-form macro expansions with $
A bare list was read as several forms, so a macro returning `((make-adder 10) 5)' -- a call of what make-adder returns -- was spliced into two. Add a new $ char to denote splicing, so ($ form ...) splices.
This commit is contained in:
27
semen.scm
27
semen.scm
@@ -52,22 +52,29 @@
|
||||
(cons (car forms) (take-until (cdr forms) tail))))
|
||||
|
||||
(define (macroexpand macro-form rest-forms)
|
||||
;; We want to replace macro with its expansion. The problem is,
|
||||
;; top-level macro can return either a single form, or a list of
|
||||
;; forms, when it for example generates some aux
|
||||
;; structures/functions/typedefs.
|
||||
;; `(defmacro (two) 2)' expands to `2', and `($ (fn a ...) (fn b ...))'
|
||||
;; to two forms, spliced where the macro was written. `($)' expands to
|
||||
;; nothing.
|
||||
;;
|
||||
;; Single form we just cons to the top of rest-forms, but multiple
|
||||
;; forms have to be appended to the rest-forms.
|
||||
;; Everything else is one form, a list whose head is itself a form
|
||||
;; included: `((make-adder 10) 5)' calls what `make-adder' returned,
|
||||
;; and without `$' to mark a splice there is no telling that from a
|
||||
;; list of the two forms `(make-adder 10)' and `5'.
|
||||
(let ((res (apply-macro macro-form))
|
||||
(src (form-source macro-form)))
|
||||
;; An expansion is fresh structure with no location of its own. Give
|
||||
;; it the call site's, the way cpp attributes a macro body to where
|
||||
;; the macro was used
|
||||
(if (list? (car res))
|
||||
(append (map (lambda (f) (stamp-form-source! f src)) res)
|
||||
rest-forms)
|
||||
(cons (stamp-form-source! res src) rest-forms))))
|
||||
(cond
|
||||
((splice-form? res)
|
||||
(append (map (lambda (f) (stamp-form-source! f src)) (cdr res))
|
||||
rest-forms))
|
||||
((null? res) rest-forms)
|
||||
(else
|
||||
(cons (stamp-form-source! res src) rest-forms)))))
|
||||
|
||||
(define (splice-form? form)
|
||||
(and (pair? form) (list? form) (eq? '$ (car form))))
|
||||
|
||||
(define (match-sex-form sex-form acc)
|
||||
(match sex-form
|
||||
|
||||
Reference in New Issue
Block a user