pfe-useful-ext
Prev? | pfe Forth Wordset List | ?Next

## 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 -&gt;zapp.a    ( zero offset from the base of the struct )
      /CELL /FIELD -&gt;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 -&gt;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 -&gt;zapp.b @         ( read a value from the field )
      16 zapp2 -&gt;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

Prev? | Up | ?Next
pfe-tools-misc-ext? | Home | ?pfe-with-spy-ext