Programming-Tools Reference

StrongForth's implementation of the ANS Forth Programming-Tools word set is provided as source code in blocks 80 to 91. A small number of these words is already included in the core and in the library.

Name Word Set Location Comment
.S TOOLS Library  
? TOOLS Block 81  
DUMP TOOLS Blocks 82 to 85 6 overloaded versions. Uses .HEX and .BYTE.
SEE TOOLS Blocks 86 to 88 Uses ?COLON, HAS-PARAM?, SEE-LIT, SEE-DLIT, SEE-SLIT and SEE-ANY.
WORDS TOOLS Blocks 80 to 81 Extended semantics. Uses . for items of data type DEFINITION.
;CODE TOOLS EXT Block 91 Uses (;CODE).
AHEAD TOOLS EXT Library  
ASSEMBLER TOOLS EXT Block 90 Dummy word.
BYE TOOLS EXT Core  
CODE TOOLS EXT Core  
CS-PICK TOOLS EXT None This word is not available in strongForth.
CS-ROLL TOOLS EXT None This word is not available in strongForth.
EDITOR TOOLS EXT Block 90 Dummy word.
FORGET TOOLS EXT None This word is not available in strongForth.
STATE TOOLS EXT Core  
[ELSE] TOOLS EXT Block 89  
[IF] TOOLS EXT Block 90  
[THEN] TOOLS EXT Block 90  

The complete Programming-Tools word set becomes available after compiling it into the dictionary with

80 91 THRU

WORDS

StrongForth's version of WORDS has an extended semantics with respect to the ANS Forth specification. If the parse area is not empty after WORDS, only words with the specified name are displayed. This is quite useful for finding all overloaded versions of a word:

WORDS .
. ( DEFINITION -- )
. ( DATA-TYPE -- )
. ( FLAG -- )
. ( CHARACTER -- )
. ( SIGNED -- )
. ( SINGLE -- )
. ( SIGNED-DOUBLE -- )
. ( DOUBLE -- )
 OK

This example reveals another word, that is included in strongForth's Programming-Tools word set. . for items of data type DEFINITION is actually used by WORDS itself to display a definition including it's stack diagram.

?

? is actually a very simple word. In many ANS Forth systems, it is simply implemented like this:

: ? ( a-addr -- ) \ ANS Forth
  @ . ;

But this doesn't work in strongForth:

: ? ( ADDRESS -- )
  @ . ;

  @ ? undefined word
ADDRESS

All versions of @ that are provided by strongForth expect the address of a specific data type on the stack. Our first approach micht look like this:

: ? ( DATA -> SINGLE -- )
  @ . ;
 OK
BASE ?
10  OK

This works fine, but it has a couple of serious drawbacks. First, we need a separate version of ? for each kind of address (DATA, CONST, CODE, PORT and FAR-ADDRESS). If we add the character addresses, we already get 10 different versions of ?. Second, all items will be displayed as unsigned single-precision numbers, even items of data type SIGNED, FLAG, CHARACTER, and DOUBLE. ? wouldn't care about the different overloaded versions of . that display all data nicely according to their data type. That is, unless we decide again to overload ? by defining separate versions for all overloaded versions of .. But with 8 different versions of . and 10 different kinds of addresses, we'd have to define 80 (!) overloaded versions of ?. No way.

But there's a simple solution. Only one version of ?, that covers all those 80 combinations, plus all future kinds of addresses and all future versions of .. Here it is:

: ? ( -- )
  POSTPONE @ POSTPONE . ; IMMEDIATE

The only drawback is that this version of ? compiles two tokens instead of one. But as a compensation, it executes a little bit faster at runtime.

DUMP

strongForth provides 6 overloaded versions of DUMP in order to cover all combinations of the data size (single-cell, double-cell and character size) with the DATA and CONST memory areas:

DUMP ( CCONST UNSIGNED -- )
DUMP ( CDATA UNSIGNED -- )
DUMP ( CONST -> DOUBLE UNSIGNED -- )
DUMP ( DATA -> DOUBLE UNSIGNED -- )
DUMP ( CONST UNSIGNED -- )
DUMP ( DATA UNSIGNED -- )

