Sunday, June 14, 2009

Primary ColorForth Chapter 2

First some housekeeping:

Since Starting Forth is based on traditional Forth, there are some examples that won't work out of the box on ColorForth. Most of the required words can be easily implemented such as spaces back in chapter 1. Some words already exist but are not available in interactive mode because they have only been defined in the macro wordlist. I will define definitions needed for the Starting Forth examples as we go along. Alternatively here are the new definitions together.

/mod ab-qr /mod ;
mod ab-r mod ;
swap ab-ba swap ;
over ab-aba over ;
rot abc-bca push swap pop swap ;
2swap abcd-cdab push rot rot pop rot rot ;
2dup ab-abab over over ;
2over abcd-abcdab push push 2dup pop pop 2swap ;
2drop ab- drop drop ;

Forth Arithmetic -- Calculator Style

Starting Forth identifies the four fundamental arithmetic instructions in traditional Forth are +, -, *, and /. ColorForth has +, * and /. You might be wondering what happened to -. It is a macro that returns the one's complement (the same as invert in ANS Forth). This corresponds to the way - is used in Charles Moore's MISC processors since MuP21. You can still subtract by adding the negative. For constants just use the negative value. For variables or calculated results you can get the negative using NEGATE.

Starting Forth then gives several examples of postfix math. Note as mentioned in chapter 2, in ColorForth you don't need to use
. in interactive mode except as a shortcut for drop. You can also clear the entire stack using c. ColorForth continuously displays the parameter stack in the lower left of the screen. Try the following:

17 5 +
7 8 *
3 4 +
500 -300 +
5 6 *
20 4 /
c


An example of adding multiple numbers:

17 20 + 132 + 3 + 9 + .

Converting infix expressions to postfix (quizzie 2-a)

Here is a little trick I learned as a computer science undergraduate. Fully parenthesize your expression and move all operators to the end of the corresponding parenthesis. Examples:

c(a + b) => (c*(a+b)) => (c(a b)+)* => c a b + *

a*b/100 => ((a * b)/100) => ((a b)*100)/ => a b * 100 /

Try the following on your own:

(3a - b)/4 + c

(a + 1)/4

x(7x + 5)

Forth Arithmetic -- Definition Style

The next examples are for converting from yards or feet to inches. We know 1 yard = 36 inches and 1 foot = 12 inches. Here is the conversion code:

yards-inches 36 * ;
feet-inches 12 * ;

Usage example:

10 yards-inches
2 feet-inches

If we always want results to be in inches, we can define:

yards 36 * ;
feet 12 * ;
inches ;

to get the phrase

10 yards 2 feet + 9 inches +

Now perhaps you want to be able to use singular or plural words for better readability. Starting Forth used the following code:

: yard yards ;
: foot feet ;
: inch ;

That has the undesiable effect of adding an extra word call just for the sake of readability. ColorForth can do the same without the overhead using fall through factoring. The same definition can have multiple entry points. So in ColorForth you can define:

yard
yards 36 * ;
foot
feet 12 * ;
inch
inches ;

Note that yard and yards, foot and feet, inch and inches all point to the same memory location.

Now let's consider the earlier example of adding 5 numbers together.

17 20 + 132 + 3 + 9 +

The same thing could be accomplished by moving the
+'s to the end.

17 20 132 3 9 + + + +


Changing this to a definition we get:

5sum + + + + ;

Now say if in the same program sometimes we needed to add 5 numbers together and sometimes we needed to add 3? We could use fall through factoring here.

5sum + +
3sum + + ;

This time
5sum and 3sum point to different locations in memory. If you call 5sum it does the first 2 additions and then "falls through" to the remaining 2 additions in 3sum. If you call 3sum it just does the required 2 additions and returns.

An equation for another definition:

(a + b) * c

In postfix:

a b + c *

Alternatively we could say:

c * (a + b)

In postfix:

c a b + *

from which we can write the definition:

solution + * ;

It's a good time to point out that in Forth it's sometimes better to re-write an equation to make it easier to manipulate on the parameter stack. Here is the same code as a word problem:

If a jet plane flies at an average air speed of 600 mph and if it flies with a tail wind of 25 mph, how far will it travel in five hours?

If we define:

flight-dist + * ;

we could enter
5 600 25 flight-dist and get 3125 on the top of the stack.

Try it with different values, including head winds (negative values).


The Division Operators

The basic division in ColorForth (and traditional Forth as well) is /. This is an interger operator which discards the remainder.

22 5 /

This leaves 4 on the stack. There are two other division operators,
mod and /mod. By default they are in the macro wordset and only available during compilation. However they can be compiled to the Forth wordset.

mod ab-r mod ; returns the remainder
/mod ab-qr /mod ; returns quotient and remainder

Testing
/mod interactively: 22 4 /mod leaves 2 5 on the stack.

We can define a word quarters that takes a number of quarters and calculates the dollars and leftover quarters.

126 load q 0 quarters ones 0 ones
quarters 4 /mod . q .s . ones .s ;
go show blank text 22 quarters ;

Test
mod interactively: 22 4 mod leaves 2 on the stack.

Stack Manipulation

Swap

As the name suggests, this word takes the top too numbers on the stack and swaps them. Again this word is only in the macro wordlist. To use it interactively:

