Name

pfe-useful-ext ? Useful kernel extensions

Synopsis

_like:COMPILE, ?=>? ();?
"EXTENSIONS";
?
($ ( [word] -- cs-token ) ?=>? ();?
"EXTENSIONS";
?
) ( cs-token -- ) ?=>? ();?
"EXTENSIONS";
?
PFE-PRINTF ( args ... format$ -- ) ?=>? ();?
"EXTENSIONS";
?
PFE-SPRINTF ( args ... format$ dest$ -- len-dest ) ?=>? ();?
"EXTENSIONS";
?
LOADF ( "filename" -- ) ?=>? ();?
"EXTENSIONS";
?
DOER ( word -- ) ?=>? ();?
"EXTENSIONS";
?
MAKE ( [word] -- ) ?=>? ();?
"EXTENSIONS";
?
;AND ( -- ) ?=>? ();?
"EXTENSIONS";
?
[NOT] ( a -- a' ) ?=>? ();?
"EXTENSIONS";
?
+FIELD: ( offset "name" -- offset ) ?=>? ();?
"EXTENSIONS";
?
/FIELD ( offset size "name" -- offset+size ) ?=>? ();?
"EXTENSIONS";
?
REPLACE-IN ( to-xt from-xt n "name" -- ) ?=>? ();?
"EXTENSIONS";
?
(LOADF-LOCATE) ( xt -- nfa ) ?=>? ();?
"EXTENSIONS";
?
LOADF-LOCATE ( "name" -- ) ?=>? ();?
"EXTENSIONS";
?
X" ( "hex-q" -- bstring ) ?=>? ();?
"EXTENSIONS";
?
EVALUATE-WITH ( i*x addr len xt[i*x--j*x] -- j*x ) ?=>? ();?
"EXTENSIONS";
?
[POSSIBLY] ( [name] -- ?? ) ?=>? ();?
"EXTENSIONS";
?
[VOCABULARY] ( "name" -- ) ?=>? ();?
"EXTENSIONS";
?
[DEF] ( -- ) ?=>? ();?
"EXTENSIONS";
?
CONTEXT? ( -- number ) ?=>? ();?
"EXTENSIONS";
?
CASE-SENSITIVE-VOC ( -- ) ?=>? ();?
"EXTENSIONS";
?
DEFS-ARE-CASE-SENSITIVE ( -- ) ?=>? ();?
"EXTENSIONS";
?
DEFS-ARE-SEARCHED-ALSO ( -- ) ?=>? ();?
"EXTENSIONS";
?

Description

!USE ( -- true ) * a synonym for => TRUE !USE SMART-WORDS!

_like:COMPILE, - no description, sorry

($ ( [word] -- cs-token ) compile-only => "EXTENSIONS"

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.

) ( cs-token -- ) => "EXTENSIONS"

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

PFE-PRINTF ( args ... format$ -- ) => "EXTENSIONS"

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.

PFE-SPRINTF ( args ... format$ dest$ -- len-dest ) => "EXTENSIONS"

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
  

LOADF ( "filename" -- ) => "EXTENSIONS"

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.

DOER ( word -- ) => "EXTENSIONS"

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.

MAKE ( [word] -- ) ... ;AND => "EXTENSIONS"

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.

;AND ( -- ) => "EXTENSIONS"

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.

[NOT] ( a -- a' ) => "EXTENSIONS"

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"

+FIELD: ( offset "name" -- offset ) => "EXTENSIONS"

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).

/FIELD ( offset size "name" -- offset+size ) => "EXTENSIONS"

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 + ;
  

REPLACE-IN ( to-xt from-xt n "name" -- ) => "EXTENSIONS"

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.

(LOADF-LOCATE) ( xt -- nfa ) => "EXTENSIONS"

the implementation of LOADF-LOCATE

LOADF-LOCATE ( "name" -- ) => "EXTENSIONS"

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 ;
  

X" ( "hex-q" -- bstring ) => "EXTENSIONS"

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 )
  

EVALUATE-WITH ( i*x addr len xt[i*x--j*x] -- j*x ) => "EXTENSIONS"

added to be visible on the forth command line on request by MLG, he has explained the usage before a lot, you can get an idea from:

     : EVALUATE ['] INTERPRET EVALUATE-WITH ;

The word is used internally in PFE for the loadlist evaluation of the binary modules: where previously each loadercode had its own CREATE-execution we do now call the original forthish CREATE-word like, so bootstrapping a VARIABLE will now call VARIABLE itself and of course we need to set up the TIB-area to point to the name of the variable that shall be created in the forth dictionary:

  : LOAD-WORD ( arg-value str-ptr str-len loader-code -- )
       CASE
         #LOAD-VARIABLE OF ['] VARIABLE EVALUATE-WITH ENDOF
         ....
       ENDCASE
       CLEARSTACK
  ;
  

[POSSIBLY] ( [name] -- ?? ) => "EXTENSIONS"

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
  

[VOCABULARY] ( "name" -- ) => "EXTENSIONS"

create an immediate vocabulary. Provides for basic modularization.

  : [VOCABULARY] VOCABULARY IMMEDIATE ;
  

[DEF] ( -- ) => "EXTENSIONS"

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)

CONTEXT? ( -- number ) => "EXTENSIONS"

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
  ;
  

CASE-SENSITIVE-VOC ( -- ) => "EXTENSIONS"

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

DEFS-ARE-CASE-SENSITIVE ( -- ) => "EXTENSIONS"

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
  

DEFS-ARE-SEARCHED-ALSO ( -- ) => "EXTENSIONS"

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