#lang scheme/base
(require "tools.ss"
"target.ss"
scheme/pretty)
(provide code-register-postponed!
code-compile!
code-print
code-pointers
code-pointers-set!
code->binary
code-clear!
code-find
code-resolve code-labels)
(define *postponed-macro-stack* '()) (define (code-register-postponed! code) (push! *postponed-macro-stack* code))
(define *postponed* '())
(define *cfg* '())
(define *labels* '())
(define (code-labels) *labels*)
(define (code-resolve addr [realm 'code])
(let next ((l *labels*))
(cond
((null? l) #f)
((and (eq? realm (cadar l))
(= addr (caddar l)))
(car l))
(else (next (cdr l))))))
(define (code-find name)
(assoc name *labels*))
(define *pointers* '((code 0) (data 0)))
(define (code-pointers) *pointers*)
(define (code-pointers-set! p) (set! *pointers* p))
(define-syntax-rule (save! *store* lst)
(set! *store* (append lst *store*)))
(define (code-compile! compile assemble!)
(let ((cfg (compile *postponed-macro-stack*)))
(let-values (((_ pointers) (assemble! cfg *pointers*)))
(save! *cfg* cfg)
(save! *labels* (chain-list->labels cfg))
(save! *postponed* *postponed-macro-stack*)
(set! *pointers* pointers)
(set! *postponed-macro-stack* '()))))
(define (code-print [cfg *cfg*])
(for-each print-target-word (reverse cfg)))
(define (code->binary [chain-list *cfg*])
(map
(lambda (c) (binchunk-split c 0 8))
(or (target-chains->bin chain-list)
(error 'code->binary))))
(define (code-clear!)
(set! *postponed-macro-stack* '())
(set! *postponed* '())
(set! *cfg* '()))
(define (chain-list->labels chains)
(apply append
(for/list ((c chains))
(for/list ((w (target-chain->list c))
#:when (symbol? (target-word-name w)))
(list (target-word-name w)
(target-word-realm w)
(target-word-address w))))))