-- useful additional primitives
Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.
description: This wordset adds some additional primitives that are useful. The structure of this file follows the the example in your-ext.c, yet some of the words here must be bound statically into the main pfe-object to work out smart and nicely.
EXTENSIONS
>COMPILE
( xt -- )(
)
;
p4:"to-compile";
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
($
( [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
)
( cs-token -- )(
)
;
p4:"prefix-end";
takes the execution-token from ($ and compiles it using >COMPILE
EXTENSIONS
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
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
PRINTF
( .. )(
)
;
as:"printf";
obsolete forthword PRINTF
is doing the same as PFE-PRINTF
This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.
EXTENSIONS
SPRINTF
( .. )(
)
;
as:"sprintf";
obsolete forthword SPRINTF
is doing the same as PFE-SPRINTF
This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.
EXTENSIONS
LOADF
( "filename" -- )(
)
;
p4:"loadf";
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
DOER
( .. )(
)
;
as:"doer";
ordinary primitive DOER
an executable word (no special usage info)
or wrapper call around p4_defer
EXTENSIONS
MAKE
( [word] -- )... ;AND(
)
;
p4:"make";
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
;AND
( -- )(
)
;
p4:"semicolon-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
[NOT]
( a -- a' )(
)
;
p4:"bracket-not";
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
+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
FIELD-OFFSET
( .. )( | ) ; |
; |
forthword synonym FIELD-OFFSET
is doing the same as +CONSTANT
this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.
EXTENSIONS
OFFSET:
( .. )(
)
;
as:"offset-colon";
forthword synonym OFFSET:
is doing the same as +CONSTANT
this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.
EXTENSIONS
+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
/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
/CHAR
( .. )(
)
;
as:"slash-char";
( sizeof(p4char) ) constant /CHAR
an ordinary constant (no special usage info)
EXTENSIONS
/WCHAR
( .. )(
)
;
as:"slash-wchar";
( sizeof(short) ) constant /WCHAR
an ordinary constant (no special usage info)
EXTENSIONS
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
(LOADF-LOCATE)
( xt -- nfa )( | ) ; |
; |
the implementation of LOADF-LOCATE
EXTENSIONS
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
#WITH-FIG
( .. )( | ) ; |
; |
( PFE_WITH_FIG+100 ) constant #WITH-FIG
an ordinary constant (no special usage info)
EXTENSIONS
#WITH-NO-FFA
( .. )( | ) ; |
; |
( WITH_NO_FFA+100 ) constant #WITH-NO-FFA
an ordinary constant (no special usage info)
EXTENSIONS
X"
( "hex-q" -- bstring )(
)
;
p4:"x-quote";
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
[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
[VOCABULARY]
( "name" -- )( | ) ; |
; |
create an immediate vocabulary. Provides for basic modularization.
: [VOCABULARY] VOCABULARY IMMEDIATE ;
EXTENSIONS
[DEF]
( -- )(
)
;
p4:"bracket-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
VOCABULARY'
( .. )(
)
;
as:"vocabulary-tick";
obsolete forthword VOCABULARY'
is doing the same as [VOCABULARY]
This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.
EXTENSIONS
DEF'
( .. )(
)
;
as:"def-tick";
obsolete immediate DEF'
is doing the same as [DEF]
This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.
EXTENSIONS
CONTEXT?
( -- number )(
)
;
p4:"context-Q";
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
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
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
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
SEARCH-ALSO-VOC
( .. )( | ) ; |
; |
obsolete forthword SEARCH-ALSO-VOC
is doing the same as DEFS-ARE-SEARCHED-ALSO
This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.
EXTENSIONS
!NO
( .. )(
)
;
as:"store-no";
forthword synonym !NO
is doing the same as FALSE
this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.
EXTENSIONS
!USE
( .. )(
)
;
as:"store-use";
forthword synonym !USE
is doing the same as TRUE
this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.