#lang scheme/base
(require
scheme/pretty
scheme/control
scheme/match
"../tools.ss"
"../code.ss"
"repl.ss"
"../ns.ss"
"../scat.ss"
"../target.ss")
(provide (all-defined-out))
(define (find-target-word/false name)
(namespace-variable-value
(ns-name '(target) name)
#t (lambda () #f)))
(define (tfind/false name)
(let ((word (find-target-word/false name)))
(and word (target-word-address word))))
(define (tfind name)
(or (tfind/false name)
(error 'target-word-not-found "~s" name)))
(define (macro-constant . code)
(eval `(state->value
((macro: ,@code) (init-state))
(ns (op ? qw)))))
(define (target-mapped-symbols [prefix '(target)])
(filter tfind/false (ns-mapped-symbols prefix)))
(define (target-words-set! words)
(for-each*
(lambda (name realm address)
(let ((word
(eval
`(new-target-word #:name ',name
#:realm ',realm
#:address ,address))))
(eval
`(begin
(ns (target) (define ,name ,word))
(ns (macro) (define ,name
,(case realm
((code) `(scat: ',word compile))
((data) `(scat: ',word literal)))))))))
words))
(define (target-words)
(for/list ((name (target-mapped-symbols)))
(let ((word (find-target-word/false name)))
(list name
(target-word-realm word)
(target-word-address word)))))
(define (reverse-lookup dict realm address)
(prompt
(for-each*
(lambda (name r a)
(when (and (eq? r realm)
(eq? a address))
(abort name)))
dict) #f))
(define (dict-snapshot)
`(begin
(target-words-set! ',(target-words))
(code-pointers-set! ',(code-pointers))))
(define (forth-load file)
(eval `(forth-load/compile ,file)))
(snarf as-push (scat)
((x) (tfind forth-load)))
(define (run)
(dynamic-wind
void
(lambda ()
(repl (lambda (cmd)
(eval `(forth-command ,cmd)))))
(lambda ()
(eval '((tethered-close))))))