#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 (target-byte-addr address realm)
((eval 'target-byte-address) address realm))
(define (target-find sym)
(match (code-find sym)
(#f (error 'target-word-not-found "~s" sym))
((list name realm address)
(values realm (target-byte-addr address realm)))))
(define (target-find-realm sym wanted-realm)
(with-handlers ((void (lambda _ #f)))
(let-values (((realm addr) (target-find sym)))
(and (eq? realm wanted-realm) addr))))
(define (target-find-code sym) (target-find-realm sym 'code))
(define (target-find-data sym) (target-find-realm sym 'data))
(define (macro-constant . code)
(eval `(state->value
((macro: ,@code) (init-state))
(ns (op ? qw)))))
(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 (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 (run [startup void])
(dynamic-wind
void
(lambda ()
(startup)
(repl (lambda (cmd)
(eval `(forth-command ,cmd)))))
(lambda ()
(eval '((tethered-close))))))
(define (read-dictionary [port (current-input-port)])
(read-line port) (values (read) (read) (read)))
(define (load-dictionary file)
(let-values (((info reqs init)
(with-input-from-file file read-dictionary)))
(eval info)
(eval reqs)
(eval init)))