#langscheme/unit;; Primitives for the control stack extension. This supports Forth's
;; control flow words, which are implemented in terms of jumps and
;; labels.
;; A practicaly Forth compiler implemented in instatiate.ss will
;; replace the underlying jump/label mechanism with a more powerful
;; control flow analysis mechanism.
(require"../sig.ss""../ns.ss""../tools.ss""../scat.ss""2stack.ss""../coma/macro.ss""../asm/directives.ss")
(importjump^cjump^stack^)
(exportcontrol^)
(patterns
(macro)
;; CONTROL STACK OPS
((m-swap) (macro-prim:ctrl>ctrl>swap>ctrl>ctrl))
((m-dup) (macro-prim:ctrl>dup>ctrl>ctrl))
((m>) (macro-prim:ctrl>literal))
(([qwa] >m) (macro-prim:',a>ctrl))
(([cwa] word>m) (macro-prim:',a>ctrl))
)
;; FORTH-STYLE CONTROL FLOW
(compositions
(macro) macro:;; Mark basic block end. The label is not used, only the effect it
;; has: to split the basic block.
;; For control flow analysis we need to obtain the conditional branch
;; target so a basic block can have two exit paths. If each block has
;; only a single conditional exit, this is possible. (Maybe mark the
;; block as a branch block too?)
(end:symlabel:)
;; 'if should be the ONLY macro calling the machine-specific 'jw/if
;; macro.
(ifsymdup>mjw/falseend:)
(elsesymdup>mjwm-swapthen)
(thenm>label:)
(beginsymdup>mlabel:)
(againm>jw)
(dobegin)
(whileif)
(repeatm-swapagainthen)
(untilnotwhilerepeat)
;; Note: for .. next used to have an optimization wrapping the inner
;; loop in a dup .. drop construct. Given the current implementation,
;; this is not so straightforward to implement, so it's currently
;; disabled. The main problem being that the composition implementing
;; the loop body can't be recovered easily, and a more direct code
;; inspection mechanism is necessary. However, using higher order
;; macros, this should be fairly trivial to do directly, so I'm not
;; bothering right now.
;; one with drop .. save wrapped around it. this generates better
;; code for loops that do 'read modify write'. platform specific
;; needs to define for0 ... next0
; (for1 dup for0 drop)
; (next1 save next0 drop)
;; amb-compile will non-deterministically compile (execute) one of
;; the two quoted macros. each macro quotes a macro implementing
;; its 'next' behavirour (next just executes macro from m>).
; (for (for0 (constraint:label-nodup
; next0) >m)
; (for1 (next1) >m)
; amb-compile)
; (amb-compile swap >m >m m-amb-run/s)
; (next m> compile)
)