#lang scheme/base ;; Forth style parsing words are implemented as binary functions bound ;; as syntax. See rpn-tx.ss : (next <code> <expr>) for more information. (provide (all-defined-out)) (require "../scat.ss" "../forth.ss" "../coma.ss" "../control.ss" "../comp.ss" "../tools.ss" (for-syntax scheme/base "../scat-tx.ss" "../forth-tx.ss" )) ;; Definitions + forth / macro mode switch syntax. (tx->syntax-ns (macro) (: :-tx) (:macro :macro-tx) (create create-tx) (forth forth-tx) (macro macro-tx) (\| locals-tx) (require require-tx) (provide provide-tx) (|[| open-paren-tx) (|]| close-paren-tx) (|{| open-sexp-tx) (load load-tx) (path path-tx) ) ;; Subtitution macros. ;; Because Forth is non-concatenative (for anything that changes the ;; semantics of names), and the macro system is purely concatenative / ;; compositional, the need arises for a mechanism to metaprogram ;; non-concatenative code. ;; In standard Forth this is implemented by a reflective operation: ;; code implementing macros has access to the current input. This ;; doesn't work in Purrr, which employs a more declarative style with ;; 'unrolled' reflection in the form of substitution macros. (substitutions (macro) ((|`| name) ('name)) ((|'| name) (',(ns (macro) name))) ((variable name) (create name 1 allot)) ((2variable name) (create name 2 allot)) ((declare name) (:macro name 'name undefined |;|)) ((parameter name) (:macro name ,(make-constant 'name) |;|)) ((|#lang| _) ()) ((string name) (',(symbol->string 'name))) ;; Trouble with the word 'f->' being defined later... ;; ((fstring name) (f-> string name |string,|)) )