\ For Gforth 0.6.2, latest in a series of CREATE/DOES> overlays for teaching.
\ This one uses return stack tricks and is therefore quite a bit harder to follow.
\ It relies on the knowledge that Gforth has a shared code/data space.
\ Rather than hardcode offset values, they are calculated dynamically in the code.
\ A pointer to the embedded code address in the most recently CREATEd word:
variable lastcreated
: (does) ( -- R: code-addr -- )
\ Backpatch the most recently CREATEd word with the addr of the DOES> clause:
r> lastcreated @ ! ;
: DOES> ( -- R: return-addr -- )
postpone (does)
postpone r> \ retrieve the associated dataspace address
postpone cell+ \ increment the address past the compiled EXIT
; immediate
: CREATE ( "name" -- )
:
(compile) call
here lastcreated ! \ this address is stored for DOES> to patch later
0 ,
postpone ;
DOES> ( -- a-addr ) \ assign a default action
;
\ Calculate the offset that converts an CREATEd word's xt into a dataspace address:
create bodyoffset
here ' bodyoffset - ,
: >BODY ( xt -- a-addr ) bodyoffset @ + ;