#lang scheme/base
(provide
forth-begin
forth-module-begin)
(require
"../tools.ss"
"../target.ss"
"../comp.ss" "../scat.ss"
(for-syntax
"../tools.ss"
(lib "pretty.ss")
"../scat-tx.ss"
"../macro-tx.ss"
"../forth-tx.ss"
scheme/base))
(define-for-syntax (forth-begin-tx stx init-forms register-code)
(define (record->define/register register! record)
(syntax-case record ()
((name lang loc rep)
(syntax-case #'lang (macro)
(macro
(syntax-case #'name ()
(#f #`(void))
(_ #`(redefine!-ns
(macro) name
(wrap-macro/mexit 'name loc rep)))))
(wrap
(syntax-case (generate-temporaries
'(label wrapper postponed)) ()
((label wrapper postponed)
(register! #'postponed)
(syntax-case #'name ()
(#f #`(define postponed rep))
(_ #`(begin
(define-values
(label
wrapper
postponed)
(wrap 'name loc rep))
(redefine!-ns (macro) name wrapper)
(define-ns (target) name label)))))))))))
(define (code->defines code)
(define words '())
#`(begin
#,@(map
(lambda (record)
(record->define/register
(lambda (x) (push! words x))
record))
(forth->records
#'wrap-macro/postponed-word
#'wrap-macro/postponed-variable
#'macro
code))
(#,register-code
(target-compile (list #,@words)))))
(parameterize
((forth-toplevel-forms init-forms))
(syntax-case stx ()
((_ . code)
(let* ((defs (with-macro-syntax
(lambda ()
(code->defines #'code))))
(topl (datum->syntax
stx
(reverse
(forth-toplevel-forms)))))
#`(begin (begin #,@topl)
#,defs))))))
(define-syntax (forth-module-begin stx)
(let ((module-name
(syntax-property
stx 'enclosing-module-name)))
#`(#%plain-module-begin
#,(forth-begin-tx stx
'((provide (all-defined-out)))
#'register-code))))
(define-syntax (forth-begin stx)
(forth-begin-tx stx '() #'register-code))