#lang scheme/base ;; This extends the control.ss macro language (which implements ;; Forth-style control words on top of the pure macro language Coma) ;; with control flow marking exported by instantiate.ss (require "instantiate.ss" ;; redefines exit "../scat.ss" "../coma.ss" "../control.ss" ;; control words without flow analysis ) (provide (all-defined-out)) ;; UTIL ;; Patch core functionality in instantiate.ss (compile-exit (ns (macro) exit)) (compile-literal (lambda (x) (macro-prim: ',x literal))) (compile-word (lambda (x) (macro-prim: ',x compile))) ;; LABELS (patterns (macro) ;; Redefine the stubs from control.ss to introduce labels used to ;; construct structured code graphs. ((sym) ([qw (make-target-label)])) (([qw name] >label) ([qw (make-target-label name)])) (([qw label] label:) (make-target-split label)) ;; EXIT ((exit) (macro: primitive-exit ,terminate-chain)) ;; Semicolon either compiles local macro exit (mexit) within macro ;; instantiation, or the target's RETURN instruction. A semicolon ;; fallen over is an 'exit' that doesnt register end-of-word. It ;; means the code after the exit is reachable. Mainly useful for jump ;; tables using 'route'. ((";") (macro: ,semicolon)) ((".,") (macro: primitive-exit)) ;; ORG ;; Since the compiler has no access to code addresses, handling an ;; address specification needs to be postponed to the assembly phase ;; in the form of a directive. This directive takes the place of a ;; symbolic target word name. (Semantically, it acts as one.) ;; There are 2 org variants: a temporary one, which manipulates the ;; current compiler chain/store state while compiling a chain. (([qw address] word-org-push) (macro: ,split-store ',(list 'org address) >label label:)) ((org-pop) (macro: ,terminate-chain ,combine-store ;; needs to be one chain ,merge-store)) ;; .. and a permanent one which just sets the current assembly ;; address, and doesn't manipulate chains (all chunks will simply ;; follow after address is changed). (([qw address] word-org) (macro: ,(make-target-split #f) ,terminate-chain ',(list 'org! address) >label label:)) )