Table of Contents

1. PFE Documentation 0.32.x
How To Make A Dist
'make doc', 'make dist-doc' and 'make install-doc'
'make rpm' and friends
Tuning The Portable Forth Environment
Loop unrolling in the inner interpreter
Using global register variables
Choosing registers to use
How To Write A PFE Module
The Current State
The Name Of The Module
Create the File And Add It To Makefile.am
What Must Be In The Source File
Semant - advanced words of PFE
Runtime - preparing PFE for call-threading
WordSets in External Modules
External Modules
WordSet Activation
Available Modules
Internal Decisions
The Head.aux Field
The Flag.byte Field
The Head Layout
Non-Const >BODY
StateSmart Words and POSTPONE
Locals in PFE
ANS Locals
Explicit Locals
Using POCKETs
Special Implementation Strategies
Environment Vocabulary
[defined] / [undefined]
state-smart over exec-only
Quoted-Parse Idea
PFE Threading types
CFA Threaded
CALL Threaded
SBR Threading
SBR-ARG Threading
extra RP or not
Porting SBR-Threading
Choosing an ARG-register
Traditional CPU
RISC w/ LR type CPU
Summary
Literature
Dirk Zoller's README
What is it?
Legalese
Why did I do it?
Design objectives
Status
Usage
Documentation
Contributions
Acknowledgements
Known Problems
The Underline on ABORT
loading an INCLUDE-file at boot or on the command line
Problems in 0.32.x
License
The GNU Lesser General Public License (LGPL)
GNU LESSER GENERAL PUBLIC LICENSE
Preamble
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
NO WARRANTY
2. ANS Forth '94
3. Wordset Reference
block wordset
block_misc wordset
cdecl wordset
chain wordset
chainlist wordset
core wordset
core_misc wordset
debug wordset
dlfcn wordset
internal wordset
double wordset
double_misc wordset
dstrings wordset
edit wordset
environ wordset
exception wordset
facility wordset
file wordset
file_misc wordset
floating wordset
floating_misc wordset
forth_83 wordset
forth_usual wordset
fpnostack wordset
gforth wordset
header wordset
help wordset
host_k12 wordset
lib_sdl wordset
locals wordset
memory wordset
misc wordset
module wordset
option wordset
forth wordset
extensions wordset
posix wordset
search wordset
shell wordset
signals wordset
smart_go wordset
string wordset
struct wordset
structs wordset
system wordset
term wordset
toolbelt wordset
tools wordset
tools_misc wordset
useful wordset
with_spy wordset
your wordset
zchar wordset
I. Words Reference
! - [:core:] - ordinary primitive
!+ - [:forth_usual.1:] - forthword synonym
!+ - [:toolbelt.1:] - ordinary primitive
!++ - [:forth_usual:] - ordinary primitive
!> - [:your.1:] - immediate synonym
" - [:core:] - immediate synonym
# - [:core:] - ordinary primitive
#! - [:posix:] - ordinary primitive
#> - [:core:] - ordinary primitive
$! - [:dstrings:] - ordinary primitive
$" - [:dstrings:] - compiling primitive
$$ - [:shell.1:] - obsolete forthword
$. - [:dstrings:] - ordinary primitive
$@ - [:dstrings:] - ordinary primitive
' - [:core:] - forthword synonym
'> - [:your:] - compiling primitive
( - [:core:] - immediate primitive
($ - [:useful:] - immediate primitive
($: - [:dstrings.1:] - immediate primitive
(.) - [:toolbelt.1:] - ordinary primitive
) - [:useful:] - immediate primitive
* - [:core:] - ordinary primitive
** - [:forth_83:] - ordinary primitive
*/ - [:core:] - ordinary primitive
+ - [:core:] - ordinary primitive
+! - [:core:] - ordinary primitive
++ - [:forth_usual:] - ordinary primitive
++ - [:toolbelt:] - ordinary primitive
, - [:core:] - ordinary primitive
," - [:toolbelt.1:] - immediate primitive
- - [:core:] - ordinary primitive
--> - [:forth_83:] - immediate primitive
. - [:core:] - ordinary primitive
." - [:core:] - compiling primitive
.( - [:core:] - immediate primitive
/ - [:core:] - ordinary primitive
// - [:cdecl.1:] - immediate synonym
0 - [:core_misc.1:] - ordinary constant
0< - [:core:] - ordinary primitive
0<= - [:core_misc:] - ordinary primitive
0<> - [:core:] - ordinary primitive
0= - [:core:] - ordinary primitive
0> - [:core:] - ordinary primitive
0>= - [:core_misc:] - ordinary primitive
1 - [:core_misc.1:] - ordinary constant
1+ - [:core:] - ordinary primitive
1- - [:core:] - ordinary primitive
2 - [:core_misc.1:] - ordinary constant
2! - [:core:] - ordinary primitive
2* - [:core:] - ordinary primitive
2+ - [:forth_83:] - ordinary primitive
2- - [:forth_83:] - ordinary primitive
2/ - [:core:] - ordinary primitive
2@ - [:core:] - ordinary primitive
3 - [:core_misc.1:] - ordinary constant
: - [:core:] - definining primitive
: - [:with_spy:] - forthword synonym
; - [:core:] - compiling primitive
; - [:with_spy:] - immediate synonym
< - [:core:] - ordinary primitive
<# - [:core:] - ordinary primitive
<= - [:core_misc:] - ordinary primitive
<> - [:core:] - ordinary primitive
= - [:core:] - ordinary primitive
> - [:core:] - ordinary primitive
>< - [:forth_83:] - ordinary primitive
>= - [:core_misc:] - ordinary primitive
? - [:tools:] - ordinary primitive
@ - [:core:] - ordinary primitive
@+ - [:forth_usual.1:] - forthword synonym
@+ - [:toolbelt.1:] - ordinary primitive
@++ - [:forth_usual:] - ordinary primitive
@> - [:your:] - compiling primitive
[ - [:core:] - immediate primitive
['] - [:core:] - compiling primitive
\ - [:core:] - immediate primitive
\\ - [:toolbelt:] - ordinary primitive
] - [:core:] - ordinary primitive
ABORT - [:exception:] - ordinary primitive
ABORT" - [:exception:] - compiling primitive
ABORT-WORDLIST - [:chainlist.1:] - - loader type P4_DVaL
ABS - [:core:] - ordinary primitive
ACCEPT - [:core:] - ordinary primitive
ACCESS-ARRAY - [:misc:] - ordinary primitive
ADDR>NAME - [:debug.1:] - ordinary primitive
ADDRESS-UNIT-BITS - [:core::environment:] - ordinary constant
AGAIN - [:core:] - compiling primitive
AHEAD - [:tools:] - immediate primitive
ALIAS - [:chainlist:] - ordinary primitive
ALIAS-ATEXIT - [:chainlist:] - ordinary primitive
ALIGN - [:core:] - ordinary primitive
ALIGNED - [:core:] - ordinary primitive
ALLOCATE - [:memory:] - ordinary primitive
ALLOT - [:core:] - ordinary primitive
ALSO - [:search:] - ordinary primitive
ALSO-MODULE - [:module:] - ordinary primitive
AND - [:core:] - ordinary primitive
;AND - [:useful:] - compiling primitive
ANDIF - [:toolbelt:] - compiling primitive
ANEW - [:core:] - ordinary primitive
APPEND - [:forth_usual:] - forthword synonym
APPEND - [:toolbelt:] - ordinary primitive
APPEND-CHAR - [:forth_usual:] - forthword synonym
APPEND-CHAR - [:toolbelt:] - ordinary primitive
APPENDZ - [:zchar.1:] - forthword synonym
APPLICATION - [:misc.1:] - threadstate variable
ARGC - [:misc:] - ordinary primitive
ARGS{ - [:dstrings:] - immediate primitive
ARGV - [:misc:] - ordinary primitive
ARRAY-OF - [:struct:] - ordinary primitive
ARRAY: - [:structs.1:] - ordinary primitive
ASCII - [:forth_usual:] - compiling primitive
ASSUME_DUMBTERM - [:term:] - ordinary primitive
ASSUME_VT100 - [:term:] - ordinary primitive
AT-XY - [:facility:] - ordinary primitive
ATEXIT-WORDLIST - [:chainlist.1:] - - loader type P4_DVaL
AUDIO_S16 - [:lib_sdl.1:] - ordinary constant
AUDIO_S16LSB - [:lib_sdl.1:] - ordinary constant
AUDIO_S16MSB - [:lib_sdl.1:] - ordinary constant
AUDIO_S16SYS - [:lib_sdl.1:] - ordinary constant
AUDIO_S8 - [:lib_sdl.1:] - ordinary constant
AUDIO_U16 - [:lib_sdl.1:] - ordinary constant
AUDIO_U16LSB - [:lib_sdl.1:] - ordinary constant
AUDIO_U16MSB - [:lib_sdl.1:] - ordinary constant
AUDIO_U16SYS - [:lib_sdl.1:] - ordinary constant
AUDIO_U8 - [:lib_sdl.1:] - ordinary constant
B/BUF - [:block_misc.1:] - ordinary constant
BACK - [:toolbelt:] - ordinary primitive
BACKSPACE - [:misc:] - ordinary primitive
#BACKSPACE-CHAR - [:forth_usual.1:] - ordinary constant
#BACKSPACE-CHAR - [:toolbelt.1:] - ordinary constant
BASE - [:core.1:] - threadstate variable
BEGIN - [:core:] - compiling primitive
BEHAVIOR - [:header:] - ordinary primitive
.BELL - [:term.1:] - ordinary primitive
BIN - [:file:] - ordinary primitive
!BITS - [:forth_83:] - ordinary primitive
@BITS - [:forth_83:] - ordinary primitive
BL - [:core.1:] - ordinary constant
BL-SCAN - [:toolbelt:] - ordinary primitive
BL-SKIP - [:toolbelt:] - ordinary primitive
BLANK - [:string:] - ordinary primitive
.BLINKING - [:term.1:] - ordinary primitive
.BLINKING.OFF - [:term.1:] - ordinary primitive
BLK - [:block.1:] - threadstate variable
BLOCK - [:block:] - ordinary primitive
BLOCK-EXT - [:block::environment:] - ordinary constant
BLOCK-FILE - [:block_misc.1:] - - loader type P4_DVaL
>BODY - [:core:] - ordinary primitive
BODY> - [:header:] - ordinary primitive
BOOT-SCRIPT: - [:host_k12:] - ordinary primitive
BOOT-SCRIPT@ - [:host_k12:] - ordinary primitive
BOUNDS - [:forth_usual:] - ordinary primitive
BOUNDS - [:toolbelt:] - ordinary primitive
BRANCH - [:system.1:] - ordinary primitive
?BRANCH - [:system.1:] - ordinary primitive
$BREAK - [:dstrings.1:] - ordinary primitive
$BUFFER - [:dstrings.1:] - ordinary primitive
BUFFER - [:block:] - ordinary primitive
BUFFER: - [:misc:] - ordinary primitive
BUILD-ARRAY - [:misc:] - ordinary primitive
<BUILDS - [:core:] - definining primitive
BYE - [:tools:] - ordinary primitive
C! - [:core:] - ordinary primitive
C" - [:core:] - compiling primitive
C+! - [:forth_usual:] - ordinary primitive
C+! - [:toolbelt:] - ordinary primitive
C+PLACE - [:forth_usual.1:] - ordinary primitive
C, - [:core:] - ordinary primitive
C@ - [:core:] - ordinary primitive
CALL-C - [:dlfcn.1:] - ordinary primitive
CASE - [:core:] - compiling primitive
CASE-SENSITIVE-VOC - [:useful:] - ordinary primitive
CASE-SENSITIVE? - [:environ::environment:] - ordinary primitive
CASE_MAGIC - [:tools_misc.1:] - ordinary constant
CAT - [:dstrings:] - ordinary primitive
CAT" - [:dstrings:] - compiling primitive
CATCH - [:exception:] - ordinary primitive
CAT` - [:dstrings:] - compiling primitive
CD - [:shell.1:] - obsolete forthword
/CELL - [:misc.1:] - ordinary constant
CELL - [:toolbelt.1:] - ordinary constant
-CELL - [:toolbelt.1:] - ordinary constant
CELL% - [:struct.1:] - ordinary primitive
CELL+ - [:core:] - ordinary primitive
CELL- - [:toolbelt:] - ordinary primitive
CELL-FALIGNED - [:fpnostack::environment:] - ordinary constant
CELL: - [:structs.1:] - ordinary primitive
CELLS - [:core:] - ordinary primitive
CELLS: - [:structs.1:] - ordinary primitive
CFA' - [:core.1:] - ordinary primitive
.chain - [:chain:] - ordinary primitive
chain-add - [:chain:] - ordinary primitive
chain-add-before - [:chain:] - ordinary primitive
chain-link - [:chain.1:] - threadstate variable
CHAIN-WORDLISTS - [:search::environment:] - ordinary constant
chained - [:gforth:] - ordinary primitive
chainperform - [:gforth:] - ordinary primitive
.chains - [:chain:] - ordinary primitive
/CHAR - [:useful.1:] - ordinary constant
CHAR - [:core:] - ordinary primitive
CHAR% - [:struct.1:] - ordinary primitive
CHAR+ - [:core:] - ordinary primitive
CHAR: - [:structs.1:] - ordinary primitive
CHARS - [:core:] - ordinary primitive
#CHARS/LINE - [:toolbelt.1:] - ordinary constant
CHARS: - [:structs.1:] - ordinary primitive
[CHAR] - [:core:] - compiling primitive
CHDIR - [:shell:] - ordinary primitive
CLEARSTACK - [:misc:] - ordinary primitive
CLK_TCK - [:posix::environment:] - ordinary primitive
CLOCK - [:posix:] - ordinary primitive
CLOSE-ALL-FILES - [:misc:] - ordinary primitive
CLOSE-BLOCKFILE - [:block_misc:] - ordinary primitive
close-dir - [:gforth:] - ordinary primitive
CLOSE-FILE - [:file:] - ordinary primitive
CLOSE-TERMINAL-LOGFILE - [:host_k12:] - ordinary primitive
.CLREOL - [:term.1:] - ordinary primitive
.CLRSCR - [:term.1:] - ordinary primitive
CLS - [:term.1:] - ordinary primitive
CMOVE - [:string:] - ordinary primitive
CMOVE> - [:string:] - ordinary primitive
COLD - [:misc:] - ordinary primitive
COLLECT-$GARBAGE - [:dstrings:] - ordinary primitive
COLS - [:term.1:] - threadstate variable
COME_BACK - [:debug:] - ordinary primitive
?COMP - [:tools_misc:] - ordinary primitive
COMPARE - [:string:] - ordinary primitive
COMPILE - [:forth_83:] - compiling primitive
>COMPILE - [:useful:] - ordinary primitive
COMPILE, - [:core:] - ordinary primitive
[COMPILE] - [:core:] - immediate primitive
CONSTANT - [:core:] - definining primitive
2CONSTANT - [:double:] - definining primitive
$CONSTANT - [:dstrings:] - definining primitive
+CONSTANT - [:useful:] - definining primitive
CONTEXT - [:system.1:] - - loader type P4_DVaL
CONTEXT? - [:useful:] - ordinary primitive
CONTROL - [:forth_usual:] - compiling primitive
CONVERT - [:core:] - ordinary primitive
COPY-FILE - [:file_misc:] - ordinary primitive
CORE-EXT - [:core::environment:] - ordinary constant
COUNT - [:core:] - ordinary primitive
/COUNTED-STRING - [:core::environment:] - ordinary constant
CP - [:shell.1:] - compiling primitive
CR - [:core:] - ordinary primitive
?CR - [:misc:] - ordinary primitive
CREATE - [:core.1:] - forthword synonym
CREATE-BLOCKFILE - [:block_misc:] - ordinary primitive
CREATE-FILE - [:file:] - ordinary primitive
CREATE: - [:misc:] - ordinary primitive
CRESET - [:forth_usual:] - ordinary primitive
CS-DROP - [:tools_misc.1:] - ordinary primitive
CS-PICK - [:tools:] - ordinary primitive
CS-ROLL - [:tools:] - ordinary primitive
CS-SWAP - [:tools_misc.1:] - ordinary primitive
CSET - [:forth_usual:] - ordinary primitive
CSP - [:tools_misc.1:] - threadstate variable
!CSP - [:tools_misc:] - ordinary primitive
?CSP - [:tools_misc:] - ordinary primitive
CTOGGLE - [:forth_usual:] - ordinary primitive
CURRENT - [:system.1:] - threadstate variable
.CVERSION - [:core_misc:] - ordinary primitive
$CWD - [:shell:] - ordinary primitive
C\" - [:zchar:] - compiling primitive
D+ - [:double:] - ordinary primitive
D- - [:double.1:] - ordinary primitive
D. - [:double:] - ordinary primitive
D.R - [:double:] - ordinary primitive
D0< - [:double:] - ordinary primitive
D0= - [:double:] - ordinary primitive
D2* - [:double:] - ordinary primitive
D2/ - [:double:] - ordinary primitive
D< - [:double:] - ordinary primitive
D= - [:double:] - ordinary primitive
D>F - [:floating.1:] - ordinary primitive
D>F - [:fpnostack.1:] - ordinary primitive
D>S - [:double:] - ordinary primitive
DABS - [:double:] - ordinary primitive
DEBUG - [:debug:] - ordinary primitive
DECIMAL - [:core:] - ordinary primitive
DEF' - [:useful.1:] - obsolete immediate
DEFAULT-ORDER - [:search:] - ordinary primitive
DEFER - [:header:] - definining primitive
#DEFINE - [:cdecl.1:] - ordinary primitive
DEFINED - [:core_misc.1:] - ordinary primitive
DEFINED - [:tools_misc.1:] - ordinary primitive
[DEFINED] - [:core_misc:] - immediate primitive
[DEFINED] - [:toolbelt:] - immediate primitive
[DEFINED] - [:tools_misc:] - immediate primitive
DEFINITIONS - [:search:] - ordinary primitive
DEFS-ARE-CASE-SENSITIVE - [:useful:] - ordinary primitive
DEFS-ARE-SEARCHED-ALSO - [:useful:] - ordinary primitive
[DEF] - [:useful:] - immediate primitive
DELETE-FILE - [:file:] - ordinary primitive
DEPTH - [:core:] - ordinary primitive
$DEPTH - [:dstrings:] - ordinary primitive
DEST_MAGIC - [:tools_misc.1:] - ordinary constant
DF! - [:floating.1:] - ordinary primitive
DF! - [:fpnostack.1:] - ordinary primitive
DF@ - [:floating.1:] - ordinary primitive
DF@ - [:fpnostack.1:] - ordinary primitive
DFALIGN - [:floating.1:] - ordinary primitive
DFALIGN - [:fpnostack.1:] - ordinary primitive
DFALIGNED - [:floating.1:] - ordinary primitive
DFALIGNED - [:fpnostack.1:] - ordinary primitive
DFLOAT% - [:struct.1:] - ordinary primitive
DFLOAT+ - [:floating.1:] - ordinary primitive
DFLOAT+ - [:fpnostack.1:] - ordinary primitive
DFLOATS - [:floating.1:] - ordinary primitive
DFLOATS - [:fpnostack.1:] - ordinary primitive
DICTFENCE - [:tools_misc.1:] - threadstate variable
(DICTFENCE) - [:tools_misc.1:] - ordinary primitive
DICTLIMIT - [:tools_misc.1:] - threadstate variable
(DICTLIMIT) - [:tools_misc.1:] - ordinary primitive
DLCALL - [:dlfcn.1:] - obsolete immediate
DLSYM - [:dlfcn.1:] - obsolete immediate
DMAX - [:double:] - ordinary primitive
DMIN - [:double:] - ordinary primitive
DNEGATE - [:double:] - ordinary primitive
DO - [:core:] - compiling primitive
?DO - [:core:] - compiling primitive
DO-ALIAS - [:chainlist:] - ordinary primitive
DO-ALL-WORDS - [:chainlist:] - ordinary primitive
DO-ALL-WORDS-WHILE - [:chainlist:] - compiling primitive
DO-ALL-WORDS-WHILE-LOOP - [:chainlist:] - ordinary primitive
do-chain - [:chain:] - ordinary primitive
DO-SYNONYM - [:chainlist:] - ordinary primitive
DOER - [:useful.1:] - ordinary primitive
DOES> - [:core:] - compiling primitive
DOUBLE% - [:struct.1:] - ordinary primitive
DOUBLE-EXT - [:double::environment:] - ordinary constant
DOUBLE: - [:structs.1:] - ordinary primitive
DP - [:misc.1:] - threadstate variable
DPL - [:forth_83.1:] - threadstate variable
DROP - [:core:] - ordinary primitive
2DROP - [:core:] - ordinary primitive
$DROP - [:dstrings:] - ordinary primitive
$2DROP - [:dstrings:] - ordinary primitive
3DROP - [:forth_usual:] - ordinary primitive
4DROP - [:forth_usual:] - ordinary primitive
3DROP - [:toolbelt:] - ordinary primitive
DROP-$FRAME - [:dstrings:] - ordinary primitive
(DROP-$FRAME) - [:dstrings.1:] - compiling primitive
DSTRINGS - [:dstrings.1:] - threadstate variable
DSTRINGS-EXT - [:dstrings::environment:] - ordinary constant
DSTRINGS-LOADED - [:dstrings::environment:] - constructor primitive
DU< - [:double_misc:] - ordinary primitive
DUMP - [:tools:] - ordinary primitive
DUP - [:core:] - ordinary primitive
2DUP - [:core:] - ordinary primitive
?DUP - [:core:] - ordinary primitive
$DUP - [:dstrings:] - ordinary primitive
$2DUP - [:dstrings:] - ordinary primitive
3DUP - [:forth_usual:] - ordinary primitive
4DUP - [:forth_usual:] - ordinary primitive
3DUP - [:toolbelt:] - ordinary primitive
DUP>R - [:misc:] - compiling primitive
/DYNAMIC-STRING - [:dstrings::environment:] - ordinary constant
EDIT-BLOCK - [:edit:] - ordinary primitive
EDIT-BLOCK-START - [:edit.1:] - ordinary primitive
EDIT-BLOCKFILE - [:misc:] - ordinary primitive
EDIT-ERROR - [:edit:] - ordinary primitive
<<edit-init>> - [:edit.1:] - constructor primitive
EDIT-TEXT - [:edit.1:] - ordinary primitive
EKEY - [:facility:] - ordinary primitive
EKEY>CHAR - [:facility:] - ordinary primitive
EKEY? - [:facility:] - ordinary primitive
#ELSE - [:cdecl:] - immediate primitive
ELSE - [:core:] - compiling primitive
[ELSE] - [:tools:] - immediate primitive
EMIT - [:core:] - ordinary primitive
(EMIT) - [:misc.1:] - ordinary primitive
*EMIT* - [:misc.1:] - threadstate variable
EMIT? - [:facility:] - ordinary primitive
EMITS - [:forth_usual:] - ordinary primitive
EMITS - [:toolbelt:] - ordinary primitive
EMPTY - [:toolbelt:] - ordinary primitive
EMPTY$ - [:dstrings:] - ordinary primitive
EMPTY-BUFFERS - [:block:] - ordinary primitive
END-MODULE - [:module:] - ordinary primitive
END-STRUCT - [:struct:] - ordinary primitive
END-SUBRECORD - [:struct:] - ordinary primitive
END-VARIANT - [:struct:] - ordinary primitive
ENDCASE - [:core:] - compiling primitive
ENDCAT - [:dstrings:] - ordinary primitive
ENDIF - [:forth_usual.1:] - immediate synonym
#ENDIF - [:cdecl:] - immediate primitive
ENDOF - [:core:] - compiling primitive
ENDS? - [:toolbelt:] - ordinary primitive
ENDSTRUCTURE - [:struct:] - ordinary primitive
ENVIRON-EXT - [:environ::environment:] - ordinary constant
ENVIRONMENT-WORDLIST - [:environ.1:] - - loader type P4_DVaL
ENVIRONMENT? - [:core:] - ordinary primitive
ENVIRONMENT? - [:environ:] - ordinary primitive
#EOL-CHAR - [:toolbelt.1:] - ordinary constant
ERASE - [:core:] - ordinary primitive
$EUID - [:shell:] - ordinary primitive
EVALUATE - [:core:] - ordinary primitive
EXCEPTION-EXT - [:exception::environment:] - ordinary constant
EXCEPTION_MAGIC - [:tools_misc.1:] - ordinary constant
?EXEC - [:tools_misc:] - ordinary primitive
EXECUTE - [:core:] - ordinary primitive
@EXECUTE - [:forth_usual:] - ordinary primitive
EXECUTES - [:misc:] - ordinary primitive
EXIT - [:core:] - compiling primitive
EXIT - [:with_spy:] - immediate synonym
EXITCODE - [:misc.1:] - threadstate variable
EXPAND-FN - [:misc:] - ordinary primitive
EXPECT - [:core:] - ordinary primitive
(EXPECT) - [:misc.1:] - ordinary primitive
*EXPECT* - [:misc.1:] - threadstate variable
EXPORT - [:module:] - ordinary primitive
EXPOSE-MODULE - [:module:] - ordinary primitive
1/F - [:floating_misc:] - ordinary primitive
1/F - [:fpnostack:] - ordinary primitive
F! - [:floating.1:] - ordinary primitive
F! - [:fpnostack.1:] - ordinary primitive
F* - [:floating.1:] - ordinary primitive
F* - [:fpnostack.1:] - ordinary primitive
F** - [:floating.1:] - ordinary primitive
F** - [:fpnostack.1:] - ordinary primitive
F+ - [:floating.1:] - ordinary primitive
F+ - [:fpnostack.1:] - ordinary primitive
F- - [:floating.1:] - ordinary primitive
F- - [:fpnostack.1:] - ordinary primitive
F-ROT - [:floating_misc.1:] - forthword synonym
F-ROT - [:fpnostack.1:] - forthword synonym
F. - [:floating.1:] - ordinary primitive
F. - [:fpnostack.1:] - ordinary primitive
F/ - [:floating.1:] - ordinary primitive
F/ - [:fpnostack.1:] - ordinary primitive
F0 - [:floating_misc.1:] - threadstate variable
F0< - [:floating.1:] - ordinary primitive
F0< - [:fpnostack.1:] - ordinary primitive
F0<> - [:floating_misc:] - ordinary primitive
F0<> - [:fpnostack:] - ordinary primitive
F0= - [:floating.1:] - ordinary primitive
F0= - [:fpnostack.1:] - ordinary primitive
F0> - [:floating_misc:] - ordinary primitive
F0> - [:fpnostack:] - ordinary primitive
F2* - [:floating_misc:] - ordinary primitive
F2* - [:fpnostack:] - ordinary primitive
F2/ - [:floating_misc:] - ordinary primitive
F2/ - [:fpnostack:] - ordinary primitive
F< - [:floating.1:] - ordinary primitive
F< - [:fpnostack.1:] - ordinary primitive
F<= - [:floating_misc.1:] - ordinary primitive
F<= - [:fpnostack.1:] - ordinary primitive
F<> - [:floating_misc:] - ordinary primitive
F<> - [:fpnostack:] - ordinary primitive
F= - [:floating_misc.1:] - ordinary primitive
F= - [:fpnostack.1:] - ordinary primitive
F> - [:floating_misc.1:] - ordinary primitive
F> - [:fpnostack.1:] - ordinary primitive
F>= - [:floating_misc.1:] - ordinary primitive
F>= - [:fpnostack.1:] - ordinary primitive
F>D - [:floating.1:] - ordinary primitive
F>D - [:fpnostack.1:] - ordinary primitive
F>S - [:floating_misc.1:] - forthword synonym
F>S - [:fpnostack.1:] - forthword synonym
F@ - [:floating.1:] - ordinary primitive
F@ - [:fpnostack.1:] - ordinary primitive
FABS - [:floating.1:] - ordinary primitive
FABS - [:fpnostack.1:] - ordinary primitive
FACILITY-EXT - [:facility::environment:] - ordinary constant
FACOS - [:floating.1:] - ordinary primitive
FACOS - [:fpnostack.1:] - ordinary primitive
FACOSH - [:floating.1:] - ordinary primitive
FACOSH - [:fpnostack.1:] - ordinary primitive
FALIGN - [:floating.1:] - ordinary primitive
FALIGN - [:fpnostack.1:] - ordinary primitive
FALIGNED - [:floating.1:] - ordinary primitive
FALIGNED - [:fpnostack.1:] - ordinary primitive
FALOG - [:floating.1:] - ordinary primitive
FALOG - [:fpnostack.1:] - ordinary primitive
FALSE - [:core.1:] - ordinary constant
FASIN - [:floating.1:] - ordinary primitive
FASIN - [:fpnostack.1:] - ordinary primitive
FASINH - [:floating.1:] - ordinary primitive
FASINH - [:fpnostack.1:] - ordinary primitive
FATAN - [:floating.1:] - ordinary primitive
FATAN - [:fpnostack.1:] - ordinary primitive
FATAN2 - [:floating.1:] - ordinary primitive
FATAN2 - [:fpnostack.1:] - ordinary primitive
FATANH - [:floating.1:] - ordinary primitive
FATANH - [:fpnostack.1:] - ordinary primitive
$FBREAK - [:dstrings.1:] - ordinary primitive
FCONSTANT - [:floating.1:] - definining primitive
FCONSTANT - [:fpnostack.1:] - definining primitive
FCOS - [:floating.1:] - ordinary primitive
FCOS - [:fpnostack.1:] - ordinary primitive
FCOSH - [:floating.1:] - ordinary primitive
FCOSH - [:fpnostack.1:] - ordinary primitive
FDEPTH - [:floating.1:] - ordinary primitive
FDEPTH - [:fpnostack.1:] - ordinary primitive
FDROP - [:floating.1:] - ordinary primitive
FDROP - [:fpnostack.1:] - ordinary primitive
FDUP - [:floating.1:] - ordinary primitive
FDUP - [:fpnostack.1:] - ordinary primitive
FE. - [:floating.1:] - ordinary primitive
FE. - [:fpnostack.1:] - ordinary primitive
FENCE - [:tools_misc.1:] - threadstate variable
FEXP - [:floating.1:] - ordinary primitive
FEXP - [:fpnostack.1:] - ordinary primitive
FEXPM1 - [:floating.1:] - ordinary primitive
FEXPM1 - [:fpnostack.1:] - ordinary primitive
>FFA - [:header:] - ordinary primitive
FFA> - [:header:] - ordinary primitive
FIELD - [:struct:] - definining primitive
+FIELD - [:useful:] - ordinary primitive
/FIELD - [:useful:] - ordinary primitive
FIELD-OFFSET - [:useful.1:] - forthword synonym
FIG-WORD - [:your.1:] - obsolete forthword
?FILE - [:tools_misc:] - ordinary primitive
FILE-BLOCK - [:file_misc:] - ordinary primitive
FILE-BUFFER - [:file_misc:] - ordinary primitive
FILE-CHECK - [:forth_usual:] - ordinary primitive
FILE-CHECK - [:toolbelt:] - ordinary primitive
FILE-EMPTY-BUFFERS - [:file_misc:] - ordinary primitive
FILE-EXT - [:file::environment:] - ordinary constant
FILE-FLUSH - [:file_misc:] - ordinary primitive
FILE-LIST - [:file_misc:] - ordinary primitive
FILE-LOAD - [:file_misc:] - ordinary primitive
FILE-POSITION - [:file:] - ordinary primitive
FILE-R/W - [:file_misc:] - ordinary primitive
FILE-SAVE-BUFFERS - [:file_misc:] - ordinary primitive
FILE-SIZE - [:file:] - ordinary primitive
FILE-STATUS - [:file:] - ordinary primitive
FILE-THRU - [:file_misc:] - ordinary primitive
FILE-UPDATE - [:file_misc:] - ordinary primitive
FILL - [:core:] - ordinary primitive
FIND - [:core:] - ordinary primitive
FIND-ARG - [:dstrings:] - ordinary primitive
FLIT - [:floating_misc.1:] - ordinary primitive
FLITERAL - [:floating.1:] - compiling primitive
FLITERAL - [:fpnostack.1:] - compiling primitive
FLN - [:floating.1:] - ordinary primitive
FLN - [:fpnostack.1:] - ordinary primitive
FLNP1 - [:floating.1:] - ordinary primitive
FLNP1 - [:fpnostack.1:] - ordinary primitive
>FLOAT - [:floating.1:] - ordinary primitive
>FLOAT - [:fpnostack.1:] - ordinary primitive
FLOAT% - [:struct.1:] - ordinary primitive
FLOAT+ - [:floating.1:] - ordinary primitive
FLOAT+ - [:fpnostack.1:] - ordinary primitive
FLOAT-INPUT - [:floating_misc.1:] - threadstate variable
FLOAT: - [:structs.1:] - ordinary primitive
FLOATING - [:fpnostack::environment:] - ordinary constant
FLOATING-EXT - [:floating::environment:] - ordinary constant
FLOATING-LOADED - [:floating::environment:] - constructor primitive
FLOATING-STACK - [:floating::environment:] - ordinary primitive
FLOATS - [:floating.1:] - ordinary primitive
FLOATS - [:fpnostack.1:] - ordinary primitive
FLOG - [:floating.1:] - ordinary primitive
FLOG - [:fpnostack.1:] - ordinary primitive
FLOOR - [:floating.1:] - ordinary primitive
FLOOR - [:fpnostack.1:] - ordinary primitive
FLOORED - [:core::environment:] - ordinary constant
FLUSH - [:block:] - ordinary primitive
FLUSH-FILE - [:file:] - ordinary primitive
FM/MOD - [:core:] - ordinary primitive
FMAX - [:floating.1:] - ordinary primitive
FMAX - [:fpnostack.1:] - ordinary primitive
FMIN - [:floating.1:] - ordinary primitive
FMIN - [:fpnostack.1:] - ordinary primitive
FNEGATE - [:floating.1:] - ordinary primitive
FNEGATE - [:fpnostack.1:] - ordinary primitive
FNIP - [:floating_misc:] - ordinary primitive
FNIP - [:fpnostack:] - ordinary primitive
FORGET - [:tools:] - ordinary primitive
(FORGET) - [:tools_misc.1:] - ordinary primitive
FORTH-CONTACT - [:environ::environment:] - ordinary primitive
FORTH-LICENSE - [:environ::environment:] - ordinary primitive
FORTH-NAME - [:environ::environment:] - ordinary primitive
FORTH-VERSION - [:environ::environment:] - ordinary primitive
FORTH-WORDLIST - [:search.1:] - - loader type P4_DVaL
FOURTH - [:toolbelt:] - ordinary primitive
FOVER - [:floating.1:] - ordinary primitive
FOVER - [:fpnostack.1:] - ordinary primitive
FP! - [:floating_misc:] - ordinary primitive
FP@ - [:floating_misc:] - ordinary primitive
FPNOSTACK-EXT - [:fpnostack::environment:] - ordinary constant
FPNOSTACK-LOADED - [:fpnostack::environment:] - constructor primitive
$FRAME - [:dstrings:] - ordinary primitive
$FRAME-DEPTH - [:dstrings.1:] - ordinary primitive
/FRAME-STACK - [:dstrings.1:] - ordinary primitive
#FRAMES - [:dstrings.1:] - ordinary primitive
FREE - [:memory:] - ordinary primitive
FROT - [:floating.1:] - ordinary primitive
FROT - [:fpnostack.1:] - ordinary primitive
-FROT - [:floating_misc:] - ordinary primitive
-FROT - [:fpnostack:] - ordinary primitive
FROUND - [:floating.1:] - ordinary primitive
FROUND - [:fpnostack.1:] - ordinary primitive
FROUND>S - [:floating_misc:] - ordinary primitive
FROUND>S - [:fpnostack:] - ordinary primitive
FS. - [:floating.1:] - ordinary primitive
FS. - [:fpnostack.1:] - ordinary primitive
FSIN - [:floating.1:] - ordinary primitive
FSIN - [:fpnostack.1:] - ordinary primitive
FSINCOS - [:floating.1:] - ordinary primitive
FSINCOS - [:fpnostack.1:] - ordinary primitive
FSINH - [:floating.1:] - ordinary primitive
FSINH - [:fpnostack.1:] - ordinary primitive
$FSP - [:dstrings.1:] - ordinary primitive
$FSP0 - [:dstrings.1:] - ordinary primitive
FSQRT - [:floating.1:] - ordinary primitive
FSQRT - [:fpnostack.1:] - ordinary primitive
FSWAP - [:floating.1:] - ordinary primitive
FSWAP - [:fpnostack.1:] - ordinary primitive
FTAN - [:floating.1:] - ordinary primitive
FTAN - [:fpnostack.1:] - ordinary primitive
FTANH - [:floating.1:] - ordinary primitive
FTANH - [:fpnostack.1:] - ordinary primitive
FTRUNC - [:floating_misc:] - ordinary primitive
FTRUNC - [:fpnostack:] - ordinary primitive
FTRUNC>S - [:floating_misc:] - ordinary primitive
FTRUNC>S - [:fpnostack:] - ordinary primitive
FTUCK - [:floating_misc:] - ordinary primitive
FTUCK - [:fpnostack:] - ordinary primitive
FVARIABLE - [:floating.1:] - definining primitive
FVARIABLE - [:fpnostack.1:] - definining primitive
F^2 - [:floating_misc:] - ordinary primitive
F^2 - [:fpnostack:] - ordinary primitive
F^N - [:floating_misc:] - ordinary primitive
F^N - [:fpnostack:] - ordinary primitive
F~ - [:floating.1:] - ordinary primitive
F~ - [:fpnostack.1:] - ordinary primitive
$GARBAGE? - [:dstrings:] - ordinary primitive
$GC-OFF - [:dstrings.1:] - ordinary primitive
$GC-ON - [:dstrings.1:] - ordinary primitive
GET-CURRENT - [:search:] - ordinary primitive
GET-ORDER - [:search:] - ordinary primitive
GETTIMEOFDAY - [:posix:] - ordinary primitive
GFORTH-DIR - [:gforth::environment:] - ordinary constant
$GID - [:shell:] - ordinary primitive
GOTOXY - [:term:] - ordinary primitive
H# - [:toolbelt:] - immediate primitive
.H2 - [:your:] - ordinary primitive
HEADER - [:header.1:] - obsolete forthword
$HEADER - [:header:] - ordinary primitive
HEADER, - [:header:] - ordinary primitive
HEADER-EXT - [:header::environment:] - ordinary constant
HELP - [:misc:] - ordinary primitive
(HELP) - [:help.1:] - ordinary primitive
HERE - [:core:] - ordinary primitive
HERE-WORD - [:your:] - ordinary primitive
HEX - [:core:] - ordinary primitive
.HIGHLIGHT - [:term.1:] - ordinary primitive
.HIGHLIGHT.OFF - [:term.1:] - ordinary primitive
HIWORD - [:toolbelt:] - ordinary primitive
HLD - [:misc.1:] - threadstate variable
/HOLD - [:core::environment:] - ordinary constant
HOLD - [:core:] - ordinary primitive
.HOME - [:term.1:] - ordinary primitive
$HOME - [:shell:] - ordinary primitive
HOST-SYSTEM - [:environ::environment:] - ordinary primitive
HTONL - [:posix.1:] - ordinary primitive
HTONS - [:posix.1:] - ordinary primitive
I - [:core:] - compiling primitive
ID. - [:misc:] - ordinary primitive
#IF - [:cdecl:] - immediate primitive
IF - [:core:] - compiling primitive
#IFDEF - [:cdecl:] - immediate primitive
#IFNDEF - [:cdecl.1:] - immediate primitive
#IFNOTDEF - [:cdecl:] - immediate primitive
[IF] - [:tools:] - immediate primitive
IMMEDIATE - [:core:] - ordinary primitive
(IMMEDIATE#) - [:header.1:] - obsolete forthword
IMMEDIATE-MASK - [:header.1:] - ordinary constant
>IN - [:core.1:] - threadstate variable
INCLUDE - [:file_misc:] - ordinary primitive
INCLUDE-FILE - [:file:] - ordinary primitive
INCLUDED - [:file:] - ordinary primitive
INPUT_MAGIC - [:tools_misc.1:] - ordinary constant
INSTANCE - [:struct:] - ordinary primitive
INSTANCE-ADDR - [:struct:] - ordinary primitive
INTEGER: - [:structs.1:] - ordinary primitive
.INTENSITY - [:term.1:] - ordinary primitive
.INTENSITY.OFF - [:term.1:] - ordinary primitive
INTERPRET - [:forth_83.1:] - ordinary primitive
INTO - [:your:] - compiling primitive
INVERT - [:core:] - ordinary primitive
IS - [:header:] - compiling primitive
IS-ALNUM - [:toolbelt:] - ordinary primitive
IS-ALPHA - [:toolbelt:] - ordinary primitive
IS-DIGIT - [:toolbelt:] - ordinary primitive
IS-WHITE - [:toolbelt:] - ordinary primitive
#IS_FALSE - [:cdecl:] - immediate primitive
#IS_TRUE - [:cdecl:] - immediate primitive
J - [:core:] - compiling primitive
K - [:forth_83:] - compiling primitive
K-DOWN - [:term.1:] - ordinary constant
K-END - [:term.1:] - ordinary constant
K-HOME - [:term.1:] - ordinary constant
K-LEFT - [:term.1:] - ordinary constant
K-NEXT - [:term.1:] - ordinary constant
K-PRIOR - [:term.1:] - ordinary constant
K-RIGHT - [:term.1:] - ordinary constant
K-UP - [:term.1:] - ordinary constant
K1 - [:term.1:] - ordinary constant
K10 - [:term.1:] - ordinary constant
#K1297-G20 - [:host_k12.1:] - ordinary constant
K2 - [:term.1:] - ordinary constant
K3 - [:term.1:] - ordinary constant
K4 - [:term.1:] - ordinary constant
K5 - [:term.1:] - ordinary constant
K6 - [:term.1:] - ordinary constant
K7 - [:term.1:] - ordinary constant
K8 - [:term.1:] - ordinary constant
K9 - [:term.1:] - ordinary constant
KEY - [:core:] - ordinary primitive
(KEY) - [:misc.1:] - ordinary primitive
*KEY* - [:misc.1:] - threadstate variable
KEY? - [:facility:] - ordinary primitive
L>NAME - [:header:] - ordinary primitive
LAST - [:header.1:] - threadstate variable
LATEST - [:header:] - ordinary primitive
LBUFFER: - [:locals:] - compiling primitive
LEAVE - [:core:] - compiling primitive
?LEAVE - [:forth_usual:] - compiling primitive
LEXEME - [:toolbelt:] - ordinary primitive
LICENSE - [:core_misc:] - ordinary primitive
.LINE - [:misc:] - ordinary primitive
>LINK - [:header:] - ordinary primitive
link, - [:chain:] - ordinary primitive
LINK> - [:header:] - ordinary primitive
linked - [:gforth:] - ordinary primitive
LIST - [:block:] - ordinary primitive
LIT - [:misc.1:] - ordinary primitive
LITERAL - [:core:] - compiling primitive
2LITERAL - [:double:] - compiling primitive
LITERAL, - [:double_misc:] - ordinary primitive
2LITERAL, - [:double_misc:] - ordinary primitive
LL - [:shell.1:] - compiling primitive
LN - [:shell.1:] - compiling primitive
LOAD - [:block:] - ordinary primitive
LOAD" - [:misc:] - compiling primitive
LOADF - [:useful:] - ordinary primitive
LOADF-LOCATE - [:useful:] - ordinary primitive
(LOADF-LOCATE) - [:useful:] - ordinary primitive
?LOADING - [:tools_misc:] - ordinary primitive
LOADM - [:dlfcn:] - ordinary primitive
(LOADM) - [:dlfcn.1:] - ordinary primitive
<<load_signals>> - [:signals.1:] - constructor primitive
(LOCAL) - [:locals.1:] - compiling primitive
LOCAL-DLCALL - [:dlfcn.1:] - immediate primitive
LOCAL-DLSYM - [:dlfcn:] - immediate primitive
#LOCALS - [:locals::environment:] - ordinary constant
LOCALS-EXT - [:locals::environment:] - ordinary constant
LOCALS-LOADED - [:locals::environment:] - constructor primitive
LOCALS| - [:locals:] - compiling primitive
LOOP - [:core:] - compiling primitive
+LOOP - [:core:] - compiling primitive
LOOP_MAGIC - [:tools_misc.1:] - ordinary constant
LOWER - [:forth_usual:] - ordinary primitive
LOWER-CASE - [:misc.1:] - threadstate variable
LOWER-CASE-FN - [:misc.1:] - threadstate variable
LOWER-CASE-FN? - [:misc.1:] - - loader type P4_DVaL
LOWORD - [:toolbelt:] - ordinary primitive
LS - [:shell.1:] - compiling primitive
LS.COLON-DEFS - [:misc:] - ordinary primitive
LS.CONSTANTS - [:misc:] - ordinary primitive
LS.DOES-DEFS - [:misc:] - ordinary primitive
LS.MARKERS - [:misc:] - ordinary primitive
LS.PRIMITIVES - [:misc:] - ordinary primitive
LS.VARIABLES - [:misc:] - ordinary primitive
LS.VOCABULARIES - [:misc:] - ordinary primitive
LS.WORDS - [:misc:] - ordinary primitive
LSHIFT - [:core:] - ordinary primitive
lt_dlclose - [:dlfcn:] - ordinary primitive
lt_dlerror - [:dlfcn:] - ordinary primitive
lt_dlinit - [:dlfcn:] - ordinary primitive
lt_dlopenext - [:dlfcn:] - ordinary primitive
lt_dlsym - [:dlfcn:] - ordinary primitive
LVALUE - [:locals:] - compiling primitive
(M$:) - [:dstrings.1:] - compiling primitive
M* - [:core:] - ordinary primitive
M*/ - [:double:] - ordinary primitive
M+ - [:double:] - ordinary primitive
MAKE - [:useful:] - compiling primitive
MAKE-$SPACE - [:dstrings:] - ordinary primitive
<MARK - [:system:] - ordinary primitive
MARK> - [:system:] - ordinary primitive
MARKER - [:core:] - ordinary primitive
(MARKER) - [:core:] - ordinary primitive
MAX - [:core:] - ordinary primitive
MAX-CHAR - [:core::environment:] - ordinary constant
MAX-D - [:double::environment:] - ordinary primitive
MAX-FILES - [:file::environment:] - ordinary primitive
MAX-FLOAT - [:floating::environment:] - ordinary primitive
MAX-FLOAT - [:fpnostack::environment:] - ordinary primitive
MAX-N - [:toolbelt.1:] - ordinary constant
MAX-N - [:core::environment:] - ordinary constant
MAX-U - [:core::environment:] - ordinary constant
MAX-UD - [:double::environment:] - ordinary primitive
.MEMORY - [:misc:] - ordinary primitive
MEMORY-ALLOC-EXT - [:memory::environment:] - ordinary constant
MEMORY-CHECK - [:forth_usual:] - ordinary primitive
MEMORY-CHECK - [:toolbelt:] - ordinary primitive
MIN - [:core:] - ordinary primitive
MKDIR - [:shell.1:] - compiling primitive
MOD - [:core:] - ordinary primitive
*/MOD - [:core:] - ordinary primitive
/MOD - [:core:] - ordinary primitive
MODULE - [:module:] - ordinary primitive
MOVE - [:core:] - ordinary primitive
MOVE-FILE - [:file_misc:] - ordinary primitive
>MOVE< - [:forth_83:] - ordinary primitive
MS - [:facility:] - ordinary primitive
MV - [:shell.1:] - compiling primitive
\n$ - [:dstrings:] - ordinary primitive
N>LINK - [:header:] - ordinary primitive
.NAME - [:misc.1:] - forthword synonym
>NAME - [:header:] - ordinary primitive
NAME-FLAGS! - [:header:] - ordinary primitive
NAME-FLAGS@ - [:header:] - ordinary primitive
NAME> - [:header:] - ordinary primitive
NAME>STRING - [:header:] - ordinary primitive
NEEDS - [:environ:] - ordinary primitive
NEGATE - [:core:] - ordinary primitive
new-chain - [:chain:] - definining primitive
new-sys-chain - [:chain.1:] - forthword synonym
NEW-WORDLIST - [:chainlist:] - ordinary primitive
NEXT-EXCEPTION - [:exception.1:] - threadstate variable
NEXT-WORD - [:toolbelt:] - ordinary primitive
NIP - [:core:] - ordinary primitive
$NIP - [:dstrings:] - ordinary primitive
2NIP - [:toolbelt:] - ordinary primitive
!NO - [:useful.1:] - forthword synonym
NO-DEBUG - [:debug:] - ordinary primitive
:NONAME - [:core:] - definining primitive
NOOP - [:forth_usual.1:] - ordinary primitive
.NORMAL - [:term.1:] - ordinary primitive
NOT - [:forth_83.1:] - compiling primitive
NOT - [:toolbelt.1:] - ordinary primitive
[NOT] - [:useful:] - immediate primitive
NTOHL - [:posix:] - ordinary primitive
NTOHS - [:posix:] - ordinary primitive
>NUMBER - [:core:] - ordinary primitive
NUMBER? - [:forth_usual:] - ordinary primitive
OCTAL - [:forth_83:] - ordinary primitive
&OF - [:your.1:] - immediate synonym
OF - [:core:] - compiling primitive
OFF - [:forth_usual:] - forthword synonym
OFF - [:toolbelt:] - ordinary primitive
OFF! - [:forth_usual.1:] - ordinary primitive
OFFSET: - [:useful.1:] - forthword synonym
OF_MAGIC - [:tools_misc.1:] - ordinary constant
ok - [:misc.1:] - ordinary primitive
ON - [:forth_usual.1:] - forthword synonym
ON - [:toolbelt.1:] - ordinary primitive
ON! - [:forth_usual:] - ordinary primitive
OPEN-BLOCKFILE - [:block_misc:] - ordinary primitive
open-dir - [:gforth:] - ordinary primitive
OPEN-FILE - [:file:] - ordinary primitive
OPEN-TERMINAL-LOGFILE - [:host_k12:] - ordinary primitive
OPTION-EXT - [:option::environment:] - ordinary constant
OR - [:core:] - ordinary primitive
ORDER - [:search:] - ordinary primitive
ORIF - [:toolbelt:] - compiling primitive
ORIG_MAGIC - [:tools_misc.1:] - ordinary constant
OUT - [:misc.1:] - threadstate variable
OUT - [:toolbelt.1:] - threadstate variable
OVER - [:core:] - ordinary primitive
2OVER - [:core:] - ordinary primitive
$OVER - [:dstrings:] - ordinary primitive
/PAD - [:core::environment:] - ordinary constant
PAD - [:core:] - ordinary primitive
PAGE - [:facility.1:] - ordinary primitive
?PAIRS - [:tools_misc:] - ordinary primitive
PARSE - [:core:] - ordinary primitive
PARSE, - [:core_misc:] - ordinary primitive
PARSE," - [:core_misc:] - immediate primitive
PARSE-WORD - [:core:] - ordinary primitive
PERFORM - [:forth_usual.1:] - obsolete forthword
.PFE-DATE - [:core_misc.1:] - forthword synonym
PFE-DEBUG - [:debug::environment:] - threadstate valueGET
PFE-PRINTF - [:useful:] - ordinary primitive
PFE-SPRINTF - [:useful:] - ordinary primitive
PICK - [:core:] - ordinary primitive
$PICK - [:dstrings:] - ordinary primitive
$PID - [:shell:] - ordinary primitive
+PLACE - [:forth_usual.1:] - ordinary primitive
PLACE - [:forth_usual:] - ordinary primitive
PLACE - [:toolbelt:] - ordinary primitive
POCKET-PAD - [:misc:] - ordinary primitive
POINTER: - [:structs.1:] - ordinary primitive
[POSSIBLY] - [:useful:] - immediate primitive
POSTPONE - [:core:] - compiling primitive
#PRAGMA - [:cdecl.1:] - ordinary primitive
PRECISION - [:floating.1:] - - loader type P4_DVaL
PRECISION - [:fpnostack.1:] - - loader type P4_DVaL
PREVIOUS - [:search:] - ordinary primitive
PRINTF - [:useful.1:] - obsolete forthword
PROMPT-WORDLIST - [:chainlist.1:] - - loader type P4_DVaL
PWD - [:shell:] - ordinary primitive
QUERY - [:core:] - ordinary primitive
QUIT - [:core:] - ordinary primitive
QUOTED-PARSE? - [:misc.1:] - - loader type P4_DVaL
.R - [:core:] - ordinary primitive
2>R - [:core:] - compiling primitive
>R - [:core:] - compiling primitive
R! - [:misc:] - compiling primitive
2R! - [:misc:] - compiling primitive
R"! - [:misc:] - compiling primitive
R"@ - [:misc:] - compiling primitive
R'! - [:misc:] - compiling primitive
R'@ - [:misc:] - compiling primitive
R'@ - [:toolbelt:] - ordinary primitive
R/O - [:file.1:] - ordinary constant
R/W - [:file.1:] - ordinary constant
R0 - [:misc.1:] - threadstate variable
R> - [:core:] - compiling primitive
2R> - [:core:] - compiling primitive
2R>2DROP - [:misc:] - compiling primitive
R>DROP - [:misc:] - compiling primitive
R@ - [:core:] - compiling primitive
2R@ - [:core:] - compiling primitive
RAISE - [:misc:] - ordinary primitive
RANDOM - [:misc:] - ordinary primitive
RAND_MAX - [:misc::environment:] - ordinary constant
read-dir - [:gforth:] - ordinary primitive
READ-FILE - [:file:] - ordinary primitive
READ-LINE - [:file:] - ordinary primitive
RECURSE - [:core:] - immediate primitive
RECURSIVE - [:header.1:] - immediate primitive
REDEFINED-MSG - [:misc.1:] - threadstate variable
REDEFINED-MSG? - [:misc.1:] - - loader type P4_DVaL
REDO-ALL-WORDS - [:chainlist:] - ordinary primitive
REFILL - [:core:] - ordinary primitive
RENAME-FILE - [:file:] - ordinary primitive
REPEAT - [:core:] - compiling primitive
REPLACE-IN - [:useful:] - ordinary primitive
REPOSITION-FILE - [:file:] - ordinary primitive
REPRESENT - [:floating.1:] - ordinary primitive
REPRESENT - [:fpnostack.1:] - ordinary primitive
REQUIRED - [:environ:] - ordinary primitive
REQUIRES - [:environ:] - ordinary primitive
RESET-ORDER - [:search:] - ordinary primitive
RESET-ORDER-IS - [:search.1:] - threadstate variable
RESIZE - [:memory:] - ordinary primitive
RESIZE-FILE - [:file:] - ordinary primitive
<RESOLVE - [:system:] - ordinary primitive
RESOLVE> - [:system:] - ordinary primitive
RESTORE-INPUT - [:core:] - ordinary primitive
RETURN-STACK-CELLS - [:core::environment:] - ordinary primitive
REVEAL - [:header:] - ordinary primitive
.REVERSE - [:term.1:] - ordinary primitive
.REVERSE.OFF - [:term.1:] - ordinary primitive
REWIND-FILE - [:toolbelt:] - ordinary primitive
RM - [:shell.1:] - compiling primitive
RMDIR - [:shell.1:] - compiling primitive
ROLL - [:core:] - ordinary primitive
-ROLL - [:misc:] - ordinary primitive
ROT - [:core:] - ordinary primitive
2ROT - [:double_misc:] - ordinary primitive
-ROT - [:forth_usual:] - ordinary primitive
ROWS - [:term.1:] - threadstate variable
RP! - [:forth_usual:] - ordinary primitive
RP@ - [:forth_usual:] - compiling primitive
RSHIFT - [:core:] - ordinary primitive
#S - [:core:] - ordinary primitive
>$S - [:dstrings:] - ordinary primitive
.S - [:tools:] - ordinary primitive
S" - [:core:] - compiling primitive
S, - [:dstrings:] - ordinary primitive
S-CAT - [:dstrings:] - ordinary primitive
>$S-COPY - [:dstrings:] - ordinary primitive
S-K1 - [:term.1:] - ordinary constant
S-K10 - [:term.1:] - ordinary constant
S-K2 - [:term.1:] - ordinary constant
S-K3 - [:term.1:] - ordinary constant
S-K4 - [:term.1:] - ordinary constant
S-K5 - [:term.1:] - ordinary constant
S-K6 - [:term.1:] - ordinary constant
S-K7 - [:term.1:] - ordinary constant
S-K8 - [:term.1:] - ordinary constant
S-K9 - [:term.1:] - ordinary constant
S0 - [:misc.1:] - threadstate variable
$S> - [:dstrings:] - ordinary primitive
$S>-COPY - [:dstrings:] - ordinary primitive
S>D - [:core:] - ordinary primitive
S>F - [:floating_misc:] - ordinary primitive
S>F - [:fpnostack:] - ordinary primitive
$S@ - [:dstrings:] - ordinary primitive
SAVE-BUFFERS - [:block:] - ordinary primitive
SAVE-INPUT - [:core:] - ordinary primitive
SCAN - [:toolbelt:] - ordinary primitive
/SCOPY - [:dstrings::environment:] - ordinary constant
SCR - [:block.1:] - threadstate variable
SDL_AllocRW - [:lib_sdl.1:] - ordinary primitive
/SDL_AudioCVT - [:lib_sdl.1:] - ordinary constant
->SDL_AudioCVT.buf - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.dst_format - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.len - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.len_cvt - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.len_mult - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.len_ratio - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.needed - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.rate_incr - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioCVT.src_format - [:lib_sdl.1:] - ordinary offsetval
SDL_AudioDriverName - [:lib_sdl.1:] - ordinary primitive
SDL_AudioInit - [:lib_sdl.1:] - ordinary primitive
SDL_AudioQuit - [:lib_sdl.1:] - ordinary primitive
/SDL_AudioSpec - [:lib_sdl.1:] - ordinary constant
->SDL_AudioSpec.channels - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioSpec.format - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioSpec.freq - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioSpec.samples - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioSpec.silence - [:lib_sdl.1:] - ordinary offsetval
->SDL_AudioSpec.size - [:lib_sdl.1:] - ordinary offsetval
SDL_AUDIO_PAUSED - [:lib_sdl.1:] - ordinary constant
SDL_AUDIO_PLAYING - [:lib_sdl.1:] - ordinary constant
SDL_AUDIO_STOPPED - [:lib_sdl.1:] - ordinary constant
SDL_BuildAudioCVT - [:lib_sdl.1:] - ordinary primitive
SDL_ClearError - [:lib_sdl.1:] - ordinary primitive
SDL_CompiledVersion - [:lib_sdl:] - ordinary primitive
SDL_ConvertCVT - [:lib_sdl.1:] - ordinary primitive
SDL_Delay - [:lib_sdl.1:] - ordinary primitive
SDL_FALSE - [:lib_sdl.1:] - ordinary constant
SDL_FreeRW - [:lib_sdl.1:] - ordinary primitive
SDL_FreeWAV - [:lib_sdl.1:] - ordinary primitive
SDL_GetAudioStatus - [:lib_sdl.1:] - ordinary primitive
SDL_GetError - [:lib_sdl:] - ordinary primitive
SDL_GetTick - [:lib_sdl.1:] - ordinary primitive
SDL_init - [:lib_sdl.1:] - ordinary primitive
SDL_InitSubSystem - [:lib_sdl.1:] - ordinary primitive
SDL_INIT_AUDIO - [:lib_sdl.1:] - ordinary constant
SDL_INIT_CDROM - [:lib_sdl.1:] - ordinary constant
SDL_INIT_EVENTTHREAD - [:lib_sdl.1:] - ordinary constant
SDL_INIT_EVERYTHING - [:lib_sdl.1:] - ordinary constant
SDL_INIT_JOYSTICK - [:lib_sdl.1:] - ordinary constant
SDL_INIT_NOPARACHUTE - [:lib_sdl.1:] - ordinary constant
SDL_INIT_TIMER - [:lib_sdl.1:] - ordinary constant
SDL_INIT_VIDEO - [:lib_sdl.1:] - ordinary constant
SDL_LinkedVersion - [:lib_sdl:] - ordinary primitive
SDL_Linked_Version - [:lib_sdl.1:] - ordinary primitive
SDL_LoadWAV - [:lib_sdl.1:] - ordinary primitive
SDL_LoadWAV_RW - [:lib_sdl.1:] - ordinary primitive
SDL_LockAudio - [:lib_sdl.1:] - ordinary primitive
SDL_LockAudio - [:lib_sdl.2:] - ordinary primitive
SDL_MixAudio - [:lib_sdl.1:] - ordinary primitive
SDL_OpenAudio - [:lib_sdl.1:] - ordinary primitive
SDL_PRESSED - [:lib_sdl.1:] - ordinary constant
SDL_Quit - [:lib_sdl.1:] - ordinary primitive
SDL_QuitSubSystem - [:lib_sdl.1:] - ordinary primitive
SDL_RELEASED - [:lib_sdl.1:] - ordinary constant
SDL_RWclose - [:lib_sdl.1:] - ordinary primitive
SDL_RWFromFile - [:lib_sdl.1:] - ordinary primitive
SDL_RWFromFP - [:lib_sdl.1:] - ordinary primitive
SDL_RWFromMem - [:lib_sdl.1:] - ordinary primitive
SDL_RWread - [:lib_sdl.1:] - ordinary primitive
SDL_RWseek - [:lib_sdl.1:] - ordinary primitive
SDL_RWtell - [:lib_sdl.1:] - ordinary primitive
SDL_RWwrite - [:lib_sdl.1:] - ordinary primitive
SDL_SetError - [:lib_sdl:] - ordinary primitive
SDL_TRUE - [:lib_sdl.1:] - ordinary constant
SDL_UnLockAudio - [:lib_sdl.1:] - ordinary primitive
SDL_UnlockAudio - [:lib_sdl.2:] - ordinary primitive
->SDL_version.major - [:lib_sdl.1:] - ordinary offsetval
->SDL_version.minor - [:lib_sdl.1:] - ordinary offsetval
->SDL_version.patch - [:lib_sdl.1:] - ordinary offsetval
SDL_WasInit - [:lib_sdl.1:] - ordinary primitive
SEAL - [:forth_83:] - ordinary primitive
SEARCH - [:string:] - ordinary primitive
SEARCH-ALSO-VOC - [:useful.1:] - obsolete forthword
SEARCH-LOADED - [:search::environment:] - constructor primitive
SEARCH-ORDER-EXT - [:search::environment:] - ordinary constant
SEARCH-WORDLIST - [:search:] - ordinary primitive
SEE - [:tools.1:] - ordinary primitive
(SEE) - [:debug.1:] - ordinary primitive
SET-BLOCKFILE - [:block_misc:] - ordinary primitive
SET-CURRENT - [:search:] - ordinary primitive
SET-ORDER - [:search:] - ordinary primitive
SET-PRECISION - [:floating.1:] - ordinary primitive
SET-PRECISION - [:fpnostack.1:] - ordinary primitive
SF! - [:floating.1:] - ordinary primitive
SF! - [:fpnostack.1:] - ordinary primitive
SF@ - [:floating.1:] - ordinary primitive
SF@ - [:fpnostack.1:] - ordinary primitive
SFALIGN - [:floating.1:] - ordinary primitive
SFALIGN - [:fpnostack.1:] - ordinary primitive
SFALIGNED - [:floating.1:] - ordinary primitive
SFALIGNED - [:fpnostack.1:] - ordinary primitive
SFLOAT% - [:struct.1:] - ordinary primitive
SFLOAT+ - [:floating.1:] - ordinary primitive
SFLOAT+ - [:fpnostack.1:] - ordinary primitive
SFLOATS - [:floating.1:] - ordinary primitive
SFLOATS - [:fpnostack.1:] - ordinary primitive
SHOW-STATUS - [:misc.1:] - forthword synonym
SHOW-TERM-CONTROLS - [:term:] - ordinary primitive
SHOW-TERM-ESC-KEYS - [:term:] - ordinary primitive
SHOW-TERMCAP - [:term:] - ordinary primitive
SIGN - [:core:] - ordinary primitive
SIGNAL - [:misc:] - ordinary primitive
SIZEOF - [:struct.1:] - compiling primitive
SKIP - [:toolbelt:] - ordinary primitive
SLITERAL - [:string:] - compiling primitive
SM/REM - [:core:] - ordinary primitive
SMART-INTERPRET! - [:smart_go:] - ordinary primitive
SMART-INTERPRET-INIT - [:smart_go:] - ordinary primitive
SMART-INTERPRET-LOADED - [:smart_go::environment:] - constructor primitive
SMUDGE - [:header.1:] - ordinary primitive
(SMUDGE#) - [:header.1:] - obsolete forthword
SMUDGE-MASK - [:header.1:] - ordinary constant
SOURCE - [:core:] - ordinary primitive
SOURCE-ID - [:core.1:] - - loader type P4_DVaL
SOURCE-LINE - [:misc:] - ordinary primitive
SOURCE-NAME - [:misc:] - ordinary primitive
$SP - [:dstrings.1:] - ordinary primitive
SP! - [:forth_usual:] - ordinary primitive
$SP0 - [:dstrings.1:] - ordinary primitive
SP@ - [:forth_83:] - ordinary primitive
/$SPACE - [:dstrings.1:] - ordinary primitive
0$SPACE - [:dstrings.1:] - ordinary primitive
SPACE - [:core:] - ordinary primitive
/$SPACE-HEADER - [:dstrings.1:] - ordinary primitive
SPACES - [:core:] - ordinary primitive
SPAN - [:core.1:] - threadstate variable
/SPLIT - [:toolbelt:] - ordinary primitive
SPLIT-NEXT-LINE - [:toolbelt:] - ordinary primitive
SPRINTF - [:useful.1:] - obsolete forthword
;SPY - [:with_spy:] - compiling primitive
SPY-ENTER - [:with_spy.1:] - - loader type P4_DVaL
SPY-EXIT - [:with_spy:] - ordinary primitive
SPY-LEAVE - [:with_spy.1:] - - loader type P4_DVaL
SPY: - [:with_spy:] - definining primitive
SPY_OFF - [:with_spy:] - ordinary primitive
SPY_ON - [:with_spy:] - ordinary primitive
SRAND - [:misc:] - ordinary primitive
?STACK - [:tools_misc:] - ordinary primitive
STACK-CELLS - [:core::environment:] - ordinary primitive
STANDARD-I/O - [:misc:] - ordinary primitive
START?CR - [:misc:] - ordinary primitive
STARTS? - [:toolbelt:] - ordinary primitive
STATE - [:core.1:] - threadstate variable
.STATUS - [:misc:] - ordinary primitive
STDERR - [:misc.1:] - - loader type P4_DVaL
STDIN - [:misc.1:] - - loader type P4_DVaL
STDOUT - [:misc.1:] - - loader type P4_DVaL
?STOP - [:misc:] - ordinary primitive
/STRING - [:string:] - ordinary primitive
STRING, - [:core_misc:] - ordinary primitive
STRING, - [:toolbelt:] - ordinary primitive
STRING-EXT - [:string::environment:] - ordinary constant
0STRINGS - [:dstrings:] - ordinary primitive
STRUCT - [:struct:] - ordinary primitive
STRUCT: - [:structs.1:] - ordinary primitive
STRUCTURE - [:struct.1:] - definining primitive
;STRUCTURE - [:structs.1:] - ordinary primitive
STRUCTURE: - [:structs.1:] - ordinary primitive
SUBRECORD - [:struct:] - ordinary primitive
SWAP - [:core:] - ordinary primitive
2SWAP - [:core:] - ordinary primitive
$SWAP - [:dstrings:] - ordinary primitive
SYNONYM - [:header:] - definining primitive
SYNONYM-OBSOLETED - [:header.1:] - definining primitive
SYSTEM - [:misc:] - ordinary primitive
SYSTEM" - [:misc:] - compiling primitive
SYSTEM-EXT - [:system::environment:] - ordinary constant
S\" - [:zchar:] - compiling primitive
TAB - [:misc:] - ordinary primitive
#TAB-CHAR - [:toolbelt.1:] - ordinary constant
?TERMINAL - [:forth_83.1:] - ordinary primitive
TERMINAL-ANSWER-LINK - [:host_k12:] - ordinary primitive
TERMINAL-EMULATION-STATE - [:host_k12:] - ordinary primitive
TERMINAL-INPUT-LINK - [:host_k12:] - ordinary primitive
TERMINAL-OUTPUT-LINK - [:host_k12:] - ordinary primitive
'th - [:toolbelt:] - compiling primitive
TH'POCKET - [:misc:] - ordinary primitive
THEN - [:core:] - compiling primitive
[THEN] - [:tools.1:] - immediate primitive
THIRD - [:toolbelt:] - ordinary primitive
THROW - [:exception:] - ordinary primitive
THRU - [:block:] - ordinary primitive
TIB - [:core.1:] - - loader type P4_DVaL
#TIB - [:core.1:] - threadstate variable
TIME&DATE - [:facility.1:] - ordinary primitive
TO - [:core:] - compiling primitive
+TO - [:misc:] - compiling primitive
TOGGLE - [:forth_usual:] - ordinary primitive
TOOLBELT-EXT - [:toolbelt::environment:] - ordinary constant
TOOLS-EXT - [:tools::environment:] - ordinary constant
TOPMOST - [:misc:] - ordinary primitive
TOUCH - [:shell.1:] - compiling primitive
TOUPPER - [:forth_usual:] - ordinary primitive
-TRAILING - [:string:] - ordinary primitive
TRIM - [:toolbelt:] - ordinary primitive
TRUE - [:core.1:] - ordinary constant
TUCK - [:core:] - ordinary primitive
$TUCK - [:dstrings:] - ordinary primitive
$TYPE - [:dstrings.1:] - ordinary primitive
TYPE - [:core:] - ordinary primitive
(TYPE) - [:misc.1:] - ordinary primitive
*TYPE* - [:misc.1:] - threadstate variable
U. - [:core.1:] - ordinary primitive
U.R - [:core:] - ordinary primitive
U< - [:core:] - ordinary primitive
U<= - [:core_misc:] - ordinary primitive
U> - [:core:] - ordinary primitive
U>= - [:core_misc:] - ordinary primitive
UD. - [:misc:] - ordinary primitive
UD.R - [:misc:] - ordinary primitive
$UID - [:shell:] - ordinary primitive
UM* - [:core:] - ordinary primitive
UM/MOD - [:core:] - ordinary primitive
UMASK - [:shell:] - ordinary primitive
UMAX - [:core_misc:] - ordinary primitive
UMIN - [:core_misc:] - ordinary primitive
[UNDEFINED] - [:core_misc:] - immediate primitive
[UNDEFINED] - [:toolbelt:] - immediate primitive
[UNDEFINED] - [:tools_misc:] - immediate primitive
+UNDER - [:misc.1:] - ordinary primitive
UNDER+ - [:misc:] - obsolete forthword
(UNDER+) - [:misc:] - ordinary primitive
.UNDERLINE - [:term.1:] - ordinary primitive
.UNDERLINE.OFF - [:term.1:] - ordinary primitive
UNLOOP - [:core:] - compiling primitive
UNSMUDGE - [:header.1:] - obsolete forthword
UNTIL - [:core:] - compiling primitive
$UNUSED - [:dstrings.1:] - ordinary primitive
UNUSED - [:core:] - ordinary primitive
UPC - [:forth_usual.1:] - obsolete forthword
UPDATE - [:block:] - ordinary primitive
UPPER - [:forth_usual:] - ordinary primitive
UPPER-CASE? - [:misc.1:] - - loader type P4_DVaL
!USE - [:useful.1:] - forthword synonym
USELIBRARY - [:dlfcn.1:] - ordinary primitive
$USER - [:shell:] - ordinary primitive
USING - [:block_misc:] - ordinary primitive
USING-NEW - [:block_misc:] - ordinary primitive
VALUE - [:core:] - definining primitive
VARIABLE - [:core:] - definining primitive
2VARIABLE - [:double:] - definining primitive
$VARIABLE - [:dstrings:] - ordinary primitive
VARIANT - [:struct:] - ordinary primitive
.VERSION - [:core_misc:] - ordinary primitive
VIEW-NEXT-LINE - [:toolbelt:] - ordinary primitive
VLIST - [:tools_misc:] - ordinary primitive
VOCABULARY - [:forth_83:] - ordinary primitive
VOCABULARY - [:forth_usual:] - ordinary primitive
VOCABULARY - [:toolbelt:] - ordinary primitive
VOCABULARY' - [:useful.1:] - obsolete forthword
[VOCABULARY] - [:useful:] - ordinary primitive
VOCS - [:forth_usual:] - ordinary primitive
[VOID] - [:core_misc.1:] - immediate constant
[VOID] - [:toolbelt.1:] - immediate constant
[VOID] - [:tools_misc.1:] - immediate constant
W! - [:misc:] - ordinary primitive
W+! - [:misc:] - ordinary primitive
W/O - [:file.1:] - ordinary constant
W@ - [:misc:] - ordinary primitive
WARRANTY - [:core_misc:] - ordinary primitive
/WCHAR - [:useful.1:] - ordinary constant
WCHAR% - [:struct.1:] - ordinary primitive
WCHAR: - [:structs.1:] - ordinary primitive
WCHARS: - [:structs.1:] - ordinary primitive
WHILE - [:core:] - compiling primitive
#WITH-FIG - [:useful.1:] - ordinary constant
#WITH-NO-FFA - [:useful.1:] - ordinary constant
WITHIN - [:core:] - ordinary primitive
WL-HASH - [:misc:] - ordinary primitive
WORD - [:core:] - ordinary primitive
>WORDLIST - [:forth_usual:] - ordinary primitive
WORDLIST - [:search:] - ordinary primitive
.WORDS - [:chainlist:] - ordinary primitive
WORDS - [:tools:] - ordinary primitive
WRITE-FILE - [:file:] - ordinary primitive
WRITE-LINE - [:file:] - ordinary primitive
WSIZE - [:misc.1:] - forthword synonym
X" - [:useful:] - compiling primitive
xdo-chain - [:chain.1:] - forthword synonym
XMAX - [:term.1:] - threadstate variable
XOR - [:core:] - ordinary primitive
?XY - [:term:] - ordinary primitive
YMAX - [:term.1:] - threadstate variable
Z" - [:zchar:] - compiling primitive
ZCHAR-EXT - [:zchar::environment:] - ordinary constant
ZCOUNT - [:zchar:] - ordinary primitive
ZMOVE - [:zchar:] - ordinary primitive
ZPLACE - [:zchar:] - ordinary primitive
+ZPLACE - [:zchar:] - ordinary primitive
ZSTRLEN - [:zchar:] - ordinary primitive
Z\" - [:zchar:] - compiling primitive

Chapter 1.  PFE Documentation 0.32.x

Make A New Dist
how to create a new tarball or series of RPM packages, or to recreate the autoref documentation.
Tuning The Forth VM
explains steps to enhance the speed of the Forth VM
How To Write A PFE Module
explains the steps to create a dynamically loadable pfe extension module
WordSets in External Modules
explains the steps to activate external modules including those pre-linked to PFE.
Some Internal Decisions
explains the structure of the headers of forth words and the reasons for its differences over FIG-forth
StateSmart words
PFE has made many compile-only words statesmart to make life of a regular forth user easier. However, it can mean trouble if used with postpone . Here are the details.
Locals in PFE
PFE uses the return-stack to store local values and enables you to get even alloca()-like buffer areas there, furthering creation of reentrant words even for the case of words handling strings.
Special Implementation Strategies
explains the solutions that were take to common problems in the implementation of an ansiforth'94 compatible system and the means to extend such a system.
a side note on quote-parse
experimental
a side note on sbr-threading
experimental
Dirk Zoller's README
the README from PFE version 0.9.10
Known Problems
there are some features that people sometimes wonder about.
the License
is the LGPL - the Lesser GNU Public License
Literature
references to (online) literature

How To Make A Dist

The toplevel Makefile supports a few targets to create a few types of distribution archives. The most heavily used is really called 'make dist'".

The current project stores the version number of the the project in just one place - the file "pfe.spec" in the toplevel directory. We use a "grep ' ver ' pfe.spec" to extract the line with the version number. This method is used by pfe/configure.ac and the dist-targets in the toplevel Makefile use it too.

To make things easier, quite some of the toplevel dist-target look for a subdirectory "pub" in either the project or parent directory. The tar.gz and tar.bz2 archive are placed there - this makes it easier to 'roll' micro-releases for revision control purpose.

The files that go into the source-release-archives are not specified explicitly in the Makefiles (what one would expect from a automake-based project), instead there is a list of file-extensions and file-names that are searched with a call to the posix "find" command. To see the complete list of files that will be rolled into the source-dist, type "make zipfiles". The current dist-scheme assumes that a zip-tool is indeed available to create a pfe-current.zip, from which a pfe-current.tar.gz is created (which adds the relase-subdir-path), which is the renamed to the release-name.tar.gz itself.

'make doc', 'make dist-doc' and 'make install-doc'

The doc-creation process does not need any information from the configure-process - it works independently. The toplevel doc-targets will forward usually to the doc/Makefile, and it will do so for quite a few other targets as well. The 'make install' will indeed not install these docs (which is a megabyte of html files), so you have to call 'make install-doc'. For the latter, we use a little trick - the install-doc is forwarded to the configure'd Makefile (which knows the configure'd prefix, e.g. /usr/local or /programs), and the configure'd Makefile forward this target in turn to doc/Makefile but adding a makfile-override prefix=@prefix@ - in makefile-speak: '$(MAKE) -C $(srcdir)/../doc/Makefile prefix=$(prefix) [sadly, bsd pmake does not support "-C"]

The doc-tarball created in the doc-subdir (e.g. words.tar, wordsets.tar and doc.tar) can be rolled into a toplevel dist-archive for the doc. This is also needed since the generated docs are so large (around a megabyte of data) and the doc-generation requires perl and a perl-based helper-package xm-tool (from xm-tool.sourceforge.net) to be made.

'make rpm' and friends

The "make rpm" is currently a bit weird in its assumptions - it looks in the local, parent, parentparent directory for a subdir called "packages". It then copy the "pfe-current.tgz" to "packages/SOURCES/" and call 'rpm -ba pfe.spec'", i.e. rpm-build-all

It is interesting to see that this scheme works for most people who create "rpm" files, but it could be just as well be a bit annoying to some other people.

The debian distro files are currently not shipped with the base pfe.

The windows archive-packages are not fully ready, currently it creates a simple zip-archive with prebuilt binaries for mingw32, but this target is not yet supported - I did this target largely to speed up the development process for this target (cygwin windows-pfe works fine for years).

Tuning The Portable Forth Environment

Loop unrolling in the inner interpreter

The most time critical piece of code in pfe is the inner interpreter, a tight loop calling all primitives compiled into a high-level definition. You find it in file support.c, function run_forth().

On some CPU's it significantly saves time when the code of the inner interpreter is unrolled several times without the need to jump back to the start of the loop after every primitive is executed. On other CPU's it doesn't help or even makes it slower.

For example the benchmark-performance of pfe on a 486 is about 15% better with unrolled NEXT, while the performance on a Pentium becomes slightly worse.

You'll have to try it, what is better on your machine. To enable the feature, you need the following compiler option in Makefile:

	 -DUNROLL_NEXT   

which you can achieve now at `configure`-time too by using

   --with-user-config=UNROLL_NEXT   

Using global register variables

pfe is designed for best portability. This means it can be compiled with a variety of compilers on many systems. Obviously this prevented me from squeezing the last bit of performance out of any special system.

Fortunately there's a way to tune it up significantly with only little effort provided you have GNU-C at hand.

Let me explain: As most of you probably know, a Forth-interpreter traditionally contains a so-called virtual machine. PFE does. This virtual machine consists of several virtual registers and a basic set of operations. The virtual registers are:

	IP	an instruction pointer
	SP	the data stack pointer
	RP	the return stack pointer
	WP	an auxiliary word pointer
 

in pfe there are additionally:

	LP	pointer to local variables
	FP	floating point stack pointer
 

In a traditional assembler-based Forth implementation these virtual registers would be mapped to physical registers of the CPU at hand. How efficient such an implementation is depends heavily on how cleverly this mapping is done.

pfe has no other choice than to declare C-language global variables to represent these virtual registers. These variables are accessed very frequently.

Now GNU-C allows us to put global variables in registers! Obviously the number of registers in a CPU is limited and the use of registers by library functions and the compiler itself interferes.

In spite of these restrictions it is possible to find a niche even in an i386 where to place the two most important virtual registers resulting in a performance boost of about 50%. (Just one more detail that shows what a great job the GNU-C developers did.)

If your system is one of those known by the config-script then all provisions to use global register variables are already taken. You can enable and disable the usage of global register variables in by specifying the option '-DPFE_USE_REGS' in the Makefile, or using the configure-option '--with-regs'.

If your system isn't known by the config script, then first make sure you have a stable port according to the instructions in the file `INSTALL'. Then read the next section to enable the usage of register variables on your system. If all works well please send me your changes.

(Old) Warning:

current versions of gcc (<= 2.6.0) seem to compile incorrect code in very special situations when global register variables are used. This is reported and fixed in later gcc versions.

When you find something not working that worked in previous versions of pfe, then please check if it works again after recompiling pfe without -DPFE_USE_REGS. Please inform me of such cases: "duz@roxi.rz.fht-mannheim.de (Dirk Zoller)"

(New) Warning

The use of gcc register-allocation has proven to be a very fine optimization technique for a C-implemented forth system. However most versions of gcc have some kind of problems on some kind of platform. The latest 2.8.x version is currently the most stable one with just a problem for the i960 target due to the peculiar call-instruction behaviour on that processor.

Later versions of gcc (2.95.x at the time of writing) show some problems involved. The most common: many platforms use a register-based calling scheme (they have 32 cpu registers or more). Using some of the cpu-registers does not make the call-frame generator to save away the forth global register - they are simply overwritten and never restored. If you look through the def-regs.h file then you'll see that we use register numbers 11 and up, so the only thing you have to watch out for are instances of function-calls with ten arguments and more. If you have such a call, save the cpu-register the hard way and restore them after the call.

Another problem are the builtin-functions, especially on the i386-platforms with later gcc. They do effectivly reserve the special-purpose registers for these builtin-functions, so that you rarely get more than three cpu registers for the forth VM. Sometime -fno-builtin helps, sometimes the compile will warn you about register-allocation overlaps, some versions of gcc won't do even that and go to generate bad code. All these problems made me disable --with-regs by default which is clearly a very poor choice, so I advise you to enable it in your default-configuration just after running some tests to ensure the compiler you installed works correctly.

The versions of pfe up to 0.30.x do also need the gcc register reservation for being multithreaded - the global thread-pointer is put into a register that is going to be saved/restored on a thread-switch. Without it, some glue code would be needed that does not currently exist in the sources - so this is another strong hint to configure --with-regs in your projects.

If you have a new processor with yet another register-assignment, please mail me the information so that I can include it to pfe-regs.h - mail to "guidod@gmx.de"

Choosing registers to use

When you use global register variables in GNU-C then you have to explicitly state which machine register to use for the global variable to declare "register". The syntax is like this:

	register type variable_name asm ("machine register name");
 

instead of just

	type variable_name;
 

As far as I see choosing machine registers to use for global register variables is just a matter of trial and error.

First find out how registers are named on your machine. Not how the CPU-manufacturer names them but how the assembler used by gcc (as or gas depending on the configuration of gcc) names them. It's easy: simply use gcc to compile one of the C files with option -S. I changed the `makefile' to allow this by simply `make core.s'.

Then look at `core.s': You don't have to know much of assembly language programming and even less of the particular CPU. All you are interested in is: what are the registers? In `core.s' search for the label `dupe_' i.e. the compiled function that does the work of the Forth word `DUP'. The C-source for DUP is:

	FCode (p4_dup)
	{
  	  --SP;
  	  SP[0] = SP[1];
	}
 

On an RS/6000 (where you won't have to do this because I did it already) using gcc you'd find the following assembler lines generated for p4_dup_:

 .p4_dup_:
        l 11,LC..106(2)
        l 9,0(11)
        cal 0,-4(9)
        st 0,0(11)
        l 0,0(9)
        st 0,-4(9)
        br
 

Reading more of the generated assembler source allowed a guess that

  • Gcc talks to the assembler about registers by their numbers only.
  • Gcc never uses registers with numbers around 16 while the cpu seems to have 32 such registers.

Next edit the file `pfe/def-regs.h'. Add a system specific section of preprocessor definitions naming CPU registers to use for virtual machine registers like this:

	...
	#elif __target_os_aix3

	#  define P4_REGIP "13"
	#  define P4_REGSP "14"
	#  define P4_REGRP "15"
	#  define P4_REGW  "16"
	#  define P4_REGLP "17"
	#  define P4_REGFP "18"

	#elif...
 

Ok, the full set needed a little more experimentation. Maybe start with only P4_REGSP or P4_REGIP.

After enabeling these declarations with the -DPFE_USE_REGS command line option another `make core.s' yields the following translation for DUP:

 .p4_dup_:
	cal 14,-4(14)
	l 0,4(14)
	st 0,0(14)
	br
 

Quite a difference!

If your CPU has different types of registers for data and for pointers then the pointers are needed in pfe. (On M68k the Ax not the Dx.)

If you don't have enough free registers in your CPU then serve the first virtual registers in the above list first. They are ordered by their importance.

Then do a `make new' with option -DPFE_USE_REGS. If you get compiler errors and warnings about `spilled' or `clobbered' registers then change the mapping until it compiles quietly. There's a good chance that it still runs now and if it does it runs significantly faster than before.

Good luck!
Dirk

(last changed by guidod)

How To Write A PFE Module

Part of the LGPL:ed PFE

The Current State

currently, building of a module has only been done within the pfe source tree. You have to add a few lines to the Makefile.am so it is build and installed. This howto will guide you through the process of creating a new module for the pfe source tree, i.e. a pfe extension module.

The Name Of The Module

the first thing you have to do of course: be creative and invent a name. This name will be used in many many occasions as a reference symbol and signon identifier. In this example the module is named 'example' which is creative enough here.

this name is called a 'wordset-name' since it will be used as that. It can even be queried with ENVIRONMENT, and it is listed in the LOADED wordlist of pfe.

Create the File And Add It To Makefile.am

the filename shall *not* be example.c, since I am compiling the pfe for some embedded/kernel targets which only need a '.o'-file, just think of a linux kernel module. Since the intermediate objects are '.o'-files and the 'ld -r' target of several intermediate objectfiles is also an '.o'-file, well, it must be assured that the intermediate objectfiles have a different name than the product '.o'-file.

If you did not understand what I want, well, don't think about it too long and add a "-ext" to the filestem, so that in here, the extension module 'example' is build from the source file 'example-ext.c'.

Have a look at the 'Makefile.am' and its 'toolbelt-ext.c'. You will instantly see what is to be done: first, add the module name to the 'pkglib_LTLIBLIBRARIES, ie.

 -pkglib_LTLIBRARIES = edit.la toolbelt.la
 +pkglib_LTLIBRARIES = edit.la toolbelt.la example.la

and then add a new _la_ section that `automake` can see, since you will probably build from just one sourcefile, it will just look like the others, ie.

 +example_la_SOURCES = example-ext.c
 +example_la_LDFLAGS = -export-dynamic -module -avoid-version
 +example-ext.lo : example-ext.c
	$(LTCOMPILE) -DMODULE -c $<

where the third line should go away in the next PFE generation, and in fact since generation 32.x there is no need for a MODULE-define anymore - the .o file is the same for being either external or internal to the pfe binary. Instead we link a loader-part into the module.so. The 32.x module automake snippet looks now like:

 +example_la_SOURCES = example-ext.c example-dll.c
 +example_la_LDFLAGS = -export-dynamic -module -avoid-version
 +example-dll.c : $(srcdir)/module-dll.c
	sed s/module/example/ $< > $@

and it allows us to modify the module glue code independently of the module source code later on.

this is it for Makefile.am, now go ahead and create the file, i.e. 'example-ext.c'

What Must Be In The Source File

I do strongly suggest that you include a header comment that goes right at the start of the file. The autodoc system of pfe will see it as a special section that should be treated specially and included in the documentation file. Just explain everything that you want to point out to anyone who would want to use your wordset. Do also include your name and a copyright information. Remember, it is the most easiest for you to send me the file, so it can be distributed along with PFE, so it can get compiled on many many platforms, and so it can get maintained over some internal changes in PFE. And actually, this very source file is stored also in the Tek/MPT Source Repository, where you don't want that some Tekkie simply adds a Tektronix Copyright in there - the files are writable by other Tek developers too, not just me.

 /** 
  *  Artistic License (C) 2000 Julius Caesar
  *
  *  @description
  *      An example module for my personal experimentation.
  */

next you need to include some headers from the pfe base system. These headers are made namespace clean, ie. they all have a prefix like 'FX_' or mostly 'p4_'. For a real programmer, this is inconvenient, and it makes the code not very readable. If you look closer, you will see that in most headers there are '#ifdef _P4_SOURCE' sections (expecially in def-types.h) which do include things like

 #define DP    p4_DP
 #define BASE  p4_BASE
 #define SP    p4_SP
 #define STATE p4_STATE

In general, most sources handwritten by users will want to have these. This is however not a good recommendation if the extension module is derived from some other source, e.g. Tek/MPT has a SWIG extension to convert C headers to pfe modules. Anyway, your file will most start with:

 #define P4_SOURCE 1
 #include <pfe/pfe-base.h>

make sure to include one of the pfe headers first, so that the gcc register allocation may work (--with-regs is greater 0). For a single wordset, you need also to include pfe/def-words.h, but I recommend to do that last, after all other includes, since there are a lot of two-char #defines (if you specified P4_SOURCE).

Now, let's have a look at a simple word, e.g. the 2NIP as implemented in 'toolbelt-ext.c'. Please add a javadoc like comment before, and make the first line of that comment show the Forth Stack Notation.

 /** 2NIP ( w x y z -- y z )
  * Drop the third and fourth elements from the stack.
  */

Now everyone knows what that word should do. All wordset words in PFE should then be declared with a prototype macro as FCode. On most systems, a 'FCode(example)' will expand to 'void example_ (void)' - note the underscore at the end that distinguishes the pfe symbol from other C symbols.

Write the body of the function. Inside of an 'FCode' word, you are assured to access the forth stacks and dictionary directly - via its pointer macros. The most common pointers are:

 SP - Parameter stack pointer (downwards)
 RP - Return stack pointer (downwards)
 FP - Floating stack pointer (downwards, not always compiled in).
 IP - Colon Instruction pointer (upwards) 
      points to the next token to be executed by the innner
      interpreter (known as NEXT in other forth systems).
 DP - dictionary pointer, the values is otherwise known as HERE.
 LAST - pointer to NFA of the last CREATE word, null after FORGET

most of the important ones are declared in def-types.h, and most of the important macros to access them are declared in def-macro.h, e.g.

 FX_DROP FX_POP FX_PUSH(x) FX_DUP FX_OVER FX_NIP ... changing SP
 and FX_COMMA to compile to HERE 
 (and comma is defined as '*DP = x, DP += sizeof(p4cell)' )

the 2NIP implementation is of course a short one. We just want to nip the third and fourth item in the parameter stack, and just as you would expect from 'PICK', the values in the SP-stack are called SP[0] SP[1] SP[2] SP[3], where SP[0] is of course the top of stack. Here we copy [0]->[2] and [1]->[3] and decrease then the stack depth by increasing the stack pointer by 2 - remember that the parameter stack is a "(p4cell*)" and it increments downward.

  SP[2] = SP[0];
  SP[3] = SP[1];
  SP += 2;

you can then declare other such words, and finally you need to make them known to forth. This is done by assembling all the words in a Wordset-table. A Wordset table is really two C strutures, where the first lists the entries and the second gives some more information. They are always written shoulder on shoulder, so it looks like

  P4_LISTWORDS(example) =
  {
	CO ("2NIP",   p4_two_nip),
  };
  P4_COUNTWORDS(example, "EXAMPLE - my own example words");

but the two-letter entries will be removed from PFE shortly, so use the new style with longer names. Since 31.x generation, you should use this style:

  P4_LISTWORDS(example) =
  {
	P4_FXco ("2NIP",   p4_two_nip),
  };
  P4_COUNTWORDS(example, "EXAMPLE - my own example words");

and in the following sections, only the longer names are referenced. Have a look into the header file to get the old-style words.

note that P4_FXco is a macro from 'pfe-words.h' that does all the relevant things. So just give it a name with a C-string and the name you used in FCode. The P4_COUNTWORDS macro has a string - and the first part (upto the first space) is used to identify the wordset in ENVIRONMENT queries. It will also show up in the LOADED WORDS.

the macro (e.g. P4_FXco) will define what the symbol should be look like in forth - P4_FXco is a subroutine code reference, i.e. a primitive. P4_IXco is the same, but immediate. There are lots of other macros, just have a look at 'def-words.h'

note: the following paragraph is outdated since the 31.x generation which has this LOADLIST table in the referenced module-dll.c. No need to declare it by hand anymore, just link it to your original source code. Anyway, you still have the option to declare an explicit loadlist, but you can not be assured that this will stay in the next generation of PFE, where the loadlist code might be removed completly. The single-level load-scheme does not need it anymore, as all kinds of loader-commands are available in wordsets too. Avoid this one.

Anyway, here's what it looked like:

 P4_LOADLIST (example) =
 {
	P4_LOAD_INTO, "EXTENSIONS",
	&P4WORDS(example),
	P4_LOAD_END
 };
 P4_MODULE_LIST (example);

And now you are basically through with it. Just compile, and when `pfe` is started, type 'LOADM example' to get access to the words in the 'EXTENSIONS' vocabulary.

Semant - advanced words of PFE

The Semant words are one of the nicest features of PFE. Without much horrors, you get compiling words and state-smart words ... and it will also be nicely decompiled by `SEE` without any further problem.

Let's have a look now at p4_literal, i.e. LITERAL

 /** LITERAL ( value -- )
  * compiling takes the value from CS-STACK and puts
  * it into the dictionary. Upon execution, it will 
  * visible the parameter stack. In exec mode, the
  * value is just left on the CS-STACK - which simply
  * is the parameter stack itself.
  */
 FCode (p4_literal)
 {
	if (STATE)
	{
		FX_COMPILE (p4_literal);
		FX_COMMA (FX_POP);
	}
 }
 FCode (p4_literal_execution)
 {
	FX_PUSH (P4_POP (IP));
 }
 P4COMPILES (p4_literal, p4_literal_execution,
	P4_SKIPS_CELL, P4_DEFAULT_STYLE);

The last COMPILES-declaration is the binding link between everything and all about Semant-words. The first parameter references the original compiling FCode. The FX_COMPILE in the compiling FCode will in turn reference this semant declaration.

The second parameter of COMPILES is of course the execution that should be COMMA into the dictionary. Since pfe is indirect threaded, you cannot just use FX_COMMA(p4_literal_execution), instead you compile the address of the pointer to p4_literal_execution that is given by the static Semant-structure. The advantage is, that the decompiler knows the address of this COMPILES-structure, and so there are some hints for the decompiler. SKIPS_CELL should be very obvious - the decompiler shall not interpret the next token in the colon-definition. And the default-style is, well, just nothing. All kinds of indentations for IF and LOOP style words could be given. See 'def-const.h' for some of them.

The compiling word should now be understandable: if in compiling mode, compile a execution-token (the address to a pointer to a C-function), and the value on the stack into the dictionary at HERE. The POP will also consume the value off the paramter stack.

The execution is supposed to do the reverse of it, so PUSH will insert the value on top of the parameter stack, and the value is retrieved by looking at IP. Remember, IP points to the next token that the colon-inner-interpreter will execute if the current C-function returns. Therefore, the value is fetched from there (i.e. *IP) and afterwards increased to the next token (i.e. IP++) which can be expressed with a single statement as in *IP++. You could however use the macro P4_POP(IP) to make for a bit of literal programming here.

Now that the implementation is done, export the semant-word in the wordset-table - and be sure to use 'CS'. All 'CS' words are of course immediate, and it does not reference the compiling word, but the semant-structure. Here you would write...

  P4_LISTWORDS(example) =
  {
	P4_SXco ("LITERAL",   p4_literal),
  };
  P4_COUNTWORDS(example, "EXAMPLE - my own example words");

The real benefit will be obvious when you make a colon-definition with a semant-word, and when done, use SEE to see what is in there. It will produce some very fine output. Well, the SEE words are of course in debug-ext.c, since decompiling is used usually during debugging or even single-stepping.

Runtime - preparing PFE for call-threading

The previous section dealt with the execution semantics of compiling words which add their execution vector to the current colon definition under creation. Here we present the style of creating new HEADER entries in the dictionary and setting up its runtime code for the new words.

Up to the 31.x generation, this was very simple - one would simply call a word that creates a header entry (or just skip that part of noname entries), and the CFA runtime vector had been simply COMMAd into its place, followed by more COMMAs to set up the parameter field. Here's a typical snippet of that style:

 FCode(p4_constant)
 {
    p4_header (PFX(p4_constant_RT), 0);
    FX_COMMA(FX_POP);
 }

With the current generation of 32.x this is not quite recommended, even that you can still use this scheme. However, use a new style for it which is much more obvious about what you want to do, so let it look like this:

 FCode(p4_constant)
 {
   FX_HEADER;   // create header up to but not including CFA
   FX_COMMA(PFX(p4_constant_RT));     // setup the CFA value
   FX_COMMA(FX_POP);
 }

The disadvantage is that it makes a specific assumption about the setting of a runtime vector of a codefield, and it even declared the codefield to be just the address of the runtime C-routine. This is true for the default indirect-threaded model.

In order to widen the range of possible threading-models, we go the same way as for the semant-words - we create an runtime info-block and the CFA-setup is done by referencing this info-block - in the default indirect-threaded model it will simply fetch the value that points to the C-routine, and COMMA it where the definition is so far. Here is the style that is recommended in the 32.x generation:

 FCode(p4_constant)
 {
    FX_HEADER;
    FX_RUNTIME1(p4_constant);
    FX_COMMA(FX_POP);
 }
 P4RUNTIME1(p4_constant, p4_constant_RT);

and unlike the traditional code, this one is not anymore just an FXco or IXco (that would get at the FCode address) in the LISTWORDS table, instead we use now the RTco designation in the LISTWORDS table that will reference the name of the P4RUNTIME info-block (just like SXco references the name of the P4COMPILES info-block).

Actually, this new style with an FX_RUNTIME macro, makes the C source much more obvious as the macro name FX_RUNTIME does point out what shall be done at this point, to setup a runtime-vector for the header just created before. But there is also another need around here which circulates around the decompiling of words. Up to here, the debug-ext will contain a large table of all known runtime-vector values and associate it with the C code to decompile its parameter area, including the colonwords. Using this new scheme, the moduleloader has the chance to see new runtime vectors, and register them dynamically. This is not done up to now, but it will be used in the 33.x generation.

In the 32.x generation, the style of the runtime implementation has also changed, although the old style is still supported. The traditional scheme for the forth systems is the use of a word-pointer, short WP, that is either an explicit variable in the inner interpreter, or it can be fetched indirectly by looking for IP[-1][] (the inner interpreter will fetch the current value from IP and increment it. Then the execution-token is executed by jumping indirectly. The value IP[-1] points to the CFA of the current word, adding one cell lets us see the PFA of the current word executed in the inner interpreter).

To access the parameter values, one can simply use the WP macros and address it with a normal C-style array index. A typical runtime would therefore look like:

 FCode(p4_constant_RT)
 {
   FX_PUSH( P4_WP_PFA[0] );
 }

To make it easier to support native-cpu sbr-threading and portable call-thereading, there is a change about here, since for either of thse we can not just fetch the IP[-1] to get at the wordpointer, nor is the latest value be fetchable from the cpu register in sbr-threading mode (atleast not without some assembler snippets). Instead of the assumption of a global wordpointer (either explicit or implicit through IP), we create a local wordpointer in the runtime-definition and a new macro can be used to capsule the needed setup-code. The new style looks like:

 FCode (p4_constant_RT)
 {
    FX_POP_RT_BODY_(pfa);
    FX_PUSH( pfa[0] );
 }

but for a single fetch, the same source code can be written a bit shorter - which will actually resolve the same code as with P4_WP_PFA, see here:

 FCode (p4_constant_RT)
 {
    FX_PUSH( FX_POP_RT_BODY );
 }

The base to call this macro something like _POP_ has a simple reason that lies in the call-threading model. Since a colonword will be made up of pointer to C-code (instead of pointers to pointers of C-code as is in the indirect-threaded model), there is no easy way to get at the address of the parameter field - unless one would use direct threading that would jump directly into a copy of native-code in the codefield of each word, and that native-code snippet would be required to set up the wordpointer then. For call-threading however we jump directly into the C-compiler generated routine, so that DATA and CODE are fully seperated in different segments, with the possibly of an unwriteable CODE segment.

To get the parameterfield address, we have to add that one explicitly into the colonword - each word that needs to access parameters will be compiled with two cells in a call-threaded colondef, the first one is the runtime-vector and the second the parameter-vector. The inner interpreter will fetch the runtime-vector, increment the IP (instruction pointer of the current colondef), and jump directly in the C code. The runtime C code will then have to fetch the parameter-vector and thereby adjust the IP to point to the next runtime-vector following the current tuple. This would not needed to be done for primitives, and well, that's what the name comes from - primitives don't have a parameter field.

Unlike the traditional indirect-threaded forth, the codefield of words in call-threaded mode do not contain a code address, instead they point to a code info-block which could actually be just the same as the info-record that is also available in the WORDSET table to export definitions. The executions done in the indirect-threaded listloader will simply be postponed to compile time.

Well, the call-threading mode of this style is not very consise w.r.t. to the memory consumption - each call-threaded colondef would get compiled as two cells, one for the colondef-runtime and one parameter-vector point to the list of exec-vectors that make upt that definition. Only the primitives being compiled from C source would be one cell entries. However this restriction can be lifted when going from call-threaded colondefs to sbr-threaded colondefs for the cpu architectures that we know about. Each runtime-vector would simply be preceded with the cpu-native code for call-subroutine, and the complete colondef would then be a native-code primitive in the end that does not need a parameter vector when compiled. Unlike direct-threading forth systems, just two native-code bitpatterns must be discovered to make it work - sbr-call and sbr-return. The rest would be just native-code optimizations.

WordSets in External Modules

Part of the LGPL:ed PFE

External Modules

The PFE has a generic extension system that a programmer can use to write his own forth extension in C. The lower C-level part is described on the page "how to write a PFE module". This external module contains a wordset loadlist table, and in fact the same tables are used internally in PFE. Traditionally, in PFE one did load the external modules via LOADM like

 LOADM gforth

however this will only work if the resp. module gforth.so had been living in a real external module. On some platforms however there is no good binary module provided by the operating system, so that the external modules are pre-linked to the PFE and all that is needed is to make the wordset entries available to the PFE runtime. This is not just an activation, the wordset table can have contructor instructions that can heavily modify the current PFE process instance.

The pre-linking does not bind anything of the external module to the basic PFE runtime system, so that (using the resp. LGPL exception rule about relinkable process binaries) these modules do not fall under LGPL themselves. The only reference is made in dl-internal to reference the data-like wordset-table of the extra module, and the table is searched later on, it is not activated in the default boot phase of PFE.

Apart from using this scheme for system that do not support a good dynaload system for binary modules, it can also be used for optimization of the system - for instance the zchar-ext wordset is usually pre-linked to the PFE core library. It implements the zero-terminated strings that are widely used in C, and it brings about the backslashstring definitions that are needed to use C-like strings with embedded newlines and other control-characters.

WordSet Activation

To make it easier to provide for the different activation routines for non-core wordsets of PFE, the PFE of 31.x and higher is now using the EXTENSION-query mechanism to activate wordsets - this follows the guidelines of the ANS Forth standard to activate additinal wordsets. Forth applications shall check the environment for a specific wordset with a query. The wordset might not be present before this call, so that references to the words in that wordset will fail (with an `undefined` exceptioin), but after a query to the environment did return true, it must stay that way and a wordset shall not be unloaded/deactivated thereafter.

The PFE adopts this mechanism with some small restrictions. First of all, the ENVIRONMENT may contain a lot more definitions than just wordset assertions - if a query is not yet defined in the ENVIRONMENT, it is hard to decide whether it is part of another wordset or a reference to a wordset assertion itself that should trigger an implicit LOADM call. Therefore, if an application writer wants the PFE to check for a wordset then it should always be done for the -EXT variant. If the resp. wordset is already loaded, it will return the value of its assert constant. Otherwise, the PFE will replace the "-EXT" part with the module file extension being used on the current operation system, and if there is such an external module, it will loaded. When loaded succesfully, the environment-query will check again whether the newest module has been pushing an assert constant into ENVIRONMENT. If yes, then this value is returned, if no then an assert constant is generated that contains null as the value but makes the next environment query to succeed.

This scheme is used for internal and external modules, it even applies to the floating wordset. Since 31.x, the floating wordset is normally compiled as a wordset module, and the basic pfe runtime system does not contain the floating definitions after boot. They have to be activated. Try the following lines to see what it does:

 : EXIST? IF ." EXIST=" .  ELSE ." NOT EXIST!" THEN CR ;

 s" floating" ENVIRONMENT? EXIST? \ no
 s" floating-ext" ENVIRONMENT? EXIST? \ yes, loaded on the fly
 s" floating" ENVIRONMENT? EXIST? \ yes, matches floating-ext 

Note that there is not even a floating-stack before the floating-ext wordset has been loaded, - it gets some memory from the forth dictionary via a constrctor, and it places a deconstructor, and it places a hook into the ABORT cleanup routine to have the floatingstack cleared when an error occurs.

Available Modules

The pfe searches its lib-directory under "$prefix/lib/pfe/" for available modules - as an example, the activation of the FLOATING-EXT wordset is looked for in the binary "$prefix/lib/pfe/floating.so". The main LGPL:ed pfe core does ship with a number of external modules, and with each new generation more modules become available. These modules use the C compiler to generate optimized native code for the primitives they provide, and they can be easily used to interface with any other C-level code.

Among the wordset modules that are currently available, the application programmer can use these for example:

ZCHAR-EXT
usually pre-linked, implements zero-terminated strings and backslashstrings.
DSTRINGS-EXT
a work kindly provided by David N. Williams, implements dynamic strings over a string stack, and allows to use strings as freely as many other integral types.
FLOATING-EXT
usually an external module now, a case of a standard ANS Forth wordset pushed to be external.
EDIT-EXT
implements a block editor for pfe, just three forth words are exported but it contains the full functionality in the C-compiled binary module.
HELP-EXT
the user doesn't need to load this module explicitly, the pfe core contains a word "HELP" that will implicitly load the HELP-EXT if it has not been loaded yet, it has actually a deferred ENVIRONMENT?-query in its definition. When the HELP-EXT module has been activated successfully, the word following "HELP" will be handed over, and the HELP-EXT module will serach the "$prefix/include/pfe/*.h" files for a description of the word. No need to leave pfe to view a short description of the word.
TOOLBELT-EXT
the PFE main core does already contain most of the toolbelt words but some are missing, and the word "NOT" has a different defintion. To help to run toolbelt-based forth applications, the TOOLBELT-EXT provides optimized routines, and it can be activated just like any other wordset extension.
GFORTH-EXT
similar for some gforth extensions, here we add some extension that are sought to be compatible with their resp. gforth definitions to help application writers to run their gforth-based programs on top of the PFE. Words are added on request, just contact the PFE maintainer, it does not implement a complete series of gforth primitives.
STRUCT-EXT
implements one of the many variants of STRUCT extensions for forth - this one follows the MPE model at great lenghts, it provides FSL structs and a few compatibility words with gforth structs. There is a STRUCTS extension that builds on top of the STRUCT extension to help even more to port applications to the PFE.
SMART-GO-EXT
A syntax extension to provide the PFE with a variant of extended literals. You can hook the outer interpreter via DEFERs and have it automatically call other words for a given prefix. For the curious.
MODULE-EXT
provides a module system with hidden words and export words. Again, just one model in a large set of other variants in the forth world, and this one is rather simple. It could be implemented in highlevel forth as well. For the curious.

Internal Decisions

Part of the LGPL:ed PFE

The following section about the Head.aux field is outdated since the 32.x generation of PFE. Please skip to the next section labelled "non-const >body"

The Head.aux Field

this section applies up to and including the 31.x generation of pfe.

The ANSI standard on forth requires that a DOES> code changes the CFA-vector of the latest CREATE to the colon's token-list right after the DOES>. However, PFE does actually regard the value in the CFA as the address of an actuall C-routine, so it does simply jump there - the bytes at the DOES> address need to be actual cpu asm code, but PFE can not compile cpu specific code as it would require knowledge about the cpu beyond that of the C compiler.

Actually, the CFA of the last CREATE word is changed to a C routine in the standard .text body that shall start to execute the colon's token-list right after DOES>. However, if the CFA of CREATE points to a common routine the .text section, how shall the DODOES code know where to start execution?

In the forth-83 and earlier forth dialects, the address where to actually jump to was stored in the field directly following the CREATE address, i.e. in the first PFA cell. Therefore they used the word <BUILDS (defined as : <BUILDS CREATE 0 , ;) to ALLOT the extra field, and the sequence after DOES> did receive the address of CREATE plus one cell. The forth'94 standard does not allow this - the sequence after DOES> gets the actual PFA address, and <BUILDS is not defined in the standard - just use CREATE.

All non-asm implementation of forth do the same trick - they add the extra field before the CFA, in PFE called the AUX-field. It is only used by DOES-words but by its implementation issues it will be allocated for every word. The header size of a word in a non-asm implementation is therefore bigger than in in asm implementations of forth just for these DOES-words.

To sum it up - between the LINK-field and the CODE-field is an AUX-field. All forth languages base on C do this.

(the name aux is from older times where this field was also used for some other information instead of the does-address. it isn't now and the field should perhaps be just named Head.does but feel free to use this field if there is a special need)

The Flag.byte Field

The forth'94 does not do any requirements on the structure of a name-field, it does not even need to exists. The forth'83 implementations had a atleast a header field, and the traditional structure of a name field from FIG-times is a counted string whose upper bits have been (mis-)used for the flag-bits. The highest bit marks it as the the flagfield (it is always set), followed by the immediate-bit and the smudge-bit. This leaves just 5 bit for the actual count of the name in the lower bits, and the names were hence limited to 31 chars.

However, 31 chars is clearly inappropriate for names more than twenty years later - the PFE is often used to interface to C-defined API and whereas old implementations of C had a 32-char limit too, they do not now anymore. The limit had to be raised for PFE, and instead of making extremely radical changes to the name-structure, the trick of F-PC was used - to move the the flags just before the count-byte of the name.

Due to some other implemenation issues (the link-to-name routine looks for the highbit that marks the flag-field) the limit is now 128 chars. As an advantage, the structure of the namefield is now a plain counted string without any flags mangled in. As always, the PFE allows to change back to the traditional ways, and in the source code a macro is used to enhance readability - "_FFA". And the other macro is called "NFACNT" which will return (*nfa&31) for the traditional mode to mask out the flag-bits from the count-value - in the default mode of pfe however, it is just (*nfa). Use these macros to calm down the #ifdef-noise.

To sum it up - the flags live in an extra byte just before the name field which is a normal counted string.

The Head Layout

  structure Head                   structure Head
    1 chars field flags              1 chars field FFA
    x chars field name               x chars field NFA
    1 cells field link               1 cells field LFA
    1 cells field aux                1 cells field AUX
    1 cells field code               1 cells field CFA
    ( followed by body)              ( followed by PFA)
  endstructure                     endstructure

Using `configure` options, both the flags-field and the aux-field can be cut out again to arrive at a header-structure that is FIG-forth compatible. The use of `with-fig` will cut out both fields.

...

(there are a lot more internal decisions to be explained, however they are of not much interest to forth programmers - they will be added to this document later)

Non-Const >BODY

this section applies to PFE generation 32.x or later.

The first PFE generation took the option to add an extra aux field into the header of a PFE word, and each word in pfe had the exact same layout which did closely follow the FIG model in earlier times. Just the flag.byte was not folded anymore with the count.byte of the name.

As explained above, there is a fundamental problem between the FIG forth and ANS forth systems about the usage of <BUILDS and CREATE related to DOES words. The ANS Forth expects that the code-field of a CREATed word is modified to point to the DOES-field which then contains a trampolin to execute the colon XTs just following it. However, this is impossible to achieve with a traditional indirect-threaded model using no assumptions about the target processor ISA. That's why the PFE does follow the habit of FIG forth to place a second field near the CFA of the CREATEd word in ANS Forth, which is simply the address of the DOES code. Therefore, the DOES-address does effectivly not need to carry an additional code address.

However, there is a problem with compatibility about the second argument, as this one is neither the actual runtime code value of the CREATEd word and it is not data parameter value to be used by the execution of the word. It constitutes its own categorization as a helper field.

In FIG forth, this was different as one was supposed to use the word <BUILDS to CREATE new words that could be extended with DOES>, and the BUILDS word did boil down to be a combination of a basic CREATE followed by " 0 , " followed by DOES> to put its HERE value into the zero just following the CREATE header. The two words CFA and PFA were simply constant operators that did always add/substract a CELL which is simply the size of the runtime time vector in an indirected forth implementation.

Well, there is a problem attached to this mode, since there might be words that want to adjust the first parameter for the DOES code to see, however the PFA[0] was occupied by the DOES-vector, so the first real parameter for the DOES-code would be in PFA[1]. The FIG programs knew this, so they added another CELL for those words being derived via a <BUILDS/DOES> creation. But - ANS Forth does explicitly disallow this, <BUILDS is identical to CREATE here, and the word >BODY is supposed to convert a CFA (code-field address) into a PFA (parameter-field address), not matter if that is a VARIABLE or a DOES word.

There are effectivly three solutions, each having its own derived problems:

code-field is two-cells, always - the first cell is the runtime vector, the second cell is the does vector, the second field is empty for non-does words.
problem: this is a waste of memory, and quite some old FIG programs made an explicit assumption about the size of the codefield, so they did use CELL- directly to end up at the CFA, which is wrong here.
code-field is one plus one cells, always - the runtime vector is preceded with a does cell that is left empty for non-does words.
problem: again a waste of memory, however old FIG problems can still add/substract a CELL to convert between CFA and PFA. The two words >BODY and PFA are identical and constant. The ANS Forth words will find the first parameter directly in PFA[0], even for DOES words, as it is written there. This breaks however FIG forth programs assuming PFA[1] or simply two cells off the CFA to be the first parameter entry for a DOES word
code-field has variable size, one cell for non-does words, two-cells for the does-words.
problem: this mode does actually follow directly the size assumptions of FIG forth programs, a VARIABLE's parameter field is just one cell after the CFA, and for a DOES-word it is two cells. Since ANS Forth's >BODY is supposed to convert to the first parameter, no matter which CFA it is given, the to-body execution becomes a non-const word, sometimes addding one cell, sometimes two, depending on the target word.

The PFE up to 31.x did use the second option, one-plus-one, which is also the model of many other portable forth systems, e.g. gforth. Since generation 32.x, we use the third model with a variable to-body execution. Among the advantages is the result of some internal code cleanup - so far the FIG variant of forth did have another header layout of the words, so there were some defines and ifdefs needed in the PFE forth implementation. With the non-const to-body variant however, the FIG and ANS header layout is identical, so it makes it easier to port FIG forth sources to the ANS mode of PFE, and it even opens the possibility to mix ANS-converted code with non-converted code, as it just boils down to replace a wordlist on the search-order. The binary result is identical (unless the flag.byte is used, which is an extra option however).

This advantage of the internal binary layout being identical is countered by some disadvantages. First of all, the ANS forth programs may not have made an assumption that the offset of the parameter field is always the same for both variables and does-words. They must have used >BODY in all places, and not memorized the offset of this word somewhere, as if the >BODY is a constant function. So far, there was no incident about this, and the people on comp.lang.forth did give their consent to this model as being fair - perhaps some native code forth systems with direct threading had been using variable size of the code field anyway, to lower memory consumption - that's because in direct threading, the code-field contains native cpu code being either just the complete runtime or a trampolin into an external runtime code. For a few things like a variable-runtime, this can be quite short for may cpu ISAs.

Secondly, the non-const nature of the to-body execution implies some runtime restrictions. First of all, it definitly needs an if-code, making it a bit slower, and the if-value to be checked is the first cell of the CFA on which to decide what size the complete codefield has, and to add this size of the codefield. The latter implies that there is an additional memory access, which is not only slower than a constant to-body offsetword, but constitutes the availability of a SIGBUS in to-body for bad addresses. The value supplied to that to-body must be a valid CFA, and nothing else. (one can however add some backward compatilibity to check for zero. It returns the size of the variable and colonword codefield).

And thirdly, there is some confusion about CREATE - in ANS Forth we must ensure that a DOES vector can be attached, so it must have the two fields ready, while in FIG Forth mode just one cell is needed, and only <BUILDS puts the two-cell type of thing. To get around this, the word CREATE is only a SYNONYM - in an ANS-Forth section, it will resolve to <BUILDS, and show this word on decompilation. The forth application writers are furthermore encouraged to use this word directly in their sources, and add a section like

  [UNDEFINED] <BUILDS [IF] : <BUILDS CREATE ; [THEN]
  

somewhere in the header of their applications for portability reasons. In a FIG Forth section, the CREATE synonym will resolve to CREATE: which makes a word that is not supposed to be extended with some DOES code later on.

The use of a variable codefield size opens new ways to create optimized code (and codefield areas) for use in native-threading systems, and it seems to be a feature well covered by ANS Forth rules. At the same time, the default pfe internal layout does exactly match that of the FIG, so it makes it a lot easier to convert legacy fig applications to the ANS Forth world. This mode is also recommended to all forth system implementors - do not anymore use the does-field model as it was used in pfe up to 31.x, and adapt your applications to expect the minor restrictions about the usage of words in this mode. It does even save you a few cells in the memory footprint.

StateSmart Words and POSTPONE

The ANSI Standard On Forth has ensured that words are usually not state-smart, since it can be a problem when trying to postpone execution in self-constructed compiling words. Only two compile-only words exist that have an extra execution-semantics, one is s-quote (for use with included, the other is to. A note in the standard says (near TO, dpans13#13.6.1.2295 )

Note:

An ambiguous condition exists if either POSTPONE or [COMPILE] is applied to TO.

This note can be seen as a big red warning for anything that is state-smart - state-smart words are one of the widely used implementation tactics to make life easier for the usage of words. It is escpially a bit cumbersone while learning the forth language. In general, a forth user can test a little series of words on the command line in interpret mode, and when the things work as expected, just surround it with ":" and ";" to memorize the word-sequence for further reference. It makes one of the strengths of forth that one can easily factor out command-sequences and attach a nice and readable name to it.

The ANS Forth describes a few pairs of words to handle the problems with postpone - one is an immediate compile-only word, the other is just the execution that is done by that word before compiling it into the dictionary - usually to leave a value on the stack. The words are:

`char` and `[char]`

` [char] ` is compile-only - it will get the (ascii-) value of the next char, and compile it as a `literal`. It's interpret-semantics are undefined, and the word `char` must be used outside of your colon-definitions. The `char` word is more or less the implementation used by `[char]`, as in

 : [char]  ?comp char postpone literal ; immediate 

In pfe, the `[char]` is state-smart - in interpret-mode, it will only do `char` and it will not call `literal`. The char-value is left on the stack just as it is done in a compiled word that has used `[char]`.

 : [char]  char state @ if literal then ; immediate 

`'` and `[']` (tick and bracket-tick)

` ['] ` is compile-only - it will get the execution-token of the next word, and compile it as a `literal`. It's interpret-semantics are undefined, and the word `'` must be used outside of your colon-definitions. The `'` word is more or less the implementation used by `[']`, as in

 : [']  ?comp ' postpone literal ; immediate 

In pfe, the `[']` is state-smart - in interpret-mode, it will only do `'` and it will not call `literal`. The tick-value is left on the stack just as it is done in a compiled word that has used `[']`.

 : [']  ' state @ if postpone literal then ; immediate 

`."` and `.(` and `type`

` ." string" ` is compile-only - it will parse the string, compile it, and when the compiled word is executed, it will print the string to the terminal. The usage of ` .( string) ` will run immediatly, to show the string to the terminal in both compile- or interpret-mode, which is good for notifications during compiling of a forth script. The non-immediate word would be `type` that needs to be passed a string which could be compiled with `sliteral`.

In PFE, the `."` is made state-smart, therefore in interpret-mode, it will instantly print the string to the terminal, just like `.(` would do. In compile-mode it parses and compiles the string (`sliteral`) and postpones a `type`-execution.

 
	: .( 	postpone "  type ; immediate
	: ."  	postpone " 
		state @ 0= if type 
		else postpone sliteral postpone type fi
	; immediate

`C"` and `S"` vs `sliteral` and (nonstandard) `parse,`

` C" string" ` is compile-only - it will parse the string, compile it, and when the compiled word is executed, the string-address will be avaiable for further usage in the word. There is originally no interpret-semantics for the strings, but ANS Forth has defined one only for the usage with `included`. You will find that the ANS Forth standard has two descriptions of `S"`, where one is in CORE, the other is in FILE-EXT - only the latter is more or less state-smart.

The problem with interpreted string constants is the question where the string is stored. In traditional systems, the stringconstant is put into a temporary location called the `pocket`. Many systems (including the PFE) have more than one pocket that are used in a round-robin fashion, but the user should be aware that interpret string-constants are only temporary - they will be overwritten in the pocket by some other call later on.

The usage of `included` from the FILE-EXT wordset however suggests that one does need stringconstants in interpret-mode, and ANS Forth has therefore defined that `S"` should be extended with an interpret-semantics if `included` is available in a forth system. However, `S"` is easier for temporary strings than `C"` - an implementation can choose to return the address and length of the charstring in the TIB - the terminal input buffer. In such a system, the use of such an intepret-mode string construct would only last for a single line entered - the following `included` call must be on the same line as the `S"`-quoted string-constant.

PFE however is very traditional (it's one of the features of PFE) and in interpret-mode, all these stringconst quote-words will actually parse the string into a pocket whose address is returned. Usually, PFE is configured to have eight pockets, and a maintainer is asked to never configure with less than two pockets to enable move-file and rename-file operations from the commandline. And always remember - interpret-mode stringconstants are temporary, and their number is limited.

( To postpone these words can again be a problem, just as it is with state-smart words. Be sure to use `sliteral` to add a string-constant to a meta-compiled definition, and look into the documentation of the nonstandard word `parse,` to add just the chars of the stringconstant to the dictionary. )
`literal` and `fliteral` and `2literal` and `sliteral`

All these words are compile-only - they are used to compile a value on the (cs-)stack into the dictionary and to return their value/address during execution of the compiled word.

It is easy to add a bit of state-smartness to these words - compilation is only done in compile-mode, while in interpret-mode it will do as if it is already running. `literal` will leave the value on stack, actually a `noop` in pfe. The same for `2literal` that leaves the 2value on stack, and for `fliteral` and the f-stack. `sliteral` will effectivly do nothing either, leaving you with the pocket-string. In compile-mode, it would `allot` and copy the string to the defined word leave that address later.

If you are interested about the whole topic of postpone, state-smart words and ANS Forth descriptions with differing compile-mode and interpret-mode semantics ("combined words"), then have a look at gforth which uses a truly different approach about compile-only/interpret-only/combined/self-parsing and other immediate/non-immediate words.

Anton Ertl (the gforth author) has some more indepth documentation about the topic availabl on the Vienna university server, see

also, there was a discussion about this topic on comp.lang.forth during 6.March.2001 to 7.March.2001, that may give you some hints

As far as I can see, state-smart implementations of the string-contant words and literal-words are very very common in the forth systems around, the state-smart variants of char/[char] and '/['] pair is not so widespread. Be sure to postpone only `char` or `'`. There is a configure-time default for PFE-compilation that can make all these statesmart words non-smart - if these compile-only words are interpeted on the command-line then a `?comp` exception is thrown - something like "trying to execute a compile-only word". The compile-default for PFE is however to make them statesmart instead of compile-only-immediate.

Locals in PFE

Part of the LGPL:ed PFE

ANS Locals

The ANS Forth provides an extra wordset dedicated to LOCALS which happens to be critized by about every forth developer around. The problem is the inverse order of declarations compared with the normal stack comment. So, if your word expects three values as input parameters, you would usually declare it with a stack comment like this:

 : MY-WORD ( a b c -- x )
     whatever instructions
 ;

however if you want these three values to end up in named places on the return-stack, you have to write this one with the following LOCALS syntax:

 : MY-WORD LOCALS| c b a |  ( a b c -- x )
   whatever instructions
 ;

To understand this scheme, we have to look at the underlying word (LOCAL) which is also provided in the ANS Forth LOCALS EXT wordset. This word is not quite useful for the user, it is meant to be used by compiling words like LVALUE to declare new LOCALS to the LOCALS machine in the system. The PFE has such an LVALUE word that declares the following name to be a new LOCAL, and it initializes it in the course. To declare three values, we would have to write this:

 : MY-WORD ( a b c -- x )
   LVALUE c
   LVALUE b
   LVALUE a
   whatever instructions
 ;

and of course, this order is necessary since the first value is the one on top of the stack being the rightmost in the stack comment declaration. The ANS Forth LOCALS|-word does simply follow this order, making the name "c" to be in the first place and therefore leftmost in its simple syntax.

Please note that PFE does not follow the solution that some other forth systems implement - using another syntax extension that does the locals declaration in the "correct" order. However, a scheme like the John Hopkins Scheme adds a lot of complexity - the declaration must be parsed and reordered to match the internal order of initializations, and in order to provide LOCALS types other than single-value items, they must extend the parsing code even further. Instead, just skip that and follow the forthish style, using the simplest syntax that is still best to read - declare each local-value seperately.

Explicit Locals

One of the explicit locals has been describe above - called LVALUE to remind you of VALUE which has the same stack execution in declaring global values. The same has been done for the other local declarators - their names shall match the declarators that do the same thing for global items with a single "L" prepended. Currently, the following two local declarators are available in PFE

  LVALUE ( a [name] -- ) : [name] ( -- a )
  LBUFFER: ( size [name] -- ) : [name] ( -- addr-of-buffer )

feel free add more. I know one project that had a good use for LFCONSTANT but there is no floating extensions module so far - although I would like to include one if you have one written.

One nice side effect of explicit Locals is the availability of init computations that you can not have with any of the compound declarations. Have a look at this example to get an idea:

  : SAVE-BUFFER-TO-FILE ( buffer-addr buffer-len file-name -- done? )
     COUNT R/W OPEN-FILE IF DROP FALSE EXIT THEN
     LVALUE FILE-ID
     LVALUE BUFFER-LEN
     LVALUE BUFFER-ADDR
     whatever needs to be done else
     BUFFER-ADDR BUFFER-LEN FILE-ID WRITE-FILE
     and so on
  ;

well, this program does nothing so complex that it would require the use of locals to enhance readibility and maintainability. Just get the idea that we did more that the pure ANS Forth locals can provide for. However, be aware that PFE does not do sanity checks so far - putting an LVALUE inside a LOOP would not be that wrong (it would just reinitialize the value at that point over and over again) but the size argument to LBUFFER: is taken at runtime, and the needed space is carved from the return stack just then. Running this one inside a LOOP or mixing such a declarator with words that affect the return-stack (like >R or R>) could lead to undesired effects that are not warned for at compile time.

Looking close at LBUFFER: a C programmer could compare the functionality to that of alloca(). The declared name is actually a simpel LVALUE that will be assigned space carved dynamically form the return-stack - and automatically FREEd on any EXIT point in the function since the LOCALS frame is given back. This can be used to change the habit of many programmers to write non-reentrant forth words whenever a local buffer is needed, for instance to combine a file name with a prefix in a local string buffer.

Looking at the ANS Forth standard, one will find another reason for this habit since the standard does not require the return-stack of forth to be very large - that was done so the complete return-stack could be left in some hardware on special Forth CPUs - the threading model of forth does benefit a lot from call/return optimizations on the CPU, making it a lot faster. And if you look through the ANS Forth documents, you will see that there is no requirement for RP@ to exist, or that any item on the return-stack has an address. All this is purely optional. However - all the forth system running inside a host OS on general-purpose CPUs will provide a proper return-stack plus and the availability to take references of the values put there.

Using POCKETs

There is another way to help around the problem of a temporary string buffer to do some concatenations and splitting - it is traditionally called a POCKET. The first forth systems had just one such global string buffer that was reused in every word. Of course, that could easily to lead to problems with a word using it and calling a word thereafter that uses the POCKET too. Plus you can not have two string buffers with a single POCKET.

That's why quite some forth systems started to provide more than one POCKET, and a developped system like PFE provides a word to automatically access each temporary buffer in a round-robin fashion to lower the potential problems of called-words to overwrite the current buffer. Be aware that this can still happen here, and that many of the PFE system words do actually use the dynamic POCKETs internally to lower the return-stack pressure.

The word to get a new POCKET is simply called POCKET-PAD to remined you that the returned pocket buffer is not exclusive to the function requiring it. And it is sometimes a good idea to put this address directly into a LOCAL value to have name for it. It will look like this:

  : MY-WORD ( filename -- )
    POCKET-PAD LVALUE filename
    S" /prefix/path" filename PLACE
    count filename +PLACE
    (USE-WORD)
  ;

and please notice how used the pocket-pad for just a short time to construct an argument to (USE-WORD). This is the recommended use, since it is hard to guess what some of the called words in MY-WORD will actually do, and whether they request POCKETs too, and finally getting hold of the same one that was used here. In most of the forth programs one can come up with a good expected value of POCKET allocations in lower words however, and a pocket-pad does lower memory pressure quite a bit. And a POCKET method scheme can be easily ported to systems that have a non-addressable hardware return-stack.

Special Implementation Strategies

Environment Vocabulary

The ansforth'94 standard describes a word to detect features of the forth environment. Forth scripts can use these hints to check whether the forth system is appropriate, and in some cases the script can try to use a different compilation path. However, the forth standard does not describe a way to extend the environment-hints - the 'environment?' word can only return the values. This is preventing a forthscript library to implement missing features, and advertise the newly gained system feature to independent application programs.

In december 2000, the developers of gforth (Anton Ertl), win32forth (Tom Zimmer) and pfe (Guido Draheim) agreed on a common approach for environment-query extensions based on a proper vocabulary named 'environment'. The implementation of 'environment?'-queries is based on a 'search-wordlist'-call. If the search fails, 'false' is returned, if it succeeds, the returned execution-token is 'execute'd and a 'true' flag is placed above.

 : ENVIRONMENT?
   ['] ENVIRONMENT >WORDLIST SEARCH-WORDLIST
   IF  EXECUTE TRUE ELSE  FALSE THEN ;

The environment hints themselves are implemented by adding word definitions to this vocabulary, in most cases these are 'constant' or '2constant' definitions.

 also environment definitions
 1994 constant locals-ext
 false constant /floored
 32 constant max-files
 -1 -1 2constant max-ud
 previous definitions

This implementation strategy allows also to place internal variable/values into this vocabulary that can be easily referenced in the actual implementation by simply placing the environment-vocabulary in the search-order (by using the name) and to let the outer interpreter see words like '/hold' and 'max-files' directly. In conjunction with the tool-ext's 'words', the user can get an overview which system features are available.

 environment words ( returns: )
  C GFORTH-DIR              C SYSTEM-EXT              C CLK_TCK 
  p PFE-DEBUG               C FORTH-83                p PFE-VERSION 
  p LICENSE                 p HOST-SYSTEM             C ENVIRON-EXT 
  C STRING-EXT              C TOOLS-EXT               C MEMORY-ALLOC-EXT 
  C #LOCALS                 C LOCALS-EXT              p MAX-FLOAT 
  p FLOATING-STACK          C FLOATING-EXT            p MAX-FILES 
  C FILE-EXT                C FACILITY-EXT            C EXCEPTION-EXT 
  p MAX-UD                  p MAX-D                   C DOUBLE-EXT 
  C BLOCK-EXT               p RETURN-STACK-CELLS      p STACK-CELLS 
  C MAX-U                   C MAX-N                   C MAX-CHAR 
  C FLOORED                 C ADDRESS-UNIT-BITS       C /PAD 
  C /HOLD                   C /COUNTED-STRING         C CORE-EXT 
  C CHAIN-WORDLISTS         C WORDLISTS               C SEARCH-ORDER-EXT ok 

In pfe, the reduced question is also fullfilled by an "-EXT"-hint in the environment-wordlist, i.e. a call like

 s" core" enviroment? .    -1 ok   

returns true since it matches the 'core-ext' hint. This is a kind of convenvience behaviour.

[defined] / [undefined]

Another issue in forthscripted librarysections is the question whether a specific word is already present. The ansforth'94 standard describes the precompiler-like [IF]-[ELSE]-[THEN] words, however it is not described how to reliably deduce flags for these. A discussion on comp.lang.forth revealed, that even the set of 'find' and 'search-wordlist' is not so strictly standardized to accomodate the need for these ifdef-words.

Over time, every forth system has implemented means for a precompiler-type ifdef-section. In pfe, the early tek-mforth ifdefs are present in a seperate cdecl-ext wordset that does implement a subset of a C-compiler's precompiler words, including '#ifdef-#else-#endif' and '#define'. Other forth system have implemented '[ifdef]'-words, however these words do all suffer from having no easily portable implementation - with the greatest problem that the standard-implementation of '[if]-[else]' must count [if]'s and [then]'s to detect proper nesting. A system which had no [ifdef]'s does not see a newly-defined [ifdef] in the execution of [if].

Therefore the usage of [ifdef] should be depracated. Instead an independent word should be used to construct the flag for [if], and from the reference to the Forth Programmers Handbook (FPH), many forth system have chosen to use the terms [defined] and [undefined]. Note that some systems still use 'defined' (which is not immediate) or 'defined?' or 'have?', or perhaps they have '[not]' instead of the '[undefined]'-call. However the pair [defined]/[undefined] has found widespread acceptance and it is therefore implemented in pfe along with the [void]-call to place a reliable immediate false-flag for usage by [if].

 [void] [if] 
    here can be any text as this if can not get true.
 [else]
    [undefined] rdrop [if] \ check for non-existance of a word
       [defined] r>drop [if] \ but found a synonym
         : rdrop postpone r>drop ; immediate
       [else]
         : rdrop r> r> drop >r ; \ this is not standard-conform
       [then]
    [then] \ the standard- bracket-if/then call is properly nested
 [then]

Although these words are not (yet) standard, with some knowledge about the target systems search-order implementation, a highlevel definition of [defined]/[undefined] can be created that does properly work with the system-provided [if]/[else] construct. About twothird of the mature forth systems do already have the [defined]/[undefined] pair, so that their usage is reasonably portable across systems, and application software can be assured to compile in future system implementations.

state-smart over exec-only

Older forth system have often used a single word for doing both, exec-mode and compile-mode. In exec-mode, it would leave the parsed-value of the following word on the stack, while in comp-mode it would compile an execution-token and the value in a way that the value would pop up at runtime again. The ansforth'94 does however prefer to define two words, one for exec-mode and the other for comp-mode, so they are not state-smart anymore. In some compiling-environments (with preprocessing functionalities) this may eventually be a nice win, however it does sometimes confuse the the average forth programmer. The programmer can not anymore use a word on the commandline, and when satisfied enclose it into a ":"-";"-pair to memorize it as a colon-sequence.

In pfe, some of the immediate or exec-only/comp-only words have been extended to be state-smart. Where the ansforth'94 will make the behaviour of the word rather undefined or not applicable, in pfe it is just state-smart, and it will hence behave in traditional ways. The traditional forth programmer has simply to watch out for the cases where a newly-invented word from the ansforth'94 standard has been overloaded instead of the traditional word which had somehow been defined to be just not state-smart.

  .( whatever ) \ not state-smart, immediate
  ." whatever ) \ state-smart, orginally comp-only
  '             \ not state-smart, not immediate
  ['] name      \ not state-smart, immediate & compiles always
  '> name       \ state-smart version
  char woo      \ not state-smart, not immediate
  [char] woo    \ not state-smart, immediate & compiles always
  ascii         \ state-smart, very common in forth systems
  control       \ also state-smart and very common. Subtracts 32.

Quoted-Parse Idea

Part of the LGPL:ed PFE

Trying to get new people into the forth arena has a big problem: forth is an unusual language. That makes people afraid to get in contact with it. Some people that I've talked to said that they can not program very well but they've learned some language once and now they can atleast "read" program sources and understand what is going on, perhaps even fix little bugs and correct misleading comment blocks.

In today's world, most people will have learned a language being somewhat C style - may that be even Java or Javascript or C++, even Perl has borrowed some syntax from this arena. That lowers the fences to get involved - so people just see the source code and ask "what's different".

When people look at a forth program first, they won't see much things they already know. They will feel some more comfortable if you remind them of a programmable desktop calculator (including the unix standard program "dc"/"bc") with its numbers and the operators in postfix position. People will then be able to grasp the idea of values on a stack. So far so good - soon they can read forth sources, as they see "3 2 *" and know it's 6.

However, at one point they are strongly mislead - with the forth string literals. Even languages being not C have gone to adopt a common notion of writing string literals - being enclosed in quotes and non-printables (and quotes themselves) can be embedded by prepending that char with a backslash. One has to point that this is the case for almost all contemporary programming languages in use.

But forth is different. One of the most Frequently Asked Question is "how can I embed a doublequote into a string literal". And the other is that people to constantly make programming errors as they forget to include the leading space after the leading doublequote. It is pretty obvious that forth as a builtin notion of integer literals but not of string literals - string literals are not in fact outer-interpreter literals but the result of parsing words.

(hint: openboot presented "H# F01A" to express hex number literals with parsing words, so it was a deliberate choice to include the integer literals into the outer-interpreter but leaving out the string literals).

Well, the deed is done. Including a string-literal notion into the outer-interpreter woulf make forth not being quite forth anymore but just another forthish variant. After some attempts of extending the outer-interpreter, I came up with the idea of a quoted-parse extension that can be even switched on/off as one wishes.

The normal PARSE word ist left as is. But for the use in the outer interpreter, most ANS Forth system will have implemented a form of PARSE-WORD (described in the annex of the forth94 standard) which skips leading spaces and parses away the next word. This word is extended with the quoted-parse idea. Currently, a PARSE-WORD will stop at (a) the end-of-line, leaving IN just after the last valid char (b) the next whitespace, leaving IN just after the whitespace (and one char beyond the last valid char). With Quoted-Parse it will also (c) stop just after the next doublequote char returning including it into the returned string - which is different from the whitespace handling which is not returned even that the IN pointer is left pointer after it.

  S" hello world" cr type
  hello world ok
  true to QUOTED-PARSE?
  S" hello world" cr type
   hello world ok

One can of course make-over the S" and C" implementation to chop away the leading blank they get when the Quoted-Parse mode is enabled, just to be fully backward compatible with traditional forth sources. However, one is free to define similar words that will leave the space that follows the opening doublequote, so they people "will get what they see" between the doublquotes.

Many forth systems implement zero-terminated string literals to make it easier to interface with a C-based operating environment. They even implement backslash-interpretation - the two words are mostly called Z" and Z\" respectivly. Now imagine that we make a word similar to the latter one, and let it do a true Quote-Parse. A text could then look like

  cr 1 .H "x" ztype 2 .H
  1x2 ok
  cr "hello\nworld" ztype
  hello
  world ok
  cr " you see \t this?" ztype
   you see       this? ok

All this is compatible with traditional forth - the ["]-word is not part of the outer-interpreter, it is still a parsing word but one with a name that ends in a doublequote and therefore ensures that the next char in the input buffer to the outer-interpreter is not chopped away automatically, so that the next PARSE can still find it there ready to be taken.

The only incompatibility that arises: you can not define colon-words with a doublequote in the middle or starting with it. You can only define new colon-words that end with a doublequote and all these do have the implication that the outer-interpreter will leave the IN pointer just after that word when being encountered in the input stream. That will affect a (small?) fraction current forth programs but it should be easy to fix the places that are in conflict with the Quoted-Parse idea.

On the upside you are free to implement a whealth of new parsing words that will look like type-prefixed string-literals. Even newer C-type languages know the U-prefix for strings to denote unicode- encoded string literals. That can be achieved with a parsing word in forth - no need to extend the outer interpreter and you still can make it look just alike the model in those languages that known unicode string literals in its basic syntax.

  : U" [char] " PARSE (unicode-literal) COMPILE, DUP W,
       DO DUP I + C@ W, LOOP DROP ; IMMEDIATE
  true to QUOTED-PARSE?
  U"hello world" cr wTYPE
  hello world

  ( and a definition for H" to bring in a hex-literal )
  H"F01A" cr .H
  F01A

As a last note: when you have enabled Quoted-Parse, be sure to remember it also on creating new colon-words as the ":"-word will usually not call PARSE but a form of PARSE-WORD to have all leading spaces be skipped and not included in the resulting NAME of the created word. It stops after the first doublequote.

  : add"1 + ;
  ( this is not similar to )
  : add-1 + ;
  ( but it is similar to )
  : add- 1 + ;
  ( and here you might get a "redefined" warning )
  : C":: [char] ; PARSE ... ;

The question is now: when leaving quoted-parse the default on startup of a system, can it be called still to be basically a normal forth? Do some propaganda to make it the default? A default that can be checked for with an environment-query in standard-forth of 2006 ?

PFE Threading types

CFA Threaded

CFA Indirect Threading is the usual way in PFE and the traditional variant being the only one compatible with the FIG model. A colon word is a list of CFA addresses where the CFA contains the address of a C subroutine and the BODY of this word directly following this Code-Field (where CFA has its name from, the body being referred to as the Parameter-Field (PFA).

 NFA       LFA      CFA       PFA
 +---------+--------+---------+-------
 | name[n] | link*  | code*   | data....
 +---------+--------+---------+-------
            nextNFA  C call    body(only for non-prims)

The DOES words will put a DOES-subroutine into the CFA of a CREATEd word - this DOES-subroutine will use the first PFA[0] field to get the indirect address of the real (modified) behaviour of the word. The DOES_CODE field exhibits itself as just another CFA directly followed by its DOES_BODY. The current TO_BODY will detect the situation for a DOES-word and return DOES_BODY when someone asks for the BODY of a DOES-word - which means to return the address of PFA[1] instead of PFA[0].

 NFA       LFA      CFA       PFA[0]   PFA[1]
 +---------+--------+---------+--------+-------
 | name[n] | link*  | code*   | does*  | data...
 +---------+--------+---------+--------+-------
            nextNFA  do-does()

Before the DEFER words (including DOER/MAKE) became part of the inner system, they were just DOES-words who stored the DEFERred execution vector in the DOES_BODY. Therefore, the current implementation will store the IS-vector in PFA[1] of a DEFER-word. This is in contrast with the behaviour of the TO-var word which will store its value into PFA[0].

 NFA       LFA      CFA       PFA[0]   PFA[1]
 +---------+--------+---------+--------+-------
 | name[n] | link*  | code*   | unused | target
 +---------+--------+---------+--------+-------
            nextNFA  do-defer()

CALL Threaded

Call-Threading is a newer model for execution. The colon word is a list of addresses of C subroutines. As long as theses are primitives (without a BODY area) it will obviously be as double as fast in execution since there is on memory access instead of two in the CFA Threading model - the latter would have to fetch the CFA from the colonword and the C subroutine address from the referenced Code-Field - while in Call-Threading it would just have to fetch the C subroutine address and use a normal indirect function call to get it executed.

However this would not quite allow parametric words other than in the Direct-Threading case - in Direct-Threading the BODY would be be prepended with a longer Code-Field which contains a complete subroutine as if assembled by a C subroutine compiler. Therefore in the Direct-Threading case, the inner interpreter could again just jump there as it would for primitives. Most of the Direct- Threading systems would just jump to the real common behaviour of the BODY-word - via the typical IP[-1] we still get the original CFA and can derive the PFA = IP[-1]+CodeFieldSize - where the CodeFieldSize is usuall larger than just a pointer since it would consist of cpu-native jump-instruction followed by the behaviour address compiled by the C compiler.

Well, this explains the model of Direct-Threading which would not be quite portable since it assumes knowledge about the cpu-native jump-instruction which would have to get pasted into the data-area of the application which gets then executed as code atleast for the CodeField part. On processors with different on-die caches for Data and Code, this would yield to considerable cache-thrashing, and some Forth implementations tried to overcome the problem by ensuring that the corresponding Data-area of a Direct-Threaded BODY-word gets put a bit away - with the distance being the cache-line length in the Instruction-Cache. Which of course assumes another set of knowledge for the underlying native cpu architecture. Therefore: Call-Threading is not Direct-Threading.

To enable BODY-words in Call-Threading we use another trick - for each BODY-word, an XT-compile ("compile,") will detect the situation and compile two addresses. The first one is the C-subroutine of the common behaviour of the BODY-word directly followed by the BODY-address of it. The behaviour-subroutine will then just have to fetch that BODY-address away so that the inner-interpreter will have its IP put onto the next real C-subroutine (and not a BODY-address). That's why you will see those POP_RT_BODY in each of the _RT-routines in the forth-implementation which will be a (*IP++) in Call-Threading model. Unlike the Direct-Threading model, the Call-Threading model is portable: the "compile," word will simply copy the address contained in the CFA to the new colonword and then add the BODY-address right thereafter.

  VARIABLE XX
  : AA XX @ ;

  in ITC mode (indirected threaded via CFA subroutine calls)
  | name... | link | code'do-colon | cfa'XX | cfa'@ | cfa'; |
    n bytes   LFA    CFA             cell     cell    cell
  
  in CTC mode (call threaded with conditional body pointer comma) 
  | name... | link | code'do-colon | code'do-var | pfa'XX | code'@ | code'; |
    n bytes   LFA    CFA             cell          cell     cell     cell

One could think that one would be able to mix FIG-style CFA-Threaded colonwords and PFE-style Call-Threaded colonwords - the outer interpreter could in fact do both and runtime switchable - we would just have to swap the behaviour of "compile," while the rest could effectly stay the same. However, we can not do this in full FIG-style mode - the outer interpreter's "compile," word does need an additional information about each word telling whether it is a primitive or a body-word. As a side note: of course, a simplistic approach would just always add a body-field for each call and the inner interpreter fetches the code-address and the data-address (even when the data-adress is just null). But this would simply make two memory-accesses for all words including primitives and there is no benefit over CFA-Threading here.

Instead, we use an extra bit in the FlagField of each word which gets set when the word is not-a-primitive. In the pfe C-level sourcecode you will see two words for creating a HEADER: FX_HEADER and FX_RUNTIME_HEADER where the latter is just a combination of FX_HEADER followed by FX_RUNTIME_WORD where this one will just set a bit in the LAST word and this bit being called P4xISxRUNTIME. - Now, the "compile," word will check the FlagField for ISxRUNTIME being set, and only in this case a BODY-address gets compiled. When no word has this FlagBit set then a Call-Threaded colonword will just be a list of C-subroutine addresses.

This makes it a very fast implementation - each primitive gets called with just an indirect-functioncall (instead of a double-indirect one), and only BODY-words will use more memory-accesses, which they would do anyway since they will surely access the data in their body. However, there is even another surplus - it makes it easier to have forth integrate with C-level projects since we are now able to construct new colonwords directly in C without the help of an inner interpreter or even "compile,". The C-level app would just have to create a list of function-pointers, adding body-address for each reference to an _RT-named routine. When the C-level-created forth-colonword has been created (as a ":noname"-colonword) the it can just be p4_call'ed.

(FIXME: stick note about implemenation of DOES-words and DEFER-words in here)

SBR Threading

From aboves model for Call-Threading we can now derive the model for SBR-Threading - there is only one difference between the two here: in SBR-Threading each of the CALL-addresses gets prepended with the cpu-native bits for an SBR-functioncall. And be noted: on many RISC- machines these bits are mangled into the CALL-address itself, usually the upper four bits so that on a 32-bit machine only the lower 28-bit addresses are reachable for CODE jumps. On machines like the i386 architecture, the cpu-native SBR-functioncall is a single byte (9E) so the code-size will increase by another 25% (CFA-Threading vs. CALL-Threading had increased the executable size by about 20%).

This derivation is largely different than SBR-Threading derived from Direct-Threading - and it does more closely follow the nativecode scheme for creating BODY-words like accessing Variables and Constants. The nativecode would just put another cpu-native bit followed by the address of the Variable to fetch. This leaves room for a nativecode optimizer which could replace the sequence (call-nativecode + varfetch-routine + vardata-address) by an optimized sequence of (varfetch-nativecode + vardata-address).

The same optimizer can be used for DOES-words: the sequence of (call-nativcode + doescall-routine + doescode-address) could get replaced with (indirectcall-nativecode + doescode-address). The doesdata-field is still easily derived as it still follows the doescode-field.

And a note about DEFERred words - without Direct-Threading, a deferred word will be executed as a doublyindirect call and there is no cpu-nativecode for that. Actually, this is good since a) we want to have the DEFERred vector to be no in the first paramfield and b) we want to check for null in the defervector and warn instead of segfault (or call a routine that CRASHes).

  VARIABLE XX
  : AA XX @ ;

  in CTC mode (call threaded with conditional body pointer comma) 
  | name... | link | code'do-colon | code'do-var | pfa'XX | code'@ | code'; |
    n bytes   LFA    CFA (a cell)    cell          cell     cell     cell

  in SBR mode (subroutine threaded with cpu-native SBR assembler snippets)
  | name... | link | colon-info | SBR-setupcode | .....
    n bytes   LFA    to infoblock (nothing on x86, 16bytes on powerpc)

  .... SBR-call + code'do-var | pfa'XX | SBR-call + code'@ | SBR-exitcode |
       1 byte   + cell          cell    1 byte   + cell     1 byte (12 on ppc)
 

SBR-ARG Threading

The above code will make do-var to fetch the following pfa'XX address from the colon-word with an extra call, thereby adjusting the subroutine return-adress to point to just after the body-arg. This will make some CPU variants picky where the L1 cache is divided into Code-cache and Data-cache. In CTC-derived SBR-threading it means alternating access as Code and Data, and some K6 are known to be panicking as soon as they see a Data-access of an address in the Code-L1-cache and do a complete flush of the Code-cache.

The solution uses arg-threading. Instead of the do-var code implementation to fetch the body-adress being compiled after its call, the SBR-ARG threading will compile an immediate arg-push before the call - which is actually the pfa-address prepended with an SBR-snippet to push it into the right place. The called do-var routine can then just use the value in place.

  in SBR-threading
  .... | to infoblock | .. | SBR-call + code'do-var | pfa'XX | ...
         cell           0    1 byte   + cell          cell

  in SBR-ARG-threading
  .... | to infoblock | .. | SBR-push + pfa'XX | SBR-call + code'do-var | ...
         cell           0    1 byte     cell     1 byte   + cell
 

Even that we consume yet another byte more, the code will actually run faster on many CPU types - but it depends on the actual implementation of the L1 cache. Another problem is to find a place to bring the value from the colon-routine into the do-var routine without the C compiler to trash the place innocently during its SBR setup. Using a register with the gcc fixed register allocation is one means and often a good one.

extra RP or not

On a register-starved architecture like x86, it helps greatly to use the CPU-native SBR-code. These are very fast calls specialized to make a subroutine call. However an architecture like powerpc does not have any specialized subroutine-call instruction, and the return-stack can be referenced from any of its CPU registers.

The problem with the CPU-native SBR-code and RP-register has to do with the habit of forth programs to use to-RP and RP-from instructions to move values from and to the return-stack as temporary values. This will require the implementation of these routines to pop-off the return-address, push/pop the value, and put the return-address back. That can heavily interfere with what the C compiler assumes about the RP depth, not to speak of some CPU architectures to have a special return-address cache that will get flushed hereon.

Instead one make up a three-stack machine, where colon-word return-address are stored on another stack than the C compiler will assume them for. It makes it quite the same as the normal token-threading but the address-tokens are interpreted with some native-code snippet - just not the SBR-call snippet but some other - and it is still native-code SBR threading.

Porting SBR-Threading

This part does not deal with simple SBR-CALL threading and concentrates on the fast-threading mode using SBR-CALL-ARG threading where it is assumed that the called C-routine will get the BODY-ptr as an argument and the CODE-ptr can be given as an argument via the same way.

Choosing an ARG-register

The ARG-register should be a scratch-register in the local ABI (application binary interface - the description about the structure of call-frames and the registers possibly affected by all into a routine) - if you choose a callee-saved register then it has the effect that the compiler will generate some code in the procedure header to save away that register to the return stack which is absolulty unncessary and possibly counterproductive.

About all cpu ABI do know some scratch register for local computations whose value must not be saved with a procedure and whose value may also not be assumed to be left untouched with an intervening function call. The latter limits the possible use of the value in that register and one should better check if the compiler is clever enough to save value around function calls - there are numourous bugs in compilers for such explicit register allocations.

When looking for a scratch register, the ABI's return register is often a good choice since all the forth words are void-routines. The return-register is generally considered to be touched by function calls, so it falls into the category of a real scratch register. However, the return-register is often the accumulator of traditional cpus, and in many cases that cpu ISA (instruction set architecture - the possible instructions and which registers they can take for operands) must take this register for some instructions to be possible. In most such cases, the displacement- register might be an alternative.

Looking at the current choice, the "%eax" accumulator register is chosen on i386 which actually works, so one does not need to look at the "%edx" register. For the m68k, the return-register "%d0" is not a good choice as the ARG to the routines is always a pointer that points to the actual data - the pointer is used to fetch data with constant displacements, and it is incremented by one cell in many cases - the m68k has some optimized opcodes for these address operations but which work on "%a*" registers only. The compiler would therefore move the "%d0" arg to the scratch "%a0" register for operations. The latter however is not a good choice either, since the compiler does want to use it for indirection function calls like "(*)()" on C level, and does not push it elsewhere. However, the "%a1" register showed to be also a scratch register in this ABI, and it works. Similar decision chains can be made for the powerpc ABI where the "r0" register is used for many hardcoded temporaries, and "r1" is used for the program return stack. Using "r2" succeeds here.

Be aware of the diffences between an ABI and an ISA for a given cpu - in the def-regs section, we do currently one differentiate by cpu-type, which does match with the ISA type. Most cpu makers hand out docs about the recommended ABI for their processor, and in most cases they are overtaken - which leads to a single matching ABI. But this one-to-one relationship can not be assured, see as an example the powerpc ISA which has no dedicated register for the return-stack (it does not even have a dedicated instruction for subroutine calls) and any of the 32 general registers can be used as the stack pointer for an ABI on top of this ISA.

Traditional CPU

A traditional CPU however has a dedicated CALL instruction, a register to save the return address, and a RTS instruction to return-from-subroutine. In this mode, it is best to alias the forth RP and the cpu RP - the current IP in the caller's routine can be deduced by looking at the value in the return-stack. This mode saves these two registers from being needed to be assigned globally.

The RP is declared locally within the USE_CODE_ADDR macro in the C-sources, and the RP value is given as the ARG to this routine (_XE routines in the sources). The current forth-RP is simply the value of the cpu-RP before the call instruction which pushes the IP on the very same stack. Within the _XE routine, the IP can therefore be modified and by using RP[-1] (in general, the offset is indeed just minus one - but most ISAs know some flavour of calls that saves more data to the stack, e.g. call-interrupt-handler).

In this mode, the RP-pointer itself must be left constant since otherwise the CPU will not find its return-adress on the stack. When some _XE routine needs to modify the RP, it must ensure to save the return-address (the IP value), then modify the RP (PUSH, POP, ROOM, DROP), and then restore the return-address as the uppermost value of the real cpu-RP. See the _NEW_RP macros around that handle this problem.

To change the IP alone, one can simply write to the value inside the call-frame - the next RTS will find that value.

As an example, take a look at this m68k assembler of the IF-execution which knows that directly after the IF-call a target-address follows which points to the resp ELSE. Here we chose the "%a5" register to hold the forth parameter-stack:

0000095e _p4_if_execution_:
     95e:       4a9d            tstl %a5@+
     960:       660a            bnes 96c
     962:       2069 fffc       moveal %a1@(-4),%a0
     966:       2350 fffc       movel %a0@,%a1@(-4)
     96a:       4e75            rts
     96c:       58a9 fffc       addql #4,%a1@(-4)
     970:       4e75            rts

reading it: pop the value and test it, if it is non-zero, jump to 96c which skips the target-address by advancing the IP by one cell. The %a1 register has been given as an argument and points into the real return-stack just below the return-address of this function - the add-instruction on "%a1@(-4)" is therefore identical with "%sp@" and you can read the code as "addql #4,%sp@" to modify the address that the following "rts" will jump to. The same accounts for the false-case - here we just fetch the value at the caller's IP which has the target-address, and then store this value into the IP so that the following "rts" will find the new value and BRANCH to it.

One might be tempted here to tell the compiler to just use "sp@" as the IP value, but this is only true if the compiler did not generate a local variable frame - in which case the "sp" would be well above the address of the return-address. The gcc supports the __builtin_return_address but it is not an lvalue, so it can not be modified nor can one take the address of it, and the other __builtin_frame_address is known to carry wrong values when compiled as -fomit-frame-pointer and the local function did not need a frame for real. Therefore, it is safest to just pass down the sp-value from just before the call to the routine and get the IP as RP[-1]. It just needs to put another opcode before the CALL-part to the _XE routine, representing "movl sp, a1" on m68k.

RISC w/ LR type CPU

The powerpc architecture does no have a dedicated return-stack or instructions to call a subroutine or return from a subroutine. Instead it has a special Link Register (LR) and the subroutine calls are derived from the branch-instructions. The branch-instruction (with the L-bit set), will first copy the next code address to the LR and then jump to the target. The code at the target address will then be responsible to fetch the value from the LR and store it on the stack - in the presented case, this stack is referenced by the "r1" global register. The same is done on return-from-subroutine - the return-address is restored into the LR and then a "blr" = branch to address in link-register is compiled.

Therefore, the setup sequence for a new procedure is quite long and simulates the behaviour of a single CALL-instruction on traditional CISC architectures - the same happens as a simulation for the RTS-instruction. This is good practice but imposes a serious problem: how to define the IP. On traditional ISAs, the IP will always be right above the last good RP value, but in this mode, the return-address is nothing more than a local variable of the called routine.

Furthermore, even very simple functions will actually have a local-frame, where they will store the RP of the previous caller, so that the current cpu-RP value is not actually the pointer to the forth-RP data - again, some assumptions may break here if just adding a displacement or trying to fiddle with that __builtin_frame_address - and an RP-change is even more problematic as not just one cell must be saved before the change, but the whole locals-frame of the caller and the callee routine.

It took several hours of experimenting that there are always cases that it will fail to describe the forth-RP as an alias of the cpu-RP. Instead, it is best to not alias the two, and allocate a separate forth-RP as a global register allocation

It turns out that this makes the setup-code for a colon-routine even shorter and faster as we are not bound to the system ABI - in the example powerpc ABI it became visible that the system ABI did usually save the return-address into a place in the callers stack-frame - that simply means that such RP space must be reserved when calling any of the primitives compiled by the C compiler. Using an extra forth RP, we do not need to deal with these specialties, and keep the setup-code down to the minimum.

Since the forth-RP is an extra independent global register on the powerpc, another question must be answered - where to get the callers IP from. One way might be to give it as an ARG to the routine, in the place of the RP that would be normally pushed down, but it happens to be not necessary - instead of suppling some setup-code in the colon-routine just before the call into the forth-subroutine, the IP arg can be setup within the forth-subroutine by creating a copy of the special LR-register in a general-purpose register where it can be easily accessed and modified. The lead-out code then pastes move-arg-to-lr and branch-via-lr into the C-routine (you may notice some garbage left over in the assembler output since the C compiler will then still compile its own lead-out code containing another branch-via-lr).

Summary

To alias the forth-RP and the cpu-RP has the advantage of saving another cpu register for local computations - and on a register-starved ISA like intel-32bit, this happens to an essential requirement for good native speed. The contrary is true for an LR-type RISC cpu where the ABI's locals-frame interferes with the forth-operations on an RP-stack. A CPU with enough cpu general registers and traditional return-stack ISA might choose either way.

Literature

A few references to to helpful information.
The Forth Programming Webring
starting at zForth.com currently a yahoo.webring :
The Comp.Lang.Forth Newsgroup
where all forth system implementors are. The newsgroup archive is a very useful resource. From time to time, people extract some relevant information, e.g. at the sourceforge' comp.lang.forth.repository or Peter Knaggs' Forth Research Page
The 4TH tutorial
A very good online tutorial - 4TH is an ansi-forth compatible forth system, so the tutorial should work fine for PFE users too. see 4THtutor
Taygeta Forth
Taygeta has taken over much of the work what FIG' forth.org should have been for - it will provide you with a lot of information about forth, and the ftp-space hosts about every piece of free forth snippets you can find. see taygeta.com/forth
Koopmann's Stack Computers
The book is a little older and definitly not for newbies but it still serves as good reference to stack computer theory. see his website and download the book.
Structure And Interpretation Of Computer Programs
a more general book mitpress.mit.edu/sicp/full-text : ISBN 0-262-01153-0 (MIT Press hardcover) : ISBN 0-07-000484-6 (McGraw-Hill hardcover)

Dirk Zoller's README

Note

Here is the README file that belongs to version 0.9.10 of November, 24 1994 of the Portable Forth Environment. (written by Dirk Zoller)

What is it?

This package contains all neccessary ANSI-C source files to build a running Forth-environment on most UNIX machines, on DOS and on OS/2.

The Forth-system is closely modeled along the new American National Standard for the programming language Forth. With the exception of the assembler words I implemented every word of every word set mentioned in the dpANS-6 document of june 1993. Additionally it is compatible to Forth-83.

Legalese

This set of source files is distributed under the GNU general public license for libraries. See the file <file>COPYING.LIB</file> for conditions.

I chose that one to point out that I don't consider programs you write on top of it a `derived work' of the portable Forth environment. To violate these conditions you have to do two things together:

  • you use a modified pfe to run your program
  • you distribute this program keeping the modification secret

Should be easy to avoid.

Why did I do it?

For fun. As an excercise in unix programming. And there was no such thing. See below, design objectives.

Design objectives

With two elaborate standards at hand, one for C, one for Forth, it should be possible to build one language in terms of the other and thus provide both where at least one is available.

While I leave the writing of an ANSI-C compiler in Forth to those who really believe in Forth's superiority and universality, I concentrated on the manageable part: Providing a Forth-system in ANSI-C that is

CORRECT
this means not just "no bugs" -- it means all the interaction of all parts works as specified by the standard AND by traditions as far as I know about them.
COMPLETE
with powerful computers on the desk and power- ful programming environments there is no need to and no use in strategies like "here kernel, there xyz word set" that might be appropriate on a microcontroller.
PORTABLE
I hate to rewrite code because of environmental dependencies. Most of the system should be a mere interface between two well defined languages. There are of course such dependencies. I tried to resort to a common subset of all UNIX bahavior known to me. Fortunately this in fact allowed porting to DOS and OS/2 thanks to the great emx-package.
USABLE
A sole kernel helps noone. It should be a development environment. You should be able to manage multiple-source-file-projects from within.
SIMPLE
or transparent. At least to my taste.

Maybe you miss the design objective SPEED. It was not my goal to provide the fastest C-based Forth-environment. This would have led to conflicts with more important goals. We all have fast computers, haven't we?

After all pfe isn't slow. With a little tuning using GNU-C's global register variable feature it is pretty fast. On an ix86-based system it seems to run with about two thirds the speed of a direct threaded assembler Forth (eforth) i.e. benchmarks take 50% more time.

Status

Did I achieve the above objectives? Some of them. I'll continue -- slowly -- working on it.

The system is in use for eighteen month now. Several quite obvious and several quite subtle bugs have been fixed. While there surely are some more, they are not as obvious since the system passes several test programs, some of them rather sophisticated.

Once you get the system running, you'll have

  • All ANSI Forth word sets with the exception of the assembler hooks `CODE', `END-CODE' etc. Nothing else is missing.
  • Several more words provided for compatibility and convenience.
  • An interface to a text editor to edit plain text sources and the ability to include them.
  • A word star lookalike block file editor to write source in the old style block format.
  • A simple source level debugger -- maybe I should better say "single stepper".

Thus you'll be able to edit, compile an run programs in a moderately comfortable way. For the final design of the development environment your suggestions still are welcome!

If you try this system, please keep in mind that it is still under development. Sometimes new --even stupid-- bugs are introduced while enhancing functionality or while fixing old ones. I appreciate every hint to a bug and I fixed every bug I've been told about in the last months. So please don't hesitate to tell me about whatever seems wrong. Please check for the latest version via anonymous ftp from

	roxi.rz.fht-mannheim.de:/pub/languages/forth/pfe-?.?.?.tar.gz
 

(accessible from germany only) or

	sunsite.unc.edu:/pub/linux/devel/forth/pfe-?.?.?.tar.gz
 

Please send suggestions and bug reports via e-mail to

	duz@roxi.rz.fht-mannheim.de
 

UPDATE: The new PFE can be found at http://pfe.sourceforge.net which is maintained by Guido Draheim, send suggestions and reports via e-mail to guidod@gmx.de (the new website from Dirk-Zoller can be found at www.dirk-zoller.de)

Usage

For installation refer to the files `INSTALL' and `TUNING'. (update: the new pfe uses autoconf/automake, i.e. gnu-style)

Once you have it running and see the "ok" prompt after typing return you can interactively type in forth words. If you mistype, you can edit the command line and recall old command lines with the arrow keys. (If you can't then your termcap doesn't work all right and you can resort to wordstar-like control keys.)

To write some more statements try "EDIT-TEXT filename". This will invoke your favorite text-file editor on the given file. If it doesn't, first check the environment variable EDITOR, then check the file "const.h" for the #defined symbol "EDITOR". (update: the new pfe has the editor not builtin by default)

Having written some code you can load it by "INCLUDE filename".

If you prefer the old style block files, give a file to use as block-file with the -b commandline option. Alternatively you can say `USING filename' or if the file doesn't exist yet: `USING-NEW filename'. Then you can edit a block by `n EDIT-BLOCK'.

If your termcap-mechanism works well, the arrow keys and some other function keys should be active. Quit the editor with ^U and load blocks with "n LOAD". If it doesn't work well you might not even get a picture.

For more commandline options try the option -h.

The interrupt key is remapped to ^U (normally it's ^C) and leads back to the FORTH input loop. Use it to break out of infinite loops. If you find the ^U annoying see src/options.h for how to change it. I needed the ^C for the Wordstar look-and-feel.

To terminate the system, type BYE at the command-prompt or press the keyboard quit key of your system (usually ^\).

Documentation

I started writing a documentation in texinfo format. This will allow you to view it online or print it in good quality. There's also an outdated and hopefully soon superseded man-page that explains some of the command line options. All documentation is highly unfinished. (update: the new pfe uses docbook format to achieve the same goals)

For more information please try to get the dpANS-document, which is an EXCELLENT REFERENCE to this system! You can (could?) ftp it at ftp.uu.net in the directory /vendor/minerva/x3j14.

Recently the ANSI standard (or the last draft) bacame available as Word document and in HTML format. From a post of Norm Smith to c.l.f:


  "I have uploaded a new HTML version of the DPANS94 document
   to Taygeta.oc.nps.navy.mil. The contents are identical to the
   original posting. The new version, V2.0, has many more hyperlinks.
   Specifically, all (well, at least most :-) of the See: references
   are now linked. Anchors have been added for each section in
   my working copy. This will faculitate filling in many additional
   links in the next version of the document."
 

(update: the best place to view the dpans is the FIG's website at forth.org - see forth.org/dpans/dpans.html htmlpage)

Contributions

are welcome! After the kernel is finished now it makes much sense to share the burden of creating and improving a well rounded programming environment for all tasks a Forth programmer wants to do. PFE is YOUR tool. Get involved in it's design!

There is a mailing list on pfe which you should subscribe to if you want to be up to date with the development of the system. Send e-mail to duz@roxi.rz.fht-mannheim.de if you want to subscribe to that mailing list. (update: there is a new maintainer and a new mailinglist at pfe.sourceforge.net )

Acknowledgements

I want to express my gratitude to the people who put their efforts in the precise descriptions I found in these documents:

  • draft proposed American National Standard -- Programming Languages -- Forth (X3J14 dpANS-6, June 30, 1993)
  • FORTH-83 Standard (August 1983)
  • fig-FORTH Installation Manual -- Glossary, Model, Editor (Version 1.3, November 1980)

Thanks for providing superb development tools:

  • Richard Stallman and the FSF, Linus Thorvalds and all who contribute to Linux and Eberhard Mattes.

Several nice people on the net continuously gave me valuable hints to bugs and possible improvements, were patient enough to try the very first releases, made ports to machines I never saw myself and thus kept me from frustration. If pfe is stable now it is thanks to it's users. Most notably:


   Lennert Benschop, Sean Conner, Holger Dietze, Kevin Haddock,
   Rob Hooft, Giorgio Richelli, Marko Teiste, Guenther Thomsen.
 

Thank You.

Known Problems

There are a few problems that are reported by some users, and which are not that easy to fix for specific reasons explained here. In the tradition of other software makers, I'll call these problems to be problematic features, not bugs.

The Underline on ABORT

In the traditional pfe and in the case of an ABORT (or any other THROW that is not CATCHed), the simple approach was use that the current input-buffer was printed and a single "^" did mark the current position of the ">IN" pointer, which is the index within the input-buffer where the next PARSE will start off.

However, the gforth showed that it is better for the user to see the last WORD being PARSEd last from the input - that is, the whole last charlenght shall be underlined. That is almost simple since there is an internal SPAN variable in forth that gives us the length of the last PARSE value, and this SPAN variable is not transient (temporary in a way).

Now, what's the problem - the outer interpreter will PARSE the next word from the input buffer using a BL space. The PARSE will read from the input buffer until it hits either that space OR the end of the input buffer. If there is a space then the ">IN" index will be left pointing to the point one beyond that space, that is two chars beyond the last valid character of the WORD just parsed out. However, if the PARSE hits the end of the input-area, the ">IN" pointer will be just after the end of the input-area, that is one char beyond the last valid character of the word just parsed out.

Now, how to detect the difference - the difference whether an additional delimiter has been parsed away that was not seen by the word calling PARSE (or any other special purpose parsing function) and which therefore does not add to the SPAN returned. The answer is that it is very hard - we could add the heuristic that at the end of the input buffer we just add one, but there are very different input SOURCEs each having a different idea of the actual end (think of a block file that is read in one go), and it we would have to check the buffer whether there might be a single delimiter just before the actual end.

So actually, the real answer would be to place additional variables to the parsing functions that can be checked at the next THROW. However, it simply means to slow down the parsing functions a bit, and all of them must follow this standard to publish what they've been returning from the input buffer.

Here I took the decision to not add either of additional complexity in the internal parsing or execption facilities. Instead, (at an ABORT) the underline of the last PARSE simply shows SPAN+1 characters - inside the input buffer, that will include the delimiter just after the last WORD, and if we had been at the end of the input buffer, it will underline the word plus the delimiter just before the last WORD. That is good enough to give the user an idea what characters in the input buffer had been affected in the last PARSE - a human mind can easily subtract addtional delimiters before and after such a word, which is usually a space or a doublequote.

In the end, the PFE does now show the complete SPAN of the last PARSEd word without adding much of additional algorithmic complexity to the forth engine. That keeps the PFE code readable and maintainable at the cost of users who sometimes wonder why the space after word is underlined too. Well, now you know...

loading an INCLUDE-file at boot or on the command line

There is a difference between an include-file that is given as the bootscript to the pfe binary via the shell commandline, and the loading of the same file via "INCLUDE >file<" directly from the forth commandline. This is most obvious with the ORDER that is forgotten when being set in a bootscript as soon as it hits the the mainloop - when the bootscript has finished, the inner endless loop is setup and will run first through the QUIT-word and ABORT-word initialization sequences which includes a RESET-ORDER.

To give you an idea, here is what is going on: first the the forth dictionary is allocated, then it gets initialized from the wordsets being compiled into the main forth binary, then the bootimage is loaded, then the bootscript is loaded, then we look for APPLICATION and jump into it. The default APPLICATION is the forth-internal MAINLOOP. The mainloop does build a CATCH-domain around the traditional forth-routine QUIT. Calling QUIT will first go through some initializations that will ensure that the forth machine is in a sane state even when it is run again explictly or implictly from an ABORT that did end in the CATCH-domain of the MAINLOOP.

That's why you can not leave values from the bootscript on the parameter stack - they will be lost. There can not be any files left open from the bootscript either, they will be closed automatically. While that does not hurt many people, the case about the order-reset can be problematic in some cases as it might change the parsing behaviour of the outer interpreter as soon as the mainloop's QUIT is reached. To get around this, you can use the PFE-specific word DEFAULT-ORDER to explictly set the order that RESET-ORDER will see.

Shall we implicitly do a DEFAULT-ORDER after loading the bootscript? That might help us but in the real world there are far too many forth scripts that change the ORDER via a lot of "ALSO" additions starting off with an "ONLY FORTH" but they never call any "PREVIOUS" at the end as they expect that the next module script will do the same and start off at "ONLY FORTH". Furthermore, there is a basic differene between a bootscript and a normal include-file since the APPLICATION variable is only checked after the bootscript but not after each include-file. In a way the include-script on the shell commandline will not be loaded through INCLUDE but through BOOTFROM which builds on top of INCLUDE.

Just make sure that an application bootscript is ready to take this difference - one of the differences is also that any error in a bootscript will let the PFE instance simply die since there is no CATCH-domain inside an endless loop, and it is up to the APPLICATION to create a CATCH-domain and a PARSE-loop if needed. It could be that a forth program is only used as a filter for some input from the shell commandline so that it shall never reach the forth commandline. That is up to the bootscript to flag (well, you can also use the comandline option "-y"/"--bye" to let APPLICATION point to BYE instead of MAINLOOP).

After all - the forthscript on the shell commandline is not exactly the same as loading the same file from within the forth commandline. In general, there should be no difference, in other cases it might lead to some unexpected differences. Now you know why...

P.S. in the Tek/MPT embedded variant, there is no use for a PFE that quits immediatly, in fact it doesn't know BYE, it can just do a COLD reboot. Here the bootscript is sent to the PFE process via putting the resp. forth commands into the terminal input queue, so it is seen within the endless-loop, and all scripts will make use of the PFE-specific DEFAULT-ORDER word to ensure a good state at an ABORT.

Problems in 0.32.x

COLD does not reset ORDER ... A problem that existed since a change in 0.32.x and which should go away. It has to do with COLD going not deep enough due to the bootscript mechanics vs include-files.

Call-threading has no debugger ... new to 0.32.x are some more threading modes including SBR-threading. While the latter is largely unstable and not available on all platforms, the CTC threading however is completly portable and should be supported by a debugger too.

License

So, you want to know about the license. Well, no need to worry, the pfe sources themselves are under LGPL - the Lesser GNU General Public License - which gives you lots of freedom just as long as you ensure that the library itself compiles from sources that are completly under LGPL - whatever changes you do and whatever other code you link the binary version of it to. An often used feature is the ability to add binary modules that extend the forth system, there are enough hooks in the pfe system to allow to change many internal characteristics of PFE, good ways to add closed source functionality through a backdoor. And that's okay as long as PFE can start up and work correctly without it.

For the documentation, I think the FDL (the Free Documentation License) is more appropriate. Oh well, please now, let's stop about all these license issues - if you have a cool application for the library, just ask and we can arrange for a special permission. No need to do like gforth, where 10% of the documentation file is just for explaining the "protection" from licenses - well, some people would even copyright garbage just to protect you from using it in the wrong places. (and don't do that at home).

The only thing that needs some explanation goes about the question who does actually have a copyright. The answer is simple - every file in the library does usually bear a copyright/author line near the top of the actual source file. This is the owner. The owner may even give another license to the file - there is just the implicit right to link it into an LGPL library that the PFE as whole represents. Some files don't have an explicit copyright statement, which will not make them public domain, just some appropriate license is imposed from the overall PFE package. And the whole of the PFE has three copyright holders - where acutally the history of the project defines these relationships, and not some legalese.

The first author of the PFE has been Dirk-Uwe Zoller, the inventor of the project. He did start with PFE around 1992 and he did work on PFE up to about 1995 with 0.9.14 being the last version. Well, Stephan Wenk of Siemens did some patches up to 0.9.22 however his version had not been seen widely, and in fact the newer PFE stems from duz' 0.9.14. In fact, I did contact Dirk a few times over the years but he does not have an actual interest about developing a forth system anymore, however he sometimes checks the comp.lang.forth newsgroup for references. Lately he opened an extra website, just have a look at www.dirk-zoller.de

The second author of PFE is Guido Draheim, however he did choose the PFE for a project request by Tektronix Berlin in 1998, and he is paid by Tektronix Berlin to work on PFE - and therefore the second copyright goes to Tektronix. In the year 2000, the PFE had been actually released to customers of Tektronix, and since the PFE is under LGPL, the customers have a right to get access to the PFE sources themselves. Guido did now take the chance to ask the Tektronix License Manager to be allowed to maintain an open-PFE version of the library - starting with the year 2000 release. Over time, quite some work has been done outside of the Tek Labs and the open-PFE project found a home at its own website at pfe.sourceforge.net From time to time, both the Tek-PFE and Open-PFE get merged together, just be aware that for both versions Guido Draheim is the main developer. In the Changelog file, the two roles are distinguished by using two mail-addresses - guidod@tek.com and guidod@gmx.de - and these flag also the two different copyrights involved.

That's it. Any problems? Just contact me: "guidod@gmx.de"

The GNU Lesser General Public License (LGPL)

GNU LESSER GENERAL PUBLIC LICENSE

Version 2.1, February 1999

(The master copy of this license lives on the GNU website.)

Copyright (C) 1991, 1999 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.

[This is the first released version of the Lesser GPL.  It also counts
 as the successor of the GNU Library Public License, version 2, hence
 the version number 2.1.]

Preamble

The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public Licenses are intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users.

This license, the Lesser General Public License, applies to some specially designated software packages--typically libraries--of the Free Software Foundation and other authors who decide to use it. You can use it too, but we suggest you first think carefully about whether this license or the ordinary General Public License is the better strategy to use in any particular case, based on the explanations below.

When we speak of free software, we are referring to freedom of use, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish); that you receive source code or can get it if you want it; that you can change the software and use pieces of it in new free programs; and that you are informed that you can do these things.

To protect your rights, we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights. These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it.

For example, if you distribute copies of the library, whether gratis or for a fee, you must give the recipients all the rights that we gave you. You must make sure that they, too, receive or can get the source code. If you link other code with the library, you must provide complete object files to the recipients, so that they can relink them with the library after making changes to the library and recompiling it. And you must show them these terms so they know their rights.

We protect your rights with a two-step method: (1) we copyright the library, and (2) we offer you this license, which gives you legal permission to copy, distribute and/or modify the library.

To protect each distributor, we want to make it very clear that there is no warranty for the free library. Also, if the library is modified by someone else and passed on, the recipients should know that what they have is not the original version, so that the original author's reputation will not be affected by problems that might be introduced by others.

Finally, software patents pose a constant threat to the existence of any free program. We wish to make sure that a company cannot effectively restrict the users of a free program by obtaining a restrictive license from a patent holder. Therefore, we insist that any patent license obtained for a version of the library must be consistent with the full freedom of use specified in this license.

Most GNU software, including some libraries, is covered by the ordinary GNU General Public License. This license, the GNU Lesser General Public License, applies to certain designated libraries, and is quite different from the ordinary General Public License. We use this license for certain libraries in order to permit linking those libraries into non-free programs.

When a program is linked with a library, whether statically or using a shared library, the combination of the two is legally speaking a combined work, a derivative of the original library. The ordinary General Public License therefore permits such linking only if the entire combination fits its criteria of freedom. The Lesser General Public License permits more lax criteria for linking other code with the library.

We call this license the "Lesser" General Public License because it does Less to protect the user's freedom than the ordinary General Public License. It also provides other free software developers Less of an advantage over competing non-free programs. These disadvantages are the reason we use the ordinary General Public License for many libraries. However, the Lesser license provides advantages in certain special circumstances.

For example, on rare occasions, there may be a special need to encourage the widest possible use of a certain library, so that it becomes a de-facto standard. To achieve this, non-free programs must be allowed to use the library. A more frequent case is that a free library does the same job as widely used non-free libraries. In this case, there is little to gain by limiting the free library to free software only, so we use the Lesser General Public License.

In other cases, permission to use a particular library in non-free programs enables a greater number of people to use a large body of free software. For example, permission to use the GNU C Library in non-free programs enables many more people to use the whole GNU operating system, as well as its variant, the GNU/Linux operating system.

Although the Lesser General Public License is Less protective of the users' freedom, it does ensure that the user of a program that is linked with the Library has the freedom and the wherewithal to run that program using a modified version of the Library.

The precise terms and conditions for copying, distribution and modification follow. Pay close attention to the difference between a "work based on the library" and a "work that uses the library". The former contains code derived from the library, whereas the latter must be combined with the library in order to run.

TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION

0. This License Agreement applies to any software library or other program which contains a notice placed by the copyright holder or other authorized party saying it may be distributed under the terms of this Lesser General Public License (also called "this License"). Each licensee is addressed as "you".

A "library" means a collection of software functions and/or data prepared so as to be conveniently linked with application programs (which use some of those functions and data) to form executables.

The "Library", below, refers to any such software library or work which has been distributed under these terms. A "work based on the Library" means either the Library or any derivative work under copyright law: that is to say, a work containing the Library or a portion of it, either verbatim or with modifications and/or translated straightforwardly into another language. (Hereinafter, translation is included without limitation in the term "modification".)

"Source code" for a work means the preferred form of the work for making modifications to it. For a library, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the library.

Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running a program using the Library is not restricted, and output from such a program is covered only if its contents constitute a work based on the Library (independent of the use of the Library in a tool for writing it). Whether that is true depends on what the Library does and what the program that uses the Library does.

1. You may copy and distribute verbatim copies of the Library's complete source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and distribute a copy of this License along with the Library.

You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee.

2. You may modify your copy or copies of the Library or any portion of it, thus forming a work based on the Library, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions:

  • a) The modified work must itself be a software library.

  • b) You must cause the files modified to carry prominent notices stating that you changed the files and the date of any change.

  • c) You must cause the whole of the work to be licensed at no charge to all third parties under the terms of this License.

  • d) If a facility in the modified Library refers to a function or a table of data to be supplied by an application program that uses the facility, other than as an argument passed when the facility is invoked, then you must make a good faith effort to ensure that, in the event an application does not supply such function or table, the facility still operates, and performs whatever part of its purpose remains meaningful.

    (For example, a function in a library to compute square roots has a purpose that is entirely well-defined independent of the application. Therefore, Subsection 2d requires that any application-supplied function or table used by this function must be optional: if the application does not supply it, the square root function must still compute square roots.)

    These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Library, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Library, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it.

    Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Library.

    In addition, mere aggregation of another work not based on the Library with the Library (or with a work based on the Library) on a volume of a storage or distribution medium does not bring the other work under the scope of this License.

3. You may opt to apply the terms of the ordinary GNU General Public License instead of this License to a given copy of the Library. To do this, you must alter all the notices that refer to this License, so that they refer to the ordinary GNU General Public License, version 2, instead of to this License. (If a newer version than version 2 of the ordinary GNU General Public License has appeared, then you can specify that version instead if you wish.) Do not make any other change in these notices.

Once this change is made in a given copy, it is irreversible for that copy, so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy.

This option is useful when you wish to copy part of the code of the Library into a program that is not a library.

4. You may copy and distribute the Library (or a portion or derivative of it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange.

If distribution of object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source code, even though third parties are not compelled to copy the source along with the object code.

5. A program that contains no derivative of any portion of the Library, but is designed to work with the Library by being compiled or linked with it, is called a "work that uses the Library". Such a work, in isolation, is not a derivative work of the Library, and therefore falls outside the scope of this License.

However, linking a "work that uses the Library" with the Library creates an executable that is a derivative of the Library (because it contains portions of the Library), rather than a "work that uses the library". The executable is therefore covered by this License. Section 6 states terms for distribution of such executables.

When a "work that uses the Library" uses material from a header file that is part of the Library, the object code for the work may be a derivative work of the Library even though the source code is not. Whether this is true is especially significant if the work can be linked without the Library, or if the work is itself a library. The threshold for this to be true is not precisely defined by law.

If such an object file uses only numerical parameters, data structure layouts and accessors, and small macros and small inline functions (ten lines or less in length), then the use of the object file is unrestricted, regardless of whether it is legally a derivative work. (Executables containing this object code plus portions of the Library will still fall under Section 6.)

Otherwise, if the work is a derivative of the Library, you may distribute the object code for the work under the terms of Section 6. Any executables containing that work also fall under Section 6, whether or not they are linked directly with the Library itself.

6. As an exception to the Sections above, you may also combine or link a "work that uses the Library" with the Library to produce a work containing portions of the Library, and distribute that work under terms of your choice, provided that the terms permit modification of the work for the customer's own use and reverse engineering for debugging such modifications.

You must give prominent notice with each copy of the work that the Library is used in it and that the Library and its use are covered by this License. You must supply a copy of this License. If the work during execution displays copyright notices, you must include the copyright notice for the Library among them, as well as a reference directing the user to the copy of this License. Also, you must do one of these things:

  • a) Accompany the work with the complete corresponding machine-readable source code for the Library including whatever changes were used in the work (which must be distributed under Sections 1 and 2 above); and, if the work is an executable linked with the Library, with the complete machine-readable "work that uses the Library", as object code and/or source code, so that the user can modify the Library and then relink to produce a modified executable containing the modified Library. (It is understood that the user who changes the contents of definitions files in the Library will not necessarily be able to recompile the application to use the modified definitions.)
  • b) Use a suitable shared library mechanism for linking with the Library. A suitable mechanism is one that (1) uses at run time a copy of the library already present on the user's computer system, rather than copying library functions into the executable, and (2) will operate properly with a modified version of the library, if the user installs one, as long as the modified version is interface-compatible with the version that the work was made with.
  • c) Accompany the work with a written offer, valid for at least three years, to give the same user the materials specified in Subsection 6a, above, for a charge no more than the cost of performing this distribution.
  • d) If distribution of the work is made by offering access to copy from a designated place, offer equivalent access to copy the above specified materials from the same place.
  • e) Verify that the user has already received a copy of these materials or that you have already sent this user a copy.

For an executable, the required form of the "work that uses the Library" must include any data and utility programs needed for reproducing the executable from it. However, as a special exception, the materials to be distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable.

It may happen that this requirement contradicts the license restrictions of other proprietary libraries that do not normally accompany the operating system. Such a contradiction means you cannot use both them and the Library together in an executable that you distribute.

7. You may place library facilities that are a work based on the Library side-by-side in a single library together with other library facilities not covered by this License, and distribute such a combined library, provided that the separate distribution of the work based on the Library and of the other library facilities is otherwise permitted, and provided that you do these two things:

  • a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library facilities. This must be distributed under the terms of the Sections above.
  • b) Give prominent notice with the combined library of the fact that part of it is a work based on the Library, and explaining where to find the accompanying uncombined form of the same work.

8. You may not copy, modify, sublicense, link with, or distribute the Library except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, link with, or distribute the Library is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance.

9. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Library or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Library (or any work based on the Library), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Library or works based on it.

10. Each time you redistribute the Library (or any work based on the Library), the recipient automatically receives a license from the original licensor to copy, distribute, link with or modify the Library subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties with this License.

11. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Library at all. For example, if a patent license would not permit royalty-free redistribution of the Library by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Library.

If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply, and the section as a whole is intended to apply in other circumstances.

It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice.

This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License.

12. If the distribution and/or use of the Library is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Library under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License.

13. The Free Software Foundation may publish revised and/or new versions of the Lesser General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns.

Each version is given a distinguishing version number. If the Library specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Library does not specify a license version number, you may choose any version ever published by the Free Software Foundation.

14. If you wish to incorporate parts of the Library into other free programs whose distribution conditions are incompatible with these, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally.

NO WARRANTY

15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.

16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.

END OF TERMS AND CONDITIONS

Chapter 2.  ANS Forth '94

Chapter 3. Wordset Reference

block wordset

description

BLOCK -- BLOCK file access

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Historically Forth was implemented on small computers as an operating system in its own right. Mass storage was not organized in files but as a sequence of 1 KB blocks. A block was addressed with a block number. This way a diskette drive provided a few hundred blocks and if you had a fixed disk you simply had thousands of those blocks.

Both program text and arbitrary data can be stored in blocks. In order to hold source text the 1K block is treated as having 16 lines with 64 charactes each. This is often referred to as a 'screen'.

When loading (i.e. interpreting) a block with source text it is simply taking to be a single line of 1024 characters. The only exception to this is the word \ (begin comment to end of line) which skips text up to the end of a 64-char line in a block.

FORTH

BLK ( .. )();
as:"blk";

threadstate variable BLK

input.blk (no special usage info)

dpANS 7.6.1.0790 - standard forth word

FORTH

BLOCK ( u -- addr )();
p4:"block";

load the specified block into a block buffer and return the address of that block buffer - see also BUFFER

dpANS 7.6.1.0800 - standard forth word

FORTH

BUFFER ( u -- addr )();
p4:"buffer";

get the block buffer address for the specified block - if it had not been loaded already it is not filled with data from the disk unlike BLOCK does.

dpANS 7.6.1.0820 - standard forth word

FORTH

FLUSH ( -- )();
p4:"flush";

call SAVE-BUFFERS and then unassign all block buffers with EMPTY-BUFFERS

dpANS 7.6.1.1559 - standard forth word

FORTH

LOAD ( u -- )();
p4:"load";

INTERPRET the specified BLOCK

dpANS 7.6.1.1790 - standard forth word

FORTH

SAVE-BUFFERS ( -- )();
p4:"save-buffers";

write all modified buffer to the disk, see UPDATE and FLUSH

dpANS 7.6.1.2180 - standard forth word

FORTH

UPDATE ( -- )();
p4:"update";

mark the current block buffer as modified, see FLUSH

dpANS 7.6.1.2400 - standard forth word

FORTH

EMPTY-BUFFERS ( -- )();
p4:"empty-buffers";

unassign all block buffers, does not even UPDATE

dpANS 7.6.2.1330 - standard forth word

FORTH

LIST ( u -- )();
p4:"list";

display the block

dpANS 7.6.2.1770 - standard forth word

FORTH

SCR ( .. )();
as:"scr";

threadstate variable SCR

scr (no special usage info)

dpANS 7.6.2.2190 - standard forth word

FORTH

THRU ( u1 u2 -- )();
p4:"thru";

LOAD a number of block in sequence.

dpANS 7.6.2.2280 - standard forth word

ENVIRONMENT

BLOCK-EXT ( .. )();
as:"block-minus-ext";

( 1994  )  constant BLOCK-EXT

an ordinary constant (no special usage info)

block_misc wordset

description

-- miscellaneous useful extra words for BLOCK-EXT

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words. ... for BLOCK-EXT

FORTH
CLOSE-BLOCKFILE ( -- )w32for(); 
 ;

w32for-implementation:

 blockhandle -1 <> if flush close-file drop then
 -1 set-blockfile

in pfe:

 : CLOSE-BLOCKFILE 
   BLOCK-FILE ?DUP IF FLUSH CLOSE-FILE DROP THEN 
   OFF> BLOCK-FILE ;
 
FORTH
OPEN-BLOCKFILE ( "filename" -- )w32for(); 
 ;
 w32for-implementation:
 close-blockfile
 parse-word r/w open-file abort" failed to open block-file"
 set-blockfile
 empty-buffers 
 
FORTH
CREATE-BLOCKFILE ( n "filename" -- )w32for(); 
 ;

w32for-implementation:

 close-blockfile
 parse-word r/w create-file abort" failed to create block-file"
 set-blockfile
 dup b/buf m* blockhandle resize-file
 abort" unable to create a file of that size"
 empty-buffers
 0 do i wipe loop 
 flush

pfe does not wipe the buffers

EXTENSIONS

BLOCK-FILE ( .. )();
as:"block-minus-file";

- loader type P4_DVaL BLOCK-FILE

input.block_file (no special usage info)

EXTENSIONS
SET-BLOCKFILE ( fid -- )win32for(); 
 ;

win32forth uses a system-filedescriptor where -1 means unused in the BLOCKHANDLE, but we use a "FILE*"-like structure, so NULL means NOT-IN-USE. Here we set it.

EXTENSIONS
USING ( 'filename' -- )obsolete(); 
 ;

use filename as a block file OBSOLETE!! use OPEN-BLOCKFILE

EXTENSIONS
USING-NEW ( 'filename' -- )obsolete(); 
 ;

like USING but can create the file OBSOLETE!! use CREATE-BLOCKFILE

EXTENSIONS

B/BUF ( .. )();
as:"b-slash-buf";

( P4_BPBUF )  constant B/BUF

an ordinary constant (no special usage info)

cdecl wordset

description

-- C-like declaration primitives

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: some words that mimic partial behaviour of a C compiler especially it's preprocessor.

FORTH

#ELSE ( -- )();
p4:"sh-else";

The implementation of #ELSE is done in C for speed and being less error prone. Better use the ANSI-compatible [IF] [ELSE] [THEN] construct.

FORTH

#ENDIF ( -- )();
p4:"sh-endif";

end of #IF #IFDEF #IFNOTDEF and #ELSE contructs

   (a dummy word that does actually nothing, but #ELSE may look for it)
 
FORTH

#IF ( -- )();
p4:"sh-if";

        ( -- state-save mfth-if-magic )

prepares for a following #IS_TRUE or #IS_FALSE, does basically switch off compile-mode for the enclosed code. <br> better use the ANSI style [IF] [ELSE] [THEN] construct.

FORTH

#IFDEF ( "word" -- )();
p4:"sh-ifdef";

better use [DEFINED] word [IF] - the word [IF] is ANSI-conform.

FORTH

#IFNDEF ( .. )();
as:"sharp-ifndef";

immediate primitive #IFNDEF

an executable word (no special usage info)

or wrapper call around p4_sh_ifnotdef

FORTH

#IFNOTDEF ( "word" -- )();
p4:"sh-ifnotdef";

better use [DEFINED] word [NOT] [IF] - the word [IF] and [ELSE] are ANSI-conform, while #IFDEF #ELSE are not.

FORTH

#IS_TRUE ( flag -- )();
p4:"sh-is-true";

              ( state-save mfth-if-magic flag -- )

checks the condition on the CS-STACK. <br> Pairs with #IF <br> better use the ANSI style [IF] [ELSE] [THEN] construct.

FORTH

#IS_FALSE ( flag -- )();
p4:"sh-is-false";

              ( state-save mfth-if-magic flag -- )

checks the condition on the CS-STACK. <br> Pairs with #IF <br> better use the ANSI style [IF] [ELSE] [THEN] construct.

FORTH

// ( .. )();
as:"slash-slash";

immediate synonym //

is doing the same as \\

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

#DEFINE ( .. )();
as:"sharp-define";

ordinary primitive #DEFINE

an executable word (no special usage info)

or wrapper call around p4_sh_define

FORTH

#PRAGMA ( .. )();
as:"sharp-pragma";

ordinary primitive #PRAGMA

an executable word (no special usage info)

or wrapper call around p4_sh_pragma

chain wordset

description

-- CHAIN words - compare with win32forth

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This wordset implements CHAINs of words as seen in win32forth - unlike LINK-chains these chains will be watched by the system and referenced globabally via the chain-link variable. During FORGET we can prune these chains and keep them in the state they deserve to be at that point. In general, CHAINs are used as defer-chains which hold a series of of executions tokens in each chain item, and a call to `do-chain` will execute each one in that chain.

new-chain semicolon-chain : items are usually called resolve-* new-chain forget-chain : items are usually called trim-* new-chain unload-chain : items are usually called release-*

a chain-item is either a PRIMITIVE or a COLONWORD we simulate that it is part of a colonword - setting the IP to the address of the CHAIN-ITEM's body should make it callable. ITC: with XT: the XT at PRIM: HERE+1 | CODE* (simulating a prim XT) CTC: with XT: flatten XT being: CODE* | BODY* at PRIM CODE* STC variants: COLONWORDS are PRIMITIVES too, so just CODE*

WARNING: this wordset is not complete - it should hang on to the forget-routine to be able to prune chains given that their chain-heads are registered in a system-wide chainlist too. This has not been implemented.

The win32forth model has shown to be not directly usable within the pfe core parts - in win32forth each routine is itself just a forth routine while in pfe there is usually a difference between a colon-routine and a (C-made) primitive-routine so that they can not easily be universally referenced as XTs. It would be a rather complex endavour requiring quite some system runtime resources according to time and speed. Instead, the chain-wordlist system has been modelled at greater extents giving you largely the same functionality on different grounds.

EXTENSIONS

link, ( list -- )();
p4:"link-comma";

 : link,        here over @ a, swap ! ;
 
EXTENSIONS

chain-link ( .. )();
as:"chain-minus-link";

threadstate variable chain-link

chain_link (no special usage info)

EXTENSIONS

.chain ( chain* -- )();
p4:"dot-chain";

show chain - compare with WORDS

EXTENSIONS

.chains ( -- )();
p4:"dot-chains";

show all chains registered in the system - compare with VLIST

EXTENSIONS
chain-add ( chain* "word-to-add" -- )(); 
 ;

add chain item, for normal setup, at end of do-chain

 : chain-add ' >r begin dup @ while @ repeat here swap ! 0 , r> , ;
 ( chain-add begin dup @ while @ repeat  here swap ! 0, ' , )
 
EXTENSIONS
chain-add-before ( chain* "word-to-add" -- )(); 
 ;

add chain item, for reverse chain like BYE

 : chain-add-before ' >r here over @ , r> , swap ! ;
 ( chain-add-before link, ' , )
 
EXTENSIONS

do-chain ( chain* -- )();
p4:"do-chain";

execute chain

 : do-chain being @ ?dup while dup>r cell+ @execute r> repeat ;
 
EXTENSIONS

new-chain ( "name" -- )();
p4:"new-chain";

create a new chain and register in chain-link

 : new-chain create: 0 , ['] noop , chain-link link, ;

layout of a chain: /cell field ->chain.link /cell field ->chain.exec /cell field ->chain.next

EXTENSIONS

xdo-chain ( .. )();
as:"xdo-minus-chain";

forthword synonym xdo-chain

is doing the same as do-chain

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

EXTENSIONS
new-sys-chain ( .. )(); 
 ;

forthword synonym new-sys-chain

is doing the same as new-chain

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

chainlist wordset

description

-- CHAINLIST words - executable WORDLISTs

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This wordset implements CHAINLISTs. Unlike standard search-order WORDLISTs, these are never hashed lists, instead they are always in order and they do not take the VOCABULARY runtime even that they are allowed to live in the search-order itself. Instead, these singular wordlists may be subject to a DO-ALL-WORDS that executes the words contained in this wordlist, not much unlike that win32for DO-CHAIN. There are words to create these wordlists and list them to the user.

There is already a wordlist known in pfe for quite a time being the ATEXIT-WORDLIST which has been not exported however to the forth-level directly so far and executions have been stored there using the older ALIAS-ATEXIT word.

for an example, try the PROMPT-WORDLIST as included with the outer interpreter - for immediate stack visuals use: PROMPT-WORDLIST DO-SYNONYM .S .S

EXTENSIONS
NEW-WORDLIST ( "name" -- )(); 
 ;

create a new WORDLIST and a "name" with a runtime of ( -- wordlist* )

 : NEW-WORDLIST WORDLIST VALUE ;
 : NEW-WORDLIST CREATE: WORDLIST ;

usually used for DO-ALL-WORDS / DO-SYNONYM

EXTENSIONS

.WORDS ( wordlist* -- )();
p4:"dot-words";

print the WORDLIST interactivly to the user

 : .WORDS ALSO SET-CONTEXT WORDS PREVIOUS ;

WORDS / ORDER / NEW-WORDLIST / DO-ALL-WORDS

EXTENSIONS
REDO-ALL-WORDS ( wordlist* -- )(); 
 ;

EXECUTE each entry in the wordlist in the original order defined

 : REDO-ALL-WORDS
      0 FIRST-NAME
      0 SWAP ( under )
      BEGIN ?DUP WHILE 
         DUP NAME> SWAP ( under )
         NAME-NEXT
      REPEAT
      BEGIN ?DUP WHILE
         EXECUTE
      REPEAT
 ;

to run the NEW-WORDLIST in last-run-first order, use DO-ALL-WORDS

EXTENSIONS
DO-ALL-WORDS ( wordlist* -- )(); 
 ;

EXECUTE each entry in the wordlist in the reverse order defined

 : DO-ALL-WORDS
      0 FIRST-NAME
      BEGIN ?DUP WHILE 
         DUP NAME> EXECUTE
         NAME-NEXT
      REPEAT
 ;

to run the NEW-WORDLIST in original order, use REDO-ALL-WORDS

EXTENSIONS
DO-ALL-WORDS-WHILE-LOOP ( wordlist* xt -- )(); 
 ;

EXECUTE each entry in the wordlist in the reverse order defined but only as long as after EXECUTE of "word" a TRUE flag is left on the stack. The wordlist execution is cut when a FALSE flag is seen. (the current wordlist entry is _not_ on the stack!)

 : DO-ALL-WORDS-WHILE-LOOP >R
      0 FIRST-NAME
      BEGIN ?DUP WHILE 
         R@ EXECUTE 0= IF R>DROP DROP EXIT THEN
         DUP NAME> EXECUTE
         NAME-NEXT
      REPEAT R>DROP
 ;

compare with DO-ALL-WORDS-WHILE

EXTENSIONS
DO-ALL-WORDS-WHILE ( wordlist* "word" -- )(); 
 ;

EXECUTE each entry in the wordlist in the reverse order defined but only as long as after EXECUTE of "word" a TRUE flag is left on the stack. The wordlist execution is cut when a FALSE flag is seen. (the current wordlist entry is _not_ on the stack!)

 : DO-ALL-WORDS-WHILE ' 
      STATE @ IF LITERAL, COMPILE DO-ALL-WORDS-WHILE-LOOP EXIT THEN
      >R 0 FIRST-NAME
      BEGIN ?DUP WHILE 
         R@ EXECUTE 0= IF R>DROP DROP EXIT THEN
         DUP NAME> EXECUTE
         NAME-NEXT
      REPEAT R>DROP
 ;

to run the NEW-WORDLIST in original order, use REDO-ALL-WORDS

EXTENSIONS
DO-SYNONYM ( wordlist* "do-name" "orig-name" -- )(); 
 ;

create a SYNONYM in the specified wordlist.

 : DO-SYNONYM GET-CURRENT SWAP SET-CURRENT SYNONYM SET-CURRENT ;

DO-ALIAS / DO-ALL-WORDS / NEW-WORDLIST / WORDLIST / ORDER

EXTENSIONS
DO-ALIAS ( exec-token wordlist* "do-name" -- )(); 
 ;

create an ALIAS with the exec-token in the specified wordlist

 : DO-ALIAS GET-CURRENT SWAP SET-CURRENT SWAP ALIAS SET-CURRENT ;

DO-SYNONYM

EXTENSIONS
ALIAS-ATEXIT ( xt "name" -- )(); 
 ;

create a defer word that is initialized with the given x-token.

 : ALIAS-ATEXIT ATEXIT-WORDLIST DO-ALIAS ;

ATEXIT-WORDLIST DO-ALL-WORDS

EXTENSIONS

ALIAS ( xt "name" -- )();
p4:"alias";

create a defer word that is initialized with the given x-token. DO-ALIAS

EXTENSIONS
ATEXIT-WORDLIST ( .. )(); 
 ;

- loader type P4_DVaL ATEXIT-WORDLIST

atexit_wl (no special usage info)

EXTENSIONS
PROMPT-WORDLIST ( .. )(); 
 ;

- loader type P4_DVaL PROMPT-WORDLIST

prompt_wl (no special usage info)

EXTENSIONS
ABORT-WORDLIST ( .. )(); 
 ;

- loader type P4_DVaL ABORT-WORDLIST

abort_wl (no special usage info)

core wordset

description

CORE-EXT -- The standard CORE and CORE-EXT wordset

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Core Wordset contains the most of the essential words for ANS Forth.

FORTH

! ( val addr -- )();
p4:"store";

store value at addr (sizeof CELL)

dpANS .6.1.0010 - standard forth word

FORTH

# ( n.n -- n.n' )();
p4:"sh";

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word divides the argument by BASE and add it to the picture space - it should be used inside of <# and #>

dpANS .6.1.0030 - standard forth word

FORTH
#> ( n.n -- str-addr str-len )(); 
 ;

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word drops the argument and returns the picture space buffer

FORTH

#S ( n.n -- n.n )f();
p4:"sh-s";

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word does repeat the word # for a number of times, until the argument becomes zero. Hence the result is always null - it should be used inside of <# and #>

dpANS .6.1.0050 - standard forth word

FORTH
( ( 'comment<closeparen>' -- )(); 
 ;

eat everything up to the next closing paren - treat it as a comment.

dpANS 11.6.1.0080 - standard forth word

FORTH

* ( a b -- a*b )();
p4:"star";

return the multiply of the two args

dpANS .6.1.0090 - standard forth word

FORTH

*/ ( a b c -- a*b/c )();
p4:"star-slash";

regard the b/c as element Q - this word has an advantage over the sequence of * and / by using an intermediate double-cell value

dpANS .6.1.0100 - standard forth word

FORTH
*/MOD ( a b c -- m n )(); 
 ;

has an adavantage over the sequence of * and /MOD by using an intermediate double-cell value.

dpANS .6.1.0110 - standard forth word

FORTH

+ ( a b -- a+b )();
p4:"plus";

return the sum of the two args

dpANS .6.1.0120 - standard forth word

FORTH

+! ( val addr -- )();
p4:"plus-store";

add val to the value found in addr

 simulate:
   : +! TUCK @ + SWAP ! ;
 

dpANS .6.1.0130 - standard forth word

FORTH

+LOOP ( increment -- )();
p4:"plus-loop";

compile ((+LOOP)) which will use the increment as the loop-offset instead of just 1. See the DO and LOOP construct.

dpANS .6.1.0140 - standard forth word

FORTH

, ( val -- )();
p4:"comma";

store the value in the dictionary

 simulate:
   : , DP  1 CELLS DP +!  ! ;
 

dpANS .6.1.0150 - standard forth word

FORTH

- ( a b -- a-b )();
p4:"minus";

return the difference of the two arguments

dpANS .6.1.0160 - standard forth word

FORTH

. ( val -- )();
p4:"dot";

print the numerical value to stdout - uses BASE

dpANS .6.1.0180 - standard forth word

FORTH

." ( [string<">] -- )();
p4:"dot-quote";

print the string to stdout

dpANS .6.1.0190 - standard forth word

FORTH

/ ( a b -- a/b )();
p4:"slash";

return the quotient of the two arguments

dpANS .6.1.0230 - standard forth word

FORTH

/MOD ( a b -- m n )();
p4:"slash-mod";

divide a and b and return both quotient n and remainder m

dpANS .6.1.0240 - standard forth word

FORTH

0< ( val -- cond )();
p4:"zero-less";

return a flag that is true if val is lower than zero

 simulate:
  : 0< 0 < ;
 
FORTH

0= ( val -- cond )();
p4:"zero-equal";

return a flag that is true if val is just zero

 simulate:
  : 0= 0 = ;
 

dpANS .6.1.0270 - standard forth word

FORTH

1+ ( val -- val+1 )();
p4:"one-plus";

return the value incremented by one

 simulate:
  : 1+ 1 + ;
 

dpANS .6.1.0290 - standard forth word

FORTH

1- ( val -- val-1 )();
p4:"one-minus";

return the value decremented by one

 simulate:
   : 1- 1 - ;
 

dpANS .6.1.0300 - standard forth word

FORTH

2! ( a,a addr -- )();
p4:"two-store";

double-cell store

dpANS .6.1.0310 - standard forth word

FORTH

2* ( a -- a*2 )();
p4:"two-star";

multiplies the value with two - but it does actually use a shift1 to be faster

 simulate:
  : 2* 2 * ; ( canonic) : 2* 1 LSHIFT ; ( usual)
 

dpANS .6.1.0320 - standard forth word

FORTH

2/ ( a -- a/2 )();
p4:"two-slash";

divides the value by two - but it does actually use a shift1 to be faster

 simulate:
  : 2/ 2 / ; ( canonic) : 2/ 1 RSHIFT ; ( usual)
 

dpANS .6.1.0330 - standard forth word

FORTH

2@ ( addr -- a,a )();
p4:"two-fetch";

double-cell fetch

dpANS .6.1.0350 - standard forth word

FORTH

2DROP ( a b -- )();
p4:"two-drop";

double-cell drop, also used to drop two items

dpANS .6.1.0370 - standard forth word

FORTH

2DUP ( a,a -- a,a a,a )();
p4:"two-dup";

double-cell duplication, also used to duplicate two items

 simulate:
   : 2DUP OVER OVER ; ( wrong would be : 2DUP DUP DUP ; !!) 
 

dpANS .6.1.0380 - standard forth word

FORTH
2OVER ( a,a b,b -- a,a b,b a,a )(); 
 ;

double-cell over, see OVER and 2DUP

 simulate:
   : 2OVER SP@ 2 CELLS + 2@ ;
 

dpANS .6.1.0400 - standard forth word

FORTH
2SWAP ( a,a b,b -- b,b a,a )(); 
 ;

double-cell swap, see SWAP and 2DUP

 simulate:
   : 2SWAP LOCALS| B1 B2 A1 A2 | B2 B1 A2 A1 ;
 

dpANS .6.1.0430 - standard forth word

FORTH

: ( 'name' -- )();
p4:"colon";

create a header for a nesting word and go to compiling mode then. This word is usually ended with ; but the execution of the resulting colon-word can also return with EXIT

dpANS .6.1.0450 - standard forth word

FORTH

; ( -- )();
p4:"semicolon";

compiles ((;)) which does EXIT the current colon-definition. It does then end compile-mode and returns to execute-mode. See : and :NONAME

dpANS .6.1.0460 - standard forth word

FORTH

< ( a b -- cond )();
p4:"less-than";

return a flag telling if a is lower than b

dpANS .6.1.0480 - standard forth word

FORTH

<# ( -- )();
p4:"less-sh";

see also HOLD for old-style forth-formatting words and PRINTF of the C-style formatting - this word does initialize the pictured numeric output space.

dpANS .6.1.0490 - standard forth word

FORTH

= ( a b -- cond )();
p4:"equals";

return a flag telling if a is equal to b

dpANS .6.1.0530 - standard forth word

FORTH

> ( a b -- cond )();
p4:"greater-than";

return a flag telling if a is greater than b

FORTH

>BODY ( addr -- addr' )();
p4:"to-body";

adjust the execution-token (ie. the CFA) to point to the parameter field (ie. the PFA) of a word. this is not a constant operation - most words have their parameters at "1 CELLS +" but CREATE/DOES-words have the parameters at "2 CELLS +" and ROM/USER words go indirect with a rom'ed offset i.e. "CELL + @ UP +"

FORTH

>IN ( .. )();
as:"back-in";

threadstate variable >IN

input.to_in (no special usage info)

FORTH
>NUMBER ( a,a str-adr str-len -- a,a' str-adr' str-len)(); 
 ;

try to convert a string into a number, and place that number at a,a respeciting BASE

FORTH

>R ( value -- )();
p4:"to-r";

save the value onto the return stack. The return stack must be returned back to clean state before an exit and you should note that the return-stack is also touched by the DO ... WHILE loop. Use R> to clean the stack and R@ to get the last value put by >R

FORTH
?DUP ( value -- value|[nothing] )(); 
 ;

one of the rare words whose stack-change is condition-dependet. This word will duplicate the value only if it is not zero. The usual place to use it is directly before a control-word that can go to different places where we can spare an extra DROP on the is-null-part. This makes the code faster and often a little easier to read.

 example:
   : XX BEGIN ?DUP WHILE DUP . 2/ REPEAT ; instead of
   : XX BEGIN DUP WHILE DUP . 2/ REPEAT DROP ;
 

dpANS .6.1.0630 - standard forth word

FORTH

@ ( addr -- value )();
p4:"fetch";

fetch the value from the variables address

dpANS .6.1.0650 - standard forth word

FORTH

ABS ( value -- value' )();
p4:"abs";

return the absolute value

dpANS .6.1.0690 - standard forth word

FORTH

ACCEPT ( a n -- n' )();
p4:"accept";

get a string from terminal into the named input buffer, returns the number of bytes being stored in the buffer. May provide line-editing functions.

dpANS .6.1.0695 - standard forth word

FORTH

ALIGN ( -- )();
p4:"align";

will make the dictionary aligned, usually to a cell-boundary, see ALIGNED

dpANS .6.1.0705 - standard forth word

FORTH

ALIGNED ( addr -- addr' )();
p4:"aligned";

uses the value (being usually a dictionary-address) and increment it to the required alignment for the dictionary which is usually in CELLS - see also ALIGN

dpANS .6.1.0706 - standard forth word

FORTH

ALLOT ( count -- )();
p4:"allot";

make room in the dictionary - usually called after a CREATE word like VARIABLE or VALUE to make for an array of variables. Does not initialize the space allocated from the dictionary-heap. The count is in bytes - use CELLS ALLOT to allocate a field of cells.

dpANS .6.1.0710 - standard forth word

FORTH

AND ( val mask -- val' )();
p4:"and";

mask with a bitwise and - be careful when applying it to logical values.

dpANS .6.1.0720 - standard forth word

FORTH

BASE ( .. )();
as:"base";

threadstate variable BASE

base (no special usage info)

dpANS .6.1.0750 - standard forth word

FORTH
BEGIN ( -- )compile-time: ( -- cs-marker )(); 
 ;

start a control-loop, see WHILE and REPEAT

dpANS .6.1.0760 - standard forth word

FORTH

BL ( .. )();
as:"bl";

( ' ' )  constant BL

an ordinary constant (no special usage info)

dpANS .6.1.0770 - standard forth word

FORTH

C! ( value address -- )();
p4:"c-store";

store the byte-value at address, see !

dpANS .6.1.0850 - standard forth word

FORTH

C, ( value -- )();
p4:"c-comma";

store a new byte-value in the dictionary, implicit 1 ALLOT, see ,

dpANS .6.1.0860 - standard forth word

FORTH

C@ ( addr -- value )();
p4:"c-fetch";

fetch a byte-value from the address, see @

dpANS .6.1.0870 - standard forth word

FORTH

CELL+ ( value -- value' )();
p4:"cell-plus";

adjust the value by adding a single Cell's width - the value is often an address or offset, see CELLS

dpANS .6.1.0880 - standard forth word

FORTH

CELLS ( value -- value' )();
p4:"cells";

scale the value by the sizeof a Cell the value is then often applied to an address or fed into ALLOT

dpANS .6.1.0890 - standard forth word

FORTH

CHAR ( 'word' -- value )();
p4:"char";

return the (ascii-)value of the following word's first character.

dpANS .6.1.0895 - standard forth word

FORTH

CHAR+ ( value -- value' )();
p4:"char-plus";

increment the value by the sizeof one char - the value is often a pointer or an offset, see CHARS

dpANS .6.1.0897 - standard forth word

FORTH

CHARS ( value -- value' )();
p4:"chars";

scale the value by the sizeof a char - the value is then often applied to an address or fed into ALLOT (did you expect that sizeof(p4char) may actually yield 2 bytes?)

dpANS .6.1.0898 - standard forth word

FORTH
CONSTANT ( value 'name' -- )(); 
 ;

CREATE a new word with runtime ((CONSTANT)) so that the value placed here is returned everytime the constant's name is used in code. See VALUE for constant-like names that are expected to change during execution of the program. In a ROM-able forth the CONSTANT-value may get into a shared ROM-area and is never copied to a RAM-address.

dpANS .6.1.0950 - standard forth word

FORTH
COUNT ( counted-string -- string-pointer string-length )(); 
 ;

usually before calling TYPE

(as an unwarranted extension, this word does try to be idempotent).

dpANS .6.1.0980 - standard forth word

FORTH

CR ( -- )();
p4:"cr";

print a carriage-return/new-line on stdout

dpANS .6.1.0990 - standard forth word

FORTH

DECIMAL ( -- )();
p4:"decimal";

set the BASE to 10

 simulate:
   : DECIMAL 10 BASE ! ;
 

dpANS .6.1.1170 - standard forth word

FORTH

DEPTH ( -- value )();
p4:"depth";

return the depth of the parameter stack before the call, see SP@ - the return-value is in CELLS

dpANS .6.1.1200 - standard forth word

FORTH

DO ( end start -- )... LOOP();
p4:"do";

pushes $end and $start onto the return-stack ( >R ) and starts a control-loop that ends with LOOP or +LOOP and may get a break-out with LEAVE . The loop-variable can be accessed with I

dpANS .6.1.1240 - standard forth word

FORTH

DOES> ( -- pfa )();
p4:"does";

does twist the last CREATE word to carry the (DOES>) runtime. That way, using the word will execute the code-piece following DOES> where the pfa of the word is already on stack. (note: FIG option will leave pfa+cell since does-rt is stored in pfa)

FORTH

DROP ( a -- )();
p4:"drop";

just drop the word on the top of stack, see DUP

dpANS .6.1.1260 - standard forth word

FORTH

DUP ( a -- a a )();
p4:"dup";

duplicate the cell on top of the stack - so the two topmost cells have the same value (they are equal w.r.t = ) , see DROP for the inverse

dpANS .6.1.1290 - standard forth word

FORTH

ELSE ( -- )();
p4:"else";

will compile an ((ELSE)) BRANCH that performs an unconditional jump to the next THEN - and it resolves an IF for the non-true case

dpANS .6.1.1310 - standard forth word

FORTH

EMIT ( char -- )();
p4:"emit";

print the char-value on stack to stdout

dpANS .6.1.1320 - standard forth word

FORTH
ENVIRONMENT? ( a1 n1 -- false | ?? true )(); 
 ;

check the environment for a property, usually a condition like questioning the existance of specified wordset, but it can also return some implementation properties like "WORDLISTS" (the length of the search-order) or "#LOCALS" (the maximum number of locals)

Here it implements the environment queries as a SEARCH-WORDLIST in a user-visible vocabulary called ENVIRONMENT

 : ENVIRONMENT?
   ['] ENVIRONMENT >WORDLIST SEARCH-WORDLIST
   IF  EXECUTE TRUE ELSE  FALSE THEN ;
 

dpANS .6.1.1345 - standard forth word

FORTH
EVALUATE ( str-ptr str-len -- )(); 
 ;

INTERPRET the given string, SOURCE id is -1 during that time.

dpANS 7.6.1.1360 - standard forth word

FORTH

EXECUTE ( xt -- )();
p4:"execute";

run the execution-token on stack - this will usually trap if it was null for some reason, see >EXECUTE

 simulate:
  : EXECUTE >R EXIT ;
 

dpANS .6.1.1370 - standard forth word

FORTH

EXIT ( -- )();
p4:"exit";

will unnest the current colon-word so it will actually return the word calling it. This can be found in the middle of a colon-sequence between : and ;

dpANS .6.1.1380 - standard forth word

FORTH
FILL ( mem-addr mem-length char -- )(); 
 ;

fill a memory area with the given char, does now simply call memset()

dpANS .6.1.1540 - standard forth word

FORTH
FIND ( bstring -- cfa|bstring -1|0|1 )(); 
 ;

looks into the current search-order and tries to find the name string as the name of a word. Returns its execution-token or the original-bstring if not found, along with a flag-like value that is zero if nothing could be found. Otherwise it will be 1 (a positive value) if the word had been immediate, -1 otherwise (a negative value).

dpANS 16.6.1.1550 - standard forth word

FORTH
FM/MOD ( n1.n1 n2 -- m n )(); 
 ;

divide the double-cell value n1 by n2 and return both (floored) quotient n and remainder m

dpANS .6.1.1561 - standard forth word

FORTH

HERE ( -- dp-value )();
p4:"here";

used with WORD and many compiling words

 simulate:   : HERE DP @ ;
 

dpANS .6.1.1650 - standard forth word

FORTH

HOLD ( char -- )();
p4:"hold";

the old-style forth-formatting system -- this word adds a char to the picutred output string.

dpANS .6.1.1670 - standard forth word

FORTH

I ( -- value )();
p4:"i";

returns the index-value of the innermost DO .. LOOP

dpANS .6.1.1680 - standard forth word

FORTH

IF ( value -- ).. THEN();
p4:"if";

checks the value on the stack (at run-time, not compile-time) and if true executes the code-piece between IF and the next ELSE or THEN . Otherwise it has compiled a branch over to be executed if the value on stack had been null at run-time.

dpANS .6.1.1700 - standard forth word

FORTH

IMMEDIATE ( -- )();
p4:"immediate";

make the LATEST word immediate, see also CREATE

dpANS .6.1.1710 - standard forth word

FORTH

INVERT ( value -- value' )();
p4:"invert";

make a bitwise negation of the value on stack. see also NEGATE

dpANS .6.1.1720 - standard forth word

FORTH

J ( -- value )();
p4:"j";

get the current DO ... LOOP index-value being the not-innnermost. (the second-innermost...) see also for the other loop-index-values at I and K

dpANS .6.1.1730 - standard forth word

FORTH

KEY ( -- char )();
p4:"key";

return a single character from the keyboard - the key is not echoed.

dpANS .6.1.1750 - standard forth word

FORTH

LEAVE ( -- )();
p4:"leave";

quit the innermost DO .. LOOP - it does even clean the return-stack and branches to the place directly after the next LOOP

dpANS .6.1.1760 - standard forth word

FORTH
LITERAL ( value -- )immediate(); 
 ;

if compiling this will take the value from the compiling-stack and puts in dictionary so that it will pop up again at the run-time of the word currently in creation. This word is used in compiling words but may also be useful in making a hard-constant value in some code-piece like this:

 : DCELLS [ 2 CELLS ] LITERAL * ; ( will save a multiplication at runtime)

(in most configurations this word is statesmart and it will do nothing in interpret-mode. See LITERAL, for a non-immediate variant)

dpANS .6.1.1780 - standard forth word

FORTH

LOOP ( -- )();
p4:"loop";

resolves a previous DO thereby compiling ((LOOP)) which does increment/decrement the index-value and branch back if the end-value of the loop has not been reached.

dpANS .6.1.1800 - standard forth word

FORTH
LSHIFT ( value shift-val -- value' )(); 
 ;

does a bitwise left-shift on value

dpANS .6.1.1805 - standard forth word

FORTH

M* ( a b -- m,m )();
p4:"m-star";

multiply and return a double-cell result

dpANS .6.1.1810 - standard forth word

FORTH

MAX ( a b -- c )();
p4:"max";

return the maximum of a and b

dpANS .6.1.1870 - standard forth word

FORTH

MIN ( a b -- c )();
p4:"min";

return the minimum of a and b

dpANS .6.1.1880 - standard forth word

FORTH

MOD ( a b -- c )();
p4:"mod";

return the module of "a mod b"

dpANS .6.1.1890 - standard forth word

FORTH

MOVE ( from to length -- )();
p4:"move";

memcpy an area

dpANS .6.1.1900 - standard forth word

FORTH

NEGATE ( value -- value' )();
p4:"negate";

return the arithmetic negative of the (signed) cell

 simulate:   : NEGATE -1 * ;
 

dpANS .6.1.1910 - standard forth word

FORTH

OR ( a b -- ab )();
p4:"or";

return the bitwise OR of a and b - unlike AND this is usually safe to use on logical values

dpANS .6.1.1980 - standard forth word

FORTH

OVER ( a b -- a b a )();
p4:"over";

get the value from under the top of stack. The inverse operation would be TUCK

dpANS .6.1.1990 - standard forth word

FORTH

POSTPONE ( [word] -- )();
p4:"postpone";

will compile the following word at the run-time of the current-word which is a compiling-word. The point is that POSTPONE takes care of the fact that word may be an IMMEDIATE-word that flags for a compiling word, so it must be executed (and not pushed directly) to compile sth. later. Choose this word in favour of COMPILE (for non-immediate words) and [COMPILE] (for immediate words)

dpANS .6.1.2033 - standard forth word

FORTH

QUIT ( -- )no-return();
p4:"quit";

this will throw and lead back to the outer-interpreter. traditionally, the outer-interpreter is called QUIT in forth itself where the first part of the QUIT-word had been to clean the stacks (and some other variables) and then turn to an endless loop containing QUERY and EVALUATE (otherwise known as INTERPRET ) - in pfe it is defined as a THROW ,

 : QUIT -56 THROW ;
 

dpANS .6.1.2050 - standard forth word

FORTH

R> ( R: a -- a R: )();
p4:"r-from";

get back a value from the return-stack that had been saved there using >R . This is the traditional form of a local var space that could be accessed with R@ later. If you need more local variables you should have a look at LOCALS| which does grab some space from the return-stack too, but names them the way you like.

FORTH

R@ ( R: a -- a R: a )();
p4:"r-fetch";

fetch the (upper-most) value from the return-stack that had been saved there using >R - This is the traditional form of a local var space. If you need more local variables you should have a look at LOCALS| , see also >R and R> . Without LOCALS-EXT there are useful words like 2R@ R'@ R"@ R!

dpANS .6.1.2070 - standard forth word

FORTH

RECURSE ( ? -- ? )();
p4:"recurse";

when creating a colon word the name of the currently-created word is smudged, so that you can redefine a previous word of the same name simply by using its name. Sometimes however one wants to recurse into the current definition instead of calling the older defintion. The RECURSE word does it exactly this.

   traditionally the following code had been in use:
   : GREAT-WORD [ UNSMUDGE ] DUP . 1- ?DUP IF GREAT-WORD THEN ;
   now use
   : GREAT-WORD DUP . 1- ?DUP IF RECURSE THEN ;
 

dpANS .6.1.2120 - standard forth word

FORTH

REPEAT ( -- )();
p4:"repeat";

ends an unconditional loop, see BEGIN

dpANS .6.1.2140 - standard forth word

FORTH

ROT ( a b c -- b c a )();
p4:"rot";

rotates the three uppermost values on the stack, the other direction would be with -ROT - please have a look at LOCALS| and VAR that can avoid its use.

dpANS .6.1.2160 - standard forth word

FORTH
RSHIFT ( value shift-val -- value' )(); 
 ;

does a bitwise logical right-shift on value (ie. the value is considered to be unsigned)

dpANS .6.1.2162 - standard forth word

FORTH
S" ( [string<">] -- string-address string-length)(); 
 ;

if compiling then place the string into the currently compiled word and on execution the string pops up again as a double-cell value yielding the string's address and length. To be most portable this is the word to be best being used. Compare with C" and non-portable "

dpANS 11.6.1.2165 - standard forth word

FORTH

S>D ( a -- a,a' )();
p4:"s-to-d";

signed extension of a single-cell value to a double-cell value

FORTH

SIGN ( a -- )();
p4:"sign";

put the sign of the value into the hold-space, this is the forth-style output formatting, see HOLD

dpANS .6.1.2210 - standard forth word

FORTH
SM/REM ( a.a b -- c d )(); 
 ;

see /MOD or FM/MOD or UM/MOD or SM/REM

dpANS .6.1.2214 - standard forth word

FORTH
SOURCE ( -- buffer IN-offset )(); 
 ;

the current point of interpret can be gotten through SOURCE. The buffer may flag out TIB or BLK or a FILE and IN gives you the offset therein. Traditionally, if the current SOURCE buffer is used up, REFILL is called that asks for another input-line or input-block. This scheme would have made it impossible to stretch an [IF] ... [THEN] over different blocks, unless [IF] does call REFILL

dpANS .6.1.2216 - standard forth word

FORTH

SPACE ( -- )();
p4:"space";

print a single space to stdout, see SPACES

 simulate:    : SPACE  BL EMIT ;
 

dpANS .6.1.2220 - standard forth word

FORTH

SPACES ( n -- )();
p4:"spaces";

print n space to stdout, actually a loop over n calling SPACE , but the implemenation may take advantage of printing chunks of spaces to speed up the operation.

dpANS .6.1.2230 - standard forth word

FORTH

STATE ( .. )();
as:"state";

threadstate variable STATE

state (no special usage info)

dpANS 15.6.2.2250 - standard forth word

FORTH

SWAP ( a b -- b a )();
p4:"swap";

exchanges the value on top of the stack with the value beneath it

dpANS .6.1.2260 - standard forth word

FORTH

THEN ( -- )();
p4:"then";

does resolve a branch coming from either IF or ELSE

dpANS .6.1.2270 - standard forth word

FORTH
TYPE ( string-pointer string-length -- )(); 
 ;

prints the string-buffer to stdout, see COUNT and EMIT

dpANS .6.1.2310 - standard forth word

FORTH

U. ( .. )();
as:"u-dot";

ordinary primitive U.

an executable word (no special usage info)

or wrapper call around p4_u_dot

dpANS .6.1.2320 - standard forth word

FORTH

U< ( a b -- cond )();
p4:"u-less-than";

unsigned comparison, see <

FORTH

UM* ( a b -- c,c )();
p4:"u-m-star";

unsigned multiply returning double-cell value

dpANS .6.1.2360 - standard forth word

FORTH

UM/MOD ( a b -- c,c )();
p4:"u-m-slash-mod";

see /MOD and SM/REM

dpANS .6.1.2370 - standard forth word

FORTH

UNLOOP ( -- )();
p4:"unloop";

drop the DO .. LOOP runtime variables from the return-stack, usually used just in before an EXIT call. Using this multiple times can unnest multiple nested loops.

dpANS .6.1.2380 - standard forth word

FORTH

UNTIL ( cond -- )();
p4:"until";

ends an control-loop, see BEGIN and compare with WHILE

dpANS .6.1.2390 - standard forth word

FORTH

VARIABLE ( 'name' -- )();
p4:"variable";

CREATE a new variable, so that everytime the variable is name, the address is returned for using with @ and ! - be aware that in FIG-forth VARIABLE did take an argument being the initial value. ANSI-forth does different here.

dpANS .6.1.2410 - standard forth word

FORTH

WHILE ( cond -- )();
p4:"while";

middle part of a BEGIN .. WHILE .. REPEAT control-loop - if cond is true the code-piece up to REPEAT is executed which will then jump back to BEGIN - and if the cond is null then WHILE will branch to right after the REPEAT (compare with UNTIL that forms a BEGIN .. UNTIL loop)

dpANS .6.1.2430 - standard forth word

FORTH
WORD ( delimiter-char -- here-addr )(); 
 ;

read the next SOURCE section (thereby moving >IN ) up to the point reaching $delimiter-char - the text is placed at HERE - where you will find a counted string. You may want to use PARSE instead.

dpANS .6.1.2450 - standard forth word

FORTH

XOR ( a b -- ab )();
p4:"xor";

return the bitwise-or of the two arguments - it may be unsafe use it on logical values. beware.

dpANS .6.1.2490 - standard forth word

FORTH

[ ( -- )();
p4:"left-bracket";

leave compiling mode - often used inside of a colon-definition to make fetch some very constant value and place it into the currently compiled colon-defintion with , or LITERAL - the corresponding unleave word is ]

dpANS .6.1.2500 - standard forth word

FORTH
['] ( [name] -- )immediate(); 
 ;

will place the execution token of the following word into the dictionary. See ' for non-compiling variant.

dpANS .6.1.2510 - standard forth word

FORTH
[CHAR] ( [word] -- char )(); 
 ;

in compile-mode, get the (ascii-)value of the first charachter in the following word and compile it as a literal so that it will pop up on execution again. See CHAR and forth-83 ASCII

dpANS .6.1.2520 - standard forth word

FORTH

] ( -- )();
p4:"right-bracket";

enter compiling mode - often used inside of a colon-definition to end a previous [ - you may find a , or LITERAL nearby in example texts.

dpANS .6.1.2540 - standard forth word

FORTH

#TIB ( .. )();
as:"sharp-tib";

threadstate variable #TIB

input.number_tib (no special usage info)

dpANS .6.2.0060 - standard forth word

FORTH
.( ( [message<closeparen>] -- )(); 
 ;

print the message to the screen while reading a file. This works too while compiling, so you can whatch the interpretation/compilation to go on. Some Forth-implementations won't even accept a ." message" outside compile-mode while the (current) pfe does.

dpANS .6.2.0200 - standard forth word

FORTH

.R ( val prec -- )();
p4:"dot-r";

print with precision - that is to fill a field of the give prec-with with right-aligned number from the converted value

dpANS .6.2.0210 - standard forth word

FORTH
0<> ( value -- cond )(); 
 ;

returns a logical-value saying if the value was not-zero. This is most useful in turning a numerical value into a boolean value that can be fed into bitwise words like AND and XOR - a simple IF or WHILE doesn't need it actually.

FORTH

0> ( value -- cond )();
p4:"zero-greater";

return value greater than zero

 simulate:    : 0> 0 > ;
 

dpANS .6.2.0280 - standard forth word

FORTH

2>R ( a,a -- R: a,a )();
p4:"two-to-r";

save a double-cell value onto the return-stack, see >R

dpANS .6.2.0340 - standard forth word

FORTH

2R> ( R: a,a -- a,a R: )();
p4:"two-r-from";

pop back a double-cell value from the return-stack, see R> and the earlier used 2>R

FORTH
2R@ ( R: a,a -- a,a R: a,a )(); 
 ;

fetch a double-cell value from the return-stack, that had been previously been put there with 2>R - see R@ for single value. This can partly be a two-cell LOCALS| value, without LOCALS-EXT there are alos other useful words like 2R! R'@ R"@

dpANS .6.2.0415 - standard forth word

FORTH
:NONAME ( -- cs.value )(); 
 ;

start a colon nested-word but do not use CREATE - so no name is given to the colon-definition that follows. When the definition is finished at the corresponding ; the start-address (ie. the execution token) can be found on the outer cs.stack that may be stored used elsewhere then.

dpANS .6.2.0455 - standard forth word

FORTH

<> ( a b -- cond )();
p4:"not-equals";

return true if a and b are not equal, see =

FORTH

?DO ( end start -- ).. LOOP();
p4:"Q-do";

start a control-loop just like DO - but don't execute atleast once. Instead jump over the code-piece if the loop's variables are not in a range to allow any loop.

dpANS .6.2.0620 - standard forth word

FORTH

AGAIN ( -- )();
p4:"again";

ends an infinite loop, see BEGIN and compare with WHILE

dpANS .6.2.0700 - standard forth word

FORTH
C" ( [string<">] -- bstring )(); 
 ;

in compiling mode place the following string in the current word and return the address of the counted string on execution. (in exec-mode use a POCKET and leave the bstring-address of it), see S" string" and the non-portable " string"

dpANS .6.2.0855 - standard forth word

FORTH
CASE ( comp-value -- comp-value )(); 
 ;

start a CASE construct that ends at ENDCASE and compares the value on stack at each OF place

dpANS .6.2.0873 - standard forth word

FORTH

COMPILE, ( xt -- )();
p4:"compile-comma";

place the execution-token on stack into the dictionary - in traditional forth this is not even the least different than a simple , but in call-threaded code there's a big difference - so COMPILE, is the portable one. Unlike COMPILE , [COMPILE] and POSTPONE this word does not need the xt to have actually a name, see :NONAME

dpANS .6.2.0945 - standard forth word

FORTH

CONVERT ( a b -- a b )();
p4:"convert";

digit conversion, obsolete, superseded by >NUMBER

dpANS .6.2.0970 - standard forth word

FORTH

ENDCASE ( comp-value -- )();
p4:"endcase";

ends a CASE construct that may surround multiple sections of OF ... ENDOF code-portions. The ENDCASE has to resolve the branches that are necessary at each ENDOF to point to right after ENDCASE

dpANS .6.2.1342 - standard forth word

FORTH

ENDOF ( -- )();
p4:"endof";

resolve the branch need at the previous OF to mark a code-piece and leave with an unconditional branch at the next ENDCASE (opened by CASE )

dpANS .6.2.1343 - standard forth word

FORTH

ERASE ( ptr len -- )();
p4:"erase";

fill an area will zeros.

 2000 CREATE DUP ALLOT ERASE
 

dpANS .6.2.1350 - standard forth word

FORTH
EXPECT ( str-adr str-len -- )(); 
 ;

input handling, see WORD and PARSE and QUERY the input string is placed at str-adr and its length

 in SPAN - this word is superceded by ACCEPT
 

dpANS .6.2.1390 - standard forth word

FORTH

FALSE ( .. )();
as:"false";

( P4_FALSE )  constant FALSE

an ordinary constant (no special usage info)

dpANS .6.2.1485 - standard forth word

FORTH

HEX ( -- )();
p4:"hex";

set the input/output BASE to hexadecimal

 simulate:        : HEX 16 BASE ! ;
 

dpANS .6.2.1660 - standard forth word

FORTH

MARKER ( 'name' -- )();
p4:"marker";

create a named marker that you can use to FORGET , running the created word will reset the dict/order variables to the state at the creation of this name.

 : MARKER PARSE-WORD (MARKER) ;

see also ANEW which is not defined in ans-forth but which uses the MARKER functionality in the way it should have been defined.

dpANS .6.2.1850 - standard forth word

FORTH

NIP ( a b -- b )();
p4:"nip";

drop the value under the top of stack, inverse of TUCK

 simulate:        : NIP SWAP DROP ;
 

dpANS .6.2.1930 - standard forth word

FORTH
OF ( comp-value case-value -- comp-value ).. ENDOF(); 
 ;

compare the case-value placed lately with the comp-value being available since CASE - if they are equal run the following code-portion up to ENDOF after which the case-construct ends at the next ENDCASE

dpANS .6.2.1950 - standard forth word

FORTH

PAD ( -- addr )();
p4:"pad";

transient buffer region

dpANS .6.2.2000 - standard forth word

FORTH
PARSE ( delim-char -- buffer-start buffer-count )(); 
 ;

parse a piece of input (not much unlike WORD) and place it into the given buffer. The difference with word is also that WORD would first skip any delim-char while PARSE does not and thus may yield that one. In a newer version, PARSE will not copy but just return the word-span being seen in the input-buffer - therefore a transient space.

dpANS .6.2.2008 - standard forth word

FORTH

PICK ( n -- value )();
p4:"pick";

pick the nth value from under the top of stack and push it note that

   0 PICK -> DUP         1 PICK -> OVER
 

dpANS .6.2.2030 - standard forth word

FORTH

QUERY ( -- )();
p4:"query";

source input: read from terminal using _accept_ with the returned string to show up in TIB of /TIB size.

dpANS .6.2.2040 - standard forth word

FORTH

REFILL ( -- flag )();
p4:"refill";

try to get a new input line from the SOURCE and set >IN accordingly. Return a flag if sucessful, which is always true if the current input comes from a terminal and which is always false if the current input comes from EVALUATE - and may be either if the input comes from a file

dpANS 11.6.2.2125 - standard forth word

FORTH
RESTORE-INPUT ( xn ... x1 -- )(); 
 ;

inverse of SAVE-INPUT

dpANS .6.2.2148 - standard forth word

FORTH
ROLL ( xn xm ... x1 n -- xm ... x1 xn )(); 
 ;

the extended form of ROT

    2 ROLL -> ROT
 

dpANS .6.2.2150 - standard forth word

FORTH
SAVE-INPUT ( -- xn .. x1 )(); 
 ;

fetch the current state of the input-channel which may be restored with RESTORE-INPUT later

dpANS .6.2.2182 - standard forth word

FORTH

SOURCE-ID ( .. )();
as:"source-minus-id";

- loader type P4_DVaL SOURCE-ID

input.source_id (no special usage info)

dpANS 11.6.1.2218 - standard forth word

FORTH

SPAN ( .. )();
as:"span";

threadstate variable SPAN

span (no special usage info)

dpANS .6.2.2240 - standard forth word

FORTH

TIB ( .. )();
as:"tib";

- loader type P4_DVaL TIB

input.tib (no special usage info)

dpANS .6.2.2290 - standard forth word

FORTH

TO ( value [name] -- )();
p4:"to";

set the parameter field of name to the value, this is used to change the value of a VALUE and it can be also used to change the value of LOCALS|

dpANS 13.6.1.2295 - standard forth word

FORTH

TRUE ( .. )();
as:"true";

( P4_TRUE )  constant TRUE

an ordinary constant (no special usage info)

dpANS .6.2.2298 - standard forth word

FORTH

TUCK ( a b -- b a b )();
p4:"tuck";

shove the top-value under the value beneath. See OVER and NIP

 simulate:    : TUCK  SWAP OVER ;
 

dpANS .6.2.2300 - standard forth word

FORTH

U.R ( value prec -- )();
p4:"u-dot-r";

print right-aligned in a prec-field, treat value to be unsigned as opposed to .R

dpANS .6.2.2330 - standard forth word

FORTH

U> ( a b -- ab )();
p4:"u-greater-than";

unsigned comparison of a and b, see >

FORTH

UNUSED ( -- val )();
p4:"unused";

return the number of cells that are left to be used above HERE

dpANS .6.2.2395 - standard forth word

FORTH

VALUE ( value 'name' -- )();
p4:"value";

CREATE a word and initialize it with value. Using it later will push the value back onto the stack. Compare with VARIABLE and CONSTANT - look also for LOCALS| and VAR

dpANS .6.2.2405 - standard forth word

FORTH

WITHIN ( a b c -- cond )();
p4:"within";

a widely used word, returns ( b <= a && a < c ) so that is very useful to check an index a of an array to be within range b to c

dpANS .6.2.2440 - standard forth word

FORTH
[COMPILE] ( [word] -- )(); 
 ;

while compiling the next word will be place in the currently defined word no matter if that word is immediate (like IF ) - compare with COMPILE and POSTPONE

dpANS .6.2.2530 - standard forth word

FORTH

\ ( [comment<eol>] -- )();
p4:"backslash";

eat everything up to the next end-of-line so that it is getting ignored by the interpreter.

dpANS 7.6.2.2535 - standard forth word

FORTH
" ( [string<">] -- bstring )or perhaps ( [..] -- str-ptr str-len )(); 
 ;

This is the non-portable word which is why the ANSI-committee on forth has created the two other words, namely S" and C" , since each implementation (and in pfe configurable) uses another runtime behaviour. FIG-forth did return bstring which is the configure default for pfe.

FORTH
PARSE-WORD ( "chars" -- c-addr u )(); 
 ;

the ANS'94 standard describes this word in a comment under PARSE, section A.6.2.2008 - quote:

Skip leading spaces and parse name delimited by a space. c-addr is the address within the input buffer and u is the length of the selected string. If the parse area is empty, the resulting string has a zero length.

If both PARSE and PARSE-WORD are present, the need for WORD is largely eliminated.

FORTH

<BUILDS ( 'name' -- )();
p4:"builds";

make a HEADER whose runtime will be changed later using DOES>

note that ans'forth does not define <BUILDS and it suggests to use CREATE directly.

... if you want to write FIG-programs in pure pfe then you have to use CREATE: to get the FIG-like meaning of CREATE whereas the ans-forth CREATE is the same as <BUILDS

 : <BUILDS BL WORD HEADER DOCREATE A, 0 A, ;
 
FORTH

CFA' ( .. )();
as:"cfa-tick";

ordinary primitive CFA'

an executable word (no special usage info)

or wrapper call around p4_tick

FORTH

CREATE ( .. )();
as:"create";

forthword synonym CREATE

is doing the same as <BUILDS

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

dpANS .6.1.1000 - standard forth word

FORTH

' ( 'name' -- xt )();
p4:"tick";

return the execution token of the following name. This word is _not_ immediate and may not do what you expect in compile-mode. See ['] and '> - note that in FIG-forth the word of the same name had returned the PFA (not the CFA) and was immediate/smart, so beware when porting forth-code from FIG-forth to ANSI-forth.

dpANS .6.1.0070 - standard forth word

EXTENSIONS
(MARKER) ( str-ptr str-len -- )(); 
 ;

create a named marker that you can use to FORGET , running the created word will reset the dict/order variables to the state at the creation of this name.

 : (MARKER) (CREATE) HERE , 
         GET-ORDER DUP , 0 DO ?DUP IF , THEN LOOP 0 , 
         ...
   DOES> DUP @ (FORGET) 
         ...
 ; 
 
EXTENSIONS

ANEW ( 'name' -- )();
p4:"anew";

creates a MARKER if it doesn't exist, or forgets everything after it if it does. (it just gets executed).

 : ANEW BL WORD   DUP FIND NIP IF EXECUTE THEN   (MARKER) ;
 
ENVIRONMENT

CORE-EXT ( .. )();
as:"core-minus-ext";

( 1994  )  constant CORE-EXT

an ordinary constant (no special usage info)

ENVIRONMENT
/COUNTED-STRING ( .. )(); 
 ;
( UCHAR_MAX  )  constant /COUNTED-STRING

an ordinary constant (no special usage info)

ENVIRONMENT

/HOLD ( .. )();
as:"slash-hold";

( MIN_HOLD  )  constant /HOLD

an ordinary constant (no special usage info)

ENVIRONMENT

/PAD ( .. )();
as:"slash-pad";

( MIN_PAD  )  constant /PAD

an ordinary constant (no special usage info)

ENVIRONMENT
ADDRESS-UNIT-BITS ( .. )(); 
 ;
( CHAR_BIT  )  constant ADDRESS-UNIT-BITS

an ordinary constant (no special usage info)

ENVIRONMENT

FLOORED ( .. )();
as:"floored";

( P4_TRUE  )  constant FLOORED

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-CHAR ( .. )();
as:"max-minus-char";

( UCHAR_MAX  )  constant MAX-CHAR

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-N ( .. )();
as:"max-minus-n";

( CELL_MAX  )  constant MAX-N

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-U ( .. )();
as:"max-minus-u";

( UCELL_MAX  )  constant MAX-U

an ordinary constant (no special usage info)

ENVIRONMENT
STACK-CELLS ( .. )(); 
 ;

ordinary primitive STACK-CELLS

an executable word (no special usage info)

or wrapper call around p__stack_cells

ENVIRONMENT
RETURN-STACK-CELLS ( .. )(); 
 ;

ordinary primitive RETURN-STACK-CELLS

an executable word (no special usage info)

or wrapper call around p__return_stack_cells

core_misc wordset

description

-- miscellaneous useful extra words for CORE-EXT

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words. ... for CORE-EXT

FORTH

0 ( .. )();
as:"zero";

( 0 )  constant 0

an ordinary constant (no special usage info)

FORTH

1 ( .. )();
as:"one";

( 1 )  constant 1

an ordinary constant (no special usage info)

FORTH

2 ( .. )();
as:"two";

( 2 )  constant 2

an ordinary constant (no special usage info)

FORTH

3 ( .. )();
as:"three";

( 3 )  constant 3

an ordinary constant (no special usage info)

FORTH

0<= ( a -- flag )();
p4:"zero-less-equal";

 simulate    : 0<= 0> 0= ;
 
FORTH
0>= ( a -- flag )(); 
 ;
 simulate    : 0>= 0< 0= ;
 
FORTH

<= ( a b -- flag )();
p4:"less-equal";

 simulate    : <= > 0= ;
 
FORTH

>= ( a b -- flag )();
p4:"greater-equal";

 simulate    : >= < 0= ;
 
FORTH

U<= ( a b -- flag )();
p4:"u-less-equal";

 simulate    : U<= U> 0= ;
 
FORTH

U>= ( a b -- flag )();
p4:"u-greater-equal";

 simulate    : U>= U< 0= ;
 
FORTH

UMIN ( a b -- min )();
p4:"u-min";

see MIN , MAX and UMAX

FORTH

UMAX ( a b -- max )();
p4:"u-max";

see MAX

FORTH

.VERSION ( -- )();
p4:"dot-version";

show the version of the current PFE system

 : .VERSION [ ENVIRONMENT ] FORTH-NAME TYPE FORTH-VERSION TYPE ;
 
FORTH

.CVERSION ( -- )();
p4:"dot-date";

show the compile date of the current PFE system

 : .CVERSION [ ENVIRONMENT ] FORTH-NAME TYPE FORTH-DATE TYPE ;
 
FORTH

.PFE-DATE ( .. )();
as:"dot-pfe-minus-date";

forthword synonym .PFE-DATE

is doing the same as .CVERSION

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

LICENSE ( -- )();
p4:"license";

show a lisence info - the basic PFE system is licensed under the terms of the LGPL (Lesser GNU Public License) - binary modules loaded into the system and hooking into the system may carry another LICENSE

 : LICENSE [ ENVIRONMENT ] FORTH-LICENSE TYPE ;
 
FORTH

WARRANTY ( -- )();
p4:"warranty";

show a warranty info - the basic PFE system is licensed under the terms of the LGPL (Lesser GNU Public License) - which exludes almost any liabilities whatsoever - however loadable binary modules may hook into the system and their functionality may have different WARRANTY infos.

FORTH

STRING, ( str len -- )();
p4:"string-comma";

Store a string in data space as a counted string.

 : STRING, HERE  OVER 1+  ALLOT  PLACE ;
 
FORTH
PARSE, ( "chars<">" -- )(); 
 ;

Store a char-delimited string in data space as a counted string. As seen in Bawd's

 : ," [CHAR] " PARSE  STRING, ; IMMEDIATE

this implementation is much different from Bawd's

 : PARSE, PARSE STRING, ;
 
FORTH
PARSE," ( "chars<">" -- )(); 
 ;

Store a quote-delimited string in data space as a counted string.

 : ," [CHAR] " PARSE  STRING, ; IMMEDIATE

implemented here as

 : PARSE," [CHAR] " PARSE, ; IMMEDIATE
 
FORTH

[VOID] ( .. )();
as:"bracket-void";

( 0 )  constant [VOID]

an immediate constant (no special usage info)

FORTH

DEFINED ( .. )();
as:"defined";

ordinary primitive DEFINED

an executable word (no special usage info)

or wrapper call around p4_defined

FORTH
[DEFINED] ( [name] -- flag )(); 
 ;

Search the dictionary for _name_. If _name_ is found, return TRUE; otherwise return FALSE. Immediate for use in definitions.

  

This word will actually return what FIND returns (the NFA). does check for the word using find (so it does not throw like ' ) and puts it on stack. As it is immediate it does work in compile-mode too, so it places its argument in the cs-stack then. This is most useful with a directly following [IF] clause, so that sth. like an [IFDEF] word can be simulated through [DEFINED] word [IF]

 : [DEFINED] DEFINED ; IMMEDIATE
 : [DEFINED] BL WORD COUNT (FIND-NFA) ; IMMEDIATE
 
FORTH
[UNDEFINED] ( [name] -- flag )(); 
 ;

Search the dictionary for _name_. If _name_ is found, return FALSE; otherwise return TRUE. Immediate for use in definitions.

see [DEFINED]

 : [UNDEFINED] DEFINED 0= ; IMMEDIATE
 

debug wordset

description

PFE-DEBUG --- analyze compiled code

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Portable Forth Environment provides a decompiler for colon words and a single stepper for debugging. After setting a breakpoint at a word saying DEBUG word. The next time the word gets executed the single stepper takes control.

When this happens you see the top stack items displayed in one line. The topmost stack item is the first in line, the second and following stack items are displayed throughout the end of line. This line is empty if the stack is empty when the word in question executes.

On the next line you see the first word to become executed inside the debugged word. There is a prompt <tt>&gt;</tt> to the right of the displayed word. At this prompt you have several options. Choose one by typing a key ([h] shows helpscreen):

 [enter], [x], [k], [down] 

The displayed word will be executed without single stepping. Note that the execution of the word is slowed down a little compared to execution outside the single stepper. This is because the single stepper has to keep control to detect when the word has finished.

After the actual word finished execution the resulting stack is printed on the current line. The next line shows the next word to become executed.

Having repeated this step several times, you can see to the the right of every decompiled word what changes to the stack this word caused by comparing with the stack display just one line above.

 [d], [l], [right] 

Begin single step the execution of the actual word. The first word to become executed inside the definition is displayed on the next line. The word's display is intended by two spaces for each nesting level.

You can single step through colon-definitions and the children of defining words. Note that most of the words in PFE are rewritten in C for speed, and you can not step those kernel words.

 [s], [j], [left] 

Leaves the nesting level. The rest of the definition currently being executed is run with further prompt. If you leave the outmost level, the single stepper won't get control again. Otherwise the debugger stops after the current word is finished and offers the next word in the previous nesting level.

 [space] 

The next word to be executed is decompiled. This should help to decide as if to single step that word.

 [q] 

Quits from the debugger. The execution of the debugged word is not continued. The stacks are not cleared or changed.

 [c] 

Displays the profiling instruction counter.

 [r] 

Reset the instruction counter, to profile some code. The debugger counts how often the inner interpreter i.e. how many Forth-primitives are executed. Use this option to reset the counter to 0 to measure an arbitrary part of code.

FORTH

DEBUG ( 'word' -- )();
p4:"debug";

this word will place an debug-runtime into the CFA of the following word. If the word gets executed later, the user will be prompted and can decide to single-step the given word. The debug-stepper is interactive and should be self-explanatory. (use NO-DEBUG to turn it off again)

FORTH

NO-DEBUG ( 'word' -- )();
p4:"no-debug";

the inverse of " DEBUG word "

FORTH

(SEE) ( .. )();
as:"paren-see";

ordinary primitive (SEE)

an executable word (no special usage info)

or wrapper call around p4_paren_see

FORTH
ADDR>NAME ( addr -- nfa|0 )(); 
 ;

search the next corresponding namefield that address is next too. If it is not in the base-dictionary, then just return 0 as not-found.

_export const p4char * p4_addr_to_name (const p4char* addr)
FORTH

COME_BACK ( -- )();
p4:"come-back";

show the return stack before last exception along with the best names as given by ADDR>NAME

ENVIRONMENT

PFE-DEBUG ( .. )();
as:"pfe-minus-debug";

threadstate valueGET PFE-DEBUG

maxlevel (no special usage info)

dlfcn wordset

description

-- Words for dynmaic loading of code modules

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This file exports a set of system words for dynamic loading of code modules.

FORTH

(LOADM) ( .. )();
as:"paren-loadm";

ordinary primitive (LOADM)

an executable word (no special usage info)

or wrapper call around p4_paren_loadm

FORTH

LOADM ( 'filename' -- )();
p4:"loadm";

dlmap the shared object (or share an already mapped object) and run the per-thread initialization code. This is the user-convenient function, otherwise use (LOADM)

 simulate:
   : LOADM  BL WORD   
     ((IS_MODULE_LOADED)) IF EXIT THEN 
     HERE (LOADM)  0= IF ." -- load failed: " HERE COUNT TYPE CR THEN ;
 
FORTH
LOCAL-DLSYM ( [symbolname] -- address )exec-only(); 
 ;

lookup the symbol that follows and leave the address (or null)

FORTH
LOCAL-DLCALL ( .. )(); 
 ;

immediate primitive LOCAL-DLCALL

an executable word (no special usage info)

or wrapper call around p4_local_dlcall

FORTH

DLSYM ( .. )();
as:"dlsym";

obsolete immediate DLSYM

is doing the same as LOCAL-DLSYM

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

FORTH

DLCALL ( .. )();
as:"dlcall";

obsolete immediate DLCALL

is doing the same as LOCAL-DLCALL

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

CALL-C ( .. )();
as:"call-minus-c";

ordinary primitive CALL-C

an executable word (no special usage info)

or wrapper call around p4_call_c

EXTENSIONS

USELIBRARY ( .. )();
as:"uselibrary";

ordinary primitive USELIBRARY

an executable word (no special usage info)

or wrapper call around p4_uselibrary

EXTENSIONS

lt_dlinit ( -- ior )();
p4:"lt-dlinit";

initialiize library, usually open the program itself so that its handles can be found under "0"

EXTENSIONS
lt_dlopenext ( name-ptr,len -- handle-ptr|0 )(); 
 ;

walk the searchpath for dlopen and try to open a binary module under the given name with the usual file extension for the current system.

EXTENSIONS
lt_dlsym ( name-ptr,len handle -- symbol-addr|0)(); 
 ;

try to find the name in the binary module denoted by its handle .. if handle is null, use the main body of the program

EXTENSIONS
lt_dlclose ( handle -- ior )(); 
 ;

close handle that was returned by lt_dlopenext

EXTENSIONS
lt_dlerror ( -- z-string* )(); 
 ;

returns string describing the last dlerror as for lt_dlopenext and lt_dlsym

internal wordset

description

-- Words to open a shared prim-module pre-linked to the executable

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This file exports a set of words referencing loader-wordsets of shared-lib prim-modules that have been pre-linked to the executable. It is formed to be a list of internal modules that are used by the dl-loader facilities. This internal-module-llist is commonly used if the target system does not support a nice way of creating shared-libs and binding them at runtime. It is a kind of libtool dlpreopen facility that is implemented here, in that it also works on some of the more peculiar embedded hostsystems around.

double wordset

description
 DOUBLE-EXT ---  The Optional Double Number Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Double Numbers use two cells per number.

The forth text interpreter' number is conversion is changed to see numbers immediatly followed by a decimal point as a two-cell number. Entering decimal 1234 leaves a single-cell number 1234 on the stack, and entering decimal 1234. leaves the double cell number 1234 0 on the stack.

FORTH
2CONSTANT ( x1 x2 "name" -- )(); 
 ;

create a word that contains the specified twocell number in its body. when the name is executed, these numbers are left on the stack

   12. 2CONSTANT X .s 
   <emtpy stack> ok
   X .s
   0 12 ok
 

dpANS 8.6.1.0360 - standard forth word

FORTH

2VARIABLE ( -- )();
p4:"two-variable";

CREATE a new variable definition. When executed leave the >BODY address on stack. In pfe, the data area of a 2VARIABLE is ERASEd initially.

dpANS 8.6.1.0440 - standard forth word

FORTH
2LITERAL ( x1 x2 -- )immediate(); 
 ;

compile a double-cell number to the current definition. When run, the doubele-cell is left on the stack for execution.

   ( -- x1 x2 )

(in most configurations this word is statesmart and it will do nothing in interpret-mode. See 2LITERAL, for a non-immediate variant)

dpANS 8.6.1.0390 - standard forth word

FORTH
D+ ( d1.ud1 d2.ud2 -- d3.ud3 )(); 
 ;

the double-cell sum operation ( + )

dpANS 8.6.1.1040 - standard forth word

FORTH

D- ( .. )();
as:"d-minus";

ordinary primitive D-

an executable word (no special usage info)

or wrapper call around p4_d_minus

dpANS 8.6.1.1050 - standard forth word

FORTH

D. ( d1.d1 -- )();
p4:"d-dot";

freefield output for a double-cell number ( . )

dpANS 8.6.1.1060 - standard forth word

FORTH

D.R ( d1.d1 n -- )();
p4:"d-dot-r";

aligned output for a double-cell number ( .R )

dpANS 8.6.1.1070 - standard forth word

FORTH

D0< ( d1.d1 -- flag )();
p4:"d-zero-less";

the double-cell less-than-zero operation ( 0< )

FORTH

D0= ( d1.d1 -- flag )();
p4:"d-zero-equals";

the double-cell equal-to-zero operation ( 0= )

dpANS 8.6.1.1080 - standard forth word

FORTH

D2* ( d1.d1 -- d1.d1' )();
p4:"d-two-star";

the double-cell arithmetic shiftleft-by-1 operation ( 2* )

dpANS 8.6.1.1090 - standard forth word

FORTH

D2/ ( d1.d1 -- d1.d1' )();
p4:"d-two-slash";

the double-cell arithmetic shiftright-by-1 operation ( 2/ )

dpANS 8.6.1.1100 - standard forth word

FORTH

D< ( d1.d1 d2.d2 -- flag )();
p4:"d-less";

the double-cell is-less operation ( < )

FORTH

D= ( d1.d1 d2.d2 -- flag )();
p4:"d-equals";

the double-cell is-equal operation ( = )

dpANS 8.6.1.1120 - standard forth word

FORTH

D>S ( d.d -- n )();
p4:"d-to-s";

result is the numeric equivalent of d. If the double number was greater than what could fit into a single cell number, the modulo cellsize will be left since the higher-significant bits are just DROPed

FORTH

DABS ( d1.d1 -- d1.d1' )();
p4:"d-abs";

the double-cell abs operation ( ABS )

dpANS 8.6.1.1160 - standard forth word

FORTH
DMAX ( d1.d1 d2.d2 -- d1.d1|d2.d2 )(); 
 ;

the double-cell max operation ( MAX )

dpANS 8.6.1.1210 - standard forth word

FORTH
DMIN ( d1.d1 d2.d2 -- d1.d1|d2.d2 )(); 
 ;

the double-cell max operation ( MIN )

dpANS 8.6.1.1220 - standard forth word

FORTH
DNEGATE ( d1.d1 -- d1.d1' )(); 
 ;

the double-cell arithmetic negate operation ( NEGATE )

dpANS 8.6.1.1230 - standard forth word

FORTH
M*/ ( d1.d1 n1 +n2 -- d2.d2 )(); 
 ;

the double-cell multiply-divide operation using a triple-cell intermediate result for * ( *\/ )

dpANS 8.6.1.1820 - standard forth word

FORTH

M+ ( d1.d1 n1 -- d2.d2 )();
p4:"m-plus";

the double-cell mixed-operand sum operation ( + / D+ )

dpANS 8.6.1.1830 - standard forth word

ENVIRONMENT

DOUBLE-EXT ( .. )();
as:"double-minus-ext";

( 1994  )  constant DOUBLE-EXT

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-D ( .. )();
as:"max-minus-d";

ordinary primitive MAX-D

an executable word (no special usage info)

or wrapper call around p__max_d

ENVIRONMENT

MAX-UD ( .. )();
as:"max-minus-ud";

ordinary primitive MAX-UD

an executable word (no special usage info)

or wrapper call around p__max_ud

double_misc wordset

description

-- miscellaneous useful extra words for DOUBLE-EXT

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words. ... for DOUBLE-EXT (which is almost complete... just almost)

FORTH
2ROT ( d1,d1 d2,d2 d3,d3 -- d2,d2 d3,d3 d1,d1 )(); 
 ;

the double-cell ROT operation. actively moves six cells, i.e.

   ( x1 x2 x3 x4 x5 x6 -- x3 x4 x5 x6 x1 x2 )
 

dpANS 8.6.2.0420 - standard forth word

FORTH
DU< ( d1,d1 d2,d2 -- flag )(); 
 ;

the double-cell unsigned-is-less operation ( U< )

FORTH

LITERAL, ( value -- )();
p4:"literal-comma";

take the value from stack (or cs-stack) and compile a runtime-code and the value as for LITERAL ... this word is never state-smart, it is not immediate, and has therefore no complications with POSTPONE (compare also with COMPILE, to make a call-stub with an exectoken)

FORTH
2LITERAL, ( x1,x2 -- )(); 
 ;

take the double-value from stack (or cs-stack) and compile a runtime-code and the value as for 2LITERAL ... this word is never state-smart, it is not immediate, and has therefore no complications with POSTPONE (compare also with COMPILE, to make a call-stub with an exectoken)

dstrings wordset

description

-- Dynamic-Strings words

Copyright (C) 2001, 2002 David N. Williams

This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version.

This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details.

You should have received a copy of the GNU Lesser General Public License along with this library; if not, write to the Free Software Foundation, 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.

If you take advantage of the option in the LGPL to put a particular version of this library part under the GPL, the author would regard it as polite if you would put any direct modifications under the LGPL as well, and include a copy of this request near the beginning of the modified library source. A "direct modification" is one that enhances or extends the library in line with its original concept, as opposed to developing a distinct application or library which might use it.

This code is based on the ^Forth Motorola 680x0 strings package as of June, 1999.

Please direct any comments to david.n.williams@umich.edu.

FORTH

EMPTY$ ( $: -- empty$ )();
p4:"empty-str";

Push the MSA of a fixed, external representation of the empty string onto the string stack. <ansref>"empty-string"</ansref>

FORTH

\n$ ( $: -- newline$ )();
p4:"newline-str";

Push the MSA of a fixed, external string whose body is the Unix newline character onto the string stack. <ansref>"newline-string"</ansref>

FORTH

DSTRINGS ( .. )();
as:"dstrings";

threadstate variable DSTRINGS

dstrings (no special usage info)

FORTH
S, ( addr len -- addr' len )(); 
 ;

ALLOT room and store the Forth string into data space as an mstring, leaving data space aligned; and leave the length and new body address. It is assumed that len is unsigned. An error is thrown if len is larger than the system parameter MAX_DATA_STR. <ansref>"s-comma"</ansref>

NOTE: MAX_DATA_STR is returned by

   S" /SCOPY" ENVIRONMENT?

Perhaps this restriction should be removed in favor of a normal data space overflow error.

NOTE: S, is the same as STRING, in Wil Baden's Tool Belt, except it stores a measured string instead of a counted string.

FORTH

0STRINGS ( -- )();
p4:"zero-strings";

Set all string variables holding bound string values in string space to the empty string, and clear string space, including the string buffer, string stack, and string stack frames. <ansref>"zero-strings"</ansref>

NOTE: If used for under the hood development, this word must be executed only when string space is in a valid state.

FORTH

$GC-OFF ( .. )();
as:"str-gc-minus-off";

ordinary primitive $GC-OFF

an executable word (no special usage info)

or wrapper call around p4_str_gc_off

FORTH

$GC-ON ( .. )();
as:"str-gc-minus-on";

ordinary primitive $GC-ON

an executable word (no special usage info)

or wrapper call around p4_str_gc_on

FORTH

$UNUSED ( .. )();
as:"str-unused";

ordinary primitive $UNUSED

an executable word (no special usage info)

or wrapper call around p4_str_unused

FORTH
COLLECT-$GARBAGE ( -- collected-flag )(); 
 ;

If string space is not marked as containing garbage, return false. If there is garbage, throw an error when garbage collection is disabled. Otherwise remove the garbage and return true. Garbage collection is "transparent", so the user would not normally use this word. <ansref>"collect-string-garbage"</ansref>

FORTH

$GARBAGE? ( -- flag )();
str:"garbage-Q";

Leave true if there is garbage in the current string space. Not normally used, since garbage collection is transparent. <ansref>"string-garbage-question"</ansref>

 
FORTH
MAKE-$SPACE ( size #frames -- addr )(); 
 ;

Allocate and initialize a string space with size bytes available for the string buffer including the string stack, and with a string frame stack for frame description entries holding up to #frames. The size is rounded up to cell alignment, and the buffer begins and ends with cell alignment. Return addr, the address of the string space. The standard word FREE with addr as input can be used to release the space. <ansref>"make-string-space"</ansref>

FORTH

(M$:) ( .. )();
as:"paren-m-str-colon";

compiling primitive (M$:)

an executable word (no special usage info)

or wrapper call around p4_marg_execution

FORTH

$" ( [ccc<">] -- $: str )();
p4:"str-quote";

Parse ccc delimited by " (double-quote) and store it in data space as an mstring. If interpreting, leave the MSA on the string stack. If compiling, append run-time semantics to the current definition that leaves the MSA on the string stack. A program should not alter the stored string. An error is thrown if the quoted string length is larger than the system parameter MAX_DATA_STR (see S,). <ansref>"string-quote"</ansref>

NOTE: In contrast to S", the string stored by $" when interpreting is not transient.

The implementation is based on PFE code for S".

FORTH
$CONSTANT ( "name" $: a$ -- )(); 
 ;

Create a definition for "name" with the execution semantics "name" execution: ($: -- a$ )

It is assumed that the input string resides as a measured, unchanging string outside of string space. <ansref>"string-constant"</ansref>

For example:

   $" This is a sample string." $constant sample$
 
FORTH
$VARIABLE ( "name" -- )(); 
 ;
   "name" execution:	( -- dfa )

Create an ordinary Forth variable and initialize it to the address of a fixed, external, measured representation of the empty string, such as that pushed onto the string stack by EMPTY$. <ansref>"string-variable"</ansref>"

FORTH

($: ( .. )();
as:"note-str-colon";

immediate primitive ($:

an executable word (no special usage info)

or wrapper call around p4_paren

FORTH
ARGS{ ( arg1'$ ... argN'$ "arg1 ... argN <}>" -- )(); 
 ;
    compilation: ( -- $: arg1$ ... argN$ )

Immediate and compilation-only.

Copy the argument strings to the string buffer, push them onto the string stack with "argN" the most accessible, and make them into the top compile-time string stack frame. Compile the run-time code to make an argument frame out of the N most accessible run-time string stack entries. Inform the system text interpreter that it should compile run-time code for any white-space delimited argument encountered in the text of the definition, that concatenates the corresponding string in the run-time frame. At the semicolon terminating the definition, drop the compile-time argument frame and compile code to drop the run-time argument frame. <ansref>"args-brace"</ansref>

Syntax for defining a string macro GEORGE:

	: george  ($: a$ b$ c$ -- cat$ )
	  args{ arg1 arg2 arg3 }
	  cat" This is arg1:  " arg1 cat" ." ENDCAT ;

The blank following the last argument is required. For a macro with no arguments, ARGS{ } does nothing but add useless overhead and should be omitted. Two of the arguments in this example are ignored and could have been left out. Words intended only as steps in building a macro would omit ENDCAT, which terminates concatenation and leaves the concatenated string on the string stack.

Sample syntax using the string macro GEORGE:

    $" bill"  $" sue"  $" marie"  george $.

The resulting display is:

     This is arg1:  bill.

NOTE: Macro argument labels must be distinct from each other and from any local labels that appear in the same definition, and there is no check for that.

NOTE: At the moment the semantics of ARGS{ is undefined before DOES>.

FORTH

CAT" ( "ccc<quote>" -- )();
p4:"cat-quote";

This word has only compile-time semantics, just like CAT`. It appends run-time semantics to the current definition that concatenates the quoted string according to the specification for CAT. An error is thrown if the length of the quoted string is longer than the system parameter MAX_DATA_STR (see S,). <ansref>"cat-quote"</ansref>

FORTH
CAT` ( "ccc<backtick>" -- )(); 
 ;

This word has only compile-time semantics, just like CAT". It appends run-time semantics to the current definition that concatenates the back-ticked string according to the specification for CAT. An error is thrown if the length of the quoted string is longer than the system parameter MAX_DATA_STR (see S,). <ansref>"cat-back-tick"</ansref>

FORTH
$2DROP ( $: a$ b$ -- )(); 
 ;

Drop the two topmost string stack entries, marking them as garbage if appropriate. <ansref>"string-two-drop"</ansref>

FORTH
$2DUP ( $: a$ b$ -- a$ b$ a$ b$ )(); 
 ;

Leave copies of the two topmost string stack entries. The string values are not copied. <ansref>"string-two-dupe"</ansref>

FORTH

$DEPTH ( -- n )();
p4:"str-depth";

Leave the number of items on the string stack. <ansref>"string-depth"</ansref>

FORTH

$DROP ( $: a$ -- )();
p4:"str-drop";

Drop the topmost string stack entry, marking it as garbage if it is initially bound to the top of the string stack. <ansref>"string-drop"</ansref>

FORTH

$DUP ( $: a$ -- a$ a$ )();
p4:"str-dup";

Leave a copy of the topmost string stack entry. The string value is not copied. <ansref>"string-dupe"</ansref>

FORTH

$NIP ($: a$ b$ -- b$ )();
p4:"str-nip";

Drop the next to top item from the string stack. <ansref>"string-nip"</ansref>

NOTE: Because of essential string space bookkeeping, the system level implementation can be little more efficient than the high-level definition:

     	: $NIP  $SWAP $DROP ;
 
FORTH
$OVER ( $: a$ b$ -- a$ b$ a$ )(); 
 ;

Leave a copy of the next most accessible string stack entry on top of the string stack. The string value is not copied. <ansref>"string-over"</ansref>

FORTH
$PICK ( u $: au$ ... a0$ -- au$ ... a0$ au$ )(); 
 ;

Copy the u-th string stack entry to the top of the string stack. The string value is not copied. Throw an error if the input string stack does not have at least u+1 items. <ansref>"string-pick"</ansref>

FORTH
$SWAP ( $: a$ b$ -- b$ a$ )(); 
 ;

Exchange the two most accessible strings on the string stack. Throw an error if there are less than two strings on the stack. Neither string value is copied. <ansref>"string-swap"</ansref>

FORTH
$S> ( $: a$ -- S: a.str )(); 
 ;

Drop a$ from the string stack and leave it as a Forth string a.str, without copying. <ansref>"string-s-from"</ansref>

WARNING: If a$ is a bound string, it may move or disappear at the next garbage collection, making a.str invalid. This can be avoided by sandwiching sections of code where this could occur between $GC-OFF and $GC-ON.

FORTH
$S>-COPY ( $: a$ -- S: a.str )(); 
 ;

Drop a$ from the string stack, copy it into data space as a measured string, and leave it as a Forth string a.str. An error is thrown if the string length is larger than the system parameter MAX_DATA_STR (see S,). <ansref>"string-s-from-copy"</ansref>

FORTH
$S@ ( $: a$ -- a$ S: a.str )(); 
 ;

Leave the string stack unchanged, and leave the string body address and length on the data stack. <ansref>"string-s-fetch"</ansref>

NOTE: In earlier versions this was call $S@S. The trailing "S" is superfluous if it is understood that the only string format that usually appears on the data stack is the Forth string format.

WARNING: If a$ is a bound string, it may move at the next garbage collection, making a.str invalid. This can be avoided by sandwiching sections of code where this could occur between $GC-OFF and $GC-ON.

FORTH
$TUCK ($: a$ b$ -- b$ a$ b$ )(); 
 ;

Copy the top string stack item just below the second item. The string value is not copied. <ansref>"string-tuck"</ansref>

NOTE: Because of essential string space bookkeeping, the system level implementation can be little more efficient than the high-level definition:

 	: $TUCK  $SWAP $OVER ;
 
FORTH
>$S-COPY ( a.str -- $: a$ )(); 
 ;

Copy the external string value whose body address and count are on the parameter stack into the string buffer and push it onto the string stack. Errors are thrown if the count is larger than MAX_MCOUNT, if there is not enough room in string space, even after garbage collection, or if there is an unterminated string concatenation. The input external string need not exist as a measured string. <ansref>"to-string-s-copy"</ansref>

NOTE: MAX_MCOUNT is the largest size the count field of a measured string can hold, e.g., 255, 64K-1, or 4,096M-1. It is returned by: S" /DYNAMIC-STRING" ENVIRONMENT?

WARNING: This word should not be used when the input string is a bound string because the copy operation may generate a garbage collection which invalidates its MSA.

FORTH

>$S ( a.str -- $: a$ )();
p4:"to-str-s";

Push the external Forth string a.str onto the string stack, without copying the string value into the string buffer. It is an unchecked error if the Forth string a.str is not stored as an external measured string. <ansref>"to-string-s"</ansref>

WARNING: If the string value of a.str is actually in the string buffer and not external, the push operation may generate a garbage collection that invalidates its MSA.

FORTH

$! ( $var.dfa $: a$ -- )();
p4:"str-store";

Store the string MSA on the string stack in the variable whose DFA is on the parameter stack. <ansref>"string-store"</ansref>

NOTES: The only situation in which $! copies the string value is when it is a bound string already stored in another variable. In that case, the new copy is the one that is stored in the variable. In particular, external strings are not copied.

If the string value held by the string variable on entry is a bound string that is also referenced deeper on the string stack, its back link is reset to point to the deepest string stack reference. If it is a bound string not deeper on the string stack and not identical to the input string, its back link is set to zero, making it garbage. If it is an external string, its MSA in the variable is simply written over by that popped from the string stack.

FORTH

$. ( $: a$ -- )();
p4:"str-dot";

Display the string on the terminal. If the system implementation of TYPE has its output vectored, $. uses the same vector. <ansref>"string-dot"</ansref>

FORTH

$TYPE ( .. )();
as:"str-type";

ordinary primitive $TYPE

an executable word (no special usage info)

or wrapper call around p4_str_dot

FORTH

$@ ( $var.pfa -- $: a$ )();
p4:"str-fetch";

Leave the MSA of the string held by the string variable. <ansref>"string-fetch"</ansref>

FORTH

CAT ($: a$ -- )();
p4:"cat";

Append the string body to the end of the string currently being concatenated as the last string in the string buffer, and update its count field. If there is no concatenating string, start one. An error is thrown if the size of the combined string would be larger than MAX_MCOUNT or if there is not enough room in string space even after a garbage collection.

If garbage collection occurs, a$ remains valid even when it is in the string buffer.

 

When there is a concatenating string, concatenation is the only basic string operation that can copy a string into the string buffer. <ansref>"cat"</ansref>

NOTE: It is left to the user to define special concatenating words like:

    : \n-cat  ( -- )  \n$ cat ;
 
FORTH

S-CAT ( a.str -- )();
p4:"s-cat";

Append the Forth string body to the end of the string currently being concatenated as the last string in the string buffer, and update its count field. If there is no concatenating string, start one. An error is thrown if the size of the combined string would be larger than MAX_MCOUNT or if there is not enough room in string space even after a garbage collection.

S-CAT is most commonly used on external strings, not assumed to exist as mstrings. In contrast to CAT, garbage collection could invalidate a.str if it is a dynamic string in the string buffer. S-CAT can be used in that situation if garbage collection is turned off with $GC-OFF.

 

When there is a concatenating string, concatenation is the only basic string operation that can copy a string into the string buffer. <ansref>"s-cat"</ansref>

FORTH
ENDCAT ( -- $: cat$ | empty$ )(); 
 ;

If there is no concatenating string, do nothing but leave the empty string. If there is, leave it as a string bound to the top of the string stack, and terminate concatenation, permitting normal copies into the string buffer. <ansref>"end-cat"</ansref>

FORTH

$FRAME ( u -- )();
p4:"str-frame";

Push the description of a string stack frame starting at the top of the string stack and containing u entries onto the string frame stack. Errors are thrown if the frame stack would overflow or if the depth of the string stack above the top frame, if there is one, is less than u. The value u = 0 is allowed. <ansref>"string-frame"</ansref>

NOTE: The current implementation pushes u and the string stack pointer onto the frame stack.

FORTH

DROP-$FRAME ( -- )();
p4:"drop-str-frame";

Drop the topmost string frame from the string frame stack and string stack. Errors are thrown if either stack would underflow or if the string frame does not begin at the top of the string stack. The case where the frame has zero entries on the string stack is handled properly. <ansref>"drop-string-frame"</ansref>

FORTH
FIND-ARG ( s -- i true | false )(); 
 ;

Leave true and its index i in the top string frame if the Forth string matches an element of the frame, else leave false. The index of the top frame element is zero. <ansref>"find-arg"</ansref>

FORTH
(DROP-$FRAME) ( .. )(); 
 ;

compiling primitive (DROP-$FRAME)

an executable word (no special usage info)

or wrapper call around p4_do_drop_str_frame

FORTH

/$SPACE ( .. )();
as:"slash-str-space";

ordinary primitive /$SPACE

an executable word (no special usage info)

or wrapper call around per_str_space

FORTH
/$SPACE-HEADER ( .. )(); 
 ;

ordinary primitive /$SPACE-HEADER

an executable word (no special usage info)

or wrapper call around per_str_space_header

FORTH

$BREAK ( .. )();
as:"str-break";

ordinary primitive $BREAK

an executable word (no special usage info)

or wrapper call around str_break

FORTH

$BUFFER ( .. )();
as:"str-buffer";

ordinary primitive $BUFFER

an executable word (no special usage info)

or wrapper call around str_buffer

FORTH

$SP ( .. )();
as:"str-sp";

ordinary primitive $SP

an executable word (no special usage info)

or wrapper call around str_sp

FORTH

$SP0 ( .. )();
as:"str-sp-zero";

ordinary primitive $SP0

an executable word (no special usage info)

or wrapper call around str_sp0

FORTH

#FRAMES ( .. )();
as:"sharp-frames";

ordinary primitive #FRAMES

an executable word (no special usage info)

or wrapper call around num_frames

FORTH
/FRAME-STACK ( .. )(); 
 ;

ordinary primitive /FRAME-STACK

an executable word (no special usage info)

or wrapper call around per_frame_stack

FORTH

$FBREAK ( .. )();
as:"str-fbreak";

ordinary primitive $FBREAK

an executable word (no special usage info)

or wrapper call around sf_break

FORTH

$FSP ( .. )();
as:"str-fsp";

ordinary primitive $FSP

an executable word (no special usage info)

or wrapper call around sf_sp

FORTH

$FSP0 ( .. )();
as:"str-fsp-zero";

ordinary primitive $FSP0

an executable word (no special usage info)

or wrapper call around sf_sp0

FORTH

0$SPACE ( .. )();
as:"zero-str-space";

ordinary primitive 0$SPACE

an executable word (no special usage info)

or wrapper call around zero_str_space

FORTH
$FRAME-DEPTH ( .. )(); 
 ;

ordinary primitive $FRAME-DEPTH

an executable word (no special usage info)

or wrapper call around frame_depth

ENVIRONMENT
DSTRINGS-EXT ( .. )(); 
 ;
( 20627 )  constant DSTRINGS-EXT

an ordinary constant (no special usage info)

ENVIRONMENT

/SCOPY ( .. )();
as:"slash-scopy";

( MAX_DATA_STR  )  constant /SCOPY

an ordinary constant (no special usage info)

ENVIRONMENT
/DYNAMIC-STRING ( .. )(); 
 ;
( MAX_MCOUNT  )  constant /DYNAMIC-STRING

an ordinary constant (no special usage info)

ENVIRONMENT
DSTRINGS-LOADED ( .. )(); 
 ;

constructor primitive DSTRINGS-LOADED

an executable word (no special usage info)

or wrapper call around dstrings_init

edit wordset

description

-- simple FORTH-screenfile editor

Copyright (C) Tektronix, Inc. 1998 - 2000. All rights reserved.

description: This is a simple fullscreen FORTH block editor.

will be missing in most builds

EXTENSIONS
<<edit-init>> ( .. )(); 
 ;

constructor primitive <<edit-init>>

an executable word (no special usage info)

or wrapper call around p4_edit_init

EXTENSIONS

EDIT-BLOCK ( blk -- )();
p4:"edit-block";

start the internal block-editor on the assigned block

EXTENSIONS

EDIT-TEXT ( .. )();
as:"edit-minus-text";

ordinary primitive EDIT-TEXT

an executable word (no special usage info)

or wrapper call around p4_edit_text

EXTENSIONS

EDIT-ERROR ( -- )();
p4:"edit-error";

if an error occured, this routine can be called to invoke an appropriate EDITOR (see also EDIT-BLOCK)

FORTH
EDIT-BLOCK-START ( .. )(); 
 ;

ordinary primitive EDIT-BLOCK-START

an executable word (no special usage info)

or wrapper call around p4_edit_block

environ wordset

description

-- Extended Environment related definitions

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: gforth and win32for are also using an extra ENVIRONMENT wordlist to register hints on the system environment. It is just a normal VOCABULARY that can be searched&executed with ENVIRONMENT? . In pfe, the environment wordlist does also register the extension status of the system including allocated slots, loaded binaries and REQUIRED source files.

FORTH
ENVIRONMENT-WORDLIST ( .. )(); 
 ;

- loader type P4_DVaL ENVIRONMENT-WORDLIST

environ_wl (no special usage info)

FORTH
ENVIRONMENT? ( a1 n1 -- false | ?? true )(); 
 ;

check the environment for a property, usually a condition like questioning the existance of specified wordset, but it can also return some implementation properties like "WORDLISTS" (the length of the search-order) or "#LOCALS" (the maximum number of locals)

Here it implements the environment queries as a SEARCH-WORDLIST in a user-visible vocabulary called ENVIRONMENT

 : ENVIRONMENT?
   ['] ENVIRONMENT >WORDLIST SEARCH-WORDLIST
   IF  EXECUTE TRUE ELSE  FALSE THEN ;
 

dpANS .6.1.1345 - standard forth word

FORTH
REQUIRED ( ... str-ptr str-len -- ??? )(); 
 ;

the filename argument is loaded via INCLUDED as an extension package to the current system. The filename is registered in the current ENVIRONMENT so that it is only INCLUDED once (!!) if called multiple times via REQUIRED or REQUIRES

FORTH
REQUIRES ( ... "name" -- ??? )(); 
 ;

parses the next WORD and passes it to REQUIRED this is the self-parsing version of REQUIRED and it does parrallel INCLUDE w.r.t. INCLUDED

FORTH

NEEDS ( name -- )();
p4:"needs-environment";

A self-parsing variant of an environment-query check. It is similar to a simulation like

 : NEEDS PARSE-WORD 2DUP ENVIRONMENT? 
   IF DROP ( extra value ) 2DROP ( success - be silent )
   ELSE TYPE ." not available " CR THEN ;

however that would only match those worset-envqueries which return a single extra item under the uppermost TRUE flag in the success case. Instead it works more like

 : NEEDS PARSE-WORD 2DUP ENVIRONMENT-WORDLIST SEARCH-WORDLIST
   IF 2DROP ( success - be silent and just drop the parsed word )
   ELSE TYPE ." not available " CR THEN ;

however we add the same extension as in ENVIRONMENT? as that it can automatically load a wordset module to fullfil a query that looks like "[wordsetname]-ext". Therefore, the following two lines are pretty much identical:

 LOADM floating
 NEEDS floating-ext

the difference between the two: if somebody did provide a forth level implementation of floating-ext then that implementation might have registered a hint "floating-ext" in the environment-wordlist. This extra-hint will inhibit loading of the binary module even if it exists and not been loaded so far. The LOADM however will not check the ENVIRONMENT-WORDLIST and only check its loadlist of binary wordset modules in the system.

It is therefore recommended to use NEEDS instead of LOADM unless you know you want the binary module, quickly and uncondtionally.

ENVIRONMENT
ENVIRON-EXT ( .. )(); 
 ;
( 2000  )  constant ENVIRON-EXT

an ordinary constant (no special usage info)

ENVIRONMENT
HOST-SYSTEM ( .. )(); 
 ;

ordinary primitive HOST-SYSTEM

an executable word (no special usage info)

or wrapper call around p__host_system

ENVIRONMENT
FORTH-LICENSE ( .. )(); 
 ;

ordinary primitive FORTH-LICENSE

an executable word (no special usage info)

or wrapper call around p__forth_license

ENVIRONMENT
CASE-SENSITIVE? ( .. )(); 
 ;

ordinary primitive CASE-SENSITIVE?

an executable word (no special usage info)

or wrapper call around p__case_sensitive_Q

ENVIRONMENT

FORTH-NAME ( .. )();
as:"forth-minus-name";

ordinary primitive FORTH-NAME

an executable word (no special usage info)

or wrapper call around p__forth_name

ENVIRONMENT
FORTH-VERSION ( .. )(); 
 ;

ordinary primitive FORTH-VERSION

an executable word (no special usage info)

or wrapper call around p__forth_version

ENVIRONMENT
FORTH-CONTACT ( .. )(); 
 ;

ordinary primitive FORTH-CONTACT

an executable word (no special usage info)

or wrapper call around p__forth_contact

exception wordset

description

-- The Optional Exception Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: These words implement an exception system in the widely known THROW &amp; CATCH concept.

see the PFE-SIG wordset for catching OS traps.

FORTH

CATCH ( xt -- 0|n )();
p4:"catch";

execute the given execution-token and catch any exception that can be caught therein. software can arbitrarily raise an exception using THROW - the value 0 means there was no exception, other denote implementation dependent exception-codes.

dpANS 9.6.1.0875 - standard forth word

FORTH

THROW ( n -- )();
p4:"throw";

raise an exception - it will adjust the depth of all stacks and start interpreting at the point of the latest CATCH <br> if n is null nothing happens, the -1 (ie. FALSE ) is the raise-code of ABORT - the other codes are implementation dependent and will result in something quite like ABORT

dpANS 9.6.1.2275 - standard forth word

FORTH

ABORT ( -- )no-return();
p4:"abort";

throw - cleanup some things and go back to the QUIT routine

 : ABORT -1 THROW ;
 

dpANS 9.6.2.0670 - standard forth word

FORTH
ABORT" ( [string<">] -- )no-return(); 
 ;

throw like ABORT but print an additional error-message to stdout telling what has happened.

dpANS 9.6.2.0680 - standard forth word

ENVIRONMENT
EXCEPTION-EXT ( .. )(); 
 ;
( 1994  )  constant EXCEPTION-EXT

an ordinary constant (no special usage info)

EXTENSIONS
NEXT-EXCEPTION ( .. )(); 
 ;

threadstate variable NEXT-EXCEPTION

next_exception (no special usage info)

facility wordset

description

FACILITY --- The Optional Facility Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: There are the following primitive words for input and output:

KEY waits for a character typed on the keyboard and returns that character, but KEY does not return non-character input events like function keys pressed - use EKEY for a more complete keyboard query. Furthermore, KEY? returns true if a key is available for reading using KEY (function key presses are not detected but discarded).

EMIT will display the character at the current cursor position, control characters take effect depending on the system. TYPE displays all the chars in the given string buffer.

To get the current cursor position, use AT-XY.

FORTH

AT-XY ( col row -- )();
p4:"at-x-y";

move the cursor position to the given row and column of the screen. If the output device is not a terminal this will have no effect but can still send an escape sequence.

dpANS 10.6.1.0742 - standard forth word

FORTH

KEY? ( -- flag )();
p4:"key-question";

if a character is available from the keyboard, return true. The KEY word will retrieve the actual character.

dpANS 10.6.1.1755 - standard forth word

FORTH

PAGE ( .. )();
as:"page";

ordinary primitive PAGE

an executable word (no special usage info)

or wrapper call around p4_dot_clrscr

dpANS 10.6.1.2005 - standard forth word

FORTH

EKEY ( -- keycode )();
p4:"ekey";

return a keyboard event, the encoding may differ, esp. that it can contain special keys.

dpANS 10.6.2.1305 - standard forth word

FORTH
EKEY>CHAR ( keycode -- keycode false | char true )(); 
 ;
FORTH

EKEY? ( -- flag )();
p4:"ekey-question";

check if a character is available from the keyboard to be received - unlike KEY? it will not discard non-visible codes.

dpANS 10.6.2.1307 - standard forth word

FORTH

EMIT? ( -- flag )();
p4:"emit-question";

if EMIT can safely output characters without blocking the forth by waiting for an indefinite time.

dpANS 10.6.2.1325 - standard forth word

FORTH

MS ( n -- )();
p4:"ms";

wait at least the specified milliseconds (suspend the forth tasklet)

dpANS 10.6.2.1905 - standard forth word

FORTH

TIME&DATE ( .. )();
as:"time-and-date";

ordinary primitive TIME&DATE

an executable word (no special usage info)

or wrapper call around p4_time_and_date

ENVIRONMENT
FACILITY-EXT ( .. )(); 
 ;
( 1994  )  constant FACILITY-EXT

an ordinary constant (no special usage info)

file wordset

description

FILE --- Optional File-Access Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Optional File-Access Word Set and File-Access Extension Words. These words imply some kind of file-system unlike the BLOCK wordset.

FORTH
BIN ( access-mode -- access-mode' )(); 
 ;

modify the give file access-mode to be a binary-mode

dpANS 11.6.1.0765 - standard forth word

FORTH
CLOSE-FILE ( file -- code )(); 
 ;

close the file and return the status-code

dpANS 11.6.1.0900 - standard forth word

FORTH
CREATE-FILE ( str-adr str-len mode -- file code )(); 
 ;

create the file with the given name and open it - returns the file id and a status code. A code of zero means success. An existing file of the same name is truncated upon open.

dpANS 11.6.1.1010 - standard forth word

FORTH
DELETE-FILE ( str-adr str-len -- code )(); 
 ;

delete the named file and return a status code

dpANS 11.6.1.1190 - standard forth word

FORTH
FILE-POSITION ( file -- p.pos code )(); 
 ;

return the current position in the file and return a status code. A code of zero means success.

dpANS 11.6.1.1520 - standard forth word

FORTH
FILE-SIZE ( file -- s.size code )(); 
 ;

return the current size of the file and return a status code. A code of zero means success.

dpANS 11.6.1.1522 - standard forth word

FORTH
INCLUDE-FILE ( file -- )(); 
 ;

INTERPRET the given file

dpANS 11.6.1.1717 - standard forth word

FORTH
INCLUDED ( str-adr str-len -- )(); 
 ;

open the named file and then INCLUDE-FILE see also the interactive INCLUDE

dpANS 11.6.1.1718 - standard forth word

FORTH
OPEN-FILE ( str-adr str-len mode -- file code )(); 
 ;

open the named file with mode. returns the file id and a status code. A code of zero means success.

dpANS 11.6.1.1970 - standard forth word

FORTH

R/O ( .. )();
as:"r-slash-o";

( FMODE_RO )  constant R/O

an ordinary constant (no special usage info)

dpANS 11.6.1.2054 - standard forth word

FORTH

R/W ( .. )();
as:"r-slash-w";

( FMODE_RW )  constant R/W

an ordinary constant (no special usage info)

dpANS 11.6.1.2056 - standard forth word

FORTH
READ-FILE ( str-adr str-len file -- count code )(); 
 ;

fill the given string buffer with characters from the buffer. A status code of zero means success and the returned count gives the number of bytes actually read. If an error occurs the number of already transferred bytes is returned.

dpANS 11.6.1.2080 - standard forth word

FORTH
READ-LINE ( str-adr str-len file -- count flag code )(); 
 ;

fill the given string buffer with one line from the file. A line termination character (or character sequence under WIN/DOS) may also be placed in the buffer but is not included in the final count. In other respects this function performs a READ-FILE

dpANS 11.6.1.2090 - standard forth word

FORTH
REPOSITION-FILE ( o.offset file -- code )(); 
 ;

reposition the file offset - the next FILE-POSITION would return o.offset then. returns a status code.

dpANS 11.6.1.2142 - standard forth word

FORTH
RESIZE-FILE ( s.size file -- code )(); 
 ;

resize the give file, returns a status code.

dpANS 11.6.1.2147 - standard forth word

FORTH

W/O ( .. )();
as:"w-slash-o";

( FMODE_WO )  constant W/O

an ordinary constant (no special usage info)

dpANS 11.6.1.2425 - standard forth word

FORTH
WRITE-FILE ( str-adr str-len file -- code )(); 
 ;

write characters from the string buffer to a file, returns a status code.

dpANS 11.6.1.2480 - standard forth word

FORTH
WRITE-LINE ( str-adr str-len file -- code )(); 
 ;

write characters from the string buffer to a file, and add the line-terminator to the end of it. returns a status code.

dpANS 11.6.1.2485 - standard forth word

FORTH
FILE-STATUS ( str-adr str-len -- sub-code code )(); 
 ;

check the named file - if it exists the status code is zero. The sub-code is implementation-specific.

dpANS 11.6.2.1524 - standard forth word

FORTH
FLUSH-FILE ( file -- code )(); 
 ;

flush all unsaved buffers of the file to disk. A status code of zero means success.

dpANS 11.6.2.1560 - standard forth word

FORTH
RENAME-FILE ( str-adr1 str-len1 str-adr2 str-len2 -- code )(); 
 ;

rename the file named by string1 to the name of string2. returns a status-code

dpANS 11.6.2.2130 - standard forth word

ENVIRONMENT

FILE-EXT ( .. )();
as:"file-minus-ext";

( 1994  )  constant FILE-EXT

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-FILES ( .. )();
as:"max-minus-files";

ordinary primitive MAX-FILES

an executable word (no special usage info)

or wrapper call around p__max_files

file_misc wordset

description

-- miscellaneous useful extra words for FILE-EXT

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words. ... for FILE-EXT

FORTH

INCLUDE ( 'filename' -- ? )();
p4:"include";

load the specified file, see also LOAD" filename"

FORTH
COPY-FILE ( src-str src-strlen dst-str dst-strlen -- errno|0 )(); 
 ;

like RENAME-FILE, copies the file from src-name to dst-name and returns an error-code or null

FORTH
MOVE-FILE ( src-str src-strlen dst-str dst-strlen -- errno|0 )(); 
 ;

like RENAME-FILE, but also across-volumes <br> moves the file from src-name to dst-name and returns an error-code or null

FORTH
FILE-R/W ( addr blk f fid -- )(); 
 ;

like FIG-Forth R/W

FORTH
FILE-BLOCK ( a file-id -- c )(); 
 ;
FORTH
FILE-BUFFER ( a file-id -- c )(); 
 ;
FORTH
FILE-EMPTY-BUFFERS ( file-id -- )(); 
 ;
FORTH
FILE-FLUSH ( file-id -- )(); 
 ;
 simulate      : FILE-FLUSH DUP FILE-SAVE-BUFFERS FILE-EMTPY-BUFFERS ;
 
FORTH
FILE-LIST ( x file-id -- )(); 
 ;
FORTH
FILE-LOAD ( x file-id -- )(); 
 ;
FORTH
FILE-SAVE-BUFFERS ( file-id -- )(); 
 ;
FORTH
FILE-THRU ( lo hi file-id -- )(); 
 ;

see THRU

FORTH
FILE-UPDATE ( file-id -- )(); 
 ;

floating wordset

description

-- The Optional Floating-Point Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Optional Floating-Point Wordset is not usually used on embedded platforms. The PFE can be configured to even not allocate the separate floating-point stack that most of the floating-point words refer to.

FORTH

>FLOAT ( .. )();
as:"back-float";

ordinary primitive >FLOAT

an executable word (no special usage info)

or wrapper call around p4_to_float

FORTH

D>F ( .. )();
as:"d-back-f";

ordinary primitive D>F

an executable word (no special usage info)

or wrapper call around p4_d_to_f

FORTH

F! ( .. )();
as:"f-store";

ordinary primitive F!

an executable word (no special usage info)

or wrapper call around p4_f_store

dpANS 12.6.1.1400 - standard forth word

FORTH

F* ( .. )();
as:"f-star";

ordinary primitive F*

an executable word (no special usage info)

or wrapper call around p4_f_star

dpANS 12.6.1.1410 - standard forth word

FORTH

F+ ( .. )();
as:"f-plus";

ordinary primitive F+

an executable word (no special usage info)

or wrapper call around p4_f_plus

dpANS 12.6.1.1420 - standard forth word

FORTH

F- ( .. )();
as:"f-minus";

ordinary primitive F-

an executable word (no special usage info)

or wrapper call around p4_f_minus

dpANS 12.6.1.1425 - standard forth word

FORTH

F/ ( .. )();
as:"f-slash";

ordinary primitive F/

an executable word (no special usage info)

or wrapper call around p4_f_slash

dpANS 12.6.1.1430 - standard forth word

FORTH

F0< ( .. )();
as:"f-zero-from";

ordinary primitive F0<

an executable word (no special usage info)

or wrapper call around p4_f_zero_less

FORTH

F0= ( .. )();
as:"f-zero-equal";

ordinary primitive F0=

an executable word (no special usage info)

or wrapper call around p4_f_zero_equal

dpANS 12.6.1.1450 - standard forth word

FORTH

F< ( .. )();
as:"f-from";

ordinary primitive F<

an executable word (no special usage info)

or wrapper call around p4_f_less_than

FORTH

F>D ( .. )();
as:"f-back-d";

ordinary primitive F>D

an executable word (no special usage info)

or wrapper call around p4_f_to_d

FORTH

F@ ( .. )();
as:"f-fetch";

ordinary primitive F@

an executable word (no special usage info)

or wrapper call around p4_f_fetch

dpANS 12.6.1.1472 - standard forth word

FORTH

FALIGN ( .. )();
as:"falign";

ordinary primitive FALIGN

an executable word (no special usage info)

or wrapper call around p4_d_f_align

dpANS 12.6.1.1479 - standard forth word

FORTH

FALIGNED ( .. )();
as:"faligned";

ordinary primitive FALIGNED

an executable word (no special usage info)

or wrapper call around p4_d_f_aligned

dpANS 12.6.1.1483 - standard forth word

FORTH

FCONSTANT ( .. )();
as:"fconstant";

definining primitive FCONSTANT

an executable word (no special usage info)

or wrapper call around p4_f_constant

dpANS 12.6.1.1492 - standard forth word

FORTH

FDEPTH ( .. )();
as:"fdepth";

ordinary primitive FDEPTH

an executable word (no special usage info)

or wrapper call around p4_f_depth

dpANS 12.6.1.1497 - standard forth word

FORTH

FDROP ( .. )();
as:"fdrop";

ordinary primitive FDROP

an executable word (no special usage info)

or wrapper call around p4_f_drop

dpANS 12.6.1.1500 - standard forth word

FORTH

FDUP ( .. )();
as:"fdup";

ordinary primitive FDUP

an executable word (no special usage info)

or wrapper call around p4_f_dup

dpANS 12.6.1.1510 - standard forth word

FORTH

FLITERAL ( .. )();
as:"fliteral";

compiling primitive FLITERAL

an executable word (no special usage info)

or wrapper call around p4_f_literal

dpANS 12.6.1.1552 - standard forth word

FORTH

FLOAT+ ( .. )();
as:"float-plus";

ordinary primitive FLOAT+

an executable word (no special usage info)

or wrapper call around p4_d_float_plus

dpANS 12.6.1.1555 - standard forth word

FORTH

FLOATS ( .. )();
as:"floats";

ordinary primitive FLOATS

an executable word (no special usage info)

or wrapper call around p4_d_floats

dpANS 12.6.1.1556 - standard forth word

FORTH

FLOOR ( .. )();
as:"floor";

ordinary primitive FLOOR

an executable word (no special usage info)

or wrapper call around p4_floor

dpANS 12.6.1.1558 - standard forth word

FORTH

FMAX ( .. )();
as:"fmax";

ordinary primitive FMAX

an executable word (no special usage info)

or wrapper call around p4_f_max

dpANS 12.6.1.1562 - standard forth word

FORTH

FMIN ( .. )();
as:"fmin";

ordinary primitive FMIN

an executable word (no special usage info)

or wrapper call around p4_f_min

dpANS 12.6.1.1565 - standard forth word

FORTH

FNEGATE ( .. )();
as:"fnegate";

ordinary primitive FNEGATE

an executable word (no special usage info)

or wrapper call around p4_f_negate

dpANS 12.6.1.1567 - standard forth word

FORTH

FOVER ( .. )();
as:"fover";

ordinary primitive FOVER

an executable word (no special usage info)

or wrapper call around p4_f_over

dpANS 12.6.1.1600 - standard forth word

FORTH

FROT ( .. )();
as:"frot";

ordinary primitive FROT

an executable word (no special usage info)

or wrapper call around p4_f_rot

dpANS 12.6.1.1610 - standard forth word

FORTH

FROUND ( .. )();
as:"fround";

ordinary primitive FROUND

an executable word (no special usage info)

or wrapper call around p4_f_round

dpANS 12.6.1.1612 - standard forth word

FORTH

FSWAP ( .. )();
as:"fswap";

ordinary primitive FSWAP

an executable word (no special usage info)

or wrapper call around p4_f_swap

dpANS 12.6.1.1620 - standard forth word

FORTH

FVARIABLE ( .. )();
as:"fvariable";

definining primitive FVARIABLE

an executable word (no special usage info)

or wrapper call around p4_f_variable

dpANS 12.6.1.1630 - standard forth word

FORTH

REPRESENT ( .. )();
as:"represent";

ordinary primitive REPRESENT

an executable word (no special usage info)

or wrapper call around p4_represent

dpANS 12.6.1.2143 - standard forth word

FORTH

DF! ( .. )();
as:"df-store";

ordinary primitive DF!

an executable word (no special usage info)

or wrapper call around p4_f_store

dpANS 12.6.2.1203 - standard forth word

FORTH

DF@ ( .. )();
as:"df-fetch";

ordinary primitive DF@

an executable word (no special usage info)

or wrapper call around p4_f_fetch

dpANS 12.6.2.1204 - standard forth word

FORTH

DFALIGN ( .. )();
as:"dfalign";

ordinary primitive DFALIGN

an executable word (no special usage info)

or wrapper call around p4_d_f_align

dpANS 12.6.2.1205 - standard forth word

FORTH

DFALIGNED ( .. )();
as:"dfaligned";

ordinary primitive DFALIGNED

an executable word (no special usage info)

or wrapper call around p4_d_f_aligned

dpANS 12.6.2.1207 - standard forth word

FORTH

DFLOAT+ ( .. )();
as:"dfloat-plus";

ordinary primitive DFLOAT+

an executable word (no special usage info)

or wrapper call around p4_d_float_plus

dpANS 12.6.2.1208 - standard forth word

FORTH

DFLOATS ( .. )();
as:"dfloats";

ordinary primitive DFLOATS

an executable word (no special usage info)

or wrapper call around p4_d_floats

dpANS 12.6.2.1209 - standard forth word

FORTH

F** ( .. )();
as:"f-star-star";

ordinary primitive F**

an executable word (no special usage info)

or wrapper call around p4_f_star_star

dpANS 12.6.2.1415 - standard forth word

FORTH

F. ( .. )();
as:"f-dot";

ordinary primitive F.

an executable word (no special usage info)

or wrapper call around p4_f_dot

dpANS 12.6.2.1427 - standard forth word

FORTH

FABS ( .. )();
as:"fabs";

ordinary primitive FABS

an executable word (no special usage info)

or wrapper call around p4_f_abs

dpANS 12.6.2.1474 - standard forth word

FORTH

FACOS ( .. )();
as:"facos";

ordinary primitive FACOS

an executable word (no special usage info)

or wrapper call around p4_f_acos

dpANS 12.6.2.1476 - standard forth word

FORTH

FACOSH ( .. )();
as:"facosh";

ordinary primitive FACOSH

an executable word (no special usage info)

or wrapper call around p4_f_acosh

dpANS 12.6.2.1477 - standard forth word

FORTH

FALOG ( .. )();
as:"falog";

ordinary primitive FALOG

an executable word (no special usage info)

or wrapper call around p4_f_alog

dpANS 12.6.2.1484 - standard forth word

FORTH

FASIN ( .. )();
as:"fasin";

ordinary primitive FASIN

an executable word (no special usage info)

or wrapper call around p4_f_asin

dpANS 12.6.2.1486 - standard forth word

FORTH

FASINH ( .. )();
as:"fasinh";

ordinary primitive FASINH

an executable word (no special usage info)

or wrapper call around p4_f_asinh

dpANS 12.6.2.1487 - standard forth word

FORTH

FATAN ( .. )();
as:"fatan";

ordinary primitive FATAN

an executable word (no special usage info)

or wrapper call around p4_f_atan

dpANS 12.6.2.1488 - standard forth word

FORTH

FATAN2 ( .. )();
as:"fatan-two";

ordinary primitive FATAN2

an executable word (no special usage info)

or wrapper call around p4_f_atan2

dpANS 12.6.2.1489 - standard forth word

FORTH

FATANH ( .. )();
as:"fatanh";

ordinary primitive FATANH

an executable word (no special usage info)

or wrapper call around p4_f_atanh

dpANS 12.6.2.1491 - standard forth word

FORTH

FCOS ( .. )();
as:"fcos";

ordinary primitive FCOS

an executable word (no special usage info)

or wrapper call around p4_f_cos

dpANS 12.6.2.1493 - standard forth word

FORTH

FCOSH ( .. )();
as:"fcosh";

ordinary primitive FCOSH

an executable word (no special usage info)

or wrapper call around p4_f_cosh

dpANS 12.6.2.1494 - standard forth word

FORTH

FE. ( .. )();
as:"fe-dot";

ordinary primitive FE.

an executable word (no special usage info)

or wrapper call around p4_f_e_dot

dpANS 12.6.2.1513 - standard forth word

FORTH

FEXP ( .. )();
as:"fexp";

ordinary primitive FEXP

an executable word (no special usage info)

or wrapper call around p4_f_exp

dpANS 12.6.2.1515 - standard forth word

FORTH

FEXPM1 ( .. )();
as:"fexpm-one";

ordinary primitive FEXPM1

an executable word (no special usage info)

or wrapper call around p4_f_expm1

dpANS 12.6.2.1516 - standard forth word

FORTH

FLN ( .. )();
as:"fln";

ordinary primitive FLN

an executable word (no special usage info)

or wrapper call around p4_f_ln

dpANS 12.6.2.1553 - standard forth word

FORTH

FLNP1 ( .. )();
as:"flnp-one";

ordinary primitive FLNP1

an executable word (no special usage info)

or wrapper call around p4_f_lnp1

dpANS 12.6.2.1554 - standard forth word

FORTH

FLOG ( .. )();
as:"flog";

ordinary primitive FLOG

an executable word (no special usage info)

or wrapper call around p4_f_log

dpANS 12.6.2.1557 - standard forth word

FORTH

FS. ( .. )();
as:"fs-dot";

ordinary primitive FS.

an executable word (no special usage info)

or wrapper call around p4_f_s_dot

dpANS 12.6.2.1613 - standard forth word

FORTH

FSIN ( .. )();
as:"fsin";

ordinary primitive FSIN

an executable word (no special usage info)

or wrapper call around p4_f_sin

dpANS 12.6.2.1614 - standard forth word

FORTH

FSINCOS ( .. )();
as:"fsincos";

ordinary primitive FSINCOS

an executable word (no special usage info)

or wrapper call around p4_f_sincos

dpANS 12.6.2.1616 - standard forth word

FORTH

FSINH ( .. )();
as:"fsinh";

ordinary primitive FSINH

an executable word (no special usage info)

or wrapper call around p4_f_sinh

dpANS 12.6.2.1617 - standard forth word

FORTH

FSQRT ( .. )();
as:"fsqrt";

ordinary primitive FSQRT

an executable word (no special usage info)

or wrapper call around p4_f_sqrt

dpANS 12.6.2.1618 - standard forth word

FORTH

FTAN ( .. )();
as:"ftan";

ordinary primitive FTAN

an executable word (no special usage info)

or wrapper call around p4_f_tan

dpANS 12.6.2.1625 - standard forth word

FORTH

FTANH ( .. )();
as:"ftanh";

ordinary primitive FTANH

an executable word (no special usage info)

or wrapper call around p4_f_tanh

dpANS 12.6.2.1626 - standard forth word

FORTH

F~ ( .. )();
as:"f-like";

ordinary primitive F~

an executable word (no special usage info)

or wrapper call around p4_f_proximate

dpANS 12.6.2.1640 - standard forth word

FORTH

PRECISION ( .. )();
as:"precision";

- loader type P4_DVaL PRECISION

precision (no special usage info)

dpANS 12.6.2.2035 - standard forth word

FORTH
SET-PRECISION ( .. )(); 
 ;

ordinary primitive SET-PRECISION

an executable word (no special usage info)

or wrapper call around p4_set_precision

dpANS 12.6.2.2200 - standard forth word

FORTH

SF! ( .. )();
as:"sf-store";

ordinary primitive SF!

an executable word (no special usage info)

or wrapper call around p4_s_f_store

dpANS 12.6.2.2202 - standard forth word

FORTH

SF@ ( .. )();
as:"sf-fetch";

ordinary primitive SF@

an executable word (no special usage info)

or wrapper call around p4_s_f_fetch

dpANS 12.6.2.2203 - standard forth word

FORTH

SFALIGN ( .. )();
as:"sfalign";

ordinary primitive SFALIGN

an executable word (no special usage info)

or wrapper call around p4_align

dpANS 12.6.2.2204 - standard forth word

FORTH

SFALIGNED ( .. )();
as:"sfaligned";

ordinary primitive SFALIGNED

an executable word (no special usage info)

or wrapper call around p4_aligned

dpANS 12.6.2.2206 - standard forth word

FORTH

SFLOAT+ ( .. )();
as:"sfloat-plus";

ordinary primitive SFLOAT+

an executable word (no special usage info)

or wrapper call around p4_s_float_plus

dpANS 12.6.2.2207 - standard forth word

FORTH

SFLOATS ( .. )();
as:"sfloats";

ordinary primitive SFLOATS

an executable word (no special usage info)

or wrapper call around p4_s_floats

dpANS 12.6.2.2208 - standard forth word

ENVIRONMENT
FLOATING-EXT ( .. )(); 
 ;
( 1994  )  constant FLOATING-EXT

an ordinary constant (no special usage info)

ENVIRONMENT
FLOATING-STACK ( .. )(); 
 ;

ordinary primitive FLOATING-STACK

an executable word (no special usage info)

or wrapper call around p__floating_stack

ENVIRONMENT

MAX-FLOAT ( .. )();
as:"max-minus-float";

ordinary primitive MAX-FLOAT

an executable word (no special usage info)

or wrapper call around p__max_float

ENVIRONMENT
FLOATING-LOADED ( .. )(); 
 ;

constructor primitive FLOATING-LOADED

an executable word (no special usage info)

or wrapper call around floating_init

floating_misc wordset

description

-- miscellaneous useful extra words for FLOATING-EXT

Copyright (C) Tektronix, Inc. 1998 - 2003. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words. ... for FLOATING-EXT

FORTH

FLIT ( .. )();
as:"flit";

ordinary primitive FLIT

an executable word (no special usage info)

or wrapper call around p4_f_literal_execution

FORTH

F0 ( .. )();
as:"f-zero";

threadstate variable F0

f0 (no special usage info)

FORTH
FLOAT-INPUT ( .. )(); 
 ;

threadstate variable FLOAT-INPUT

float_input (no special usage info)

FORTH

FP@ ( -- addr )();
p4:"f-p-fetch";

returns the floating point stack pointer

FORTH

FP! ( addr -- )();
p4:"f-p-store";

sets the floating point stack pointer - this is the inverse of FP@

FORTH

F= ( .. )();
as:"f-equal";

ordinary primitive F=

an executable word (no special usage info)

or wrapper call around p4_f_equal

FORTH
F<> ( f: a b -- s: a!=b )(); 
 ;
FORTH

F> ( .. )();
as:"f-back";

ordinary primitive F>

an executable word (no special usage info)

or wrapper call around p4_f_greater_than

FORTH

F<= ( .. )();
as:"f-from-equal";

ordinary primitive F<=

an executable word (no special usage info)

or wrapper call around p4_f_less_than_or_equal

FORTH

F>= ( .. )();
as:"f-back-equal";

ordinary primitive F>=

an executable word (no special usage info)

or wrapper call around p4_f_greater_than_or_equal

FORTH

S>F ( n -- f: x )();
p4:"s-to-f";

it's inverse is F>S - convert a cell parameter to floating-point.

FORTH
FTRUNC>S (f: x -- s: n )(); 
 ;

The word F>S was sometimes defined with a different behavior than FTRUNC>S which is the type-cast behaviour of C according to C99 section 6.3.1.4 - truncation would also match the ANS-Forth specification for F>D.

Some systems used F>S defined to FROUND>S instead. The pfe provides explicit words for both conversions, the word FROUND>S and FTRUNC>S which return single-cell parameters for a floating point number with the conversion method of FTRUNC or FROUND.

In PFE, F>S is a synonym pointing to FTRUNC>S in analogy of the behavior of F>D where no explicit word exists. The inverse of F>S is the cast conversion of S>F.

FORTH
FROUND>S (f: x -- s: n)(); 
 ;

complements FTRUNC>S for applications that expect F>S to be defined with a rounding behavior like

 : FROUND>S FROUND FTRUNC>S ;
 
FORTH

F>S ( .. )();
as:"f-back-s";

forthword synonym F>S

is doing the same as FTRUNC>S

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

FTRUNC (f: x -- x' )();
p4:"f-trunc";

truncate towards zero, discard a fractional part. See also FTRUNC>S conversion and the FROUND and FLOOR adaptors.

 : FTRUNC FDUP F0< IF FCEIL ELSE FLOOR THEN ;

(When available, uses a single call to C99 trunc() internally)

FORTH
-FROT (f: x1 x2 x3 -- x3 x1 x2 )(); 
 ;

F-stack equivalent of -ROT

note, some systems call this work F-ROT, here it is the inverse of FROT

FORTH

F-ROT ( .. )();
as:"f-minus-rot";

forthword synonym F-ROT

is doing the same as -FROT

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

FNIP (f: x1 x2 -- x2 )();
p4:"f-nip";

F-stack equivalent of NIP

FORTH
FTUCK (f: x1 x2 -- x2 x1 x2 )(); 
 ;

F-stack equivalent of TUCK

FORTH

1/F (f: x -- 1/x )();
p4:"one-over-f";

FORTH

F^2 (f: x -- x^2 )();
p4:"f-square";

FORTH

F^N ( u f: x -- x^u )();
p4:"f-power-n";

For large exponents, use F** instead. Of course u=-1 is large.

FORTH

F2/ (f: x -- x/2 )();
p4:"f-two-slash";

FORTH

F2* (f: x -- x*2 )();
p4:"f-two-star";

FORTH
F0> (f: x -- s: flag )(); 
 ;
FORTH
F0<> (f: x -- s: flag )(); 
 ;

forth_83 wordset

description

-- Compatiblity with the FORTH-83 standard.

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: All FORTH-83-Standard words are included here that are not in the dpANS already. Though most of the "uncontrolled reference words" are omitted.

FORTH

2+ ( i -- i )();
p4:"two-plus";

add 2 to the value on stack (and leave the result there)

 simulate:
   : 2+ 2 + ;
 
FORTH

2- ( i -- i )();
p4:"two-minus";

substract 2 from the value on stack (and leave the result there)

 simulate:
   : 2- 2 - ;
 
FORTH

?TERMINAL ( .. )();
as:"question-terminal";

ordinary primitive ?TERMINAL

an executable word (no special usage info)

or wrapper call around p4_key_question

FORTH

COMPILE ( 'word' -- )();
p4:"compile";

compile the next word. The next word should not be immediate, in which case you would have to use [COMPILE]. For this reason, you should use the word POSTPONE, which takes care it.

 simulate:
   : COMPILE  R> DUP @ , CELL+ >R ;  ( not immediate !!! )
 
FORTH

NOT ( .. )();
as:"not";

compiling primitive NOT

an executable word (no special usage info)

or wrapper call around p4_not

FORTH

VOCABULARY ( 'name' -- )();
p4:"vocabulary";

create a vocabulary of that name. If the named vocabulary is called later, it will run ((VOCABULARY)) , thereby putting it into the current search order. Special pfe-extensions are accessible via CASE-SENSITIVE-VOC and SEARCH-ALSO-VOC

 simulate:
   : VOCABULARY  CREATE ALLOT-WORDLIST
        DOES> ( the ((VOCABULARY)) runtime )
          CONTEXT ! 
   ; IMMEDIATE
 
FORTH

--> ( -- )no-return();
p4:"next-block";

does increase BLK and refills the input-buffer from there. Does hence break interpretation of the current BLK and starts with the next. Old-style forth mechanism. You should use INCLUDE

FORTH

INTERPRET ( .. )();
as:"interpret";

ordinary primitive INTERPRET

an executable word (no special usage info)

or wrapper call around p4_interpret

FORTH

K ( -- counter-val )();
p4:"k";

the 3rd loop index just like I and J

FORTH

OCTAL ( -- )();
p4:"octal";

sets BASE to 8. Compare with HEX and DECIMAL

 simulate:
   : OCTAL  8 BASE ! ;
 
FORTH

SP@ ( -- )();
p4:"s-p-fetch";

the address of the top of stack. Does save it onto the stack. You could do

   : DUP  SP@ @ ;
 
FORTH
!BITS ( bits addr mask -- )(); 
 ;

at the cell pointed to by addr, change only the bits that are enabled in mask

 simulate:
   : !BITS  >R 2DUP @ R NOT AND SWAP R> AND OR SWAP ! DROP ;
 
FORTH
@BITS ( addr mask -- value )(); 
 ;

see the companion word !BITS

 simulate:
   : @BITS  SWAP @ AND ;
 
FORTH

>< ( a -- a' )();
p4:"byte-swap";

byte-swap a word

FORTH
>MOVE< ( from-addr to-addr count -- )(); 
 ;

see MOVE , does byte-swap for each word underway

FORTH

** ( a b -- r )();
p4:"power";

raise second to top power

FORTH

DPL ( .. )();
as:"dpl";

threadstate variable DPL

dpl (no special usage info)

FORTH

SEAL ( -- )();
p4:"seal";

looks through the search-order and kills the ONLY wordset - hence you can't access the primary vocabularies from there.

forth_usual wordset

description

-- usually implemented words.

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: There are lots of useful words that do not appear in any standard. This wordset defines some of them.

FORTH
#BACKSPACE-CHAR ( .. )(); 
 ;
( '\b' )  constant #BACKSPACE-CHAR

an ordinary constant (no special usage info)

FORTH

C+! ( n addr -- )();
p4:"c-plus-store";

Add the low-order byte of _n_ to the byte at _addr_, removing both from the stack.

FORTH

VOCABULARY ( 'name' -- )();
p4:"vocabulary";

create a vocabulary of that name. If the named vocabulary is called later, it will run ((VOCABULARY)) , thereby putting it into the current search order. Special pfe-extensions are accessible via CASE-SENSITIVE-VOC and SEARCH-ALSO-VOC

 simulate:
   : VOCABULARY  CREATE ALLOT-WORDLIST
        DOES> ( the ((VOCABULARY)) runtime )
          CONTEXT ! 
   ; IMMEDIATE
 
FORTH
BOUNDS ( str len -- str+len str )(); 
 ;

Convert _str len_ to range for DO-loop.

 : BOUNDS  ( str len -- str+len str )  OVER + SWAP ;
 
FORTH

OFF! ( .. )();
as:"off-store";

ordinary primitive OFF!

an executable word (no special usage info)

or wrapper call around p4_off_store

FORTH

ON! ( addr -- )();
p4:"on-store";

Store -1 at _addr_. Defined in f83 as ON. See antonym OFF!.

  : ON!  ( addr -- )  -1 SWAP ! ;
 
FORTH

OFF ( addr -- )();
p4:"off-store";

Store 0 at _addr_. Defined in f84 as OFF. See antonym ON!.

  : OFF  ( addr -- )  0 SWAP ! ;
 
FORTH

ON ( .. )();
as:"on";

forthword synonym ON

is doing the same as ON!

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

PLACE ( str len addr -- )();
p4:"place";

Place the string _str len_ at _addr_, formatting it as a counted string.

 : PLACE  2DUP 2>R  1+ SWAP  MOVE  2R> C! ;
 : PLACE  2DUP C!   1+ SWAP CMOVE ;
 
FORTH

+PLACE ( .. )();
as:"plus-place";

ordinary primitive +PLACE

an executable word (no special usage info)

or wrapper call around p4_append

FORTH

C+PLACE ( .. )();
as:"c-plus-place";

ordinary primitive C+PLACE

an executable word (no special usage info)

or wrapper call around p4_append_char

FORTH

APPEND ( str len add2 -- )();
p4:"append";

Append string _str len_ to the counted string at _addr_. a.k.a. +PLACE of the PLACE family

 : APPEND   2DUP 2>R  COUNT +  SWAP MOVE ( ) 2R> C+! ;
 

Append string _str len_ to the counted string at _addr_. a.k.a. APPEND (being a SYNONYM now)

 : +PLACE   2DUP 2>R  COUNT +  SWAP MOVE ( ) 2R> C+! ;
 
FORTH
APPEND-CHAR ( char addr -- )(); 
 ;

Append _char_ to the counted string at _addr_. a.k.a. C+PLACE of the PLACE family

 : APPEND-CHAR   DUP >R  COUNT  DUP 1+ R> C!  +  C! ;
 

Append _char_ to the counted string at _addr_. a.k.a. APPEND-CHAR (being a SYNONYM now)

 : C+PLACE   DUP >R  COUNT  DUP 1+ R> C!  +  C! ;
 
FORTH

@EXECUTE ( xt -- ? )();
p4:"fetch-execute";

same as @ EXECUTE , but checks for null as xt and silently ignores it. Same as in most forths where defined.

 simulate:
   : @EXECUTE  @ ?DUP IF EXECUTE THEN ;
 
FORTH

?LEAVE ( cond -- )();
p4:"question-leave";

leave a (innermost) loop if condition is true

FORTH

NOOP ( .. )();
as:"noop";

ordinary primitive NOOP

an executable word (no special usage info)

or wrapper call around p4_noop

FORTH

RP@ ( -- addr )();
p4:"r-p-fetch";

returns the return stack pointer

 example:
   : R@ RP@ @ ;
 
FORTH

RP! ( addr -- )();
p4:"r-p-store";

sets the return stack pointer, reverse of RP@

FORTH

SP! ( ... addr -- )();
p4:"s-p-store";

sets the stack pointer, reverse of SP@

FORTH

-ROT ( a b c -- c a b )();
p4:"dash-rot";

inverse of ROT

FORTH

CSET ( n addr -- )();
p4:"c-set";

set bits in byte at given address

 simulate:
   : CSET  TUCK @ SWAP OR SWAP ! ;
 
FORTH

CRESET ( n addr -- )();
p4:"c-reset";

reset bits in byte at given address

 simulate:
   : CRESET  TUCK @ SWAP NOT AND SWAP ! ;
 
FORTH

CTOGGLE ( n addr -- )();
p4:"c-toggle";

toggle bits in byte at given address

 simulate:
   : CTOGGLE  TUCK @ SWAP XOR SWAP ! ;
 
FORTH
TOGGLE ( c-addr charmask -- )(); 
 ;

toggle the bits given in charmask, see also SMUDGE and = UNSMUDGE

 example: the fig-style SMUDGE had been defined such
   : FIG-SMUDGE LATEST >FFA (SMUDGE#) TOGGLE ;
 
FORTH
3DUP ( x y z -- x y z x y z )(); 
 ;

Copy top three elements on the stack onto top of stack.

 : 3DUP   THIRD THIRD THIRD ;

or

 : 3DUP  3 PICK 3 PICK 3 PICK ;
 
FORTH

3DROP ( x y z -- )();
p4:"three-drop";

Drop the top three elements from the stack.

 : 3DROP   DROP 2DROP ;
 
FORTH
4DUP ( a b c d -- a b c d a b c d )(); 
 ;
 simulate:
  : 4DUP  4 PICK 4 PICK 4 PICK 4 PICK ;
 
FORTH

4DROP ( x y z -- )();
p4:"four-drop";

Drop the top three elements from the stack.

 : 4DROP   2DROP 2DROP ;
 
FORTH

TOUPPER ( c1 -- c2 )();
p4:"toupper";

convert a single character to upper case

   : TOUPPER  >R _toupper ;
 
FORTH

UPPER ( addr cnt -- )();
p4:"upper";

convert string to upper case

 simulate:
   : UPPER  0 DO  DUP I +  DUP C@ UPC SWAP C!  LOOP  DROP ;
 
FORTH

LOWER ( addr cnt -- )();
p4:"lower";

convert string to lower case This is not in L&P's F83 but provided for symmetry

 simulate:
   : LOWER  0 DO  DUP I +  DUP C@ >R _tolower SWAP C!  LOOP  DROP ;
 
FORTH

ASCII ( [word] -- val )();
p4:"ascii";

state smart version of CHAR or [CHAR] resp.

 simulate:
   : ASCII  [COMPILE] [CHAR] 
            STATE @ IF [COMPILE] LITERAL THEN ;
 
FORTH

CONTROL ( [word] -- val )();
p4:"control";

see ASCII, but returns char - '@'

 simulate:
   : CONTROL  [COMPILE] [CHAR]  [CHAR] @ -  
              STATE @ IF [COMPILE] LITERAL THEN ;
 
FORTH
NUMBER? ( addr -- d flag )(); 
 ;

convert counted string to number - used in inner interpreter ( INTERPRET ), flags if conversion was successful

 example:
   BL WORD  HERE NUMBER? 0= IF ." not a number " THEN . 
 
FORTH

VOCS ( -- )();
p4:"vocs";

list all vocabularies in the system

 simulate:
   : VOCS VOC-LINK @ BEGIN DUP WHILE
                           DUP ->WORDLIST.NAME @ ID.
                           ->WORDLIST.LINK @
                     REPEAT DROP ; 
 
FORTH

EMITS ( n char -- )();
p4:"emits";

Emit _char_ _n_ times.

 : EMITS             ( n char -- )
    SWAP 0 ?DO  DUP EMIT  LOOP DROP ;

also compare

 : SPACES BL EMITS ;
 : SPACE BL EMIT ;
 
FORTH

FILE-CHECK ( n -- )();
p4:"file-check";

Check for file access error.

 \ : FILE-CHECK    ( n -- )  THROW ;
 : FILE-CHECK      ( n -- )  ABORT" File Access Error " ;
 
FORTH

MEMORY-CHECK ( n -- )();
p4:"memory-check";

Check for memory allocation error.

 \ : MEMORY-CHECK  ( n -- )  THROW ;
 : MEMORY-CHECK    ( n -- )  ABORT" Memory Allocation Error " ;
 
FORTH

++ ( addr -- )();
p4:"plus-plus";

Increment the value at _addr_.

 : ++  ( addr -- )  1 SWAP +! ;
 
FORTH
@++ ( addr -- addr' x )(); 
 ;

Fetch the value _x_ from _addr_, and increment the address by one cell.

 : @++  ( addr -- addr' x )  DUP CELL+ SWAP  @ ;
 
FORTH
!++ ( addr x -- addr' )(); 
 ;

Store the value _x_ into _addr_, and increment the address by one cell.

 : !++  ( addr x -- addr' )  OVER !  CELL+ ;
 
FORTH

@+ ( .. )();
as:"fetch-plus";

forthword synonym @+

is doing the same as @++

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

!+ ( .. )();
as:"store-plus";

forthword synonym !+

is doing the same as !++

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

ENDIF ( .. )();
as:"endif";

immediate synonym ENDIF

is doing the same as THEN

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

EXTENSIONS
>WORDLIST ( xt -- wordl* )(); 
 ;

convert a VOCABULARY-xt into its wordlist reference (as in win32forth)

EXTENSIONS

PERFORM ( .. )();
as:"perform";

obsolete forthword PERFORM

is doing the same as @EXECUTE

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

UPC ( .. )();
as:"upc";

obsolete forthword UPC

is doing the same as TOUPPER

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

fpnostack wordset

description

-- The No-FP-Stack Floating-Point Word Set

Copyright (C) Krishna Myneni and Guido Draheim, 2002

description: The No-FP-Stack Floating-Point Wordset is not usually used on embedded platforms. This Module implements the floating-point words but expects and puts the floating-point values on the forth parameter-stack.

EXTENSIONS

>FLOAT ( .. )();
as:"back-float";

ordinary primitive >FLOAT

an executable word (no special usage info)

or wrapper call around p4_nofp_to_float

EXTENSIONS

D>F ( .. )();
as:"d-back-f";

ordinary primitive D>F

an executable word (no special usage info)

or wrapper call around p4_nofp_d_to_f

EXTENSIONS

F! ( .. )();
as:"f-store";

ordinary primitive F!

an executable word (no special usage info)

or wrapper call around p4_nofp_f_store

dpANS 12.6.1.1400 - standard forth word

EXTENSIONS

F* ( .. )();
as:"f-star";

ordinary primitive F*

an executable word (no special usage info)

or wrapper call around p4_nofp_f_star

dpANS 12.6.1.1410 - standard forth word

EXTENSIONS

F+ ( .. )();
as:"f-plus";

ordinary primitive F+

an executable word (no special usage info)

or wrapper call around p4_nofp_f_plus

dpANS 12.6.1.1420 - standard forth word

EXTENSIONS

F- ( .. )();
as:"f-minus";

ordinary primitive F-

an executable word (no special usage info)

or wrapper call around p4_nofp_f_minus

dpANS 12.6.1.1425 - standard forth word

EXTENSIONS

F/ ( .. )();
as:"f-slash";

ordinary primitive F/

an executable word (no special usage info)

or wrapper call around p4_nofp_f_slash

dpANS 12.6.1.1430 - standard forth word

EXTENSIONS

F0< ( .. )();
as:"f-zero-from";

ordinary primitive F0<

an executable word (no special usage info)

or wrapper call around p4_nofp_f_zero_less

EXTENSIONS

F0= ( .. )();
as:"f-zero-equal";

ordinary primitive F0=

an executable word (no special usage info)

or wrapper call around p4_nofp_f_zero_equal

dpANS 12.6.1.1450 - standard forth word

EXTENSIONS

F< ( .. )();
as:"f-from";

ordinary primitive F<

an executable word (no special usage info)

or wrapper call around p4_nofp_f_less_than

EXTENSIONS

F> ( .. )();
as:"f-back";

ordinary primitive F>

an executable word (no special usage info)

or wrapper call around p4_nofp_f_greater_than

EXTENSIONS

F= ( .. )();
as:"f-equal";

ordinary primitive F=

an executable word (no special usage info)

or wrapper call around p4_nofp_f_equal

EXTENSIONS
F<> ( f: a b -- s: a!=b )(); 
 ;
EXTENSIONS

F<= ( .. )();
as:"f-from-equal";

ordinary primitive F<=

an executable word (no special usage info)

or wrapper call around p4_nofp_f_less_than_or_equal

EXTENSIONS

F>= ( .. )();
as:"f-back-equal";

ordinary primitive F>=

an executable word (no special usage info)

or wrapper call around p4_nofp_f_greater_than_or_equal

EXTENSIONS

F>D ( .. )();
as:"f-back-d";

ordinary primitive F>D

an executable word (no special usage info)

or wrapper call around p4_nofp_f_to_d

EXTENSIONS

F@ ( .. )();
as:"f-fetch";

ordinary primitive F@

an executable word (no special usage info)

or wrapper call around p4_nofp_f_fetch

dpANS 12.6.1.1472 - standard forth word

EXTENSIONS

FALIGN ( .. )();
as:"falign";

ordinary primitive FALIGN

an executable word (no special usage info)

or wrapper call around p4_nofp_d_f_align

dpANS 12.6.1.1479 - standard forth word

EXTENSIONS

FALIGNED ( .. )();
as:"faligned";

ordinary primitive FALIGNED

an executable word (no special usage info)

or wrapper call around p4_nofp_d_f_aligned

dpANS 12.6.1.1483 - standard forth word

EXTENSIONS

FCONSTANT ( .. )();
as:"fconstant";

definining primitive FCONSTANT

an executable word (no special usage info)

or wrapper call around p4_nofp_f_constant

dpANS 12.6.1.1492 - standard forth word

EXTENSIONS

FDEPTH ( .. )();
as:"fdepth";

ordinary primitive FDEPTH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_depth

dpANS 12.6.1.1497 - standard forth word

EXTENSIONS

FDROP ( .. )();
as:"fdrop";

ordinary primitive FDROP

an executable word (no special usage info)

or wrapper call around p4_nofp_f_drop

dpANS 12.6.1.1500 - standard forth word

EXTENSIONS

FDUP ( .. )();
as:"fdup";

ordinary primitive FDUP

an executable word (no special usage info)

or wrapper call around p4_nofp_f_dup

dpANS 12.6.1.1510 - standard forth word

EXTENSIONS

FLITERAL ( .. )();
as:"fliteral";

compiling primitive FLITERAL

an executable word (no special usage info)

or wrapper call around p4_nofp_f_literal

dpANS 12.6.1.1552 - standard forth word

EXTENSIONS

FLOAT+ ( .. )();
as:"float-plus";

ordinary primitive FLOAT+

an executable word (no special usage info)

or wrapper call around p4_nofp_d_float_plus

dpANS 12.6.1.1555 - standard forth word

EXTENSIONS

FLOATS ( .. )();
as:"floats";

ordinary primitive FLOATS

an executable word (no special usage info)

or wrapper call around p4_nofp_d_floats

dpANS 12.6.1.1556 - standard forth word

EXTENSIONS

FLOOR ( .. )();
as:"floor";

ordinary primitive FLOOR

an executable word (no special usage info)

or wrapper call around p4_nofp_floor

dpANS 12.6.1.1558 - standard forth word

EXTENSIONS

FMAX ( .. )();
as:"fmax";

ordinary primitive FMAX

an executable word (no special usage info)

or wrapper call around p4_nofp_f_max

dpANS 12.6.1.1562 - standard forth word

EXTENSIONS

FMIN ( .. )();
as:"fmin";

ordinary primitive FMIN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_min

dpANS 12.6.1.1565 - standard forth word

EXTENSIONS

FNEGATE ( .. )();
as:"fnegate";

ordinary primitive FNEGATE

an executable word (no special usage info)

or wrapper call around p4_nofp_f_negate

dpANS 12.6.1.1567 - standard forth word

EXTENSIONS

FOVER ( .. )();
as:"fover";

ordinary primitive FOVER

an executable word (no special usage info)

or wrapper call around p4_nofp_f_over

dpANS 12.6.1.1600 - standard forth word

EXTENSIONS

FROT ( .. )();
as:"frot";

ordinary primitive FROT

an executable word (no special usage info)

or wrapper call around p4_nofp_f_rot

dpANS 12.6.1.1610 - standard forth word

EXTENSIONS

FROUND ( .. )();
as:"fround";

ordinary primitive FROUND

an executable word (no special usage info)

or wrapper call around p4_nofp_f_round

dpANS 12.6.1.1612 - standard forth word

EXTENSIONS

FSWAP ( .. )();
as:"fswap";

ordinary primitive FSWAP

an executable word (no special usage info)

or wrapper call around p4_nofp_f_swap

dpANS 12.6.1.1620 - standard forth word

EXTENSIONS

FVARIABLE ( .. )();
as:"fvariable";

definining primitive FVARIABLE

an executable word (no special usage info)

or wrapper call around p4_nofp_f_variable

dpANS 12.6.1.1630 - standard forth word

EXTENSIONS

REPRESENT ( .. )();
as:"represent";

ordinary primitive REPRESENT

an executable word (no special usage info)

or wrapper call around p4_nofp_represent

dpANS 12.6.1.2143 - standard forth word

EXTENSIONS

DF! ( .. )();
as:"df-store";

ordinary primitive DF!

an executable word (no special usage info)

or wrapper call around p4_nofp_f_store

dpANS 12.6.2.1203 - standard forth word

EXTENSIONS

DF@ ( .. )();
as:"df-fetch";

ordinary primitive DF@

an executable word (no special usage info)

or wrapper call around p4_nofp_f_fetch

dpANS 12.6.2.1204 - standard forth word

EXTENSIONS

DFALIGN ( .. )();
as:"dfalign";

ordinary primitive DFALIGN

an executable word (no special usage info)

or wrapper call around p4_nofp_d_f_align

dpANS 12.6.2.1205 - standard forth word

EXTENSIONS

DFALIGNED ( .. )();
as:"dfaligned";

ordinary primitive DFALIGNED

an executable word (no special usage info)

or wrapper call around p4_nofp_d_f_aligned

dpANS 12.6.2.1207 - standard forth word

EXTENSIONS

DFLOAT+ ( .. )();
as:"dfloat-plus";

ordinary primitive DFLOAT+

an executable word (no special usage info)

or wrapper call around p4_nofp_d_float_plus

dpANS 12.6.2.1208 - standard forth word

EXTENSIONS

DFLOATS ( .. )();
as:"dfloats";

ordinary primitive DFLOATS

an executable word (no special usage info)

or wrapper call around p4_nofp_d_floats

dpANS 12.6.2.1209 - standard forth word

EXTENSIONS

F** ( .. )();
as:"f-star-star";

ordinary primitive F**

an executable word (no special usage info)

or wrapper call around p4_nofp_f_star_star

dpANS 12.6.2.1415 - standard forth word

EXTENSIONS

F. ( .. )();
as:"f-dot";

ordinary primitive F.

an executable word (no special usage info)

or wrapper call around p4_nofp_f_dot

dpANS 12.6.2.1427 - standard forth word

EXTENSIONS

FABS ( .. )();
as:"fabs";

ordinary primitive FABS

an executable word (no special usage info)

or wrapper call around p4_nofp_f_abs

dpANS 12.6.2.1474 - standard forth word

EXTENSIONS

FACOS ( .. )();
as:"facos";

ordinary primitive FACOS

an executable word (no special usage info)

or wrapper call around p4_nofp_f_acos

dpANS 12.6.2.1476 - standard forth word

EXTENSIONS

FACOSH ( .. )();
as:"facosh";

ordinary primitive FACOSH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_acosh

dpANS 12.6.2.1477 - standard forth word

EXTENSIONS

FALOG ( .. )();
as:"falog";

ordinary primitive FALOG

an executable word (no special usage info)

or wrapper call around p4_nofp_f_alog

dpANS 12.6.2.1484 - standard forth word

EXTENSIONS

FASIN ( .. )();
as:"fasin";

ordinary primitive FASIN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_asin

dpANS 12.6.2.1486 - standard forth word

EXTENSIONS

FASINH ( .. )();
as:"fasinh";

ordinary primitive FASINH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_asinh

dpANS 12.6.2.1487 - standard forth word

EXTENSIONS

FATAN ( .. )();
as:"fatan";

ordinary primitive FATAN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_atan

dpANS 12.6.2.1488 - standard forth word

EXTENSIONS

FATAN2 ( .. )();
as:"fatan-two";

ordinary primitive FATAN2

an executable word (no special usage info)

or wrapper call around p4_nofp_f_atan2

dpANS 12.6.2.1489 - standard forth word

EXTENSIONS

FATANH ( .. )();
as:"fatanh";

ordinary primitive FATANH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_atanh

dpANS 12.6.2.1491 - standard forth word

EXTENSIONS

FCOS ( .. )();
as:"fcos";

ordinary primitive FCOS

an executable word (no special usage info)

or wrapper call around p4_nofp_f_cos

dpANS 12.6.2.1493 - standard forth word

EXTENSIONS

FCOSH ( .. )();
as:"fcosh";

ordinary primitive FCOSH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_cosh

dpANS 12.6.2.1494 - standard forth word

EXTENSIONS

FE. ( .. )();
as:"fe-dot";

ordinary primitive FE.

an executable word (no special usage info)

or wrapper call around p4_nofp_f_e_dot

dpANS 12.6.2.1513 - standard forth word

EXTENSIONS

FEXP ( .. )();
as:"fexp";

ordinary primitive FEXP

an executable word (no special usage info)

or wrapper call around p4_nofp_f_exp

dpANS 12.6.2.1515 - standard forth word

EXTENSIONS

FEXPM1 ( .. )();
as:"fexpm-one";

ordinary primitive FEXPM1

an executable word (no special usage info)

or wrapper call around p4_nofp_f_expm1

dpANS 12.6.2.1516 - standard forth word

EXTENSIONS

FLN ( .. )();
as:"fln";

ordinary primitive FLN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_ln

dpANS 12.6.2.1553 - standard forth word

EXTENSIONS

FLNP1 ( .. )();
as:"flnp-one";

ordinary primitive FLNP1

an executable word (no special usage info)

or wrapper call around p4_nofp_f_lnp1

dpANS 12.6.2.1554 - standard forth word

EXTENSIONS

FLOG ( .. )();
as:"flog";

ordinary primitive FLOG

an executable word (no special usage info)

or wrapper call around p4_nofp_f_log

dpANS 12.6.2.1557 - standard forth word

EXTENSIONS

FS. ( .. )();
as:"fs-dot";

ordinary primitive FS.

an executable word (no special usage info)

or wrapper call around p4_nofp_f_s_dot

dpANS 12.6.2.1613 - standard forth word

EXTENSIONS

FSIN ( .. )();
as:"fsin";

ordinary primitive FSIN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_sin

dpANS 12.6.2.1614 - standard forth word

EXTENSIONS

FSINCOS ( .. )();
as:"fsincos";

ordinary primitive FSINCOS

an executable word (no special usage info)

or wrapper call around p4_nofp_f_sincos

dpANS 12.6.2.1616 - standard forth word

EXTENSIONS

FSINH ( .. )();
as:"fsinh";

ordinary primitive FSINH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_sinh

dpANS 12.6.2.1617 - standard forth word

EXTENSIONS

FSQRT ( .. )();
as:"fsqrt";

ordinary primitive FSQRT

an executable word (no special usage info)

or wrapper call around p4_nofp_f_sqrt

dpANS 12.6.2.1618 - standard forth word

EXTENSIONS

FTAN ( .. )();
as:"ftan";

ordinary primitive FTAN

an executable word (no special usage info)

or wrapper call around p4_nofp_f_tan

dpANS 12.6.2.1625 - standard forth word

EXTENSIONS

FTANH ( .. )();
as:"ftanh";

ordinary primitive FTANH

an executable word (no special usage info)

or wrapper call around p4_nofp_f_tanh

dpANS 12.6.2.1626 - standard forth word

EXTENSIONS

F~ ( .. )();
as:"f-like";

ordinary primitive F~

an executable word (no special usage info)

or wrapper call around p4_nofp_f_proximate

dpANS 12.6.2.1640 - standard forth word

EXTENSIONS

PRECISION ( .. )();
as:"precision";

- loader type P4_DVaL PRECISION

precision (no special usage info)

dpANS 12.6.2.2035 - standard forth word

EXTENSIONS
SET-PRECISION ( .. )(); 
 ;

ordinary primitive SET-PRECISION

an executable word (no special usage info)

or wrapper call around p4_nofp_set_precision

dpANS 12.6.2.2200 - standard forth word

EXTENSIONS

SF! ( .. )();
as:"sf-store";

ordinary primitive SF!

an executable word (no special usage info)

or wrapper call around p4_nofp_s_f_store

dpANS 12.6.2.2202 - standard forth word

EXTENSIONS

SF@ ( .. )();
as:"sf-fetch";

ordinary primitive SF@

an executable word (no special usage info)

or wrapper call around p4_nofp_s_f_fetch

dpANS 12.6.2.2203 - standard forth word

EXTENSIONS

SFALIGN ( .. )();
as:"sfalign";

ordinary primitive SFALIGN

an executable word (no special usage info)

or wrapper call around p4_align

dpANS 12.6.2.2204 - standard forth word

EXTENSIONS

SFALIGNED ( .. )();
as:"sfaligned";

ordinary primitive SFALIGNED

an executable word (no special usage info)

or wrapper call around p4_aligned

dpANS 12.6.2.2206 - standard forth word

EXTENSIONS

SFLOAT+ ( .. )();
as:"sfloat-plus";

ordinary primitive SFLOAT+

an executable word (no special usage info)

or wrapper call around p4_nofp_s_float_plus

dpANS 12.6.2.2207 - standard forth word

EXTENSIONS

SFLOATS ( .. )();
as:"sfloats";

ordinary primitive SFLOATS

an executable word (no special usage info)

or wrapper call around p4_nofp_s_floats

dpANS 12.6.2.2208 - standard forth word

EXTENSIONS

S>F ( n -- f: x )();
p4:"s-to-f";

it's inverse is F>S - convert a cell parameter to floating-point.

EXTENSIONS
FTRUNC>S (f: x -- s: n )(); 
 ;

The word F>S was sometimes defined with a different behavior than FTRUNC>S which is the type-cast behaviour of C according to C99 section 6.3.1.4 - truncation would also match the ANS-Forth specification for F>D.

Some systems used F>S defined to FROUND>S instead. The pfe provides explicit words for both conversions, the word FROUND>S and FTRUNC>S which return single-cell parameters for a floating point number with the conversion method of FTRUNC or FROUND.

In PFE, F>S is a synonym pointing to FTRUNC>S in analogy of the behavior of F>D where no explicit word exists. The inverse of F>S is the cast conversion of S>F.

EXTENSIONS
FROUND>S (f: x -- s: n)(); 
 ;

complements FTRUNC>S for applications that expect F>S to be defined with a rounding behavior like

 : FROUND>S FROUND FTRUNC>S ;
 
EXTENSIONS

F>S ( .. )();
as:"f-back-s";

forthword synonym F>S

is doing the same as FTRUNC>S

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

EXTENSIONS

FTRUNC (f: x -- x' )();
p4:"f-trunc";

truncate towards zero, discard a fractional part. See also FTRUNC>S conversion and the FROUND and FLOOR adaptors.

 : FTRUNC FDUP F0< IF FCEIL ELSE FLOOR THEN ;

(When available, uses a single call to C99 trunc() internally)

EXTENSIONS
-FROT (f: x1 x2 x3 -- x3 x1 x2 )(); 
 ;

F-stack equivalent of -ROT

note, some systems call this work F-ROT, here it is the inverse of FROT

EXTENSIONS

F-ROT ( .. )();
as:"f-minus-rot";

forthword synonym F-ROT

is doing the same as -FROT

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

EXTENSIONS

FNIP (f: x1 x2 -- x2 )();
p4:"f-nip";

F-stack equivalent of NIP

EXTENSIONS
FTUCK (f: x1 x2 -- x2 x1 x2 )(); 
 ;

F-stack equivalent of TUCK

EXTENSIONS

1/F (f: x -- 1/x )();
p4:"one-over-f";

EXTENSIONS

F^2 (f: x -- x^2 )();
p4:"f-square";

EXTENSIONS

F^N ( u f: x -- x^u )();
p4:"f-power-n";

For large exponents, use F** instead. Of course u=-1 is large.

EXTENSIONS

F2/ (f: x -- x/2 )();
p4:"f-two-slash";

EXTENSIONS

F2* (f: x -- x*2 )();
p4:"f-two-star";

EXTENSIONS
F0> (f: x -- s: flag )(); 
 ;
EXTENSIONS
F0<> (f: x -- s: flag )(); 
 ;
ENVIRONMENT

FLOATING ( .. )();
as:"floating";

( 1994  )  constant FLOATING

an ordinary constant (no special usage info)

ENVIRONMENT
FPNOSTACK-EXT ( .. )(); 
 ;
( 1994  )  constant FPNOSTACK-EXT

an ordinary constant (no special usage info)

ENVIRONMENT

MAX-FLOAT ( .. )();
as:"max-minus-float";

ordinary primitive MAX-FLOAT

an executable word (no special usage info)

or wrapper call around p__nofp_max_float

ENVIRONMENT
FPNOSTACK-LOADED ( .. )(); 
 ;

constructor primitive FPNOSTACK-LOADED

an executable word (no special usage info)

or wrapper call around fpnostack_init

ENVIRONMENT
CELL-FALIGNED ( .. )(); 
 ;
( 2003  )  constant CELL-FALIGNED

an ordinary constant (no special usage info)

gforth wordset

description

-- Words designed to mimic gforth behaviour.

Copyright (C) Guido Draheim 2001 - xxxx. All rights reserved.

description: Usually the following words are defined to mimic a certain gforth extension that some application writers need. They are only added on request, and they may be removed without warning requesting to use the functionality provided by pfe itself.

gforth'
linked ( list -- )\ gforth(); 
 ;
 : linked        here over @ a, swap ! ;

(note: win32forth calls it "link," )

gforth'
chained ( xt list -- )\ gforth(); 
 ;

generic chains

 : chained  linked , ;
 
gforth'
chainperform ( list -- )\ gforth(); 
 ;
 : chainperform  BEGIN @ dup WHILE dup cell+ perform REPEAT drop ;
 
gforth'
open-dir ( c_addr u -- wdirid wior )gforth open_dir(); 
 ;

will vanish without warning. see gforth documentation.

gforth'
read-dir ( c_addr u1 wdirid -- u2 flag wior )gforth read_dir(); 
 ;

will vanish without warning. see gforth documentation.

gforth'
close-dir ( wdirid -- wior )gforth close_dir(); 
 ;

will vanish without warning. see gforth documentation.

ENVIRONMENT

GFORTH-DIR ( .. )();
as:"gforth-minus-dir";

( 500  )  constant GFORTH-DIR

an ordinary constant (no special usage info)

header wordset

description

Implements header creation and navigation and defer/synonym words.

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

FORTH

BODY> ( pfa -- cfa )();
p4:"body-from";

trying to convert a pointer to the parameter-field (PFA) to point then to the corresponding code-field (CFA) - note that this is not necessarily the inverse of >BODY instead it is a fast implementation assuming a VARIABLE thing had been used. Every use of "BODY>" is warned in the logfile.

 implementation-specific simulation:
   : BODY> CELL - ;
FORTH

>LINK ( cfa -- lfa )();
p4:"to-link";

converts a pointer to the code-field (CFA) to point then to the corresponding link-field (LFA) - in some configurations this can be a very slow operation since the system might need to walk through all header-words in the system, looking for a >NAME that has the cfa and *then* returning the "N>LINK" result here - which might be none at all if the word is a :NONAME. Use always >NAME and treat this word as non-portable just like any assumption about the contents of the >LINK-field. Only in fig-mode and for traditional fig-mode programs, this word may possibly have enough extra assertions to be somewhat reliable. (and fig-mode did not know about SYNONYMs - see note at LINK>).

FORTH

LINK> ( lfa -- cfa )();
p4:"link-from";

converts a pointer to the link-field (LFA) to point then to the corresponding code-field (CFA)

BEWARE: this one does not care about SYNONYMs and it is the only way to get at the data of a SYNONYM. Therefore, if you have a synonym called A for an old word B then there is a different result using "NAME>" on an A-nfa or using "N>LINK LINK>" since the first "NAME>" will return the xt of B while the latter will return the xt of A - but executing an xt of A is an error and it will THROW

this difference is intentional to allow knowledgable persons to do weird things looking around in the dictionary. The forth standard words will not give you much of a chance to get hold of the nfa of a SYNONYM word anyway - asking FIND for a word A will return the execution token of B immediatly and "NAME>" on that one lead to the nfa of B and not that of A.

FORTH

>NAME ( cfa -- nfa )();
p4:"to-name";

converts a pointer to the code-field (CFA) to point then to the corresponding name-field (NFA)

 implementation-specific simulation:
   : >NAME  >LINK L>NAME ;
 
FORTH

NAME> ( nfa -- cfa )();
p4:"name-from";

converts a pointer to the name-field (NFA) to point then to the corresponding code-field (CFA) (in all cases but a SYNONYM the pfe will behave not unlike the original fig-forth did - being identical to N>LINK LINK> )

FORTH

L>NAME ( lfa -- nfa )();
p4:"l-to-name";

converts a pointer to the link-field (LFA) to point then to the corresponding name-field (CFA) - this one is one of the slowest operation available. One should always use the inverse operation N>LINK and cache an older value if that is needed. Some words might be linked but they do not have a name-field (just the other fields) but this word can not detect that and will try to look into the bits of the dictionary anway in the assumption that there is something - and if done in the wrong place it might even segfault. Only in fig-mode and for traditional fig-mode programs, this word may possibly have enough extra assertions to be somewhat reliable. (and fig-mode did not know about SYNONYMs - see note at LINK>).

 implementation-specific configure-dependent fig-only simulation:
 : L>NAME BEGIN DUP C@ 128 AND 0= WHILE 1- REPEAT ;
 
FORTH

N>LINK ( nfa -- lfa )();
p4:"n-to-link";

converts a pointer to the name-field (NFA) to point then to the corresponding link-field (LFA) - this operation is quicker than the inverse L>NAME. This word is a specific implementation detail and should not be used by normal users - instead use always NAME> which is much more portable. Many systems may possibly not even have a >LINK-field in the sense that a @ on this adress will lead to another >NAME. Any operation on the resulting >LINK-adress is even dependent on the current configuration of PFE - only in fig-mode you are asserted to have the classic detail. (and fig-mode did not know about SYNONYMs - see note at LINK>).

 implementation-specific configure-dependent fig-only simulation:
   : N>LINK  C@ + ;
 
FORTH
NAME>STRING ( name-token -- str-ptr str-len )(); 
 ;

convert a name-token into a string-span, used to detect the name for a word and print it. The word ID. can be defined as

 : ID. NAME>STRING TYPE ;

the implementation of NAME>STRING depends on the header layout that is defined during the configuration of the forth system.

 : NAME>STRING COUNT 31 AND ; ( for fig-like names )
 : NAME>STRING COUNT ;        ( default, name is a simple counted string )
 : NAME>STRING @ ZCOUNT ;     ( name-token is a pointer to a C-level string )
 : NAME>STRING COUNT 31 AND   ( hybrid of fig-like and zero-terminated )
      DUP 31 = IF DROP 1+ ZCOUNT THEN
 ;
 : NAME>STRING HEAD:: COUNT CODE:: PAD PLACE PAD ; ( different i86 segments )
FORTH

LAST ( .. )();
as:"last";

threadstate variable LAST

last (no special usage info)

FORTH

LATEST ( -- nfa )();
p4:"latest";

return the NFA of the lateset definition in the CURRENT vocabulary

EXTENSIONS

>FFA ( nfa -- ffa )obsolete();
p4:"to-ffa";

converts a pointer to the name-field (NFA) to point then to the corresponding flag-field (FFA) - in traditinal Forth this is the same address. pfe _can_ do different.

 implementation-specific configure-dependent simulation:
   : FFA  1- ;
 
EXTENSIONS
FFA> ( ffa -- nfa )obsolete(); 
 ;

converts a pointer to the flag-field (FFA) to point then to the corresponding name-field (NFA) - in traditinal Forth this is the same address. pfe _can_ do different.

 implementation-specific configure-dependent simulation:
   : FFA  1+ ;
 
EXTENSIONS
NAME-FLAGS@ ( nfa -- nfa-flags )(); 
 ;

get the nfa-flags that corresponds to the nfa given. Note that in the fig-style would include the nfa-count in the lower bits. (see NAME-FLAGS!)

EXTENSIONS
NAME-FLAGS! ( nfa-flags nfa -- )(); 
 ;

set the nfa-flags of nfa given. Note that in the fig-style the nfa-flags would include the nfa-count in the lower bits - therefore this should only set bits that had been previously retrieved with NAME-FLAGS@

 : IMMEDIATE LAST @ NAME-FLAGS@ IMMEDIATE-MASK OR LAST @ NAME-FLAGS! ;
 
EXTENSIONS
HEADER, ( str-ptr str-len -- )(); 
 ;

CREATE a new header in the dictionary from the given string, without CFA

 usage: : VARIABLE  BL WORD COUNT HEADER, DOVAR , ;
 
EXTENSIONS

$HEADER ( bstring -- )();
p4:"str-header";

CREATE a new header in the dictionary from the given string with the variable runtime (see HEADER, and CREATE:)

 usage: : VARIABLE  BL WORD $HEADER ;
 
EXTENSIONS

HEADER ( .. )();
as:"header";

obsolete forthword HEADER

is doing the same as $HEADER

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

SMUDGE ( .. )();
as:"smudge";

ordinary primitive SMUDGE

an executable word (no special usage info)

or wrapper call around p4_smudge

EXTENSIONS

REVEAL ( -- )();
p4:"reveal";

the FIG definition toggles the SMUDGE bit, and not all systems have a smudge bit - instead one should use REVEAL or HIDE

 : REVEAL LAST @ FLAGS@ SMUDGE-MASK INVERT AND LAST @ FLAGS! ;
 : REVEAL LAST @ CHAIN-INTO-CURRENT ;
 
EXTENSIONS

RECURSIVE ( .. )();
as:"recursive";

immediate primitive RECURSIVE

an executable word (no special usage info)

or wrapper call around p4_reveal

EXTENSIONS

UNSMUDGE ( .. )();
as:"unsmudge";

obsolete forthword UNSMUDGE

is doing the same as REVEAL

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS
IMMEDIATE-MASK ( .. )(); 
 ;
( P4xIMMEDIATE )  constant IMMEDIATE-MASK

an ordinary constant (no special usage info)

EXTENSIONS
SMUDGE-MASK ( .. )(); 
 ;
( P4xSMUDGED )  constant SMUDGE-MASK

an ordinary constant (no special usage info)

EXTENSIONS
(IMMEDIATE#) ( .. )(); 
 ;

obsolete forthword (IMMEDIATE#)

is doing the same as IMMEDIATE-MASK

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

(SMUDGE#) ( .. )();
as:"paren-smudge-sharp";

obsolete forthword (SMUDGE#)

is doing the same as SMUDGE-MASK

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

DEFER ( 'word' -- )();
p4:"defer";

create a new word with ((DEFER))-semantics

 simulate:
   : DEFER  CREATE 0, DOES> ( the ((DEFER)) runtime ) 
      @ ?DUP IF EXECUTE THEN ;
   : DEFER  DEFER-RT HEADER 0 , ;

declare as <c>"DEFER deferword"</c> <br> and set as <c>"['] executionword IS deferword"</c> (in pfe, you can also use TO deferword to set the execution)

EXTENSIONS

IS ( xt-value [word] -- )();
p4:"is";

set a DEFER word (in pfe: set the DOES-field - which is the BODY-field in ans-mode and therefore the same as TO / in fig-mode the DOES-field is one cell higher up than for a CREATE: VARIABLE Use IS freely on each DOES-words in both modes).

 : IS ' 
   STATE @ IF LITERAL, POSTPONE >DOES-BODY POSTPONE ! 
   ELSE >DOES-BODY ! THEN 
 ; IMMEDIATE
 
EXTENSIONS

BEHAVIOR ( xt1 -- xt2 )();
p4:"behavior";

get the execution token xt2 that would be executed by the DEFER identified by xt1.

This command is used to obtain the execution contents of a deferred word. A typical use would be to retrieve and save the execution behavior of the deferred word, set the deferred word to a new behavior, and then later restore the old behavior.

If the deferred word identified by _xt1_ is associated with some other deferred word, _xt2_ is the execution token of that other deferred word. To retrieve the execution token of the word currently associated with that other deferred word, use the phrase BEHAVIOR BEHAVIOR .

Experience: Many years of use in OpenBoot and OpenFirmware systems. (Proposed for ANS Forth 2001)

In PFE it is the inverse of an IS operation and it will never fail if applied to a word with atleast a body. That's just like IS can be applied to almost every DOES> word where BEHAVIOR will get the value back.

EXTENSIONS
SYNONYM ( "newname" "oldname" -- )(); 
 ;

make an name-alias for a word - this is very different from a DEFER since a DEFER will resolve at runtime. Changing the target of a DEFER via IS will result in changing the BEHAVIOR of all words defined earlier and containing the name of the DEFER.

A SYNONYM however does not have any data field (theoretically not even an execution token), instead it gets resolved at compile time. In theory, you can try to FIND the name of the SYNONYM but as soon as you apply NAME> the execution token of the end-point is returned. This has also the effect that using the inverse >NAME operation will result in the name-token of the other name.

   SYNONYM CREATE <BUILDS ( like it is in ANS Forth )
   : FOO CREATE DOES> @ ;
   SEE FOO
   : foo <builds
     does> @ ;
   SYNONYM CREATE CREATE:
   : BAR CREATE 10 ALLOT ;
   SEE BAR
   : bar create: 10 allot ;

(only LINK> does not care about SYNONYMs)

EXTENSIONS
SYNONYM-OBSOLETED ( .. )(); 
 ;

definining primitive SYNONYM-OBSOLETED

an executable word (no special usage info)

or wrapper call around p4_obsoleted

ENVIRONMENT

HEADER-EXT ( .. )();
as:"header-minus-ext";

( 1983 )  constant HEADER-EXT

an ordinary constant (no special usage info)

help wordset

description

-- extra words for external HELP system

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: we grep the installed header files for comments ;-)

FORTH

(HELP) ( .. )();
as:"paren-help";

ordinary primitive (HELP)

an executable word (no special usage info)

or wrapper call around p4_paren_help

host_k12 wordset

description

-- useful additional primitives for K12xx platforms

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This wordset adds some additional primitives that are useful in K12xx environments.

FORTH
BOOT-SCRIPT: ( "string" -- )(); 
 ;

DO NOT USE! will vanish w/o warning in the next version! see BOOT-SCRIPT@

FORTH
BOOT-SCRIPT@ ( -- s-a s-n )(); 
 ;

the file that will be include on next COLD boot DO NOT USE! will vanish w/o warning in the next version!

FORTH
#K1297-G20 ( .. )(); 
 ;
( _K12_SOURCE+100 )  constant #K1297-G20

an ordinary constant (no special usage info)

EXTENSIONS
OPEN-TERMINAL-LOGFILE ( s-buf s-len -- )(); 
 ;

open terminal logfile named by the string-buffer all further output to the terminal window is also logged into this file. This is especially useful in embedded environments where the terminal connection is often not used or it is directed to a different location that does not easily allow to redirect the forth output to a file for further examination.

EXTENSIONS
CLOSE-TERMINAL-LOGFILE ( -- )(); 
 ;

close terminal logfile opened with OPEN-TERMINAL-LOGFILE

EXTENSIONS
TERMINAL-EMULATION-STATE ( -- state* )(); 
 ;

returns the address of the emulations state variable so it can be read and explicitly changed to another value from forth text. This is a very questionable thing to do as the emulation-state is actually an enumerated value, the ESE will just show question-marks setting this variable to something not understood.

EXTENSIONS
TERMINAL-ANSWER-LINK ( -- sap#* )(); 
 ;

send terminal-output as a data-message to the specified link sap. Unlike TERMINAL-OUTPUT-LINK the data-messages are in line-mode. The flushed characters are buffered until a non-printable character is seen. This is somewhat more useful when treating pfe as a print service and testing machine, but can not provide for interactivity.

 60 TERMINAL-ANSWER-LINK !
 ...
 TERMINAL-ANSWER-LINK OFF
 
EXTENSIONS
TERMINAL-OUTPUT-LINK ( -- sap#* )(); 
 ;

send terminal-output as a data-message to the specified link sap. This can be used in an embedded systems for a terminal session simulation. setting zero-sap will disable sending message-frames (the zero sap is therefore not usable for output-to-link). The startup default is zero.

 60 TERMINAL-OUTPUT-LINK !
 ...
 TERMINAL-OUTPUT-LINK OFF
 
EXTENSIONS
TERMINAL-INPUT-LINK ( -- sap#* )(); 
 ;

let the forth stdin-handling look for data-messages on this link too. These will be interpreted like messages that come from the interactive forth terminal. This can be used in an embedded systems for a terminal session simulation. setting zero-sap will disable interpreting these incoming data-frames as keyboard-strings (so that the zero sap is therefore not usable for an input-link!). The startup default is zero.

 60 TERMINAL-INPUT-LINK !
 ...
 TERMINAL-INPUT-LINK OFF
 

lib_sdl wordset

[SDL]
SDL_INIT_TIMER ( .. )(); 
 ;
( SDL_INIT_TIMER )  constant SDL_INIT_TIMER

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_AUDIO ( .. )(); 
 ;
( SDL_INIT_AUDIO )  constant SDL_INIT_AUDIO

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_VIDEO ( .. )(); 
 ;
( SDL_INIT_VIDEO )  constant SDL_INIT_VIDEO

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_CDROM ( .. )(); 
 ;
( SDL_INIT_CDROM )  constant SDL_INIT_CDROM

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_JOYSTICK ( .. )(); 
 ;
( SDL_INIT_JOYSTICK )  constant SDL_INIT_JOYSTICK

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_NOPARACHUTE ( .. )(); 
 ;
( SDL_INIT_NOPARACHUTE )  constant SDL_INIT_NOPARACHUTE

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_EVENTTHREAD ( .. )(); 
 ;
( SDL_INIT_EVENTTHREAD )  constant SDL_INIT_EVENTTHREAD

an ordinary constant (no special usage info)

[SDL]
SDL_INIT_EVERYTHING ( .. )(); 
 ;
( SDL_INIT_EVERYTHING )  constant SDL_INIT_EVERYTHING

an ordinary constant (no special usage info)

[SDL]

SDL_init ( .. )();
as:"sdl-init";

ordinary primitive SDL_init

an executable word (no special usage info)

or wrapper call around SDL_init

[SDL]
SDL_InitSubSystem ( .. )(); 
 ;

ordinary primitive SDL_InitSubSystem

an executable word (no special usage info)

or wrapper call around SDL_InitSubSystem

[SDL]
SDL_QuitSubSystem ( .. )(); 
 ;

ordinary primitive SDL_QuitSubSystem

an executable word (no special usage info)

or wrapper call around SDL_QuitSubSystem

[SDL]

SDL_WasInit ( .. )();
as:"sdl-wasinit";

ordinary primitive SDL_WasInit

an executable word (no special usage info)

or wrapper call around SDL_WasInit

[SDL]

SDL_Quit ( .. )();
as:"sdl-quit";

ordinary primitive SDL_Quit

an executable word (no special usage info)

or wrapper call around SDL_Quit

[SDL]

SDL_FALSE ( .. )();
as:"sdl-false";

( SDL_FALSE )  constant SDL_FALSE

an ordinary constant (no special usage info)

[SDL]

SDL_TRUE ( .. )();
as:"sdl-true";

( SDL_TRUE )  constant SDL_TRUE

an ordinary constant (no special usage info)

[SDL]

SDL_PRESSED ( .. )();
as:"sdl-pressed";

( SDL_PRESSED )  constant SDL_PRESSED

an ordinary constant (no special usage info)

[SDL]

SDL_RELEASED ( .. )();
as:"sdl-released";

( SDL_RELEASED )  constant SDL_RELEASED

an ordinary constant (no special usage info)

[SDL]
SDL_SetError ( str-ptr str-len -- )(); 
 ;

set it, based on

 void SDL_SetError(const char *fmt, ...);
 
[SDL]
SDL_GetError ( -- str-ptr str-len )(); 
 ;

get it, based on

 char * SDL_GetError(void);
 
[SDL]
SDL_ClearError ( .. )(); 
 ;

ordinary primitive SDL_ClearError

an executable word (no special usage info)

or wrapper call around SDL_ClearError

[SDL]
SDL_RWFromFile ( .. )(); 
 ;

ordinary primitive SDL_RWFromFile

an executable word (no special usage info)

or wrapper call around SDL_RWFromFile

[SDL]

SDL_RWFromFP ( .. )();
as:"sdl-rwfromfp";

ordinary primitive SDL_RWFromFP

an executable word (no special usage info)

or wrapper call around SDL_RWFromFP

[SDL]

SDL_RWFromMem ( .. )();
as:"sdl-rwfrommem";

ordinary primitive SDL_RWFromMem

an executable word (no special usage info)

or wrapper call around SDL_RWFromMem

[SDL]

SDL_AllocRW ( .. )();
as:"sdl-allocrw";

ordinary primitive SDL_AllocRW

an executable word (no special usage info)

or wrapper call around SDL_AllocRW

[SDL]

SDL_FreeRW ( .. )();
as:"sdl-freerw";

ordinary primitive SDL_FreeRW

an executable word (no special usage info)

or wrapper call around SDL_FreeRW

[SDL]

SDL_RWseek ( .. )();
as:"sdl-rwseek";

ordinary primitive SDL_RWseek

an executable word (no special usage info)

or wrapper call around SDL_RWseek

[SDL]

SDL_RWtell ( .. )();
as:"sdl-rwtell";

ordinary primitive SDL_RWtell

an executable word (no special usage info)

or wrapper call around SDL_RWtell

[SDL]

SDL_RWread ( .. )();
as:"sdl-rwread";

ordinary primitive SDL_RWread

an executable word (no special usage info)

or wrapper call around SDL_RWread

[SDL]

SDL_RWwrite ( .. )();
as:"sdl-rwwrite";

ordinary primitive SDL_RWwrite

an executable word (no special usage info)

or wrapper call around SDL_RWwrite

[SDL]

SDL_RWclose ( .. )();
as:"sdl-rwclose";

ordinary primitive SDL_RWclose

an executable word (no special usage info)

or wrapper call around SDL_RWclose

[SDL]

SDL_GetTick ( .. )();
as:"sdl-gettick";

ordinary primitive SDL_GetTick

an executable word (no special usage info)

or wrapper call around SDL_GetTick

[SDL]

SDL_Delay ( .. )();
as:"sdl-delay";

ordinary primitive SDL_Delay

an executable word (no special usage info)

or wrapper call around SDL_Delay

[SDL]
->SDL_AudioSpec.freq ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.freq

offsetof(SDL_AudioSpec,freq) (no special usage info)

[SDL]
->SDL_AudioSpec.format ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.format

offsetof(SDL_AudioSpec,format) (no special usage info)

[SDL]
->SDL_AudioSpec.channels ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.channels

offsetof(SDL_AudioSpec,channels) (no special usage info)

[SDL]
->SDL_AudioSpec.silence ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.silence

offsetof(SDL_AudioSpec,silence) (no special usage info)

[SDL]
->SDL_AudioSpec.samples ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.samples

offsetof(SDL_AudioSpec,samples) (no special usage info)

[SDL]
->SDL_AudioSpec.size ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioSpec.size

offsetof(SDL_AudioSpec,size) (no special usage info)

[SDL]
/SDL_AudioSpec ( .. )(); 
 ;
( sizeof(SDL_AudioSpec) )  constant /SDL_AudioSpec

an ordinary constant (no special usage info)

[SDL]

AUDIO_U8 ( .. )();
as:"audio-u-eight";

( AUDIO_U8 )  constant AUDIO_U8

an ordinary constant (no special usage info)

[SDL]

AUDIO_S8 ( .. )();
as:"audio-s-eight";

( AUDIO_S8 )  constant AUDIO_S8

an ordinary constant (no special usage info)

[SDL]
AUDIO_U16LSB ( .. )(); 
 ;
( AUDIO_U16LSB )  constant AUDIO_U16LSB

an ordinary constant (no special usage info)

[SDL]
AUDIO_S16LSB ( .. )(); 
 ;
( AUDIO_S16LSB )  constant AUDIO_S16LSB

an ordinary constant (no special usage info)

[SDL]
AUDIO_U16MSB ( .. )(); 
 ;
( AUDIO_U16MSB )  constant AUDIO_U16MSB

an ordinary constant (no special usage info)

[SDL]
AUDIO_S16MSB ( .. )(); 
 ;
( AUDIO_S16MSB )  constant AUDIO_S16MSB

an ordinary constant (no special usage info)

[SDL]

AUDIO_U16 ( .. )();
as:"audio-u-sixteen";

( AUDIO_U16 )  constant AUDIO_U16

an ordinary constant (no special usage info)

[SDL]

AUDIO_S16 ( .. )();
as:"audio-s-sixteen";

( AUDIO_S16 )  constant AUDIO_S16

an ordinary constant (no special usage info)

[SDL]
AUDIO_U16SYS ( .. )(); 
 ;
( AUDIO_U16SYS )  constant AUDIO_U16SYS

an ordinary constant (no special usage info)

[SDL]
AUDIO_S16SYS ( .. )(); 
 ;
( AUDIO_S16SYS )  constant AUDIO_S16SYS

an ordinary constant (no special usage info)

[SDL]
->SDL_AudioCVT.needed ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.needed

offsetof(SDL_AudioCVT,needed) (no special usage info)

[SDL]
->SDL_AudioCVT.src_format ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.src_format

offsetof(SDL_AudioCVT,scr_format) (no special usage info)

[SDL]
->SDL_AudioCVT.dst_format ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.dst_format

offsetof(SDL_AudioCVT,dst_format) (no special usage info)

[SDL]
->SDL_AudioCVT.rate_incr ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.rate_incr

offsetof(SDL_AudioCVT,rate_incr) (no special usage info)

[SDL]
->SDL_AudioCVT.buf ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.buf

offsetof(SDL_AudioCVT,buf) (no special usage info)

[SDL]
->SDL_AudioCVT.len ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.len

offsetof(SDL_AudioCVT,len) (no special usage info)

[SDL]
->SDL_AudioCVT.len_cvt ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.len_cvt

offsetof(SDL_AudioCVT,len_cvt) (no special usage info)

[SDL]
->SDL_AudioCVT.len_mult ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.len_mult

offsetof(SDL_AudioCVT,len_mult) (no special usage info)

[SDL]
->SDL_AudioCVT.len_ratio ( .. )(); 
 ;

ordinary offsetval ->SDL_AudioCVT.len_ratio

offsetof(SDL_AudioCVT,ratio) (no special usage info)

[SDL]
/SDL_AudioCVT ( .. )(); 
 ;
( sizeof(SDL_AudioCVT) )  constant /SDL_AudioCVT

an ordinary constant (no special usage info)

[SDL]

SDL_AudioInit ( .. )();
as:"sdl-audioinit";

ordinary primitive SDL_AudioInit

an executable word (no special usage info)

or wrapper call around SDL_AudioInit

[SDL]

SDL_AudioQuit ( .. )();
as:"sdl-audioquit";

ordinary primitive SDL_AudioQuit

an executable word (no special usage info)

or wrapper call around SDL_AudioQuit

[SDL]
SDL_AudioDriverName ( .. )(); 
 ;

ordinary primitive SDL_AudioDriverName

an executable word (no special usage info)

or wrapper call around SDL_AudioDriverName

[SDL]

SDL_OpenAudio ( .. )();
as:"sdl-openaudio";

ordinary primitive SDL_OpenAudio

an executable word (no special usage info)

or wrapper call around SDL_OpenAudio

[SDL]
SDL_GetAudioStatus ( .. )(); 
 ;

ordinary primitive SDL_GetAudioStatus

an executable word (no special usage info)

or wrapper call around SDL_GetAudioStatus

[SDL]
SDL_AUDIO_STOPPED ( .. )(); 
 ;
( SDL_AUDIO_STOPPED )  constant SDL_AUDIO_STOPPED

an ordinary constant (no special usage info)

[SDL]
SDL_AUDIO_PLAYING ( .. )(); 
 ;
( SDL_AUDIO_PLAYING )  constant SDL_AUDIO_PLAYING

an ordinary constant (no special usage info)

[SDL]
SDL_AUDIO_PAUSED ( .. )(); 
 ;
( SDL_AUDIO_PAUSED )  constant SDL_AUDIO_PAUSED

an ordinary constant (no special usage info)

[SDL]
SDL_LoadWAV_RW ( .. )(); 
 ;

ordinary primitive SDL_LoadWAV_RW

an executable word (no special usage info)

or wrapper call around SDL_LoadWAV_RW

[SDL]

SDL_LoadWAV ( .. )();
as:"sdl-loadwav";

ordinary primitive SDL_LoadWAV

an executable word (no special usage info)

or wrapper call around SDL_LoadWAV

[SDL]

SDL_FreeWAV ( .. )();
as:"sdl-freewav";

ordinary primitive SDL_FreeWAV

an executable word (no special usage info)

or wrapper call around SDL_FreeWAV

[SDL]
SDL_BuildAudioCVT ( .. )(); 
 ;

ordinary primitive SDL_BuildAudioCVT

an executable word (no special usage info)

or wrapper call around SDL_BuildAudioCVT

[SDL]
SDL_ConvertCVT ( .. )(); 
 ;

ordinary primitive SDL_ConvertCVT

an executable word (no special usage info)

or wrapper call around SDL_ConvertCVT

[SDL]

SDL_MixAudio ( .. )();
as:"sdl-mixaudio";

ordinary primitive SDL_MixAudio

an executable word (no special usage info)

or wrapper call around SDL_MixAudio

[SDL]

SDL_LockAudio ( .. )();
as:"sdl-lockaudio";

ordinary primitive SDL_LockAudio

an executable word (no special usage info)

or wrapper call around SDL_LockAudio

[SDL]
SDL_UnLockAudio ( .. )(); 
 ;

ordinary primitive SDL_UnLockAudio

an executable word (no special usage info)

or wrapper call around SDL_UnLockAudio

[SDL]

SDL_LockAudio ( .. )();
as:"sdl-lockaudio";

ordinary primitive SDL_LockAudio

an executable word (no special usage info)

or wrapper call around SDL_LockAudio

[SDL]
SDL_UnlockAudio ( .. )(); 
 ;

ordinary primitive SDL_UnlockAudio

an executable word (no special usage info)

or wrapper call around SDL_UnlockAudio

[SDL]
->SDL_version.major ( .. )(); 
 ;

ordinary offsetval ->SDL_version.major

offsetof(SDL_version,major) (no special usage info)

[SDL]
->SDL_version.minor ( .. )(); 
 ;

ordinary offsetval ->SDL_version.minor

offsetof(SDL_version,minor) (no special usage info)

[SDL]
->SDL_version.patch ( .. )(); 
 ;

ordinary offsetval ->SDL_version.patch

offsetof(SDL_version,patch) (no special usage info)

[SDL]
SDL_Linked_Version ( .. )(); 
 ;

ordinary primitive SDL_Linked_Version

an executable word (no special usage info)

or wrapper call around SDL_Linked_Version

[SDL]
SDL_LinkedVersion ( -- SDL_versionnum )(); 
 ;

This function gets the version of the dynamically linked SDL library. it should NOT be used to fill a version structure, instead you should use the SDL_Version() macro. see SDL_LinkedVersion

 implementation applies the SDL_VERSIONNUM macro to
 extern DECLSPEC const SDL_version * SDL_Linked_Version(void);
 
[SDL]
SDL_CompiledVersion ( -- SDL_versionnum )(); 
 ;

This function gets the version of the SDL library headers the PFE has been linked with. It returns the compact code from SDL_VERSIONNUM macro

locals wordset

description

-- The Optional Locals Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Portable Forth Environment does implement locals in such an extended form as that additional variable names can be declared anywhere in the compiled word.

Locals are names for values that live in a locals-frame on the return-stack - on entry to the procedure that locals-frame is carved from the return-stack and a frame-pointer is setup. Locals are in two forms, one is inialized by a chunk from the parameter-stack as it is with LOCALS| while the others are local variables declared later. The latter are left unitialized on setup of the locals-frame.

For unnamed returnstack locals, see words like R@ R! R'@ R'! R"@ R"! 2R@ 2R! but here the setup and cleanup of the return-stack frame is left to the user, possibly using some words like >R R> 2>R 2R> R>DROP while the locals-ext will take care to provide a frame-creation token and some cleanup-code for each EXIT or ;

FORTH

(LOCAL) ( .. )();
as:"paren-local";

compiling primitive (LOCAL)

an executable word (no special usage info)

or wrapper call around p4_paren_local

dpANS 13.6.1.0086 - standard forth word

FORTH
LOCALS| ( xN ... x2 x1 [name1 .. nameN <|>] -- )(); 
 ;

create local identifiers to be used in the current definition. At runtime, each identifier will be assigned a value from the parameter stack. <br> The identifiers may be treated as if being a VALUE , it does also implement the ansi TO extensions for locals. Note that the identifiers are only valid inside the currently compiled word, the SEE decompiled word will show them as <A> <B> ... <N> a.s.o. <br> see also LVALUE

dpANS 13.6.2.1795 - standard forth word

EXTENSIONS
LVALUE ( value [name] -- )(); 
 ;

declares a single local VALUE using (LOCAL) - a sequence of LVALUE declarations can replace a LOCALS| argument, ie. LOCALS| a b c | is the same as LVALUE a LVALUE b LVALUE c . This should also clarify the runtime stack behaviour of LOCALS| where the stack parameters seem to be assigned in reverse order as opposed to their textual identifier declarations. <br> compare with VALUE and the pfe's convenience word VAR.

 : LVALUE 
   STATE @ IF 
     VALUE 
   ELSE 
     BL WORD COUNT DUP (LOCAL) (TO)
   THEN
 ; IMMEDIATE
 
EXTENSIONS
LBUFFER: ( size [name] -- )(); 
 ;

declares a single local VALUE using (LOCAL) - which will hold the address of an area like BUFFER: but carved from the return-stack (as in C with alloca). This local buffer will be automatically given up at the end of the word. The return-stack-pointer will be increased only at the time of this function (and the address assigned to the LVALUE) so that the provided size gets determined at runtime. Note that in some configurations the forth-return-stack area is quite small - for large string operations you should consider to use a POCKET-PAD in pfe.

 : LBUFFER:
   STATE @ IF 
     BUFFER:
   ELSE 
     :NONAME ( size -- rp* ) R> RP@ - DUP RP! SWAP >R ;NONAME
     COMPILE, POSTPONE LVALUE
   THEN
 ; IMMEDIATE
 
ENVIRONMENT

LOCALS-EXT ( .. )();
as:"locals-minus-ext";

( 1994  )  constant LOCALS-EXT

an ordinary constant (no special usage info)

ENVIRONMENT

#LOCALS ( .. )();
as:"sharp-locals";

( MAX_LOCALS  )  constant #LOCALS

an ordinary constant (no special usage info)

ENVIRONMENT
LOCALS-LOADED ( .. )(); 
 ;

constructor primitive LOCALS-LOADED

an executable word (no special usage info)

or wrapper call around locals_init

memory wordset

description

-- The Optional Memory Allocation Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The optional memory allocation wordset interfaces to the surrounding OS heap memory management.

FORTH
ALLOCATE ( size -- ptr|0 code )(); 
 ;

allocate a chunk of memory from the system heap. use FREE to release the memory area back to the system. <br> a code of zero means success.

dpANS 14.6.1.0707 - standard forth word

FORTH

FREE ( ptr -- code )();
p4:"free";

free the memory from ALLOCATE a code of zero means success.

dpANS 14.6.1.1605 - standard forth word

FORTH
RESIZE ( ptr newsize -- ptr' code )(); 
 ;

resize the system memory chunk. a code of zero means success.

dpANS 14.6.1.2145 - standard forth word

ENVIRONMENT
MEMORY-ALLOC-EXT ( .. )(); 
 ;
( 1994  )  constant MEMORY-ALLOC-EXT

an ordinary constant (no special usage info)

misc wordset

description

-- miscellaneous useful words, mostly stemming from fig-forth

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Compatiblity with former standards, miscellaneous useful words.

FORTH

ok ( .. )();
as:"ok";

ordinary primitive ok

an executable word (no special usage info)

or wrapper call around p4_ok

FORTH

COLD ( -- )();
p4:"cold";

cold abort - reinitialize everything and go to QUIT routine ... this routine is implemented as a warm-boot in pfe.

 : WARM FENCE @ (FORGET) INCLUDE-FILE ?DUP IF COUNT INCLUDED THEN QUIT ;
 
FORTH

LIT ( .. )();
as:"lit";

ordinary primitive LIT

an executable word (no special usage info)

or wrapper call around p4_literal_execution

FORTH

.LINE ( line# block# -- )();
p4:"dot-line";

FORTH

OUT ( .. )();
as:"out";

threadstate variable OUT

out (no special usage info)

FORTH

DP ( .. )();
as:"dp";

threadstate variable DP

dp (no special usage info)

FORTH

HLD ( .. )();
as:"hld";

threadstate variable HLD

hld (no special usage info)

FORTH

R0 ( .. )();
as:"r-zero";

threadstate variable R0

r0 (no special usage info)

FORTH

S0 ( .. )();
as:"s-zero";

threadstate variable S0

s0 (no special usage info)

FORTH

UD.R ( 2val r -- )();
p4:"u-d-dot-r";

FORTH

UD. ( 2val -- )();
p4:"u-d-dot";

see also UD.R

FORTH

ID. ( nfa -- )();
p4:"id-dot";

print the name-field pointed to by the nfa-argument. a synonym for .NAME - but this word is more portable due its heritage from fig-forth.

in fig-forth the name-field is effectivly a bstring with some flags, so the nfa's count has to be masked out, e.g.

 : .NAME COUNT 32 AND TYPE ;

in other pfe configurations, the name might not contain the flags it it just a counted string - and there may be even more possibility.

 : .NAME COUNT TYPE ;

you should more and more convert your code to use the sequence NAME>STRING TYPE

FORTH

.NAME ( .. )();
as:"dot-name";

forthword synonym .NAME

is doing the same as ID.

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH
-ROLL ( xn ... x2 x1 n -- x1 xn ... x2 )(); 
 ;

the inverse of ROLL

FORTH

RANDOM ( n1 -- n2 )();
p4:"random";

returns random number with 0 <= n2 < n1)

 : RANDOM ?DUP IF _random SWAP MOD ELSE _random THEN ;
 
FORTH

SRAND ( n -- )();
p4:"srand";

FORTH
(UNDER+) ( n1 n2 -- n1+n2 n2 )(); 
 ;

quicker than

 : (UNDER+) TUCK + SWAP ; or : (UNDER+) DUP UNDER+ ;
 
FORTH
UNDER+ ( n1 x n2 -- n1+n2 x )TF(); 
 ;

quicker than

 : UNDER+  ROT + SWAP ;
 
FORTH

+TO ( val [name] -- )();
p4:"plus-to";

add the val to the named VALUE or LOCALS| value

FORTH
BUILD-ARRAY ( n1 n2 ... nX X --- n )(); 
 ;

writes X, n1, ... nX into the dictionary - returns product n1 * n2 * ... * nX

FORTH
ACCESS-ARRAY ( i1 i2 ... iX addr1 --- addr2 n )(); 
 ;

see BUILD-ARRAY

FORTH

.STATUS ( -- )();
p4:"dot-status";

display internal variables

 : .STATUS .VERSION .CVERSION .MEMORY .SEARCHPATHS .DICTVARS .REGSUSED ;
 
FORTH
SHOW-STATUS ( .. )(); 
 ;

forthword synonym SHOW-STATUS

is doing the same as .STATUS

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH
UPPER-CASE? ( .. )(); 
 ;

- loader type P4_DVaL UPPER-CASE?

wordl_flag (no special usage info)

FORTH

LOWER-CASE ( .. )();
as:"lower-minus-case";

threadstate variable LOWER-CASE

wordl_flag (no special usage info)

FORTH
LOWER-CASE-FN? ( .. )(); 
 ;

- loader type P4_DVaL LOWER-CASE-FN?

lower_case_fn (no special usage info)

FORTH
LOWER-CASE-FN ( .. )(); 
 ;

threadstate variable LOWER-CASE-FN

lower_case_fn (no special usage info)

FORTH
REDEFINED-MSG? ( .. )(); 
 ;

- loader type P4_DVaL REDEFINED-MSG?

redefined_msg (no special usage info)

FORTH
REDEFINED-MSG ( .. )(); 
 ;

threadstate variable REDEFINED-MSG

redefined_msg (no special usage info)

FORTH
QUOTED-PARSE? ( .. )(); 
 ;

- loader type P4_DVaL QUOTED-PARSE?

quoted_parse (no special usage info)

FORTH

SOURCE-LINE ( -- n )();
p4:"source-line";

if SOURCE is from EVALUATE (or QUERY ) then the result is 0 else the line-numbers start from 1

FORTH
SOURCE-NAME ( -- str-ptr str-len )(); 
 ;

if SOURCE is from INCLUDE then the result is the filename, otherwise a generic name for the SOURCE-ID is given.

FORTH

TH'POCKET ( n -- addr u )();
p4:"th-pocket";

returns the specified pocket as a S" string reference

FORTH

POCKET-PAD ( -- addr )();
p4:"pocket-pad";

Returns the next pocket. A pocket has usually the size of a maxstring, see ENVIRONMENT /STRING (but can be configured to be different, mostly when MAXPATH > /STRING ) Note that a pocket is a temporary and forth internal functions do sometimes call POCKET-PAD too, especially when building filenames and getting a literal (but temporary) string from the keyboard. Functions are not expected to hold references to this transient area any longer than building a name and calling another word with it.

Usage of a pocket pad is a good way to make local temporary buffers superfluous that are only used to construct a temporary string that usually gets swallowed by another function.

 depracated code:
   create temp-buffer 255 allot
   : make-temp ( str buf ) 
          temp-buffer place  " .tmp" count temp-buffer append 
          temp-buffer count make-file ;
 replace with this:
   : make-temp ( str buf )
        pocket-pad >r    
        r place  " .tmp" count r append
        r> count make-file
   ;
 
FORTH

/CELL ( .. )();
as:"slash-cell";

( sizeof (p4cell) )  constant /CELL

an ordinary constant (no special usage info)

FORTH

WSIZE ( .. )();
as:"wsize";

forthword synonym WSIZE

is doing the same as /CELL

this word is provided only for compatibility with common forth usage in programs. Thegiven synonym should be preferred however.

FORTH

W@ ( addr -- w-val )();
p4:"w-fetch";

fetch a 2byte-val from address

FORTH

W! ( w-val addr -- )();
p4:"w-store";

store a 2byte-val at addressed 2byte-value

FORTH

W+! ( w-val addr -- )();
p4:"w-plus-store";

add a 2byte-val to addressed 2byte-value

FORTH

WL-HASH ( c-addr n1 -- n2 )();
p4:"wl-hash";

calc hash-code for selection of thread in a threaded-vocabulary

FORTH

TOPMOST ( wid -- a-addr )();
p4:"topmost";

that last valid word in the specified vocabulary

FORTH

LS.WORDS ( -- )();
p4:"ls-words";

see WORDS

FORTH

LS.PRIMITIVES ( -- )();
p4:"ls-primitives";

see WORDS

FORTH

LS.COLON-DEFS ( -- )();
p4:"ls-cdefs";

see WORDS

FORTH

LS.DOES-DEFS ( -- )();
p4:"ls-ddefs";

see WORDS

FORTH

LS.CONSTANTS ( -- )();
p4:"ls-constants";

see WORDS

FORTH

LS.VARIABLES ( -- )();
p4:"ls-variables";

see WORDS

FORTH
LS.VOCABULARIES ( -- )(); 
 ;

see WORDS

FORTH

LS.MARKERS ( -- )();
p4:"ls-markers";

see WORDS

FORTH

TAB ( n -- )();
p4:"tab";

jump to next column divisible by n

FORTH

BACKSPACE ( -- )();
p4:"backspace";

reverse of SPACE

FORTH

?STOP ( -- flag )();
p4:"Q-stop";

check for 'q' pressed - see ?CR

FORTH

START?CR ( -- )();
p4:"start-Q-cr";

initialized for more-like effect - see ?CR

FORTH

?CR ( -- flag )();
p4:"Q-cr";

like CR , stop 25 lines past START?CR

FORTH
CLOSE-ALL-FILES ( -- )(); 
 ;
FORTH

.MEMORY ( -- )();
p4:"dot-memory";

FORTH

*EMIT* ( .. )();
as:"star-emit-star";

threadstate variable *EMIT*

emit (no special usage info)

FORTH

*EXPECT* ( .. )();
as:"star-expect-star";

threadstate variable *EXPECT*

expect (no special usage info)

FORTH

*KEY* ( .. )();
as:"star-key-star";

threadstate variable *KEY*

key (no special usage info)

FORTH

*TYPE* ( .. )();
as:"star-type-star";

threadstate variable *TYPE*

type (no special usage info)

FORTH

(EMIT) ( .. )();
as:"paren-emit";

ordinary primitive (EMIT)

an executable word (no special usage info)

or wrapper call around p4_paren_emit

FORTH

(EXPECT) ( .. )();
as:"paren-expect";

ordinary primitive (EXPECT)

an executable word (no special usage info)

or wrapper call around p4_paren_expect

FORTH

(KEY) ( .. )();
as:"paren-key";

ordinary primitive (KEY)

an executable word (no special usage info)

or wrapper call around p4_paren_key

FORTH

(TYPE) ( .. )();
as:"paren-type";

ordinary primitive (TYPE)

an executable word (no special usage info)

or wrapper call around p4_paren_type

FORTH

STANDARD-I/O ( -- )();
p4:"standard-io";

initialize *TYPE* , *EMIT* , *EXPECT* and *KEY* to point directly to the screen I/O routines, <br> namely (TYPE) , (EMIT) , (EXPECT) , (KEY)

FORTH

HELP ( name -- )();
p4:"help";

will load the help module in the background and hand over the parsed name to (HELP) to be resolved. If no (HELP) word can be loaded, nothing will happen.

FORTH
EDIT-BLOCKFILE ( name -- )(); 
 ;

will load the edit module in the background and look for a word called EDIT-BLOCK that could be used to edit the blockfile. If no EDIT-BLOCKFILE word can be loaded, nothing will happen. Otherwise, OPEN-BLOCKFILE is called followed by 0 EDIT-BLOCK to start editing the file at the first block.

FORTH

APPLICATION ( .. )();
as:"application";

threadstate variable APPLICATION

application (no special usage info)

FORTH

ARGC ( -- n )();
p4:"argc";

FORTH

ARGV ( n -- addr u )();
p4:"argv";

FORTH

EXITCODE ( .. )();
as:"exitcode";

threadstate variable EXITCODE

exitcode (no special usage info)

FORTH

STDIN ( .. )();
as:"stdin";

- loader type P4_DVaL STDIN

stdIn (no special usage info)

FORTH

STDOUT ( .. )();
as:"stdout";

- loader type P4_DVaL STDOUT

stdOut (no special usage info)

FORTH

STDERR ( .. )();
as:"stderr";

- loader type P4_DVaL STDERR

stdErr (no special usage info)

FORTH
EXPAND-FN ( addr1 u1 addr2 -- addr2 cnt2 )(); 
 ;
FORTH
LOAD" ( [filename<">] -- ? )obsolete (); 
 ;

load the specified file - this word can be compiled into a word-definition obsolete! use OPEN-BLOCKFILE name LOAD

FORTH

SYSTEM ( addr u -- ret-val )();
p4:"system";

run a shell command (note: embedded systems have no shell)

FORTH
SYSTEM" ( [commandline<">] -- ret-val )obsolete(); 
 ;

run a shell command (note:embedded systems have no shell) obsolete! use S" string" SYSTEM

FORTH

RAISE ( n -- )();
p4:"raise";

send a SIGNAL to self

FORTH

SIGNAL ( xt1 n -- xt2 )();
p4:"signal";

install signal handler - return old signal handler

FORTH

CREATE: ( 'name' -- )();
p4:"create-var";

this creates a name with the VARIABLE runtime. Note that this is the FIG-implemenation of CREATE whereas in ANS-Forth mode we have a CREATE identical to FIG-style <BUILDS

 : CREATE: BL WORD $HEADER DOVAR A, ;
 
FORTH
BUFFER: ( size 'name' -- )(); 
 ;

this creates a name with the VARIABLE runtime and ALLOTs memory

 : BUFFER: BL WORD $HEADER DOVAR A, ALLOT ;
 
FORTH
R'@ ( R: a b -- a R: a b )(); 
 ;

fetch the next-under value from the returnstack. used to interpret the returnstack to hold two LOCALS| values. ( R@ / 2R@ / R>DROP / R"@)

FORTH
R'! ( x R: a b -- R: x b )(); 
 ;

store the value into the next-under value in the returnstack. used to interpret the returnstack to hold two LOCALS| values. see R'@ for inverse operation

FORTH
R"@ ( R: a b c -- a R: a b c )(); 
 ;

fetch the second-under value from the returnstack. used to interpret the returnstack to hold three LOCALS| values. see R"! for inverse operation ( R'@ R@ / 2R@ / R>DROP )

FORTH
R"! ( x R: a b c -- R: x b c )(); 
 ;

store the value into the second-under value in the returnstack. used to interpret the returnstack to hold three LOCALS| values. see R"@ for inverse operation

FORTH

R! ( x R: a -- R: x )();
p4:"r-store";

store the value as the topmost value in the returnstack. see R@ for inverse operation ( R'@ / R"@ / 2R@ / 2R!)

FORTH
2R! ( x y R: a b -- R: x y )(); 
 ;

store the value as the topmost value in the returnstack. see 2R@ for inverse operation ( R'@ / R"@ / 2R@ / 2R!)

FORTH

DUP>R ( val -- val )();
p4:"dup-to-r";

shortcut, see R>DROP <br> note again that the following will fail:

 : DUP>R DUP >R ;
 
FORTH

R>DROP ( -- )();
p4:"r-from-drop";

shortcut (e.g. in CSI-Forth) <br> note that the access to R is configuration dependent - only in a traditional fig-forth each NEST will be one cell wide - in case that there are no LOCALS| of course. And remember, the word above reads like the sequence R> and DROP but that is not quite true.

 : R>DROP R> DROP ; ( is bad - correct might be )  : R>DROP R> R> DROP >R ;
 
FORTH

2R>2DROP ( -- )();
p4:"two-r-from-drop";

this is two times R>DROP but a bit quicker. it is however really quick compared to the sequence 2R> and 2DROP

FORTH

CLEARSTACK ( -- )();
p4:"clearstack";

reset the parameter stack to be empty

 : CLEARSTACK  S0 SP! ;
 
EXTENSIONS

+UNDER ( .. )();
as:"plus-under";

ordinary primitive +UNDER

an executable word (no special usage info)

or wrapper call around p4_plus_under

EXTENSIONS

EXECUTES ( n [word] -- )();
p4:"executes";

stores the execution token of following word into the callback pointer for the specified function-key

ENVIRONMENT

RAND_MAX ( .. )();
as:"rand-max";

( RAND_MAX )  constant RAND_MAX

an ordinary constant (no special usage info)

module wordset

description

(C) 2000 - 2001 Guido Draheim

@see LGPL for licensedescription: this wordset implements a simple module-system. the basic module-system is based on the three words MODULE/END-MODULE/EXPORT - these three were present TEK' mforth, here the MPE' forth is used as an example for the naming scheme. This implementation has also mpe's EXPOSE-MODULE, and it has a serious form of mpe's REQUIRES under the name ALSO-MODULE which clarifies that the search-order is modified. Note also that pfe defines a REQUIRES in require-ext that works like INCLUDE-ONCE

EXTENSIONS
MODULE ( "name" -- old-current )(); 
 ;

create a new WORDLIST with the given name. It will also have an implicit hidden vocabulary just as well and all DEFINITIONS will go into that hidden wordlist. Therefore the old CURRENT is memorized on the cs-stack.

effectivly, CONTEXT[1] will have the wordlist-id of the public wordlist "name" and CONTEXT[0] will have the hidden wordlist contained in "name" - the hidden wordlist will always be known as HIDDEN' so that it can be re-referenced without need to use ALSO just to access a single definition from just another vocabulary. Note that HIDDEN' is defined immediate (a VOCABULARY' ) to modify the ORDER inside a colon definition.

 : MODULE
   CURRENT @ ( -- old-current )
   VOCABULARY
   ALSO LATEST NAME> EXECUTE ALSO DEFINITIONS
   C" HIDDEN'" $CREATE WORDLIST CONTEXT !
 ;
 
EXTENSIONS
END-MODULE ( old-current -- )(); 
 ;

clean up the cs-stack from the last MODULE definition. Effectivly, MODULE definitions can be nested.

 : END-MODULE ( old-current )
   PREVIOUS PREVIOUS CURRENT ! 
 
EXTENSIONS
EXPORT ( old-current "name" -- old-current )(); 
 ;

the named word in the hidden dictionary (i.e. the wordlist referenced in CURRENT) is exported into the public wordlist of it (i.e. which is in this implementation CONTEXT[1]). The actual implemenation will create a DEFER-word in the public wordlist withits parameter area pointing to the cfa of the hidden implementation.

 : EXPORT
   CURRENT @ CONTEXT CELL+ @ CURRENT !
   DEFER CURRENT !
   LATEST COUNT CURRENT @ SEARCH-WORDLIST
   IF LATEST NAME> >BODY ! ELSE ABORT" can't find word to export" THEN
 ;
 
EXTENSIONS
EXPOSE-MODULE ( "name" -- )(); 
 ;

affects the search order, ALSO module-wid CONTEXT ! hidden'

 : EXPOSE-MODULE 
    ALSO S" HIDDEN'" 
    ' DUP VOC? ABORT?" is no vocabulary" >VOC 
    SEARCH-WORDLIST 0= IF " no hidden vocabulary found" THEN
    DUP VOC? ABORT?" hidden is no vocabulary" EXECUTE
 ;
 
EXTENSIONS
ALSO-MODULE ( "name" -- )(); 
 ;

affects the search-order, ALSO module-wid CONTEXT !

 : ALSO-MODULE
   ' DUP VOC? ABORT?" is no vocabulary" 
   ALSO EXECUTE
 ;
 

option wordset

description

-- Almost-Non-Volatile Environment Options

Copyright (C) Tektronix, Inc. 2001 - 2001. All rights reserved.

description: the openfirmware standard specifies some means to add options to a non-volatile ram-area (nvram) that are used in the bootup sequence of the forth-based bootsystem. Here we add an internal API for looking for bootup options, an internal API to add bootup options through commandline processing, and an external API to change the bootup options for a COLD reboot or an APPLICATION specific sequence. The external API will try to follow openfirmware as closely as possible without having a real non-volatile ram-area. Instead there is a session-struct that can be changed and from which multiple forth-threads can be instantiated later using those options. The forth-instantion processing is not supposed to scan for commandline options, which is a mere necessity in embedded enviroments where option transferal is done in a completly different way and where the forth thread is never killed but just stopped or restarted for various reasons. Even that there is no real nvram we add a cold-options reboot-area in this wordset. The option-ram is organized just along a normal dictionary just need to add a wordlist-handlestruct to find the definitions in this dictlike ram-portion.

ENVIRONMENT

OPTION-EXT ( .. )();
as:"option-minus-ext";

( 2001  )  constant OPTION-EXT

an ordinary constant (no special usage info)

forth wordset

description

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

extensions wordset

description

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

posix wordset

description

-- Words making sense in POSIX-like systems only.

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: This file exports a set of system words for a posixish OS environment. So should do any alternative wordset you might create for your OS.

EXTENSIONS

#! ( "...<eol>" -- )();
p4:"ignore-line";

ignores the rest of the line, defining `#!' is used to support forth scripts executed by the unix kernel

EXTENSIONS

CLOCK ( --- ticks )();
"clock";

return clock()

EXTENSIONS
GETTIMEOFDAY ( -- double-time )(); 
 ;

returns SVR/BSD gettimeofday(2). Never defined on 16-bit systems, hence TIME&DATE is more portable.

EXTENSIONS

NTOHL ( l -- l' )();
p4:"ntohl";

if current host-encoding is bigendian, this is a NOOP otherwise byteswap the lower 32-bit bits of the topofstack. see L@ and L! (being usually just @ and ! ) (on some platforms, the upper bits are erased, on others not)

EXTENSIONS

HTONL ( .. )();
as:"htonl";

ordinary primitive HTONL

an executable word (no special usage info)

or wrapper call around p4_ntohl

EXTENSIONS

NTOHS ( w -- w' )();
p4:"ntohs";

if current host-encoding is bigendian, this is a NOOP otherwise byteswap the lower 16-bit bits of the topofstack. see W@ and W! (on some platforms, the upper bits are erased, on others not)

EXTENSIONS

HTONS ( .. )();
as:"htons";

ordinary primitive HTONS

an executable word (no special usage info)

or wrapper call around p4_ntohs

ENVIRONMENT

CLK_TCK ( .. )();
as:"clk-tck";

ordinary primitive CLK_TCK

an executable word (no special usage info)

or wrapper call around p4__clk_tck

search wordset

description

-- The Optional Search Order Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The Search Order Word Set as defined by the Standard.

Note that there a some extensions in the Portable Forth Environment. Wordlists can be made case-sensitive always or only at request. Wordlists can be linear or hashed vocabularies. There are other words to recursivly search an implicit vocabulary along with another.

FORTH

DEFINITIONS ( -- )();
p4:"definitions";

make the current context-vocabulary the definition-vocabulary, that is where new names are declared in. see ORDER

dpANS 16.6.1.1180 - standard forth word

FORTH

GET-CURRENT ( -- voc )();
p4:"get-current";

return the current definition vocabulary, see DEFINITIONS

dpANS 16.6.1.1643 - standard forth word

FORTH
GET-ORDER ( -- vocn ... voc1 n )(); 
 ;

get the current search order onto the stack, see SET-ORDER

dpANS 16.6.1.1647 - standard forth word

FORTH
SEARCH-WORDLIST ( str-ptr str-len voc -- 0 | xt 1 | xt -1 )(); 
 ;

almost like FIND or (FIND) -- but searches only the specified vocabulary.

dpANS 16.6.1.2192 - standard forth word

FORTH

SET-CURRENT ( voc -- )();
p4:"set-current";

set the definition-vocabulary. see DEFINITIONS

dpANS 16.6.1.2195 - standard forth word

FORTH
SET-ORDER ( vocn ... voc1 n -- )(); 
 ;

set the search-order -- probably saved beforehand using GET-ORDER

dpANS 16.6.1.2197 - standard forth word

FORTH

WORDLIST ( -- voc )();
p4:"wordlist";

return a new vocabulary-body for private definitions.

dpANS 16.6.1.2460 - standard forth word

FORTH

ALSO ( -- )();
p4:"also";

a DUP on the search ORDER - each named vocabulary replaces the topmost ORDER vocabulary. Using ALSO will make it fixed to the search-order. (but it is not nailed in trap-conditions as if using DEFAULT-ORDER )

 order:   vocn ... voc2 voc1 -- vocn ... voc2 voc1 voc1
 

dpANS 16.6.2.0715 - standard forth word

FORTH

ORDER ( -- )();
p4:"order";

show the current search-order, followed by the CURRENT DEFINITIONS vocabulary and the ONLY base vocabulary

dpANS 16.6.2.1985 - standard forth word

FORTH

PREVIOUS ( -- )();
p4:"previous";

the invers of ALSO , does a DROP on the search ORDER of vocabularies.

 order: vocn ... voc2 voc1 -- vocn ... voc2 
 example: ALSO PRIVATE-VOC DEFINTIONS (...do some...) PREVIOUS DEFINITIONS
 

dpANS 16.6.2.2037 - standard forth word

FORTH
FORTH-WORDLIST ( .. )(); 
 ;

- loader type P4_DVaL FORTH-WORDLIST

forth_wl (no special usage info)

dpANS 16.6.1.1595 - standard forth word

FORTH

DEFAULT-ORDER ( -- )();
p4:"default-order";

nail the current search ORDER so that it will even survive a trap-condition. This default-order can be explicitly loaded with RESET-ORDER

FORTH

RESET-ORDER ( -- )();
p4:"reset-order";

load the DEFAULT-ORDER into the current search ORDER - this is implicitly done when a trap is encountered.

FORTH
RESET-ORDER-IS ( .. )(); 
 ;

threadstate variable RESET-ORDER-IS

reset_order (no special usage info)

ENVIRONMENT
SEARCH-ORDER-EXT ( .. )(); 
 ;
( 1994  )  constant SEARCH-ORDER-EXT

an ordinary constant (no special usage info)

ENVIRONMENT
CHAIN-WORDLISTS ( .. )(); 
 ;
( P4_TRUE  )  constant CHAIN-WORDLISTS

an ordinary constant (no special usage info)

ENVIRONMENT
SEARCH-LOADED ( .. )(); 
 ;

constructor primitive SEARCH-LOADED

an executable word (no special usage info)

or wrapper call around p4_search_init

shell wordset

description

-- os-like / shell-like commands for pfe

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: These builtin words are modelled after common shell commands, so that the Portable Forth Environment can often be put in the place of a normal OS shell.

EXTENSIONS

$PID ( -- pid )();
p4:"getpid";

calls system's getpid

EXTENSIONS

$$ ( .. )();
as:"str-str";

obsolete forthword $$

is doing the same as $PID

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

$UID ( -- val )();
p4:"getuid";

calls system's getuid

EXTENSIONS

$EUID ( -- val )();
p4:"geteuid";

calls system's geteuid

EXTENSIONS

$GID ( -- val )();
p4:"getgid";

calls system's getgid

EXTENSIONS

UMASK ( val -- ret )();
p4:"umask";

calls system's umask

EXTENSIONS

$HOME ( -- str-ptr str-len )();
p4:"home";

calls system's getenv(HOME)

EXTENSIONS

$USER ( -- str-ptr str-len )();
p4:"user";

calls system's getenv(USER)

EXTENSIONS

$CWD ( -- str-ptr str-len )();
p4:"cwd";

calls system's getcwd

EXTENSIONS

PWD ( -- )();
p4:"pwd";

calls system's getcwd and prints it to the screen

 : PWD  $CWD TYPE ;
 
EXTENSIONS

RM ( .. )();
as:"rm";

compiling primitive RM

an executable word (no special usage info)

or wrapper call around p4_remove

EXTENSIONS

TOUCH ( .. )();
as:"touch";

compiling primitive TOUCH

an executable word (no special usage info)

or wrapper call around p4_touch

EXTENSIONS

CHDIR ( bstring -- )();
p4:"chdir";

change the current directory. <br>

Note

(under VxWorks it is global! do not use in scripts!!)

EXTENSIONS

CD ( .. )();
as:"cd";

obsolete forthword CD

is doing the same as CHDIR

This word should be replaced. It will be deleted in the near future. Instead use the (newer) synonym word given above.

EXTENSIONS

RMDIR ( .. )();
as:"rmdir";

compiling primitive RMDIR

an executable word (no special usage info)

or wrapper call around p4_rmdir

EXTENSIONS

MKDIR ( .. )();
as:"mkdir";

compiling primitive MKDIR

an executable word (no special usage info)

or wrapper call around p4_md

EXTENSIONS

LN ( .. )();
as:"ln";

compiling primitive LN

an executable word (no special usage info)

or wrapper call around p4_link

EXTENSIONS

MV ( .. )();
as:"mv";

compiling primitive MV

an executable word (no special usage info)

or wrapper call around p4_mv

EXTENSIONS

LL ( .. )();
as:"ll";

compiling primitive LL

an executable word (no special usage info)

or wrapper call around p4_ll

EXTENSIONS

LS ( .. )();
as:"ls";

compiling primitive LS

an executable word (no special usage info)

or wrapper call around p4_ls

EXTENSIONS

CP ( .. )();
as:"cp";

compiling primitive CP

an executable word (no special usage info)

or wrapper call around p4_cp

signals wordset

description

-- Handle signals in forth

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The signal-callback system divides signals internally into the following classes:

P4_ON_XXXXX:

a signal which will be assigned a corresponding THROW on forth level, e.g. for SIGFPE

Abort:

a signal that will not kill the current forth process but which has not forth-level THROW either, e.g. SIGILL. It will result in an ABORT" Signal-Description"

Fatal:

the current forth process will die gracefully.

Default:

A signal with some unknown meaning, exported to allow a forth-programmer to hook it anyway, e.g. to let a programmer on AIX to intercept SIGGRANT and run a forth word, otherwise the signal will be left untouched.

Chandled:

A signal used internally be PFE and initially hooked by the runtime system, in general this would be the Job-Control signals and SIGWINCH that will get send when an xterm changes its size.

The first three classes will go to the default Forth Signal-Handler. Its execution will look for user-routine being registered (in which cases that forth-routine will be executed) and otherwise do its default action (to throw, abort" or exit).

The fourth class is not hooked until some user-code requests that signal in which case the user-defiend forth-routine is executed as its action, otherwise the system-defined default-action will be left untouched.

The signal of the fourth type are not handled by the default signal handler defined herein, so can not just call a forth word, if I still get this right ;-)

Dirk-Uwe Zoller

note: forth-level callbacks might not work as expected on all systems that the rest of PFE runs on. Be careful.

Guido Draheim

EXTENSIONS
<<load_signals>> ( .. )(); 
 ;

constructor primitive <<load_signals>>

an executable word (no special usage info)

or wrapper call around p4_load_signals

smart_go wordset

description

-- smart outer interpreter

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: Smart Outer Interpreter allows to register executions tokens that get tied to a single char - if the outer interpreter Compatiblity with former standards, miscellaneous useful words. ... for TOOLS-EXT

EXTENSIONS
SMART-INTERPRET-INIT ( -- )(); 
 ;

creates a set of interpret-words that are used in the inner interpreter, so if a word is unknown to the interpreter-loop it will use the first char of that word, attach it to an "interpret-" prefix, and tries to use that IMMEDIATE-DEFER-word on the rest of the word. This SMART-INTERPRET-INIT will set up words like interpret-" so you can write <c>"hello"</c> instead of <c>" hello"</c> and it creates interpret-\ so that words like \if-unix are ignoring the line if the word \if-unknown is unknown in itself. This is usually not activated on startup.

EXTENSIONS
SMART-INTERPRET! ( -- )(); 
 ;

enables/disables the SMART-INTERPRET extension in INTERPRET , (actually stores an XT in DEFER inside the mainloop interpreter)

ENVIRONMENT
SMART-INTERPRET-LOADED ( .. )(); 
 ;

constructor primitive SMART-INTERPRET-LOADED

an executable word (no special usage info)

or wrapper call around smart_interpret_init

string wordset

description

-- The Optional String Word Set

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: The basic words for handling string buffers. There are much more buffer words used in most Forth implementations around but they can usually implemented as colon-word quite effectivly on the basis of the STRING wordset.

FORTH
-TRAILING ( str-ptr str-len -- str-ptr str-len' )(); 
 ;

check the given buffer if it contains whitespace at its end. If so, shorten str-len to meet the last non-whitespace character in the buffer.

dpANS 17.6.1.0170 - standard forth word

FORTH
/STRING ( str-ptr str-len n -- str-ptr' str-len' )(); 
 ;

shorten the buffer from the beginning by n characters, i.e.

  str-ptr += n ;
  str-len -= n; 
 

dpANS 17.6.1.0245 - standard forth word

FORTH

BLANK ( str-ptr str-len -- )();
p4:"blank";

FILL a given buffer with BL blanks

dpANS 17.6.1.0780 - standard forth word

FORTH
CMOVE ( from-ptr to-ptr len -- )(); 
 ;

memcpy an area from->to for len bytes, starting at the lower addresses, see CMOVE>

dpANS 17.6.1.0910 - standard forth word

FORTH
CMOVE> ( from-ptr to-ptr len -- )(); 
 ;

memcpy an area from->to for len bytes, starting with the higher addresses, see CMOVE

FORTH
COMPARE ( str-ptr1 str-len1 str-ptr2 str-len2 -- n )(); 
 ;

compare both str-buffers, return 0 if they are equal, -1 if lower or shorter, and 1 if greater or longer

dpANS 17.6.1.0935 - standard forth word

FORTH
SEARCH ( str-ptr1 str-len1 str-ptr2 str-len2 -- str-ptr1' str-len1' flag )(); 
 ;

search the str-buffer1 for the text of str-buffer2, if it is contained return TRUE and return buffer-values that point to the contained string, otherwise return FALSE and leave the original str-buffer1.

dpANS 17.6.1.2191 - standard forth word

FORTH

SLITERAL ( -- string )();
p4:"sliteral";

 compile-time: ( CS: str-ptr str-len -- )

this word does almost the same as LITERAL - it takes an S" string as specified in the CS-STACK at compile time and compiles into the current definition where it is returned as if there were a direct string-literal. This can be used to compute a string-literal at compile-time and hardwire it.

 example:
   : ORIGINAL-HOME  [ $HOME COUNT ] SLITERAL ; ( -- str-ptr str-len )
 

dpANS 17.6.1.2212 - standard forth word

ENVIRONMENT

STRING-EXT ( .. )();
as:"string-minus-ext";

( 1994  )  constant STRING-EXT

an ordinary constant (no special usage info)

struct wordset

description

(C) 2000 - 2001 Guido Draheim

lisence: GNU LGPL, non-substantial parts may promote to any opensource.org approved license.

description: "struct" implements neon/mops/mpe-like structures. "structs" implements fsl/mforth-like structures.

the two wordsets are designed to let the sub-words to be used interchangably both inside STRUCT and STRUCTURE definitions. They will also work inside pfe's class-definitions btw.

The provided words try to be compatible with the simple implementation guidelines as provided in the survey at the comp.lang.forth.repository (http://forth.sourceforge.net/word/structure) and the documentation on MPE' forth's implementation (/vol/c/Programme/PfwVfx/Doc/VfxMan.Htm/struct.html) and the structs-source of the Forth Scientific Library (lib/fsl/structs.fth) plus some compatibility sugar for the gforth' struct (gforth/struct.fs)

field-layout PFA[0] has the offset (elsewhere for the method-table) PFA[1] has the sizeof (may serve as minimalistic type-id)

struct-layout PFA[0] unused (elswehere method-table or type-id) PFA[1] has the sizeof (that is instantiated)

therefore SIZEOF is designed to give a nice result in both places.

EXTENSIONS
STRUCT ( "name" -- here zero-offset )(); 
 ;

begin definition of a new structure (mpe.000)

 : STRUCT CREATE  !CSP
   HERE
   0 DUP ,
 DOES>
   @
 ;
 
EXTENSIONS
END-STRUCT ( here some-offset -- )(); 
 ;

terminate definition of a new structure (mpe.000)

 : END-STRUCT  SWAP !  ?CSP ;
 
EXTENSIONS
FIELD ( offset size "name" -- offset+size )(); 
 ;

create a field - the workhorse for both STRUCT and STRUCTURE implementations. The created fieldname is an OFFSET:-word that memorizes the current offset in its PFA and will add that offset on runtime. This forth-word does *not* align.

 : FIELD CREATE
   OVER ,
   +
 DOES>
    @ +
 ;
 
EXTENSIONS
SUBRECORD ( outer-offset "name" -- outer-offset here zero-offset )(); 
 ;

begin definition of a subrecord (mpe.000)

 : STRUCT CREATE  
   HERE
   0 DUP ,
 DOES>
   @
 ;
 
EXTENSIONS
END-SUBRECORD ( outer-offset here some-offset -- outer-offset+some )(); 
 ;

end definition of a subrecord (mpe.000)

 : END-SUBRECORD  TUCK SWAP !  + ;
 
EXTENSIONS
ARRAY-OF ( some-offset n len "name" -- some-offset )(); 
 ;

a FIELD-array

 : ARRAY-OF * FIELD ;
 
EXTENSIONS
VARIANT ( outer-offset "name" -- outer-offset here zero-offset )(); 
 ;

Variant records describe an alternative view of the current record or subrecord from the start to the current point. The variant need not be of the same length, but the larger is taken

 : VARIANT SUBRECORD ;
 
EXTENSIONS
END-VARIANT ( outer-offset here some-offset -- outer-offset )(); 
 ;

terminate definition of a new variant (mpe.000)

 : END-STRUCT  TUCK SWAP !  2DUP < IF NIP ELSE DROP THEN ;
 
EXTENSIONS

INSTANCE ( len "name" -- )();
p4:"instance";

Create a named instance of a named structure.

 : INSTANCE  CREATE ALLOT ;
 
EXTENSIONS
INSTANCE-ADDR ( len -- addr )(); 
 ;

Create nameless instance of a structure and return base address.

 : INSTANCE-ADDR  HERE SWAP ALLOT ;
 
EXTENSIONS
STRUCTURE ( "name" -- here zero-offset )exec(); 
 ;

start a structure definition

 : STRUCTURE: CREATE !CSP
   HERE
   0 DUP ,
 DOES>
   CREATE @ ALLOT
 ;
 
FCode_RT (p4_structure_RT)
EXTENSIONS
ENDSTRUCTURE ( here some-offset -- )(); 
 ;

finalize a previously started STRUCTURE definition

 : ENDSTRUCTURE  SWAP !  ?CSP ;
 
EXTENSIONS

SIZEOF ( "name" -- size )();
as:"sizeof";

get the size-value from a previous structure definition

 : SIZEOF   ' >BODY @  STATE @ IF [COMPILE] LITERAL THEN ; IMMEDIATE
 
FCode_XE (p4_sizeof_XT)
EXTENSIONS

CHAR% ( .. )();
as:"char-percent";

ordinary primitive CHAR%

an executable word (no special usage info)

or wrapper call around p4_char_mod

EXTENSIONS

CELL% ( .. )();
as:"cell-percent";

ordinary primitive CELL%

an executable word (no special usage info)

or wrapper call around p4_cell_mod

EXTENSIONS

WCHAR% ( .. )();
as:"wchar-percent";

ordinary primitive WCHAR%

an executable word (no special usage info)

or wrapper call around p4_wchar_mod

EXTENSIONS

DOUBLE% ( .. )();
as:"double-percent";

ordinary primitive DOUBLE%

an executable word (no special usage info)

or wrapper call around p4_double_mod

EXTENSIONS

FLOAT% ( .. )();
as:"float-percent";

ordinary primitive FLOAT%

an executable word (no special usage info)

or wrapper call around p4_float_mod

EXTENSIONS

SFLOAT% ( .. )();
as:"sfloat-percent";

ordinary primitive SFLOAT%

an executable word (no special usage info)

or wrapper call around p4_sfloat_mod

EXTENSIONS

DFLOAT% ( .. )();
as:"dfloat-percent";

ordinary primitive DFLOAT%

an executable word (no special usage info)

or wrapper call around p4_dfloat_mod

structs wordset

description

(C) 2000 - 2001 Guido Draheim

lisence: GNU LGPL, non-substantial parts may promote to any opensource.org approved license.

description: "struct" implements neon/mops/mpe-like structures. "structs" implements fsl/mforth-like structures.

the two wordsets are designed to let the sub-words to be used interchangably both inside STRUCT and STRUCTURE definitions. They will also work inside pfe's class-definitions btw.

The provided words try to be compatible with the simple implementation guidelines as provided in the survey at the comp.lang.forth.repository (http://forth.sourceforge.net/word/structure) and the documentation on MPE' forth's implementation (/vol/c/Programme/PfwVfx/Doc/VfxMan.Htm/struct.html) and the structs-source of the Forth Scientific Library (lib/fsl/structs.fth)

field-layout PFA[0] has the offset (elsewhere for the method-table) PFA[1] has the sizeof (may serve as minimalistic type-id)

struct-layout PFA[0] unused (elswehere method-table or type-id) PFA[1] has the sizeof (that is instantiated)

therefore SIZEOF is designed to give a nice result in both places.

EXTENSIONS

STRUCTURE: ( .. )();
as:"structure-colon";

ordinary primitive STRUCTURE:

an executable word (no special usage info)

or wrapper call around p4_structure

EXTENSIONS
;STRUCTURE ( .. )(); 
 ;

ordinary primitive ;STRUCTURE

an executable word (no special usage info)

or wrapper call around p4_endstructure

EXTENSIONS

CHAR: ( .. )();
as:"char-colon";

ordinary primitive CHAR:

an executable word (no special usage info)

or wrapper call around p4_char_colon

EXTENSIONS

WCHAR: ( .. )();
as:"wchar-colon";

ordinary primitive WCHAR:

an executable word (no special usage info)

or wrapper call around p4_wchar_colon

EXTENSIONS

CELL: ( .. )();
as:"cell-colon";

ordinary primitive CELL:

an executable word (no special usage info)

or wrapper call around p4_cell_colon

EXTENSIONS

DOUBLE: ( .. )();
as:"double-colon";

ordinary primitive DOUBLE:

an executable word (no special usage info)

or wrapper call around p4_two_cell_colon

EXTENSIONS

FLOAT: ( .. )();
as:"float-colon";

ordinary primitive FLOAT:

an executable word (no special usage info)

or wrapper call around p4_float_colon

EXTENSIONS

CHARS: ( .. )();
as:"chars-colon";

ordinary primitive CHARS:

an executable word (no special usage info)

or wrapper call around p4_chars_colon

EXTENSIONS

WCHARS: ( .. )();
as:"wchars-colon";

ordinary primitive WCHARS:

an executable word (no special usage info)

or wrapper call around p4_wchars_colon

EXTENSIONS

CELLS: ( .. )();
as:"cells-colon";

ordinary primitive CELLS:

an executable word (no special usage info)

or wrapper call around p4_cells_colon

EXTENSIONS

INTEGER: ( .. )();
as:"integer-colon";

ordinary primitive INTEGER:

an executable word (no special usage info)

or wrapper call around p4_cell_colon

EXTENSIONS

POINTER: ( .. )();
as:"pointer-colon";

ordinary primitive POINTER:

an executable word (no special usage info)

or wrapper call around p4_cell_colon

EXTENSIONS

STRUCT: ( .. )();
as:"struct-colon";

ordinary primitive STRUCT:

an executable word (no special usage info)

or wrapper call around p4_field

EXTENSIONS

ARRAY: ( .. )();
as:"array-colon";

ordinary primitive ARRAY:

an executable word (no special usage info)

or wrapper call around p4_array_of

system wordset

description

-- FORTH-83 SYSTEM EXTENSION WORD SET

Copyright (C) Tektronix, Inc. 1998 - 2001. All rights reserved.

description: forth-83 did define a system extension word set which was deleted in dpans94 due to some problems with the native-compiling variants of forth. pfe is traditional enough to use the words as they were originally intended.

FORTH
<MARK ( -- DP-mark )compile-only(); 
 ;

memorizes the current DP on the CS-STACK used for <RESOLVE later. Useful for creation of compiling words, eg. BEGIN , see AHEAD

 simulate:
   : <MARK ?COMP  HERE ;
 
FORTH
<RESOLVE ( DP-mark -- )compile-only(); 
 ;

resolves a previous <MARK , actually pushes the DP-address memorized at <MARK into the dictionary. Mostly used after BRANCH or ?BRANCH in compiling words like UNTIL

 simulate:
   : <RESOLVE ?COMP  , ;
 
FORTH
MARK> ( -- DP-mark )compile-only(); 
 ;

makes room for a pointer in the dictionary to be resolved through RESOLVE> and does therefore memorize that cell's address on the CS-STACK Mostly used after BRANCH or ?BRANCH in compiling words like IF or ELSE

 simulate:
   : MARK> ?COMP  HERE 0 , ;
 
FORTH
RESOLVE> ( DP-mark -- )compile-only(); 
 ;

resolves a pointer created by MARK> Mostly used in compiling words like THEN

 simulate:
   : RESOLVE> ?COMP  HERE SWAP ! ;
 
FORTH

BRANCH ( .. )();
as:"branch";

ordinary primitive BRANCH

an executable word (no special usage info)

or wrapper call around p4_else_execution

FORTH

?BRANCH ( .. )();
as:"question-branch";

ordinary primitive ?BRANCH

an executable word (no special usage info)

or wrapper call around p4_if_execution

FORTH

CONTEXT ( .. )();
as:"context";

- loader type P4_DVaL CONTEXT

context (no special usage info)

FORTH

CURRENT ( .. )();
as:"current";

threadstate variable CURRENT

current (no special usage info)

ENVIRONMENT

SYSTEM-EXT ( .. )();
as:"system-minus-ext";

( 1983  )  constant SYSTEM-EXT

an ordinary constant (no special usage info)

term wordset

description

-- terminal i/o, system independent parts

Copyright (C) Tektronix, Inc, 1998 - 2001. All rights reserved.

description: this wordset exports words to talk to the terminal driver of forth. Depending on the active terminal driver, not all of these words are fully functional.

EXTENSIONS
SHOW-TERMCAP ( -- )for debugging(); 
 ;

print the termcap strings used for input and output may give hints about what is wrong if the terminal seems to miss some functionality

EXTENSIONS
SHOW-TERM-CONTROLS ( -- )for debugging(); 
 ;

show the current mappings for the terminal output may give hints about what is wrong if the output seems to miss some functionality

EXTENSIONS
SHOW-TERM-ESC-KEYS ( -- )for debugging(); 
 ;

show the current mappings for the terminal input may give hints about what is wrong if the input seems to miss some functionality

EXTENSIONS

ASSUME_VT100 ( -- )();
p4:"assume-vt100";

load hardwired VT100-termcap into the terminal-driver

EXTENSIONS
ASSUME_DUMBTERM ( -- )(); 
 ;

load hardwired DUMBTERM-termcap into the terminal-driver

EXTENSIONS

ROWS ( .. )();
as:"rows";

threadstate variable ROWS

rows (no special usage info)

EXTENSIONS

COLS ( .. )();
as:"cols";

threadstate variable COLS

cols (no special usage info)

EXTENSIONS

XMAX ( .. )();
as:"xmax";

threadstate variable XMAX

xmax (no special usage info)

EXTENSIONS

YMAX ( .. )();
as:"ymax";

threadstate variable YMAX

ymax (no special usage info)

EXTENSIONS

GOTOXY ( x y -- )();
p4:"gotoxy";

move the cursor to the specified position on the screen - this is usually done by sending a corresponding esc-sequence to the terminal.

EXTENSIONS

?XY ( -- x y )();
p4:"question-xy";

returns the cursor position on screen, on a real unix system this includes a special call to the screen driver, in remote systems this can be the expected position as seen on the client side's terminal driver.

EXTENSIONS

CLS ( .. )();
as:"cls";

ordinary primitive CLS

an executable word (no special usage info)

or wrapper call around p4_dot_clrscr

EXTENSIONS

.CLRSCR ( .. )();
as:"dot-clrscr";

ordinary primitive .CLRSCR

an executable word (no special usage info)

or wrapper call around p4_dot_clrscr

EXTENSIONS

.CLREOL ( .. )();
as:"dot-clreol";

ordinary primitive .CLREOL

an executable word (no special usage info)

or wrapper call around p4_dot_clreol

EXTENSIONS

.HOME ( .. )();
as:"dot-home";

ordinary primitive .HOME

an executable word (no special usage info)

or wrapper call around p4_dot_home

EXTENSIONS

.HIGHLIGHT ( .. )();
as:"dot-highlight";

ordinary primitive .HIGHLIGHT

an executable word (no special usage info)

or wrapper call around p4_dot_highlight

EXTENSIONS
.HIGHLIGHT.OFF ( .. )(); 
 ;

ordinary primitive .HIGHLIGHT.OFF

an executable word (no special usage info)

or wrapper call around p4_dot_highlight_off

EXTENSIONS

.UNDERLINE ( .. )();
as:"dot-underline";

ordinary primitive .UNDERLINE

an executable word (no special usage info)

or wrapper call around p4_dot_underline

EXTENSIONS
.UNDERLINE.OFF ( .. )(); 
 ;

ordinary primitive .UNDERLINE.OFF

an executable word (no special usage info)

or wrapper call around p4_dot_underline_off

EXTENSIONS

.INTENSITY ( .. )();
as:"dot-intensity";

ordinary primitive .INTENSITY

an executable word (no special usage info)

or wrapper call around p4_dot_intensity

EXTENSIONS
.INTENSITY.OFF ( .. )(); 
 ;

ordinary primitive .INTENSITY.OFF

an executable word (no special usage info)

or wrapper call around p4_dot_intensity_off

EXTENSIONS

.BLINKING ( .. )();
as:"dot-blinking";

ordinary primitive .BLINKING

an executable word (no special usage info)

or wrapper call around p4_dot_blink

EXTENSIONS
.BLINKING.OFF ( .. )(); 
 ;

ordinary primitive .BLINKING.OFF

an executable word (no special usage info)

or wrapper call around p4_dot_blink_off

EXTENSIONS

.REVERSE ( .. )();
as:"dot-reverse";

ordinary primitive .REVERSE

an executable word (no special usage info)

or wrapper call around p4_dot_reverse

EXTENSIONS
.REVERSE.OFF ( .. )(); 
 ;

ordinary primitive .REVERSE.OFF

an executable word (no special usage info)

or wrapper call around p4_dot_reverse_off

EXTENSIONS

.NORMAL ( .. )();
as:"dot-normal";

ordinary primitive .NORMAL

an executable word (no special usage info)

or wrapper call around p4_dot_normal

EXTENSIONS

.BELL ( .. )();
as:"dot-bell";

ordinary primitive .BELL

an executable word (no special usage info)

or wrapper call around p4_dot_bell

EXTENSIONS

K-LEFT ( .. )();
as:"k-minus-left";

( P4_KEY_kl )  constant K-LEFT

an ordinary constant (no special usage info)

EXTENSIONS

K-RIGHT ( .. )();
as:"k-minus-right";

( P4_KEY_kr )  constant K-RIGHT

an ordinary constant (no special usage info)

EXTENSIONS

K-UP ( .. )();
as:"k-minus-up";

( P4_KEY_ku )  constant K-UP

an ordinary constant (no special usage info)

EXTENSIONS

K-DOWN ( .. )();
as:"k-minus-down";

( P4_KEY_kd )  constant K-DOWN

an ordinary constant (no special usage info)

EXTENSIONS

K-HOME ( .. )();
as:"k-minus-home";

( P4_KEY_kh )  constant K-HOME

an ordinary constant (no special usage info)

EXTENSIONS

K-END ( .. )();
as:"k-minus-end";

( P4_KEY_kH )  constant K-END

an ordinary constant (no special usage info)

EXTENSIONS

K-PRIOR ( .. )();
as:"k-minus-prior";

( P4_KEY_kP )  constant K-PRIOR

an ordinary constant (no special usage info)

EXTENSIONS

K-NEXT ( .. )();
as:"k-minus-next";

( P4_KEY_kN )  constant K-NEXT

an ordinary constant (no special usage info)

EXTENSIONS

K1 ( .. )();
as:"k-one";

( P4_KEY_k1 )  constant K1

an ordinary constant (no special usage info)

EXTENSIONS

K2 ( .. )();
as:"k-two";

( P4_KEY_k2 )  constant K2

an ordinary constant (no special usage info)

EXTENSIONS

K3 ( .. )();
as:"k-three";

( P4_KEY_k3 )  constant K3

an ordinary constant (no special usage info)

EXTENSIONS

K4 ( .. )();
as:"k-four";

( P4_KEY_k4 )  constant K4

an ordinary constant (no special usage info)

EXTENSIONS

K5 ( .. )();
as:"k-five";

( P4_KEY_k5 )  constant K5

an ordinary constant (no special usage info)

EXTENSIONS

K6 ( .. )();
as:"k-six";

( P4_KEY_k6 )  constant K6

an ordinary constant (no special usage info)

EXTENSIONS

K7 ( .. )();
as:"k-seven";

( P4_KEY_k7 )  constant K7

an ordinary constant (no special usage info)

EXTENSIONS

K8 ( .. )();
as:"k-eight";

( P4_KEY_k8 )  constant K8

an ordinary constant (no special usage info)

EXTENSIONS

K9 ( .. )();
as:"k-nine";

( P4_KEY_k9 )  constant K9

an ordinary constant (no special usage info)

EXTENSIONS

K10 ( .. )();
as:"k-ten";

( P4_KEY_k0 )  constant K10

an ordinary constant (no special usage info)

EXTENSIONS

S-K1 ( .. )();
as:"s-minus-k-one";

( P4_KEY_F1 )  constant S-K1

an ordinary constant (no special usage info)

EXTENSIONS

S-K2 ( .. )();
as:"s-minus-k-two";

( P4_KEY_F2 )  constant S-K2

an ordinary constant (no special usage info)

EXTENSIONS

S-K3 ( .. )();
as:"s-minus-k-three";

( P4_KEY_F3 )  constant S-K3

an ordinary constant (no special usage info)

EXTENSIONS

S-K4 ( .. )();
as:"s-minus-k-four";

( P4_KEY_F4 )  constant S-K4

an ordinary constant (no special usage info)

EXTENSIONS

S-K5 ( .. )();
as:"s-minus-k-five";

( P4_KEY_F5 )  constant S-K5

an ordinary constant (no special usage info)

EXTENSIONS

S-K6 ( .. )();
as:"s-minus-k-six";

( P4_KEY_F6 )  constant S-K6

an ordinary constant (no special usage info)

EXTENSIONS

S-K7 ( .. )();
as:"s-minus-k-seven";

( P4_KEY_F7 )  constant S-K7

an ordinary constant (no special usage info)

EXTENSIONS

S-K8 ( .. )();
as:"s-minus-k-eight";

( P4_KEY_F8 )  constant S-K8

an ordinary constant (no special usage info)

EXTENSIONS

S-K9 ( .. )();
as:"s-minus-k-nine";

( P4_KEY_F9 )  constant S-K9

an ordinary constant (no special usage info)

EXTENSIONS

S-K10 ( .. )();
as:"s-minus-k-ten";

( P4_KEY_FA )  constant S-K10

an ordinary constant (no special usage info)

toolbelt wordset

description

LGPL (C) 2000 - 2001 Guido Draheim <guidod@gmx.de>

description:: Words as defined by Neil Bawd's toolbelt, quite a few of these have been around for a while, invented and implemented independently. Some of these were also present as PFE's extensions words, and they are referenced here due to the fact that Neil Bawd's website had been given quite some attention, hence these words should be assembled in a wordset to clarify their behaviour is compatible. Comments taken from toolbelt.txt

FORTH

[VOID] ( .. )();
as:"bracket-void";

( 0 )  constant [VOID]

an immediate constant (no special usage info)

FORTH
[DEFINED] ( [name] -- flag )(); 
 ;

Search the dictionary for _name_. If _name_ is found, return TRUE; otherwise return FALSE. Immediate for use in definitions.

  

This word will actually return what FIND returns (the NFA). does check for the word using find (so it does not throw like ' ) and puts it on stack. As it is immediate it does work in compile-mode too, so it places its argument in the cs-stack then. This is most useful with a directly following [IF] clause, so that sth. like an [IFDEF] word can be simulated through [DEFINED] word [IF]

 : [DEFINED] DEFINED ; IMMEDIATE
 : [DEFINED] BL WORD COUNT (FIND-NFA) ; IMMEDIATE
 
FORTH
[UNDEFINED] ( [name] -- flag )(); 
 ;

Search the dictionary for _name_. If _name_ is found, return FALSE; otherwise return TRUE. Immediate for use in definitions.

see [DEFINED]

 : [UNDEFINED] DEFINED 0= ; IMMEDIATE
 
FORTH

NOT ( .. )();
as:"not";

ordinary primitive NOT

an executable word (no special usage info)

or wrapper call around p4_zero_equal

FORTH

C+! ( n addr -- )();
p4:"c-plus-store";

Add the low-order byte of _n_ to the byte at _addr_, removing both from the stack.

FORTH

EMPTY ( -- )();
p4:"empty";

Reset the dictionary to a predefined golden state, discarding all definitions and releasing all allocated data space beyond that state.

FORTH

VOCABULARY ( 'name' -- )();
p4:"vocabulary";

create a vocabulary of that name. If the named vocabulary is called later, it will run ((VOCABULARY)) , thereby putting it into the current search order. Special pfe-extensions are accessible via CASE-SENSITIVE-VOC and SEARCH-ALSO-VOC

 simulate:
   : VOCABULARY  CREATE ALLOT-WORDLIST
        DOES> ( the ((VOCABULARY)) runtime )
          CONTEXT ! 
   ; IMMEDIATE
 
FORTH
BOUNDS ( str len -- str+len str )(); 
 ;

Convert _str len_ to range for DO-loop.

 : BOUNDS  ( str len -- str+len str )  OVER + SWAP ;
 
FORTH

OFF ( addr -- )();
p4:"off-store";

Store 0 at _addr_. Defined in f84 as OFF. See antonym ON!.

  : OFF  ( addr -- )  0 SWAP ! ;
 
FORTH

ON ( .. )();
as:"on";

ordinary primitive ON

an executable word (no special usage info)

or wrapper call around p4_on_store

FORTH

APPEND ( str len add2 -- )();
p4:"append";

Append string _str len_ to the counted string at _addr_. a.k.a. +PLACE of the PLACE family

 : APPEND   2DUP 2>R  COUNT +  SWAP MOVE ( ) 2R> C+! ;
 

Append string _str len_ to the counted string at _addr_. a.k.a. APPEND (being a SYNONYM now)

 : +PLACE   2DUP 2>R  COUNT +  SWAP MOVE ( ) 2R> C+! ;
 
FORTH
APPEND-CHAR ( char addr -- )(); 
 ;

Append _char_ to the counted string at _addr_. a.k.a. C+PLACE of the PLACE family

 : APPEND-CHAR   DUP >R  COUNT  DUP 1+ R> C!  +  C! ;
 

Append _char_ to the counted string at _addr_. a.k.a. APPEND-CHAR (being a SYNONYM now)

 : C+PLACE   DUP >R  COUNT  DUP 1+ R> C!  +  C! ;
 
FORTH

PLACE ( str len addr -- )();
p4:"place";

Place the string _str len_ at _addr_, formatting it as a counted string.

 : PLACE  2DUP 2>R  1+ SWAP  MOVE  2R> C! ;
 : PLACE  2DUP C!   1+ SWAP CMOVE ;
 
FORTH

STRING, ( str len -- )();
p4:"string-comma";

Store a string in data space as a counted string.

 : STRING, HERE  OVER 1+  ALLOT  PLACE ;
 
FORTH

," ( .. )();
as:"comma-quote";

immediate primitive ,"

an executable word (no special usage info)

or wrapper call around p4_parse_comma_quote

FORTH

THIRD ( x y z -- x y z x )();
p4:"third";

Copy third element on the stack onto top of stack.

 : THIRD   2 PICK ;
 
FORTH
FOURTH ( w x y z -- w x y z w )(); 
 ;

Copy fourth element on the stack onto top of stack.

 : FOURTH  3 PICK ;
 
FORTH
3DUP ( x y z -- x y z x y z )(); 
 ;

Copy top three elements on the stack onto top of stack.

 : 3DUP   THIRD THIRD THIRD ;

or

 : 3DUP  3 PICK 3 PICK 3 PICK ;
 
FORTH

3DROP ( x y z -- )();
p4:"three-drop";

Drop the top three elements from the stack.

 : 3DROP   DROP 2DROP ;
 
FORTH

2NIP ( w x y z -- y z )();
p4:"two-nip";

Drop the third and fourth elements from the stack.

 : 2NIP   2SWAP 2DROP ;
 
FORTH
R'@ ( R: a b -- a R: a b )(); 
 ;

fetch the next-under value from the returnstack. used to interpret the returnstack to hold two LOCALS| values. ( R@ / 2R@ / R>DROP / R"@)

FORTH

ANDIF ( p ... -- flag )();
p4:"andif";

Given `p ANDIF q THEN`, _q_ will not be performed if _p_ is false.

 : ANDIF  S" DUP IF DROP " EVALUATE ; IMMEDIATE
 
FORTH

ORIF ( p ... -- flag )();
p4:"orif";

Given `p ORIF q THEN`, _q_ will not be performed if _p_ is true.

 : ORIF   S" DUP 0= IF DROP " EVALUATE ; IMMEDIATE
 
FORTH
SCAN ( str len char -- str+i len-i )(); 
 ;

Look for a particular character in the specified string.

 : SCAN     
    >R  BEGIN  DUP WHILE  OVER C@ R@ -
        WHILE  1 /STRING  REPEAT THEN
    R> DROP ;

ie. scan for first occurence of c in string

   : SCAN >R BEGIN DUP OVER C@ R@ = 0= OR WHILE 
                    1- SWAP 1- SWAP REPEAT R> DROP ;
 
FORTH
SKIP ( str len char -- str+i len-i )(); 
 ;

Advance past leading characters in the specified string.

 : SKIP     
   >R  BEGIN  DUP WHILE  OVER C@ R@ =
        WHILE  1 /STRING  REPEAT THEN
    R> DROP ;

ie. skip leading characters c

   : SKIP  >R BEGIN DUP OVER C@ R@ = OR WHILE 
                    1- SWAP 1- SWAP REPEAT R> DROP ;
 
FORTH
BACK ( str len char -- str len-i )(); 
 ;

Look for a particular character in the string from the back toward the front.

 : BACK     
    >R  BEGIN  DUP WHILE
        1-  2DUP + C@  R@ =
    UNTIL 1+ THEN
    R> DROP ;
 
FORTH
/SPLIT ( a m a+i m-i -- a+i m-i a i )(); 
 ;

Split a character string _a m_ at place given by _a+i m-i_. Called "cut-split" because "slash-split" is a tongue twister.

 : /SPLIT  DUP >R  2SWAP  R> - ;
 
FORTH

IS-WHITE ( char -- flag )();
p4:"is-white";

Test char for white space.

 : IS-WHITE   33 - 0< ;
 
FORTH

TRIM ( str len -- str len-i )();
p4:"trim";

Trim white space from end of string.

 : TRIM    
    BEGIN  DUP WHILE
        1-  2DUP + C@ IS-WHITE NOT
    UNTIL 1+ THEN ;
 
FORTH
BL-SCAN ( str len -- str+i len-i )(); 
 ;

Look for white space from start of string

 : BL-SCAN 
    BEGIN  DUP WHILE  OVER C@ IS-WHITE NOT
    WHILE  1 /STRING  REPEAT THEN ;
 
FORTH
BL-SKIP ( str len -- str+i len-i )(); 
 ;

Skip over white space at start of string.

 : BL-SKIP 
    BEGIN  DUP WHILE  OVER C@ IS-WHITE
    WHILE  1 /STRING  REPEAT THEN ;

 
FORTH
STARTS? ( str len pattern len2 -- str len flag )(); 
 ;

Check start of string.

 : STARTS?   DUP >R  2OVER  R> MIN  COMPARE 0= ;
 
FORTH
ENDS? ( str len pattern len2 -- str len flag )(); 
 ;

Check end of string.

 : ENDS?   DUP >R  2OVER  DUP R> - /STRING  COMPARE 0= ;
 
FORTH

IS-DIGIT ( char -- flag )();
p4:"is-digit";

Test _char_ for digit [0-9].

 : IS-DIGIT   [CHAR] 0 -  10 U< ;
 
FORTH

IS-ALPHA ( char -- flag )();
p4:"is-alpha";

Test _char_ for alphabetic [A-Za-z].

 : IS-ALPHA  32 OR  [CHAR] a -  26 U< ;
 
FORTH

IS-ALNUM ( char -- flag )();
p4:"is-alnum";

Test _char_ for alphanumeric [A-Za-z0-9].

 : IS-ALNUM  
    DUP IS-ALPHA  ORIF  DUP IS-DIGIT  THEN  NIP ;
 
FORTH
#BACKSPACE-CHAR ( .. )(); 
 ;
( '\b' )  constant #BACKSPACE-CHAR

an ordinary constant (no special usage info)

FORTH
#CHARS/LINE ( .. )(); 
 ;
( 80 )  constant #CHARS/LINE

an ordinary constant (no special usage info)

FORTH
#EOL-CHAR</