Working Notes: a commonplace notebook for recording & exploring ideas.
Home. Site Map. Subscribe. More at expLog.

Forth Starting Forth

- =INVERT= is the not used after conditionals
- =OR=, =AND=
- =?DUP=
  - Duplicates non zero topmost values
- =ABORT"=
  - raise error and die
- =PAGE= clear terminal screen
- =ABS= absolute value, =NEGATE=, =MIN=, =MAX=
- *Parameter Stack*  -- standard stack used by parameters
  - arguments passed from word to word
- *Return Stack* --
  - used by forth to hold pointers
  - can be used to temporarily hold values
    - must be cleared by the time we reach ;
- =>R= moves value from parameter to return stack
- =R>= moves value from return to parameter stack
- =R@= copies top item from return stack to parameter stack
- Processors that support hardware floating point are faster than fixed point
- Scaling operators help with fixed point
- =*/= ( n1 n2 n3 -- n4 )  n1 * n2 / n3 with a double length intermediate result
- =*/MOD= similar
- Can approximate constants by pairs of integers with errors < 10^-8
- Definite loop: =<LIMIT> <INDEX> DO...LOOP=
  - index and limit are stored on the loop control stack
  - =I= copies loop index onto stack; =J= next outer loop index
- =U.R= unsigned number print, right justified
- =DO ... <INC> +LOOP= uses a custom increment
  - INC must be put on the loop each time around
- Adding random words triggers =ABORT=, which also clears all stacks
- Indefinite loop: =BEGIN ... <flag> UNTIL=
- Infinite loop: =BEGIN ... AGAIN=
  - Unconditionally branches back
- =BEGIN ... <f> WHILE ... REPEAT=
  - test happens in the middle
- =LEAVE= causes loops to immediately end
- =QUIT= removes ok at end of execution
- =NIP= drop first item below stack
- =2*= arithmetic left shift, =2/= arithmetic right shift
- Stack holds unsigned or signed numbers
  - you have to remember to handle appropriately
- =.,= prints stack value as signed number
- =U.= prints it as unsigned
- =UM*=, =UM/MOD=, =U<= -- single length unsigned ops
- =HEX=, =OCTAL=, =DECIMAL= change base
- Prefix hexadecimals with a 0
- = n BASE ! ;= Change base
- Number followed by a . is converted to a double cell number
- =D.= print double length number
- =<# #S #> TYPE ;=
  - =<#= bracket-number
  - =#>= number-bracket
  - =#S= "numbers"
    - converts value on stack into ascii
  - TYPE prints out the characters
- =HOLD= inserts character at current position
- =<# ... #>= converts double length unsigned values to strings
- =<# ... ROT SIGN #>= double length signed value etc. etc.
- =M+= double length + single length
- =SM/REM= d1 / n1, returning n2 and n3
- =FM/MOD=, =M*=, =M*/=
- Defined numbers get compiled into the dictionary, depending on defined base
- =VARIABLE DATE=, creating variables;
  - =12 DATE != ! == store
  - =DATE @= @ == fetch onto stack
  - =DATE ?= == =DATE @ .=
- Variables are useful for values that need to be changed /after/ the definition has been compiled
- =+!= increment stored value
- =<VALUE> CONSTANT <NAME> =
  - constants for readability
- =2VARIABLE=, =2CONSTANT=, =2!=, =2@=
- =VARIABLE <name> <x> CELLS ALLOT=
  - adds additional cells to the variable
  - =<val> <name> <index> CELLS + <ops>=
- =FILL (addr  n char -- )= fills n bytes
- =ERASE (addr n -- )= zeroes out n bytes
- =addr count DUMP= to print out arrays
- Can also use byte arrays: =C! ( char addr - )=, =C@ ( addr - )=
- =CREATE name <value1> , <value2> , <value3> ... ,=
  - =CREATE= Puts a new name in the dictionary
  - =,= takes a number from the stack and puts it into the array
  - =C,= for creating byte arrays
- ='= Identifies location in memory from dictionary, returns execution token
- =EXECUTE= executes token on stack
- =DUMP= shows raw contents
- Vectored execution
  - Execute indirectly by storing execution token (xt) in a variable
  - allows changing the pointer later -- like a lambda!
- Label pointers with a ='= prefix, eg. ='aloha=
- Tick always goes to the next word in the input stream, not the definition
- =[']= goes to the next word in the definition
- Dictionary entries
  - name field, link field, code/code pointer field and data field
  - name: first byte defines number of characters, then an ascii rep of the name
  - precedence bit: if it should be executed during compilation or compiled into the definition
  - link: address of previous definition, allows for searching dictionary
    - ' starts with the most recent word and walks backwards
  - code pointer
    - address of instruction executed for this word
    - for variables, pushes address of variable onto stack
    - for constant, pushes contents onto stack
    - etc.
    - points to "run-time" code
    - can be actual machine code
  - data field
    - length depends on type variable, constant, array, etc.
    - =>BODY= gets beginning of data field
    - contains execution tokens of words that comprise the definition
  - execution token is code pointer
- =EXIT= returns execution to next higher level definition, return from subroutine
- return stack keeps return addresses
- =QUIT= is the outermost loop, =INTERPRET= s and prints oks.
- Memory map
  - forth / system variables / load definitions / user dictionary (stack)
  - pad stores ascii, etc. that are being manipulated
  - parameter stack grows up
  - TIB grows down / terminal input buffer -- stores text from terminal
  - return stack grows up
  - user variables/buffers at the end
  - =CP= points to the next cell in dictionary
  - =HERE= puts =CP= on the stack, can be used to estimate size of stack
  - =SP= provides address of top stack location
  - =S0= contains address of cell below the empty stack
  - =TIB=, =#TIB=, =BASE=, =H=, =>IN=
  - User variables
    - kept in an "user table"
    - each task can get a custom variable even if the definition is same
    - defined with =USER=
- Vocabularies manage the dictionary
- =EMIT= ASCII re on the stack and prints it
- =TYPE= prints entire string given starting address in memory
*

Kunal