12.07.2015 Views

ertl-paf

ertl-paf

ertl-paf

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

ErtlPAF: A portable assembly language\ Forth: selector ( offset -- )create ,does> ( ... o -- ... )@ over @ + @ execute ;1 cells selector foo2 cells selector bar\ PAF: foo ( ... o -- ... )dup @ 1 cells + @ jump.foo ;: bar ( ... o -- ... )dup @ 2 cells + @ jump.bar ;Figure 1: Defining method selectors in Forth and inPAF (simplified)In contrast, Forth needs to have a separate memoryarea and stack pointer for each stack, and whilestack items can be kept in registers for most of thecode, there are some words (in particular, execute)and code patterns (unbalanced stack effects on controlflow joins), that force stack items into memoryand usually also force stack pointer updates.This property of Forth is avoided in PAF byrequiring balanced stack effects on control flowjoins (see Section 3.9), and by replacing executewith exec.tag (see Section 3.10); all definition addressesreturned for a particular tag are required tohave compatible stack effects, so exec.tag has astatically determined stack effect.5.2 Effect on ProgramsThe effect on real programs is relatively small: mostForth code has balanced stack effects for controlflow anyway, and most occurences of ’ andexecutecan be converted to their tagged variants, becauseprogrammers keep the stack depth statically determinablein order to keep the code understandable.However, there are cases where the restrictionsare not so easy to comply with. E.g., objectorientedpackages in Forth use execute for wordswith arbitrary stack effects. Programs using thesewords have a statically determined stack effect, too,but it is only there at a higher level; e.g., if youuse a separate tag (and a separate exec.tag) foreach method selector, typical uses comply with therestriction, but in most object-oriented packagesthere is only one execute.Figure 1 shows code for this example: the Forthvariant defines a defining word selector, and theselectors are then defined with this defining word;in contrast, the PAF variant defines the selectorsdirectly (and pretty repetetively), each with its owntag.If you want to define a defining word for methodselectors like you usually do in Forth, the tag wouldhave to be passed around as a define-time parameterbetween the involved defining words. This supportfor higher-level programming is not required insidePAF (there we leave such meta-programming to thehigher-level language), but if we want to transferthe tag idea back to Forth, we would have to addsuch things.5.3 Compiling Forth to PAFTranslating Forth code that is not PAF code intoPAF code can be instructive.As an example, we use another variant of the selectorcode above 6 :: do-selector ( .. obj m-off -- .. )over @ + @ execute ;: foo ( .. obj -- .. )1 cells do-method ;: bar ( -- )1 2 my-obj foo . ;This is not PAF because of the execute, whichcan have an arbitrary stack effect. We translate thisexecute into a PAFjump with tagforth; we decidethat the PAF calling convention for xts with thattag is ( -- ). I.e., any Forth stack effects have tobe translated into accesses to an explicitly implementedmemory stack in PAF. The stack pointer ofthe data stack is implemented as a value sp.Do-selector itself only needs to store the stackitem obj into this explicit stack, but the direct andindirect callers of do-selector usually have to accessthis explicit stack as well. In our example, barhas to push two items on the explicit stack and popone item from the explicit stack:0 value sp: do-methodover sp cell- tuck ! to spswap @ + @ jump.forth ;: foo1 cells jump:do-method ;: barsp cell- 1 over !cell- 2 over !to spmy-obj foosp dup @ swap cell+ to spjump:. ;

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!