#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 (word-not-found? ex)
(and (pair? ex)
(eq? (car ex) 'target-word-not-found)))
(define (target-find sym [error-thunk
(lambda ()
(raise `(target-word-not-found ,sym)))])
(match (code-find sym)
(#f (error-thunk))
((list name realm address)
(values realm (target-byte-addr address realm)))))
(define (target-find-realm sym wanted-realm)
(with-handlers ((word-not-found?
(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 `(with-handlers ((void (lambda _ #f)))
(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 (target-words-check! words)
(void))
(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 ()
(with-handlers
((void (lambda (ex)
(printf "Console startup failed:\n~a\n" ex)
(printf "Continuing with REPL anyway:\n"))))
(startup))
(repl (lambda (cmd)
(eval `(forth-command ,cmd)))))
(lambda ()
(eval '((comm-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)))
(define (print-tword sym)
(eval `(print-target-word (ns (target) ,sym))))