Trace: » forth05.html

[hemmerling] FORTH 5/7

Implementation of your own FORTH System & Applications

FORTH - The Good, the Bad and the Ugly

The Good - Valuable OpenSource FORTHs

⇒ See FORTH 3/4.

The Bad - Commercial FORTH Systems

  1. No source code. Means you can´t learn about the implementation of FORTH words & libraries... for better understanding. The application developers are lost!
  2. Compatibility problems, and nobody takes care of it. The application developers are lost!

The Ugly - Toy FORTH

  1. Not beeing developed by
    1. Senior developers with professional skills in compiler design, embedded systems,.. with 5+y experience ( e.g. college / university professors, engineers with much professional industrial experience,... ).
    2. Senior “assembly language artists” :-) with 5+y of experience.
  2. Without free and immediate / fast / quick support on professional level.
  3. Without comprehensive paper / PDF / HTML,... documentation.
  4. Without comprensive comments in the source code.
  5. Without much sample code & sample projects.
  6. Which might be “not in active development anymore”.
  7. Where the developer gets angry if his / her FORTH is considered to be a “Toy FORTH” :-(.
  8. Do most of the 1000 FORTHs have “more than one user” ? Or is it typical, that either
    1. The FORTH has no killer-application at all ( the only developer develops for all the years just FORTH, not a software solution for a real given application / problem ),
    2. Or the only developer has ONE software / hardware application for which he/she is using the self-developed FORTH with his self-developed software application code on top of the bare FORTH implementation?

Valuable FORTH vs. Toy FORTH

  • User experience and feedback: “If you have a good FORTH it is great fun to talk to the computer. Otherwise it is also torture :-(”.
  • User opinions:
    • “You can't write your own FORTH as rookie in compiler design & assembly language coding. That's all stupid what these 'Toy FORTH' developers tell you, that they can do it. Of course you can write a FORTH of 35 words yourself, but what's the benefit?”.
    • “Maybe there are '10000 FORTHs' on GitHub, but as you can see I can't name more than 10 that are really useful. So for me there are 9990 Toy FORTHs ... :-)”.
      • User #1 opinion: “99 % of all Forths I know are simple Toys , this means unfinished proyects. They implement the basic VMachine and then basta. They do not offer a simple Editor embedded in their Forths (as it was in the past a no question theme) they do not offer an Assembler or Disassembler :-(. Old style Forths as the ones I used to learn from in the past, had all those tools and much more. They offered Multitasking right from the start, vocabularies, block-file or os-file interfaces, direct video access, etc etc etc...:-)”.
      • User #2 opinion: “Forth has @ and !. You've missed the OP's point; it's the underlying architecture (for instance, Java and the JVM) that lacks direct memory access through pointers. That makes it hard implementing Forth on these types of systems”.
      • User #3 opinion: “Java has ByteBuffers, which can either be based on a Java byte array or on a directly-mapped file. That's everything a Forth needs”... “But I thought the JVM was sandboxed?”, “It is. ByteBuffers can only reach into the memory allocated for that buffer, but that's all that a Forth implementation needs. You could put the entire dictionary into a ByteBuffer. That'd be nice from the point of view of saving a precompiled image”.

Write your own FORTH Compiler

Slogan "Roll your own programming language - Roll your own Forth"

  • Inspired by the articles in Dr. Dobb's Journal of Software Tools “Roll your own DOS extender” ( Volume 15, Number 10, October 1990 + Number 11, November, 1990 ) and “Roll your own object-oriented language” ( Volume 15, Number 11, November, 1990, and online articles like InfoWorld "Learn Linux by rolling your own distro", 2017, I imagined the slogan “Roll your own programming language - Roll your own Forth” :-).

Implementation Types

Threaded Code
Tethered FORTH
  • Interactivity it just done on the host. The tethered Forth is just the compiled code.
  • High-level languages ( C, Lua,.. ) might be involved, for rapid development.
Native FORTH with Threaded Code
  • 100% pure assembly language. No high-level language involved ( C, Lua,.. ). This is how FORTH started, in the mid-1970th, with the first implementations for 8-bit microprocessor boards.
Native tethered FORTH
SRT / NCI FORTH ( Subroutine threaded / native Code inlining FORTH )
  • SRT/NCI means “subroutine threaded / native code inlining”.
    • “Subroutine threaded” specifically means that the code overall consists of subroutine calls to other words written as native code.
    • “Native code inlining” means that smaller words that are called that are able to be inlined are incorporated into the body of code which calls it as native code, eliminating the need for subroutine calls in those cases.
  • Example: zeptoforth.
FORTH which may create Application Executables
  • Examples: “Win32Forth”, “calForth”.
Resources
  • BYTE Magazine.
    • C5J Harris* K.* “FORTH Extensibility: Or How to Write a Compiler in 25 Words or Less*” Byte (Ausfust* 1980). pp. 164-184.
  • Narkive Archive "comp.lang.forth", Thread "TTC v DTC" - “token-threaded code versus direct-threaded code”.
  • Suggested reading: “Moving Forth: a series on writing Forth kernels” #.
  • An expert told me:
    • “Basic forth is all real mode. Mixed code and data”.
    • “That's not the only way to do it though. I've started doing Forth in web assembly which is part of the JavaScript engine of all browsers. This is a protected memory model which means you can't execute data directly. In those cases your pointers are really just offsets into a table of primitive functions. Forth runs completely fine in this model”.
    1. “ALForth” ⇒ See Forth 4/6.
    2. “f2u” ⇒ See Forth 4/6.
    3. “My Vectrex has a 6809 and 1KiB of RAM. Vectrex Forth (aka CamelForth 6809 with extensions) uses 1/2 of the RAM for buffers, TIB, etc. and after the BIOS reserved RAM is avoided, there are 256 bytes dictionary space available. Given Vectrex Forth is cross compiled and the whole compile+send process takes 1-2 seconds, 256 bytes is plenty for ongoing development”.
    4. With very small systems, one is better off using a tethered Forth such as Mecrisp-Across (for programming the MSP430 with one of the TI Tiva boards, I don't remember which) rather than a hosted Forth, which will inevitably take up some space. Tethered Forths can operate in very small spaces yet provide interactivity, and thus provide the best of both worlds”.

Implementation Suggestions "How to start"

  • A FORTH expert told me his impression of the proceedings of hobbyist FORTH implementators from the maker-scene of the last 40 years: “Most developers implement FORTH-79 and then pick and choose what they want from later versions”.

Implementation Ideas

  • Several FORTHs on a single computer may share data by a common ( extra? ) stack. Either the FORTHs may run concurrently, or just one FORTH is active and by a semaphore, a “baton” is passed to the next-active FORTH. By this, some code of an application might be written in different FORTH dialects ( proprietary, fig-FORTH, FORTH-79, FORTH-83, fig-FORTH, ANS94-FORTH,..).

The Input, Input Processing & Compile Process ( Experts told me so )

  • Delimiter - not just “SPACE”.
    • “Generally all white space is treated as a delimiter. You can write words that parse from the input stream so this can be changed. The parser is usually about skipping all whitespace before the word starts. It will then read in every non whitespace character. The parser usually also recognises \ as the start of a comment and skips to the end of the the line and starts reading from there”.
    • Comments as delimiters: “Not with the way they decided to add line comments but I don't think this was the original comment system of Forth but added in the 80s. The original comment was the ( word which is an immediate words (a macro) which reads the input stream until it encounters a ) character. These kinds of comments these days are restricted to stack effects diagrams but there is nothing special about them, they are just comments”.
  • Input parsing:
    • The parser processes a whole line of input, not character-by-character as the characters are sent: “The parser can work on the line after the return has been entered. There are some subtle alternative approaches but this way is the simplest”.
    • “The input stream will go into a buffer and you read each word and execute the word. If you encounter a special word : it will go into compile mode and the rules change, macros (immediate words) like ; will be executed immediately, other words will be compiled into the heap (compiled into a definition)”.
    • “Forth usually processes input a line at a time and ways until the line is entered before processing it. This gives the user a chance to edit the line before executing it. Forth processes the text stored in the input buffer which is usually TIB but it can be changed. Each word is parsed, looked up, if it is marked immediate in its header it is executed immediately, otherwise it depends on the compilation state variable. If it is in compilation state then the xt of the looked up word is compiled into the currently definition. If it is in interpret state then it is executed”.
    • “You can be more immediate if you want to implement your own line editor. This is usually a bit crude unless it handles arrow keys and insertion and deletion. However it could end up more powerful than relying on the OS readline functionality”.
  • Word processing.
    • “The words are processed as a stream”.
  • Stack.
    • “The stack is only used for interpreting and also for calculating loops and branches”.
  • Heap Allocator.
    • The heap pointer (bump allocator) is where you can allot new data objects. It can also allocate new words”.
    • “I think you can learn the majority of this flow from this article which I think it's really good. It's about implementing a Forth using Python” ⇒ OpenBookProject, Chris Meyers and Fred Obermann "Python for Fun", Chapter "FORTH - A simple stack oriented language".
    • Execution of FORTH words immediately, before end of line is reached:
      • “Peter Jackaki does exactly this with his Forth. I am very interested in his approach which has many advantages over traditional Forth”.
      • “The main disadvantage of traditional Forth is that it has two modes: interpret mode and compile mode. This creates complications like no loops or branches on the command line. Peter Jackaki's TAQOZ forth ( = Tachyon Forth ) compiles everything as it comes in. He watches the return and executes the compiled code. This changes a few things about Forth but I think it makes things simpler”.
  • Word list:
    • “The normal scheme is to store the name of the word in a Pascal style string. With a length byte followed by characters. But you never need more than 31 characters in a manner so the upper bits of the length byte are used for flags. But there's not reason not to allow names of any length, it was a practical limitation based on implementation. So you'll never see a common Forth word longer than 31 characters in any spec. The only real reason was that Pascal strings (ie “counted” strings) are faster to compare than null terminated strings. But remember you need to mask the bottom five bits the get the length. The upper bits are used to mark HIDDEN, IMMEDIATE and whatever other flag (compile only?).
    • HIDDEN words: “A word that is currently being defined is marked hidden so it doesn't appear in searches. This means that normally a word cannot call itself. This also means that if a word is redefined it can can refer to the older version of the word in its body. When the defining is compete at ; the word is marked as visible. Recursion is not common in classic Forth (but is in colorForth). To make self referential code you use the RECURSE word. It works by making the currently being defined word not hidden. But you have the ability to define new words. They happen in RAM. ROM based words that are in the dictionary are always not hidden”.
    • “The dictionary needs to span ROM and RAM so a linked list seems the right way to go. Or an array needs to exist in RAM and be initialised with items in ROM but also able to take new items defined in RAM”.
    • Facebook "FORTH PROGRAMMING LANGUAGE 21st CENTURY", Thread "WORDS" - Discussion about how to create own WORDS word, about “SEE WORDS”,...

Java VM Bytecode => Forth VM Bytecode Mapping by Chen-hanson Ting

The minimal FORTH System "Minimal Forth Machine" by Mikael Patel

Primitives
Primitive Stack effects Description
>r ( x – )
r> ( – x )
1+ ( x – y )
0= ( x – flag )
nand ( x y – z )
@ ( addr – x )
dup! ( x addr – x )
execute ( addr – )
exit ( – )
May be included because of hardware considerations
drop ( x – )
dup ( x – x x )
swap ( x y – y x )
Resources

The minimal FORTH System "sectorforth"

Primitives
Primitive Stack effects Description
@ ( addr – x ) Fetch memory contents at addr
! ( x addr – ) Store x at addr
sp@ ( – sp ) Get pointer to top of data stack
rp@ ( – rp ) Get pointer to top of return stack
0= ( x – flag ) -1 if top of stack is 0, 0 otherwise
+ ( x y – z ) Sum the two numbers at the top of the stack
nand ( x y – z ) NAND the two numbers at the top of the stack
exit ( r:addr – ) Pop return stack and resume execution at addr
key ( – x ) Read key stroke as ASCII character
emit ( x – ) Print low byte of x as an ASCII character
Variables
Variable Description
state 0: execute words; 1: compile word addresses to the dictionary
tib Terminal input buffer, where input is parsed from
>in Current parsing offset into terminal input buffer
here Pointer to next free position in the dictionary
latest Pointer to most recent dictionary entry
Compiler
  • : and ; provided.
  • NO immediate, [, or ].
What can I do?
  • “hello, world” of course :-).
  • BEGIN, WHILE, REPEAT, UNTIL, DO, LOOP.
  • Variables.
  • Stack debugging (.s, etc. )

The minimal FORTH System of GreenArrays' GA144

#(oct) Primitive FORTH Word #1 FORTH Word #2 Stack effects Description
Jump Instructions
00 Ret ”;” ”;” Jump thru R (destructive)
01 Exec “ex” ” ;:” Jump thru R, save P in R
02 Jmp “jump” “jump” Jump thru I ( The opcode is not used explicitly. The compiler generates it )
03 Call “call” “call” Jump thru I, push current address to R ( The opcode is not used explicitly. Referencing any defined word generates a call )
04 Unext “unext” “unext” Jump to slot 0 ( Discards the address left by for )
05 Next “next” “next” If R is non-zero, jump thru I and decrement R. Otherwise pop R
06 If “if” “if” Jump thru I if T is zero
07 MinusIf ”-if” ”-if” Jump thru I if T is positive
Memory Instructions
10 FetchP ”@p” ”@p+” Fetch thru P, increment P
11 FetchPlus ”@+” ”@+” Fetch thru A, increment A
12 FetchB ”@b” ”@b” Fetch thru B
13 Fetch ”@” ”@” Fetch thru A
14 StoreP ”!p” ”!p+” Store thru P, increment P
15 StorePlus ”!+” ”!+” Store thru A, increment A
16 StoreB ”!b” ”!b” Store thru B
17 Store ”!” ”!” Store thru A
ALU Instructions
20 MultiplyStep ”+*” ”+*” Multiply step: add S to T if A0=1 then shift T and A right
21 Times2 “2*” “2*” Shift T left
22 Div2 “2/” “2/” Shift T right; sign fill
23 Not ”-” ”-” One's complement T
24 Plus ”+” ”+” Add S to T (discard S)
24 Add S to T with carry ( Requires bit 9 of P be set )
25 And “and” “and” Bit-wise and of S and T
26 Or “or” “or” Bit-wise exclusive-or of S and T
27 Drop “drop” “drop” Discard T
Stack Instructions
30 Dup “dup” “dup” Create a working copy of T
31 Pop “pop” “pop” Fetch R (destructive)
32 Over “over” “over” Fetch S (non-destructive)
33 ReadA “a” “a” Fetch A (non-destructive)
34 Nop ”.” ”.” Do nothing
35 Push “push” “push” Push T into R
36 SetB “b!” “b!” Store into B ( Be careful to distinguish b! and !b )
37 SetA “a!” “a!” Store into A

The minimal FORTH System Proposal & Comparison by Peter Knaggs and Paul E. Bennet

The minimal FORTH System Comparison by Paul E. Bennet
Type Ting Brinkhoff Plichota GA-F18 Stack effect Comments
Memory Access C@ C@
C@ C@
@ @ @ @
a
@a
@p
@b
@+
!p
!+
!b
a!
b!
! ! ! !
Math + + + +
- -
+*
2*
* *
/
2/
MOD
Logic AND NAND NAND and
OR or
XOR XOR
INVERT
Stack DUP DUP dup
SWAP SWAP
OVER over
DROP DROP drop
>R >R push
R> R> pop
R@
Control IF 0BRANCH IF if
-if
ELSE
THEN
BEGIN
WHILE
REPEAT
AGAIN
DO
LOOP
EXECUTE ex
<name>;
<name>
unext
next
EXIT EXIT
Defining : :
; ; ;
CONSTANT
VARIABLE
I/O & Comms IN IN i/o
OUT OUT
Other DODOES LIT
data
- - -u
- -l-
–lu
-d- -
-d-u
-dl-
-dlu
r- - -
r-l-
r-lu
rd- -
rdl-
rdlu
The minimal FORTH System Proposal by Peter Knaggs and Paul E. Bennet
Type Word Name Stack effect Comments
1 Memory Access ! store
, comma
@ fetch
ALIGN
ALIGNED
CELL+ cell-plus
CELLS
C! c-store
C, c-comma
C@ c-fetch
CALIGN c-allign
CALIGNED c-alligned
CHAR+ char-plus
CHARS chars
2 Arithmetic + plus
* star
2* two-star
*/MOD star-slash-mod
- minus
/ slash
2/ two-slash
MOD
3 Logic 0= zero-equals
< less-than
AND
INVERT
TRUE
LSHIFT l-shift
= equals
> greater-than
OR
XOR x-or
FALSE
RSHIFT r-shift
4 Stack DUP dupe
SWAP
>R to-r
R@ r-fetch
DROP
OVER
R> r-from
ROT rote
5 Flow Control IF
THEN
WHILE
REPEAT
DO
I
tick
ELSE
BEGIN
AGAIN
UNTIL
LOOP
J
EXECUTE
6 Definitions : colon
CONSTANT
CREATE
; semicolon
VARIABLE
DOES> does
7 Device KEY
EMIT
KEY? key-question
CR c-r
8 Tools ( paren
.S dot-s
\ backslash
Resources
      • “Peter Knaggs and Paul E. Bennet: Minimal Forth ( PDF ).
        • “A Proposed minimal word set”.
        • “Comparison of minimal word sets of Ting, Brinkhoff, Plichota, GA-F18”.
  • GitHub "uho / minimal" - “Minimal Forth Workbench” by Ulrich Hoffmann.
    • “Their aim is to define a Standard Forth subset suitable for educational purposes. For this they propose to cut down the number of Forth words initially explained to Forth newcomers and only stepwise introduce new concepts such as number output, compiling words, strings, file access, exceptions, ...”.
    • “This package - the Minimal Forth Workbench - allows to experiment with different sets of primitive (i.e. predefined) definitions in order to further elaborate on Paul's and Peter's ideas”.

General Compiler Building Resources

FORTH System Building Resources

Build Tools for FORTH Virtual Machines ( FVMs )
FORTH in LUA
Some other minimal FORTH
Resources

Excursus: C Data Types

    • “The minimum size for char is 8 bits, the minimum size for short and int is 16 bits, for long it is 32 bits and long long must contain at least 64 bits”.
    • “long long - Specified since the C99 version of the standard”.
  • WATCOM-C datatypes:
    • INTEGER*4 ⇒ 32 bit.
    • COMPLEX*16 ⇒ REAL 64 bit, IMAGINARY 64 bit ⇒ 64 bit.

Excursus: Use of SQL Databases to store FORTH Words

Write your own FORTH Code - FORTH Code Style

Traditional FORTH

"!", "C!" ( of fig-FORTH ) versus "=" and "\=" ( of pre fig-FORTH )

  • ATARIWiki.org "CoinOp FORTH" - “Coinop forth was developed in Atari coinop division ..., based on DECUS forth for the PDP-11.. Later, as Forth became popular and fig forth came out, we did a port of it to the 800 as well. A major visible difference is that fig forth uses the new operators for stores ( ! and C! ) rather than the original ( = and \= ) which DECUS, coinop, Colleen forth does”

Readability

Stack-Orientation

  • Traditional FORTH = Stack-oriented, like with RPN language of HP pocket calculators.

Style Conventions

  • Still the reference #1: Leon Brodie's “Thinking Forth”, appendix E, “Summary of Style Conventions”.
  • Additionally , experts told me about FORTH style conventions:
    • Words in parenthesis, i.e. (NAME) ⇒ Please don´t use these words in your application code!

Modern FORTH

1Kbyte Screens / Blocks

  • See FORTH 2/4 ⇒ “The FORTH 64×16 Screen Paradigma”.

Array Words

  • For 50 years, array words were not delivered with standard traditional FORTH implementations :-(.

Batch Processing

  • Batch processing example, output is “1 3 5 2 4 6”:
    vocabulary voc1
    vocabulary voc2
    voc1
    definitions
    : txt1 ." 1 " ;
    : txt2 ." 2 " ;
    voc2
    definitions
    : txt1 ." 3 " ;
    : txt2 ." 4 " ;
    forth
    definitions
    : txt1 ." 5 " ;
    : txt2 ." 6 " ;
    voc1 txt1
    voc2 txt1
    forth txt1
    voc1 txt2
    voc2 txt2
    forth txt2 
    

Built-in Web Server

  1. Forth2020 will be shipped with a little Web Server.
  2. Server written with RETRO FORTH.
    • The OpenSource FORTH ForthWorks by Charles Childers "RETRO" ( RETRO Forth ).
      • “A clean, elegant, and pragmatic dialect of Forth. It provides a simple alternative for those willing to make a break from legacy systems”.
      • “You can view the glossary via Gopher or HTTP. This is served off the latest documentation in the repository by a server written in RETRO”.

Capitalisation, or not?

  • Experts told me: “This is a legacy issue. Classical FORTH is supposed to be case insensitive. In practice it's easier to be case sensitive but some Forths use DUP and others use dup”. The experts suggest to assume sensitivity and expect uppercase, and to implement such with new FORTH implementations.
  • LMI WinFORTH is case senstive.

Clean Code

  • Experts told me: “Most forth could be better written for clarity. My view remains that it is by far clearer to read than assembly language (which was the dominant language on microcomputers in the early 80s) but was beaten by the ALGOL languages as 16 bit architectures took hold. Algol based languages permits a much simpler making of algorithms to code because of its built-in control and data structure. Forth has no data structures, requires composition of small code snippets. It discourages multiple parameter passing. It discourages intermediate values. It discourages nesting. The end result is a language which makes machine code much easier but is lower level than C or Pascal. However being good at Forth has positive impacts on programming in other languages I believe. Using the Forth approach to writing C leads to shorter functions that are quicker and easier to test and debug. C spoils the programmer while Forth does not. Forth influenced C is more likely to be correct on its first run”.

Code Quality

CREATE DOES> ;

Data Formats

Input of Values with a specific Data Type ( Single Precision Integer, Double Precision Integer, Floats,.. )
Floating Point Arithmetics

Deferred Words ( DEFER, IS )

Functional Programming with FORTH?

Concept for an in-FORTH Help

  • Experts suggested: “Use ' to read the next word and get it's xt. You can then look up info related to it. There's also WORD. It reads the input stream and returns a pointer.

Input / Output - CPU / OS specific Memory I/O & Port I/O Access

Standard FORTH Memory I/O
  • “C@” ( read a 8-bit value / byte / character from a location ).
  • “C!” ( write a 8-bit value / byte / character to a location ).
  • ”@” ( read a number / pointer, e.g. 16/32/64-bit on a 8&16/32/64-bit systems, from a location ).
  • ”!” ( write a number / pointer, e.g. 16/32/64-bit on a 8&16/32/64-bit systems, from a location ).
  • “L@” ( read a 32-bit / 64-bit value / long number / long word, e.g. 32-bit on a 8&16/32-bit systems, but 64-bit on a 64-bit system from a location ).
  • “L!” ( write a 32-bit / 64-bit value / long number / long word, e.g. 32-bit on a 8&16/32-bit systems, but 64-bit on a 64-bit system to a location ).
  • “D@” ( read a 32-bit value / double word from a location ).
  • “D!” ( write a 32-bit value / double word to a location ).
  • Infos:
ESP32forth
  • “C@” ( 8-bit value / byte read access ).
  • “C!” ( 8-bit value / byte write access ).
  • ”@” = “L@” ( 32-bit value / number / pointer read access ).
  • ”!” = “L!” ( 32-bit value / number / pointer write access ).
  • Infos:
    • Forth2020 "Esp32forth" - “ESP32forth digital R/W from a reg. - “You can access any address on the memory space of the ESP32 with the words L@ ( to retrieve a value ) and L! ( to store a value )”.
Open Firmware provides "Register" Access Words meant to access Hardware Devices
  • “RB@”.
  • “RB!”.
Port I/O for Intel 80x86, 808x & Z80
  • “PC@” ( 808X, Z80 and 80×86 ).
  • “PC!” ( 808X, Z80 and 80×86 ).
  • “P@” ( 808X, Z80, 80×86, though 808X and Z80 have just 8-bit I/O address space ).
  • “P!” ( 808X, Z80, 80×86, though 808X and Z80 have just 8-bit I/O address space ).
  • “PL@” ( 80×86 only ).
  • “PL!” ( 80×86 only ).
  • Demo implementation:
    \G Read the 16 bit port x1.
    CODE P@ ( x1 -- x2 ) \ EXTRA "p-fetch"
    MOV DX, BX
    IN AX, DX
    MOV BX, AX
    NEXT
    END-CODE
    
    \G Read the 8 bit port x.
    CODE PC@ ( x -- char ) \ EXTRA "p-c-fetch"
    MOV DX, BX
    IN AL, DX
    $IF386
    MOVZX BX, AL
    $ELSE
    XOR AH, AH
    MOV BX, AX
    $THEN
    NEXT
    END-CODE
    
    \G Write x1 to 16 bit port x2.
    CODE P! ( x1 x2 -- ) \ EXTRA "p-store"
    MOV DX, BX
    POP AX
    OUT DX, AX
    POP BX
    NEXT
    END-CODE
    
    \G Write char to 8 bit port x.
    CODE PC! ( char x -- ) \ EXTRA "p-c-store"
    MOV DX, BX
    POP AX
    OUT DX, AL
    POP BX
    NEXT
    END-CODE
    
  • Infos:
    • Usermanual Wiki "FT-86C and FT-86C/FP USER'S MANUAL" - “3.5 INTERRUPT CONTROL. The 8259A programmable interrupt controller is in local I/O space at Hex address 0008. It can be programmed using the P@ and P! commands in the same manner as the serial communications ports”.
    • Implemented by “CHForth”,...
BoardForth
  • “C@” ( 8-bit value / byte read access ).
  • “C!” ( 8-bit value / byte write access ).
  • “W@” ( 16-bit value / number / pointer read access ).
  • “W!” ( 16-bit value / number / pointer write access ).
  • ”@” ( 32-bit value / number / pointer read access ).
  • ”!” ( 32-bit value / number / pointer write access ).
Memory I/O for highly-optimizing FORTH Compilers to avoid Memory Access Optimisation
  • “P@”.
  • “P!”
  • “PC!”.
  • “PC@”.
  • “PW!”.
  • “PW@”.
  • “PL!”.
  • “PL@”.
  • Infos:
Port I/O, alternative Syntax
  • “IO@”.
  • “IO!”.
Jupiter Ace ( "FORTH Programming" Manual, Chapter 26 )
  • “IN”.
  • “OUT”.
Excursus: Intel 8086 Port I/O with MSDOS C Compilers
Excursus: ARM Memory I/O with C Compilers
Resources

Interoperability

Locals

Loops ( DO ... LOOP )

  • Gforth Manual "5.8.3 Counted Loops" - “Unfortunately, +DO, U+DO, -DO, U-DO and -LOOP are not defined in ANS Forth” :-(. “However, an implementation for these words that uses only standard words is provided in compat/loops.fs” :-).

Mocking for Top-Down Development

  • Mocking example:
    : I_dont_now_jet ;
    variable #I_dont_now_jet ' I_dont_now_jet #I_dont_now_jet !
    : bike #I_dont_now_jet @ execute ;
    : two_bike ." four weels " ;
    : one_bike ." two weels " ;
    : one ' one_bike #I_dont_now_jet ! ;
    : two ' two_bike #I_dont_now_jet ! ;
    one bike
    two bike
    
  • Mocking example #2:
    forth            \ use the vocabulary forth, use ORDER to see the vocabulary stack
    : bicycle ( -- ) \ make a word bicycle, ( -- ) that does not change number of items on the stack
    2 wheels !       \ store 2 in the variable wheels ,but gif a error becose it is not defind jet
    vehicle          \ call the word vehicle, but gif a error because it is not defind jet
    ; so bicycle is not made
    
  • Mocking example #3:
    variable wheels
    5 wheels !
    wheels @ .
    " it works
    
  • Mocking example #4:
    / "variable wheels" is a pointer
    variable wheels
    : vehicle cr ." my vhicle has " wheels @ . ." wheels " ;
    : bicycle 2 wheels ! vehicle ;
    bicycle
    

Provision of a Unit Test Framework

  • As support for the Test-Driven-Development approach ⇒ See FORTH 3/4.

Stack

Stack Juggling vs. Use of Global Variables & Registers

Stack Juggling
  • Experts told me: Chen-Hanson Ting tends to do more stack juggling. He more of a pure Forth guy and an educator.
Use of Global Variables & Registers
  • Experts told me: Charles “Chuck” Moore is not afraid to use global variables to get around needing excessive stack use. He also uses dedicated registers in colorForth to act as pointers. He is still more like an assembly programmer.

The 3 States - Interpret, Immediate, Compile

  • Experts told me
    • “Topic: Attributes on words. colorForth gets rid of the STATE variable which adds so much confusion and complexity. However he replaces this with the concept of “colours” which I think can be imagined as prefixes. So the same word can be executed as a compile colour or an interpret colour. The complexity of using the right colour for the situation is pushed back to the programmer”.
    • “In classic forth some words can be used in compile mode and interpret mode DUP, + etc, some are compile only IF, THEN or interpret only [IF], [THEN].
    • “POSTPONE ends up being a monstrously complicated word to implement for this reason. It has to handle every permutation. This is the sign that classic Forth has a code smell”.
    • “There is an alternative to the STATE variable, to prefixes or colours. Peter Jackaki talks about ALWAYS compiling. Even his interpreted lines at the REPL are compiled first. He does this by compiling to HERE and throwing away these compiled sequences away afterward running once”.
    • “Immediate words can be understood as 'macros' in other languages. They work at compile time and the STATE variable switches between compile and interpret modes”.
    • “An interpret attribute is not really needed, except as an error check. Some words like IF cannot be used on the command line except inside a definition. The reason why IF THEN have to be immediate is because they compile branches into the definition. These branches mean nothing in an interpreter. [IF] [THEN] can be used instead. These are very slow in comparison, especially [DO][LOOP] because they are interpreted. You can see how these words address kind of like different 'coloured' words. So IF performs no action but compiles a branch. That's why it can be called a macro. (words) generally represent internal words, not meant to be used directly [words] refer to the STATE of Forth. The word [ switches the state to interpret. The word ] switches the state to compile”.
    • “Example: So
      ' DUP EXECUTE

      gets the xt of DUP and executes it. You can't use ' inside a definition. To do that you use”

      ['] : X ['] DUP EXECUTE ;

      . Some Forthers find these words very ugly and annoying. They want Forth to always use the same words”.

    • ”[”: “It gives the definition of : as
      : : CREATE ] ;
    • “This means create a dictionary entry by reading the next word. Then switch into compile mode. The next word is the name. The definition of ; is something like”
      : ; [ ; IMMEDIATE
    • “In other words make the last immediate and turn the compile mode off”.
    • ?? “Not sure about [,] You can do ['] though” ??.
    • “Some experts find camelForth to be the most sane reference. Can't vouch for those weird British micro Forths from the 1980s. They had to cut corners. It's also more standard than eForth. camelForth dates from the 1990s”.
  • HectorForth ( based on figForth ) , CamelForth, Jupiter Forth, the special 'Python for Fun' Forth have ”[”, BBCMicro Forth ( based on FORTH-79 ) does not have ”[” in the vocabulary.

Warnings

Word List by VLIST, WORDS

  • Experts told me:
    • The order of words is usually just the order they appear in the dictionary. The order will reflect the dependencies of one word on another earlier word. They tend to be listed in reverse order of the definition order.
    • Order in the word list only matters for colon words!
    • *The experts suggested to reverse the word list order in the dictionary. “DUP” should appear long before ”.S”, for example.
    • Fast look ups by ordering the word list by Quicksort or other sort algorithm: That will speed up compilation and interpretation. THe search starts at the last word and then walk back over the linked list.
    • “If all words are all C functions it makes no difference. It's only when you read in Forth source code that the order matters.
    • “You need a fast way to parse and compile Forth. Or better, a binary representation of compiled Forth words which is fast to read. Compiled words are extremely simple of course but they need to be linked to tell addresses. To real addresses!”.
    • “Forth programming is like assembly language programming so in systems with memory protection the same rules apply as in assembly language. That usually means that code and data can't share the same memory space. In systems like that an 'execution token' for a primitive routine can't simply represent a memory address just like a data memory address. In those cases the token represents a offset into a table of functions. Colon words on the other hand can be built in normal data memory along with the dictionary”.
  • Experts told me about an important difference beween figFORTH & FORTH-79 on one hand, and FORTH-83 on the other:
    • figFORTH & FORTH-79 have a single wordlist in the form of a tree, created by its implementation is the source code, fixed at compile time. By this, the search order is determined and fixed.
    • With FORTH-83, Bill Ragsdale's “ONLY ALSO” prinziple was implemented: The wordlists are in a list structure. There is a wordlist “ROOT”. By adding different wordlists to the list, the developer may change the search order at runtime.

Appropriate OpenDirectory Directory Pages

 
en/forth05.html.txt · Last modified: 2022/01/13 20:56 (external edit) · []
Recent changes RSS feed Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki