POSTPONE - CORE (original) (raw)

6.1.2033 POSTPONE CORE

Interpretation:

Interpretation semantics for this word are undefined.

Compilation:

( "name" -- )

Skip leading space delimiters. Parse name delimited by a space. Find name. Append the compilation semantics of_name_ to the current definition. An ambiguous condition exists if name is not found.

See:

Rationale:

Typical use:

: ENDIF POSTPONE THEN ; IMMEDIATE

: X ...IF ... ENDIF ... ;

POSTPONE replaces most of the functionality ofCOMPILE and [COMPILE]. COMPILE and[COMPILE] are used for the same purpose: postpone the compilation behavior of the next word in the parse area.COMPILE was designed to be applied to non-immediate words and [COMPILE] to immediate words. This burdens the programmer with needing to know which words in a system are immediate. Consequently, Forth standards have had to specify the immediacy or non-immediacy of all words covered by the standard. This unnecessarily constrains implementors.

A second problem with COMPILE is that some programmers have come to expect and exploit a particular implementation, namely:

: COMPILE R> DUP @ , CELL+ >R ;

This implementation will not work on native code Forth systems. In a native code Forth using inline code expansion and peephole optimization, the size of the object code produced varies; this information is difficult to communicate to a "dumb"COMPILE. A "smart" (i.e., immediate) COMPILE would not have this problem, but this was forbidden in previous standards.

For these reasons, COMPILE has not been included in the standard and [COMPILE] has been moved in favor ofPOSTPONE. Additional discussion can be found in Hayes, J.R., "Postpone", Proceedings of the 1989 Rochester Forth Conference.

Testing:

T{ : GT4 POSTPONE GT1 ; IMMEDIATE -> }T
T{ : GT5 GT4 ; -> }T
T{ GT5 -> 123 }T

T{ : GT6 345 ; IMMEDIATE -> }T
T{ : GT7 POSTPONE GT6 ; -> }T
T{ GT7 -> 345 }T

ContributeContributions

ruvavatar of ruv [98] Ambiguous condition could be removedComment2019-07-19 15:08:09

Applying POSTPONE to some words is an ambiguous condition. Actually, it is just a concession to some Forth system implementations (see discussion wrt TO). Since the compilation semantics for these words are well defined, there is no normative cause for an ambiguous condition.

These words are: TO, IS, ACTION-OF.

Another two words are: S" and S" (the variants from FILE word set).

All these five words are "dual-semantics" words (and there are no other such standard words). It is not clear what is the difference that applying POSTPONE to the last two is not an ambiguous condition. In any case, it seems that in any standard Forth system, POSTPONE can be correctly implemented for these five words.

If these words are implemented as STATE-smart immediate words then it is enough to put a special flag to them and implement POSTPONE as the following:

: [ STATE OFF ; IMMEDIATE
: ] STATE ON ;

: EXECUTE-COMPILING ( i*x xt --j*x )
  STATE @ IF  EXECUTE  EXIT  THEN
  STATE 1+!   EXECUTE  STATE @ 1 = IF STATE OFF THEN
;

: POSTPONE
    \ ...
    \ ( xt flags )
    DUP MASK-DUALSMART AND IF DROP LIT, ['] EXECUTE-COMPILING COMPILE, EXIT THEN
    \ ...
; IMMEDIATE

The [COMPILE] can be implemented in the similar way too.

Reply New Version

MitraArdronavatar of MitraArdron [177] Needs an example of replacing COMPILEExample2021-01-22 03:42:24

I don't know about anyone else, but how POSTPONE replaces [COMPILE] is clear, much as I've tried I can't figure out how POSTPONE replaces COMPILE.

For example with something like : AGAIN COMPILE branch ; ( a -- ) how is that intended to be replaced by POSTPONE is unclear.

Reply New Version

ruvavatar of ruv [198] Portable implementation for POSTPONESuggested reference implementation2021-05-06 09:19:58

One simple and almost portable implementation of POSTPONE is following:

: POSTPONE ( "name" -- )
  BL WORD FIND DUP 0= -13 AND THROW 1 = ( xt flag-compilation )
  SWAP LIT,  IF ['] EXECUTE  ELSE ['] COMPILE,  THEN  COMPILE,
; IMMEDIATE

This implementation uses the non-standard LIT, word (that is factor of LITERAL), and applies Tick to COMPILE, (that is ambiguous in the general case due to undefined interpretation semantics for COMPILE, at the moment). Also this implementation relies on the TC reply to RFI Q99-027 and doesn't meet the common expectations concerning a system behavior in this regard (a more completed implementation can be found in my gist on GitHub).

LIT, execution: ( x -- ) append the run-time semantics "place x on the stack" to the current definition.

If LIT, is absent, it can be replaced by the phrase 0 <# #S #> EVALUATE in the definition above.

LITERAL can be defined via LIT, and vise versa:

: LITERAL ( x -- ) LIT, ; IMMEDIATE

: LIT, ( x -- ) POSTPONE LITERAL ;

To make applying Tick to COMPILE, compliant, it's enough to redefined it:

: COMPILE, ( xt -- ) COMPILE, ;

Reply New Version

LSchmidtavatar of LSchmidt [221] I suggest to complete the testComment2022-02-27 14:26:42

add a word : GT1 123 ; as first line.
Currently it is necessary to extrapolate from context that a non-immediate word with that name and semantics is required.

Reply New Version