STRENGTH IN FORTH
part three
IS FORTH A LIE-DETECTOR ?
( By C. Janssen )
Read the second part of this time's Forth course here!
REMEMBER
TO FETCH -a verb used to express the action when a
particular value at a particular address has to
be copied onto the stack. The value at that
address is left unchanged. See {@}.
TO STORE -a verb to express the action when a particular
value on the stack has to be moved at a
particular address in memory. The value on the
stack is removed. See {!}.
TO SCALE -a verb used to express a certain way of
numberhandling in calculating arithmetic
expressions. The numbers must conform to the
same "scale". That is, all decimal points must
be at the same place. The decimal points are
even not actually present. Inside, the computer
treats the numbers as integers. The output of
a "correct" answer is performed by inserting a
decimal point at the right place. So you can
avoid floating-point arithmetic, if your system
lacks floating-point operators. An example of
scaling all values to integers: the constant
is approximately 3.1416. The area of a circle
with a radius of 10 cm is calculated as 10 X 10
X 3.1416 in floating-point. We could scale
to 31416 10000 {*/}. Or better to 355 113 {*/}
which is accurate to more then 6 places beyond
the decimal point. The definition of is the
written as : PI 355 113 */ ; . The area is then
calculated as 10 {DUP} {*} {PI} . The kind of
arithmetic used is called fixed-point
arithmetic.
PARAMETER -a noun used to denote the value a general
routine is given to perform the actual action.
5 3 {+}. Addition is a general routine. The 5
and 3 are the two parameters on which the
actual addition is performed to give the result
of 8. Parameters are also called arguments.
MNEMONIC -a noun used to denote a lettercombination or a
wordcontraction in a assemblerlanguage. The
process of assembling translates the mnemonics
into binary code, ones and nulls, the only code
a computer really can take action upon.
GATE -a noun used to denote an electronic
connection, which allows to determine wether or
not a voltage is created at some other point of
that connection. An NAND-gate for instance
consists of two entrances and one exit. The
entrances can be high (=voltage,=1) or low (=no
voltage,=0). Just as for the logical operators
you can set up truthtables. So if one entrance
is high and the other low (1 - 0) the result of
the NAND-function is 1, is high. The exit-line
then will be high too.
1 |¯¯¯¯¯¯¯\
| |o-- 1
| /
0 ¯¯¯¯¯¯
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| WORD | STACKNOTATION | DESCRIPTION |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| .S | ( -- ) |Outputs the stackcontents |
| SP0 | ( -- addr ) |Outputs the address of the |
| | |initial address of TOS |
| SP@ | ( -- addr ) |Outputs the actual address |
| | |of the TOS |
| SP! | ( -- ) |Initialises the stackpoin- |
| | |ter i.e. clears the stack. |
| DEPTH | ( -- n ) |n= number of stackitems |
| OVER | ( n1 n2 -- n1 n2 n1) |Copy the 2nd item over TOS |
| ROT | (n1 n2 n3 -- n2 n3 n1) |Moves the 3rd item to TOS |
| DROP | ( n -- ) |Removes the TOS-item. |
| ?DUP | (n -- n n) or (n -- n) |Dups if TOS is non-zero |
| PICK | used as n PICK |Copies the nth number TOS |
| ROLL | used as n ROLL |Rotates the nth item TOS |
| 2DUP | Stacksize dependent |Stacksize dependent. On 16-|
| 2OVER | " |bit stacks they work on |
| 2SWAP | " |d.l.-numbers or a combina- |
| 2ROT | " |tion of two s.l.-numbers. |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| WORD | STACKNOTATION | DESCRIPTION |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| 2DROP " |On a 32-bit stack on 32-bit|
| | |numbers in pairs. |
| TUCK | (n1 n2 -- n2 n1 n2) |Same as DUP ROT SWAP. |
| NIP | (n1 n2 -- n2) |Drops the 2nd item |
| -ROT | (n1 n2 n3 -- n3 n1 n2) |Rotates TOS to 3rd item |
| = | (n1 n2 -- f) |Leaves TRUE if the top two |
| | |stackitems are equal. |
| < | (n1 n2 -- f) |f is TRUE if n1 is less n2 |
| > | (n1 n2 -- f) |f is TRUE if n2 is less n1 |
| <> | (n1 n2 -- f) |f is TRUE if the top two |
| | |stackitems are not equal. |
| <= | (n1 n2 -- f) |f is TRUE if n1 is less or |
| | |equal n2. |
| >= | (n1 n2 -- f) |f is TRUE if n2 is less or |
| | |equal n1. |
| 0= | (n -- f) |f is TRUE if n equals 0. |
| 0< | (n -- f) |f is TRUE if n is less 0 |
| 0> | (n -- f) |f is TRUE if n is higher 0 |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| WORD | STACKNOTATION | DESCRIPTION |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| 0<> | (n -- f) |f is TRUE if n unequal 0 |
| 0<= | (n -- f) |f is TRUE if n equals or is|
| | |less 0. |
| 0>= | (n-- f) |f is TRUE if n equals or is|
| | |higher than 0 |
| THERE MAY BE RELATIONAL OPERATORS FOR UNSIGNED NUMBERS |
| THEY LOOK LIKE U=, U>, U<, U<> ETC. THEIR ACTION IS THE SAME. |
| MIN | (n1 n2 -- n-min) |Leaves the smaller of the |
| | |top two stacknumbers |
| MAX | (n1 n2 -- n-max) |Leaves the larger of the |
| | |top two stacknumbers. |
| NOT | (f1-- f2) |f2 is TRUE if f1 is FALSE |
| | |f2 is FALSE if f1 is TRUE |
| | |Equivalent to 0=. |
| AND | (n1 n2 -- and) |Returns the logical AND |
| OR | (n1 n2 -- or ) |Returns the logical OR |
| XOR | (n1 n2 -- xor) |Returns the logical XOR |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| WORD | STACKNOTATION | DESCRIPTION |
|¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯|
| ! | (n addr -- ) |Value n is stored at |
| | |address addr |
| @ | (addr -- n ) |Value n is fetched from |
| | |address addr. |
¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
EXTRAS
In experimenting with the stack, it's very handy to have a tool to
print out the contents of the stack, without destroying it. Such a
tool is the word {.S}. Another useful word is a stackcleaner.
{SP!} happens to be one. As I learned, {SP!} failed to do his job
right in at least one FORTH-system. So here are 2 definitions of
a new stack cleaner. : CLR SP0 @ SP! ; Use it as CLR and the
stack is clean. The other definition works in a more roundabout
way. : EST DEPTH DUP 0= NOT IF 0 DO DROP LOOP THEN ." Stack
empty" ; EST is short for Empty STack.
EXERCISES
1. Explain the difference between {OVER} {OVER} and {2OVER} !
2. Which word has the same result as {OVER} {OVER} ?
3. In EXTRAS I defined a word {EST}. Can you replace the sequence
of {DUP} {0=} {NOT} by just one word ?
4. Write a phrase that does what {-ROT} does, without using
{-ROT).
5. Define some words for the equations below, given the stack
effects shown. Use a sheet of paper to write out the stack
actions as done in the example.
a + 3 x(6x + 5) 16y^2 - xy
a x
(a -- result) (x -- result) (x y -- result)
6. The truthtable of NAND is: 1 1 NAND gives FALSE
1 0 NAND gives TRUE
0 1 NAND gives TRUE
0 0 NAND gives TRUE.
Make a colondefinition for the logic function NAND, not using
logic operators: : NAND .................... ;.
7. You are entering the world of big business. Ten (10 !!)
different products you are offering mankind at ten different
prices. Define a set of words, so you can enter TOTAL_OF 1
SUGAR 3 BUTTER 2 BREAD 4 BEER 5 FISH IS, and on your display
is printed out the total price your client has to pay. Use of
course integer prices.
8. Same as exercise seven, but...you must be able to enter the
single as well as the plural name of a product e.g. TOTAL_OF 1
COW 4 PIGS 2 COWS 5 HORSES 3 DOGS 1 PIG 1 CAT IS.
9. Rewrite {*} so that it always multiplies a number by at most 5.
: * ......... ;. FORTH will oppose 'not Unique'. Negate 'm !
Later you can {FORGET} your newly defined {*}.
10. This one is too difficult. If you succeeded in defining NAND,
you can redefine all logical operators EQV and IMP inclusive !
Try that one in BASIC as easily !!
SOLUTIONS
1. The 16th bit (or 32th bit) is always 1, as is normal for
negative numbers, or always 0 as is normal for positive numbers.
Calling that bit the sign-bit is due to the fact that the state of
that bit (1 - 0) indicates wether a number has a positive or
negative sign.
2. Very simple !! 768 8 {/} 113 {*} . A matter of order !
3. A. Using {*/} 344 105 35 {*/}. B. Using {wit} 105 35 {/} 344
{*}.
4. Use {*/MOD}. 576 861 15 {*/MOD} and TWO times {.} to see the
remainder on your monitor.
5. The unsigned equivalent of -986 is 64550 in 16-bit.
6. The solution is 18 5 69 3 {+} {*} {SWAP} (!) {/} or 5 18 69 3
{+} {SWAP} {/} {*}. The swapping did it !!!
7. The remainder is second on the stack.
8. Use {NEGATE}. So 8 4 {NEGATE} {+} will do the job.
9. The word {QUAD} needs one number on the stack before executing
and gives the square of that number TOS after being executed.
10. The definition is : 3POWER DUP DUP * * ; .
Disclaimer
The text of the articles is identical to the originals like they appeared
in old ST NEWS issues. Please take into consideration that the author(s)
was (were) a lot younger and less responsible back then. So bad jokes,
bad English, youthful arrogance, insults, bravura, over-crediting and
tastelessness should be taken with at least a grain of salt. Any contact
and/or payment information, as well as deadlines/release dates of any
kind should be regarded as outdated. Due to the fact that these pages are
not actually contained in an Atari executable here, references to scroll
texts, featured demo screens and hidden articles may also be irrelevant.