"Useful kernel extensions"

useful EXTENSIONS
* >COMPILE ( xt -- )

does the work of POSTPONE on the execution token that
you got from somewhere else - so it checks if the name
(that correspond to the execution-token argument) is
actually immediate, so it has to be executed to compile
something, e.g. IF or THEN - see also POSTPONE ,
COMPILE , [COMPILE] , INTERPRET

EXTENSIONS useful ordinary primitive

* ($ ( [word] -- cs-token ) compile-only

takes the execution token of the following word and
saves it on the compile-stack. The correspondig closing
) will then feed it into >COMPILE - so this pair
of word provides you with a prefix-operation syntax
that you may have been seen in lisp-like languages.
   ($ IF ($ 0= A1 @ )) ($ THEN ." hello " )
Note that an opening simple ( paren is a comment.

EXTENSIONS useful immediate primitive

* ) ( cs-token -- )

takes the execution-token from ($ and compiles
it using >COMPILE

EXTENSIONS useful immediate primitive

* PFE-PRINTF ( args ... format$ -- )

uses SPRINTF to print to a temporary 256-char buffer
and prints it to stdout afterwards. See the example
at SPRINTF of what it does internally.

EXTENSIONS useful ordinary primitive

* PFE-SPRINTF ( args ... format$ dest$ -- len-dest )

just like the standard sprintf() function in C, but
the format is a counted string and accepts %#s to
be the format-symbol for a forth-counted string.
The result is a zeroterminated string at dest$ having
a length being returned. To create a forth-counted
string, you could use:
   variable A 256 ALLOT
   15 " example" " the %#s value is %i" A 1+ SPRINTF A C!
   A COUNT TYPE

EXTENSIONS useful ordinary primitive

PRINTF

[] no special info, see general notes

EXTENSIONS useful obsolete forthword

SPRINTF

[] no special info, see general notes

EXTENSIONS useful obsolete forthword

* LOADF ( "filename" -- )

loads a file just like INCLUDE but does also put
a MARKER in the LOADED dictionary that you can
do a FORGET on to kill everything being loaded
from that file.

EXTENSIONS useful ordinary primitive

* DOER ( word -- )

In PFE it is a synonym to DEFER which a semistandard word.
Unlike DEFER, the DOER-vector was set with an a small
piece of code between MAKE and ;AND. The "DOER"-word
should be replaced with DEFER IS, which is easy since
the DEFER and DOER point to the same internal runtime.

EXTENSIONS useful ordinary primitive

* MAKE ( [word] -- ) ... ;AND

make a seperated piece of code between MAKE and ;AND
and on execution of the MAKE the named word is twisted
to point to this piece of code. The word is usually
a DOER but the current implementation works
on DEFER just as well, just as it does on other words who
expect to find an execution-token in its PFA. You could even
create a colon-word that starts with NOOP and can then make
that colon-word be prefixed with the execution of the code piece.
This MAKE
does even work on LOCALS| and VAR but it is uncertain
what that is good for.

EXTENSIONS useful compiling primitive

* ;AND ( -- )

For the code piece between MAKE and ;AND , this word
will do just an EXIT . For the code outside of
the MAKE construct a branch-around must be resolved then.

EXTENSIONS useful compiling primitive

* [NOT] ( a -- a' )

executes 0= but this word is immediate so that it does
affect the cs-stack while compiling rather than compiling
anything. This is useful just before words like [IF] to
provide semantics of an [IFNOT]. It is most useful in
conjunction with "[DEFINED] word" as it the sequence
"[DEFINED] word [NOT] [IF]" can simulate "[IFNOTDEF] word"

EXTENSIONS useful immediate primitive

* +CONSTANT ( offset "name" -- )

create a new offsetword. The word is created and upon execution
it adds the offset, ie. compiling the OFFSET-RT runtime:
       ( address -- address+offset )
This word is just a convenience word, just use the word +FIELD
directly and choose a DROP to flag the end of a current
offset-field declaration series. See also /FIELD series to
declare simple structures which end with a final CONSTANT to
memorize the complete size. The /FIELD style is more traditional.

EXTENSIONS useful defining primitive

FIELD-OFFSET

[] no special info, see general notes

EXTENSIONS useful forthword synonym

OFFSET:

[] no special info, see general notes

EXTENSIONS useful forthword synonym

* +FIELD ( offset "name" -- offset )

created a new name with an OFFSET-RT runtime using the given offset.
Leave the offset-value untouched, so it can be modified with words
like CHAR+ and CELL+ and SFLOAT+ ; This word is the simplest way
to declared structure access words in forth - the two STRUCT modules
contain a more elaborate series of words. Use this one like:
 0                        ( a fresh definition is started )
 +FIELD zapp.a+ CHAR+     ( zero offset from the base of the struct )
 +FIELD zapp.b+ CELL+     ( no alignment, starts off at 1 from base )
 +FIELD zapp+   DROP      ( store size of complete zap structure )

 0 zapp+                  ( extend the zap structure )
 +FIELD zappx.c+ CELL+    ( a new field )
 +FIELD zappx+   DROP     ( and save it again )

 CREATE zapp1  0 zapp+ ALLOT ( a way to allocate a strucutre )

 zapp2 zapp.b+ @         ( read a value from the field )
 16 zapp2 zapp.b+ !      ( store a value in there )

this form is not the traditional form used in forth, it is however
quite simple. Use the simplefield declaration with /FIELD to
be compatible with traditional styles that build on top of sizeof
constants in forth (which are not part of the ANS Forth standard).

EXTENSIONS useful ordinary primitive

* /FIELD ( offset size "name" -- offset+size )

created a new +FIELD name with an OFFSET-RT
of offset. Then add the size value to the offset so that
the next /FIELD declaration will start at the end of the
field currently declared. This word is the simplest way to
declared structure access words in forth - the two STRUCT modules
contain a more elaborate series of words. This one is used like:
 0                        ( a fresh definition is started )
 /CHAR /FIELD ->zapp.a    ( zero offset from the base of the struct )
 /CELL /FIELD ->zapp.b    ( no alignment, starts off at 1 from base )
 CONSTANT /zapp           ( store size of complete zap structure )

 /zapp                    ( extend the zap structure )
 /CELL /FIELD ->zappx.c   ( a new field )
 CONSTANT /zappx          ( and save it again )

 CREATE zapp1 /zapp ALLOT ( a way to allocate a strucutre )
 /zapp BUFFER: zapp2      ( another way to do it, semi-standard )

 zapp2 ->zapp.b @         ( read a value from the field )
 16 zapp2 ->zapp.b !      ( store a value in there )

compare also with /CHAR /WCHAR /CELL /DCELL
and use +FIELD as the lowlevel word, can simulate as
 : /FIELD SWAP +FIELD + ;

EXTENSIONS useful ordinary primitive

/CHAR

[] no special info, see general notes

EXTENSIONS useful ordinary constant

/WCHAR

[] no special info, see general notes

EXTENSIONS useful ordinary constant

* REPLACE-IN ( to-xt from-xt n "name" -- )

will handle the body of the named word as a sequence of cells (or tokens)
and replaces the n'th occurences of from-xt into to-xt. A negative value
will change all occurences. A zero value will not change any.

EXTENSIONS useful ordinary primitive

* (LOADF-LOCATE) ( xt -- nfa )

the implementation of LOADF-LOCATE

EXTENSIONS useful ordinary primitive

* LOADF-LOCATE ( "name" -- )

look for the filename created by LOADF that had been
defining the given name. LOADF has created a marker
that is above the INCLUDED file and that
marker has a body-value just below the
INCLUDED file. Hence the symbol was defined during
LOADF execution of that file.
 : LOADF-LOCATE ?EXEC POSTPONE ' (LOADF-LOCATE) .NAME ;

EXTENSIONS useful ordinary primitive

# ifdef PFE_WITH_FIG
#WITH-FIG

[] no special info, see general notes

EXTENSIONS useful ordinary constant

# endif # ifdef WITH_NO_FFA
#WITH-NO-FFA

[] no special info, see general notes

EXTENSIONS useful ordinary constant

# endif
* X" ( "hex-q" -- bstring )

places a counted string on stack
containing bytes specified by hex-string
- the hex string may contain spaces which will delimit the bytes
 example: 
    X" 41 42 4344" COUNT TYPE ( shows ABCD )

EXTENSIONS useful compiling primitive

* [POSSIBLY] ( [name] -- ?? )

check if the name exists, and execute it immediatly
if found. Derived from POSSIBLY as seen in other forth systems.
 : [POSSIBLY] (') ?DUP IF EXECUTE THEN ; IMMEDIATE

EXTENSIONS useful immediate primitive

* [VOCABULARY] ( "name" -- )

create an immediate vocabulary. Provides for basic
modularization.
 : [VOCABULARY] VOCABULARY IMMEDIATE ;

EXTENSIONS useful ordinary primitive

* [DEF] ( -- )

immediatly set topmost CONTEXT voc to CURRENT compilation voc.
 : DEF' CURRENT @ CONTEXT ! ; IMMEDIATE
note that in PFE most basic vocabularies are immediate, so that
you can use a sequence of
 FORTH ALSO  DEFINITIONS
 [DEF] : GET-FIND-3  [ANS] ['] FIND  [FIG] ['] FIND  [DEF] ['] FIND ;
where the first wordlist to be searched via the search order are
[ANS] and [FIG] and FORTH (in this order) and which may or may not
yield different flavours of the FIND routine (i.e. different XTs)

EXTENSIONS useful immediate primitive

VOCABULARY'

[] no special info, see general notes

EXTENSIONS useful obsolete forthword

DEF'

[] no special info, see general notes

EXTENSIONS useful obsolete immediate

* CONTEXT? ( -- number )

GET-CONTEXT and count how many times it is in the order but
the CONTEXT variable itself. The returned number is therefore
minus one the occurences in the complete search-order.
usage:
   ALSO EXTENSIONS CONTEXT? [IF] PREVIOUS [THEN]
   ALSO DEF' DEFAULT-ORDER
 : CONTEXT? 
   0 LVALUE _count
   GET-ORDER 1- SWAP  LVALUE _context
   0 ?DO _context = IF 1 +TO _count THEN LOOP
   _count
 ;

EXTENSIONS useful ordinary primitive

* CASE-SENSITIVE-VOC ( -- )

accesses CONTEXT which is generally the last named VOCABULARY .
sets a flag in the vocabulary-definition so that words are matched
case-sensitive.
 example: 
    VOCABULARY MY-VOC  MY-VOC CASE-SENSITIVE-VOC
OBSOLETE! use DEFS-ARE-CASE-SENSITIVE

EXTENSIONS useful ordinary primitive

* DEFS-ARE-CASE-SENSITIVE ( -- )

accesses CURRENT which is generally the last wordlist that the
DEFINITIONS shall go in. sets there a flag in the vocabulary-definition
so that words are matched case-sensitive.
 example: 
    VOCABULARY MY-VOC  MY-VOC DEFINITIONS DEFS-ARE-CASE-SENSITIVE

EXTENSIONS useful ordinary primitive

* DEFS-ARE-SEARCHED-ALSO ( -- )

binds CONTEXT with CURRENT. If the CURRENT VOCABULARY is in
the search-order (later), then the CONTEXT vocabulary will
be searched also. If the result of this word could lead into
a recursive lookup with FIND it will throw CURRENT_DELETED
and leave the CURRENT VOCABULARY unaltered.
 example:
MY-VOC DEFINITIONS MY-VOC-PRIVATE DEFS-ARE-SEARCHED-ALSO

EXTENSIONS useful ordinary primitive

SEARCH-ALSO-VOC

[] no special info, see general notes

EXTENSIONS useful obsolete forthword

!NO

[] no special info, see general notes

EXTENSIONS useful forthword synonym

!USE

[] no special info, see general notes

EXTENSIONS useful forthword synonym

|(

[] no special info, see general notes

EXTENSIONS useful immediate synonym