Because the definitions of all these overloaded versions look very similar, it's easy to define the missing versions for addresses of data types CODE, PORT and FAR-ADDRESS, and the respective character addresses,

The versions of DUMP for character addresses display 16 2-digit hexadecimal numbers per line. The double-cell versions display 4 8-digit hexadecimal numbers per line. All other addresses are assumed to refer to single-cell data, which are displayed as 8 4-digit hexadecimal numbers per line. Here are some examples:

85 BLOCK 64 DUMP
05EC: 5C 20 50 52 4F 47 52 41 4D 4D 49 4E 47 2D 54 4F
05FC: 4F 4C 53 3A 20 44 55 4D 50 20 20 20 20 20 20 20
060C: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
061C: 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20 20
 OK
' DUMP >CODE 20 DUMP
2282: 14BC 0088 0080 00FC 023E 0074 0236 0000
2292: 018A 021C 0036 0074 0212 0010 00FC 0236
22A2: 0000 0182 0074 0090
 OK
DTP@ 5 DUMP
0140: 061E0000 061E0000 062A0000 06160000
0150: 063A0000
 OK

.BYTE and .HEX are used within DUMP for displaying one number as 2, 4 and 8 hexadecimal digits:

.BYTE ( SINGLE -- )
.HEX ( SINGLE -- )
.HEX ( DOUBLE -- )

SEE

Colon definitions can be decompiled and displayed with SEE. Other definitions, like code definitions, constants, variables and values, may easily be included by extending the semantics of SEE. SEE traverses the virtual code of a colon definition, displaying the names of the words that are assiciated with the compiled execution tokens. It further recognizes tokens that have a parameter, like (R@) or BRANCH. The parameters are displayed as signed numbers, because they are either branch offsets or return stack offset:

: TEST1 ( SIGNED -- 1ST )
  DUP 0< IF 2* 1- THEN ;
 OK
SEE TEST1
: TEST1 ( SIGNED -- 1ST )
DUP 0< 0BRANCH 6 2* 1- ;  OK

The tokens of LIT, DLIT and SLIT are handled in a special way. Instead of displaying the names of these tokens, SEE directly displays the assumed source code:

: TEST2 100699. 533 UM/MOD . DROP " EURO" TYPE ;
 OK
SEE TEST2
: TEST2 ( -- )
100699 533 UM/MOD . DROP " EURO" TYPE ;  OK

Of course, this implementation of SEE leaves many opportunities for improvements. Inclusion of non colon definitions, recognising conditionals and loops, indenting according to nested control structures, and other things are possible. On the other hand, the availability of the original source code makes these efforts mostly obsolete.

Programming-Tools Extension Words

Three words specified by ANS Forth are not implemented in strongForth. CS-PICK and CS-ROLL had to be left out for the same reason as PICK and ROLL: strongForth's data type system does not allow defining words with ambiguous stack diagrams at compile time. They are obsolete anyway, because strongForth does not need a separate control-flow stack. Items of data type CONTROL-FLOW, which are processed by conditionals and loop structures, are simply kept on the data stack.

The third word from the Programming-Tools word set that is not available in strongForth is FORGET. ANS Forth declares this word as obsolete, because it does not work reliably. It is actually specified for backward compatibility only. Its semantics is now covered by MARKER.

The implementations of [IF], [ELSE] and [THEN] are identical to those suggested in section A.15 of the ANS Forth specification. Some syntactical differences are caused by words that are not available in strongForth, like WORD, 2DUP, 2DROP and S".

EDITOR and ASSEMBLER are implemented as dummy words, because strongForth does not yet support the Search-Order word set.

The definition of ;CODE is quite similar to the definition of DOES>. Both create defining words, and both compile a separate runtime portion ((;CODE) and (DOES)). An example of how to use ;CODE is included in the documentation of the strongForth assembler.


Dr. Stephan Becher - December 13th, 2005