;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; ;;; begin-syntax.scm - Convenience macro for inline syntax expansion. ;;; ;;; Copyright (c) 2016, Evan Hanson ;;; See LICENSE for details. ;;; (declare (module begin-syntax) (export begin-syntax) (import-for-syntax (chicken memory representation) (matchable))) ;; ;; Evaluates its body and immediately inserts the final result into the ;; program, as though by macro expansion. ;; ;; If the result is a macro transformer, it is immediately invoked with ;; no arguments and the result is inserted into the program. ;; ;; This form can be thought of as a macro definition followed by its ;; immediate expansion. For example: ;; ;; (begin-syntax '(+ 1 2)) ;; ;; ; => (let-syntax ((a (er-macro-transformer ;; (lambda (_ _ _) '(+ 1 2))))) ;; (a)) ;; (define-syntax begin-syntax (er-macro-transformer (lambda (e i c) (match e ((_ exp0 ... expn) (let* ((_ (for-each ##sys#eval/meta exp0)) (x (##sys#eval/meta expn))) (let loop ((x x)) (cond ((eq? (void) x) '(##core#undefined)) ((record-instance? x 'transformer) (let ((name (gensym "transformer"))) (parameterize ((##sys#macro-environment (##sys#macro-environment))) (##sys#extend-macro-environment name '() x) (loop (expand `(,name)))))) (else x)))))))))