swap swap ;

Testing this interactively:
1 2 swap leaves 2 1 on the stack.

Dup

Dup takes the top number on the stack and duplicates it.
2 dup leaves 2 2 on the stack.

You can use dup to square a number.
4 dup * leaves 16 on the stack.

Over

Over is defined only in the macro wordlist. To use it interactively define:

over over ;

Over takes the second item on the stack and copies it to the top of the stack.

Testing it interactively,
1 2 over leaves 1 2 1 on the stack.

Thus the expression

a * (a + b)

can be written as:

over * +

Rot

Rot is in traditional Forth but is not by default defined in ColorForth. However defining it is simple. It requires a the words
push and pop. These words manipulate the second stack called the "return stack". Starting Forth doesn't cover this until another chapter. Basically push takes the top number from the parameter stack and moves it to the return stack. pop does the opposite. Using them rot is defined as:

rot push swap pop swap ;

Rot takes the 3rd item on the stack and rotates it to the top.

Testing it interactively:
1 2 3 rot leaves 2 3 1 on the stack.

Say if you wanted to evaluate the expression
ab - bc. First factor out the b's.

b*(a - c)

Now starting with
c b a on the stack we can use rot - *.

Drop

Drop, as its name suggests, drops the top item on the stack. Testing interactively:
1 2 drop leaves 1 on the stack.

Note: Look ma! No .s. Starting Forth mentions at this point that .s can be used to display the stack non destructively. But ColorForth shows the stack in interactive mode at the bottom left of the screen. Thus .s is not needed and not defined. Hence I can use .s is ColorForth for printing strings.

Stack Manipulation and Math Definitions (Quizzie 2-c)

1. Write a phrase which flips three items on the stack, leaving the middle number in the middle; that is:

a b c ==> c b a

Answer:
swap rot

2. Write a phrase that does what
over does, without using over.

Answer:
swap dup rot rot

3. Write a definition called
-rot, which rotates the top three stack items in the opposite direction from rot; that is:

a b c ==> c a b


Answer: -rot rot rot ;

Write definitions for the following:

4. (n+1) / n

Answer: 2c4 dup 1 + swap / ;

5. x(7x + 5)

Answer: 2c5 dup 7 * 5 + * ;

6.
9a2 - ba

a(9a - b)

Answer:
2c6 over 9 * swap - * ;

Playing Doubles

Many early Forths ran on 16 bit computers. As such "double" words, which allowed 32 bit math, were very important. ColorForth was initially written for a 32 bit computer and thus does not implement double words. However double stack manipulation words are not difficult to write.

2swap abcd-cdab push rot rot pop rot rot ;
2dup ab-abab over over ;
2over abcd-abcdab push push 2dup pop pop 2swap ;
2drop ab- drop drop ;

Problems -- Chapter 2

1. What's the difference between DUP DUP and 2DUP?

2. Write a phrase which will reverse the order of the top four items on the stack; that is,

( 1 2 3 4 -- 4 3 2 1 )

Answer:
reverse swap 2swap swap ;

3. Write a definition called 3DUP which will duplicate the top three numbers on the stack; for example,

Answer:
3dup abc-abcabc dup 2over rot ;

Write definitions for the following infix equations, given the stack effects shown:
4. a2 + ab + c ( c a b -- result )

a(a + b) + c

Answer:
prob4 over + * + ;

5. (a-b) / (a+b) ( a b -- result ) [answer]

Answer:
prob5 2dup - -rot + / ;

6. Write a set of words to compute prison sentences for hardened criminals such that the judge can enter:

CONVICTED-OF ARSON HOMICIDE TAX-EVASION ok
WILL-SERVE 35 years ok

or any series of crime beginning with the word CONVICTED-OF and ending with WILL-SERVE. Use these sentences

HOMICIDE 20 years
ARSON 10 years
BOOKMAKING 2 years
TAX-EVASION 5 years

Answer:

126 load years 0 years
convicted-of 0 ;
homicide 20 + ;
arson 10 + ;
bookmaking 2 + ;
tax-evasion 5 + ;
will-serve . years .s ;
ok show blank text convicted-of homicide arson tax-evasion will-serve ;

7. You're the inventory programmer at Maria's Egg Ranch. Define a word called EGG.CARTONS which expects on the stack the total number of eggs laid by the chickens today and prints out the number of cartons that can be filled with a dozen each, as well as the number of left-over eggs.

126 load cartons 0 cartons eggs 0 eggs
egg.cartons e-cr 12 /mod . cartons .s . eggs .s ;
ok show blank text 55 egg.cartons ;

2 comments:

Mike said...

Very interesting colorforth tutorial. Where can I download most recent version of colorforth?
I'm very much interested in SEAForth chips as well. Is it advisable to buy one at moment?

johnmdrake said...

The version I'm using can be found here:

http://colorforthray.info/colorforth2.0a.zip

Unfortunately IntellaSys isn't selling SEAForth chips at the moment. Something strange happened with that company and Chuck Moore is no longer with them. (See: http://www.colorforth.com/vTPL.htm)

Chuck is starting a new company called GreenArrays. (See:
http://www.colorforth.com/GA.htm)

That's the best I can tell you for now.