;; Tools for creating forth macros. This does not include the bulk of ;; the forth macros (see comp.ss for that), but includes all the ;; syntax definitions, and basic support words for macro definitions. (module macro mzscheme (require "composite.ss" "primitive.ss" "macro-stx.ss" ;; for binding macro syntax to the (macro) namespace "macro-prim.ss" ;; primitive macros "ns.ss" "list-utils.ss" "rpn.ss" "base.ss" ;; I don't remember why macro.ss should depend on badnop.ss ;; "badnop.ss" ;; "lambda-tx.ss" ) (provide macro-prim: ;; re-export primitive macro compiler macro: ;; recursive macro compiler macro-lex: ;; macro with lexical variables ) (require-for-syntax "macro-lambda-tx.ss") ;; *** MACRO DICT **** ;; On to the primitive macros. We use the 'macro-prim:' syntax above ;; to create words to populate the (macro) dictionary. ;; (ns-new '(macro)) ;; These can be defined using the code below. The bulk is left for ;; comp.ss which implements the shared forth parts. (compositions (macro) macro-prim: (m> literal) (m>word compile)) ;; Once the macro primitives are bootstrapped, it makes sense to ;; want to compose macros: write new macros in terms of old ones. As ;; a matter of fact, that will be the main interface to the macros ;; from the forth language. ;; So we define the 'macro:' compiler word, which can generate a ;; compiler for an entire forth program. Invoking this compiler on ;; a (reversed) assembly buffer compiles the program. (macro-stx (macro:) ((macro))) ;; Augment the macro: syntax with some lambda magic. ;; To make this fit in the ordinary compiler syntax, the first ;; element of the body is interpreted as the formal list. See ;; macro-lambda-tx.ss (define-syntax (macro-lex: stx) (syntax-case stx () ((_ . words) (macro-lambda-tx #'macro: #'macro-lex: #'words)))) )