Monday, January 18, 2021

Primary ColorForth Chapter 1

As mentioned in the intro, Primary ColorForth is loosely based on Starting Forth. You can follow along in it for this tutorial series either with a hardcopy version or online. Starting Forth chapter 1 starts by describing a way of organizing work by defining useful tasks and giving them a name, then grouping tasks together into larger tasks and naming them. It gives the example of an embedded washing machine program which we will explore. 

Washing Machine Example 

 Here is the top level washing machine program in ColorForth. 

washer wash spin rinse spin ; 

 In ColorForth red words signify the start of a new definition. So washer is the new procedure. The ";" represents the call return. Green words are ones that have already been defined and are compiled into the new definition. Note that unlike traditional Forth words cannot be defined from the command line. All words must be defined in the editor. Then the block containing the source text must be loaded. For example, to define new words in block 22 you would use 22 edit, then to compile then you would use 22 load. Let's look at the definition of rinse

rinse fill agitate drain ; 

 And now the definition of fill

fill faucets open till-full faucets close ; 

 The definition includes "things" (faucets) and verbs (open and close). The word "till-full" represents a delay loop. After the faucets "open" the word waits "till-full" before they "close". Every word must be defined before it can be compiled into a definition, so fill must be compiled before rinse and rinse must be compiled before washer

fill faucets open till-full faucets close ; 
rinse fill agitate drain ; 
washer wash spin rinse spin ; 

 This system is just an example. For a real system the definitions for open, close, faucets, till-full, agitate, drain and spin would all have to be defined. At some point it would be direct machine code to activate stepper motors, read sensors etc. 

Putting On a Show 

Forth was originally designed around a TTY display model. But ColorForth uses a GUI display, albeit one that is MUCH simpler than MS Windows, X-Windows or MacIntosh. So getting things displayed on the screen is a bit trickier than traditional Forth, but simpler than raw programming of most GUI operating system. The ColorForth word show creates a display task using the words following it. Consider this definition. 

ok show text 93 emit keyboard ; 

This creates a new definition ok that draws a "*" at the top left corner of the screen. The word text moves the cursor to the top left of the screen and sets the drawing color to white. The word emit takes a number off the stack and draws the corresponding charecter. It's the same as emit in traditional Forth. Note that the character set is different from ASCII. You can look up the characters in a code map, or you can use the command icons. The word keyboard redraws the keyboard and stack. 

Chapter 1 of Starting Forth builds up an example on how to draw the letter "F" as a large character using "ASCII art". Here is a walkthrough of that example using colorForth. First we need to define the word spaces which is built into traditional Forth. 

spaces for space next ; 

Note ColorForth uses for...next for its counted loop structure. Using spaces with what we learned earlier we can code the following: 

(Also note that when this blog post was first published in 2009, the word "space" was built into ColorForth.  But the latest version of ColorForth from GreenArrays called "arrayForth" does not have that word built it.  It is defined:
space 0 emit ; )

space 0 emit ; 
spaces for space next ; 
ok show text 15 spaces 93 emit ; 

Notice when we run this, the word spaces doesn't erase the text already on the screen, but just moves the star over. That's another example of how graphical CF is different from TTY TF. Now let's define star as it's own word. spaces for space next ; star 93 emit ; go show text 15 spaces star ; Moving sections of code into their own definitions is called factoring. Factoring is used to increase readability and/or code density. The next words define the "F" using combinations of the above defined words. Note that "cr" stands for "carriage return". That simply moves the cursor to the next line. 

stars for star next ; 
side star spaces star ; margin cr 30 spaces ; blip margin star ; bar margin 5 stars ; f bar blip bar blip blip cr ; ok show text f keyboard ; 

After loading the block containing these words and typing ok from the command line a large "F" will be displayed on the screen. 

Hello World from ColorForth 

 The next Starting Forth example is a variation on the venerable "Hello World" program. This particular program has cause some needless controvery and confusion over the years. Sure you emit each character one at a time, but that's not the most readable solution nor the most flexible. ColorForth can type blocks of text just like traditional Forth. And since ColorForth is extensible, just like traditional Forth is extensible, you extend it to where you can do a program like "Hello World" in just two lines. First you have to understand how text is stored in the ColorForth editor. ColorForth doesn't store ASCII characters in bytes. Instead it packs several characters in one 32 bit word using Shannon encoding, eabling it to store 5 to 7 characters plus a color token in one word. ColorForth includes a word unpack for decompressing such words. We have already discussed red and green words. ColorForth uses white words for comments. Comments can be as all lowercase, all upper case, or mixed case. So one way to display a block of text is to store it as comments in a Forth block, put that address on the stack, and then unpack and properly display the words until a non comment word is reached. Here is the code to set this up: 

+first 0 +rest 0 
type space fffffff0 and unpack +first @ + emit 
rest unpack if +rest @ + emit rest ; then drop drop ; 
done drop drop pop drop ; 
norm 0 +first ! 0 +rest ! type ; 
cap 48 +first ! 0 +rest ! type ; 
caps 48 +first ! 48 +rest ! type ; 
select jump rest done done done done done done done done norm cap caps done done done done ; 
.s nextw 1 + dup @ 
tag dup 15 and select .s ; 

That may look like a lot, but realize that you can load this block whenever you need it or you can even have it load automatically when ColorForth boots. Here is an example of its usage (assuming the code was stored in block 126). 

126 load s 0 Hello world, I speak ColorForth 
ok show text s .s ; 

 Note that magenta words like s define variables. Variables in ColorForth point to the blocks where they are defined as opposed to the dictionary. So s is being used here to point to the comment block of text we want to type. 

Run-time Versus Compile-time Versus Edit Time 

 Starting Forth then goes into a discussion about "run time versus compile time". This is a good time (no pun intended) to go into the other color states in ColorForth. We've already gone over how red defines a new word and how green compiles a previously defined word into a new definition. Green words are executed at run time. There are also yellow words that are executed at compile time. Consider the "hello world" example given earlier. 

126 load s 0 Hello world, I speak ColorForth 
ok show text s .s ; 

 Note the phrase 126 load. This will load the text display code in block 126 as soon as the current block is loaded. You don't have to wait until ok is run. Also note that the acess to the variable s is in yellow too. A variable is really just a name for an address. Why wait until run time to look up the address? Why not look it up at compile time and compile the address directly into the code? Accessing variables as yellow words instead of green ones accomplishes that. In fact that is the preferred way. Another way to use yellow words are with constants. When a constant is coded in yellow its value is compiled into the code on the yellow to green transition. This is also true for calculations that are done in yellow. Using the earlier "big F" exampe: 

side star spaces star ; 
margin cr 30 spaces ; 
blip margin star ; 
bar margin 5 stars ; 
f bar blip bar blip blip cr ; 
ok show text f keyboard ; 

Yellow words can also be used to do calculations that can be determined at compile time such as calculations based on a constant. Cyan words are used to create inline macros. 

The Dictionary 

 ColorForth, like traditional Forth, stores definitions in a dictionary. One difference is the way ColorForth handles numbers. In traditional Forth the interpreter first looks in the dictionary find a word and if it's not found it checks to see if it is a number. The ColorForth editor handles numbers differently. So the compiler never has to check to see if something is really a number. 

The Stack: Forth's Worksite for Arithmetic 

 If you are already familiar with Forth (or with HP scientific calculators) you know you to use the stack. If not here's a brief overview. Everytime a number is entered it is pushed on the stack. Forth arithmetic words will take numbers off the stack, do some operation with them, and return the results to the stack. To do 3 + 4 you must first push the 3 and the 4 to the stack then execute the "+" word. 3 4 + Note that the current state of the stack is shown on the bottom left of the screen. If you use the dot command . by itself all you will notice is that one number drops off. In traditional Forth . displays the top number on the stack. If you use . inside of a show word you get the traditional result. go show 3 4 + . ; Problems Problem 1-1: Define a word called gift that, when executed, will type out the name of some .gift, a word .giver that prints out a person's name, and a word .thanks that prints out something like this: 

 Dear Stephanie, Thanks for the bookends. 

 Solution: 

gift 0 bookends. giver 0 Stephanie, dear 0 Dear thank 0 Thanks for the 
.gift gift .s ; 
.giver giver .s ; 
.thank thank .s ; 
.dear dear .s ; 
thanks show black screen text .dear .giver .thank .gift ; 

Alternatively: 

gift 0 bookends. giver 0 Stephanie, dear 0 Dear thank 0 Thanks for the
thanks show black screen text dear .s giver .s thank .s gift .s ; 

 Problem 1-2: Define a word tenless that takes a number on the stack, substracts 10, and returns the answer on the stack. (Hint: You can use +.) 

Be sure to include stack effects. 

 Solution tenless n-n' -10 + ; 

 Problem 1-3: After entering the words in Problems 1-1, enter a new definition for .giver to print someone else's name, then without redefining thanks, execute thanks again. Can you explain why thanks still prints out the first giver's name?

 Solution 

gift 0 bookends. giver 0 Stephanie, dear 0 Dear thank 0 Thanks for the 
.gift gift .s ; 
.giver giver .s ; 
.thank thank .s ; 
.dear dear .s ;
thanks .dear .giver .thank .gift ; giver 0 Jill
.giver giver .s ; 
go show black screen text thanks .giver ; 

 Alternatively: 

gift 0 bookends. giver 0 Stephanie, dear 0 Dear thank 0 Thanks for the
thanks dear .s giver .s thank .s .gift .s ; giver 0 Jill 
go show black screen text thanks giver .s ; 

Whenever a new word is compiled it is appended to the end of the dictionary. The old definition isn't overwritten, but the interpreter starts at the newest definition and searches backwards so it doesn't find the older definition. However words that were defined using the old definition still work the same.

Labels:

Sunday, June 14, 2009

Fall through factoring

The idea is that you can have multiple entry points to the same word. Here's an example. Say if you needed code for shifting right twice (4 *) and shifting right3 times (8 *). You could code that without factoring as:

4* 2* 2* ;
8* 2* 2* 2* ;

You could also code it using traditional factoring as:

4* 2* 2* ;
8* 2* 4* ;

Using fall through factoring that becomes:

8* 2*
4* 2* 2* ;

With fall through factoring 8* doesn't have the overhead of having to call 4*, but you still get the code density benefit of having 4* factored out. Fall through factoring can also be used to increase code readability without added overhead. Consider the example from Starting Forth chapter 2.

: YARDS 36 * ;
: FEET 12 * ;
: INCHES ;

: YARD YARDS ;
: FOOT FEET ;
: INCH INCHES ;

The only reason for yard, foot and inch is readability. Here is the same result using fall through factoring.

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

Note that there is now no overhead for yard, foot, or inch being their own separate words. Each word is a separate label for the same code address. In traditional Forth the words yard, foot and inch all have the overhead of making a call to their plural versions. Some traditional Forths have a word alias that can give a similar result as this last example, but that's not standard.

Labels:

Saturday, June 13, 2009

Typing ColorForth 4.1

Well I thought I had done my last post on "typing ColorForth" at version 4.0. That version does everything I want. However it doesn't quite do it the way I wanted it to. I took code I found on the web that types comment text to the screen, modified it to use yellow "immediate" mode for accessing variables, and then factored the word ".s" (stype in the original version) using inline macros. At least I thought I was using inline macros. The reason is that I wanted to make it clear what .s does. Again the code from the original stype.

stype 1 + dup @ dup 15 and select stype ;

Anyone who understands ColorForth's tail recursion feature can tell what
stype ; does. And select is explained in the shadow block comments. But what does 1 + dup @ dup 15 and do? Not obvious is it? 1 + dup @ dup increments then retrieves from the string address. 15 and gets the tag value. You can factor that out those two phrases as "nextw" and "tag", but that doesn't do anything for code density in this case because the words are only used once yet you still have the penalty (albeit small) of the extra call.

So I thought about trying to inline it using
cyan words. My thought was that I could define the words inside the macro wordlist and then use them as cyan words in the normal forth wordlist and everything would be inlined. I'd get the readability improvement from factoring without the overhead.

On retrospect I believe my understanding of cyan words was not right.
Cyan should be used inside macro wordlist and not the forth wordlist. I believe the result of using cyan for a word defined as a macro is that a call was inserted instead of inline code.

Now I'm not sure if this is right either. But there is a better way to get the results I want. One of the key features of ColorForth is fall through factoring. The idea is that you can have multiple entry points to the same word. Using fall through factoring I can rewrite
.s as this:

select jump rest done done done done done done done done norm cap caps done done done done ;
.s
nextw 1 + dup @ dup
tag f and select .s ;

I can now document nextw and tag in the corresponding shadow block. Again, the entire code.

+first 0 +rest 0
type space fffffff0 and unpack +first @ + emit
rest unpack if +rest @ + emit rest ; then drop drop ;
done drop drop pop drop ;
norm 0 +first ! 0 +rest ! type ;
cap 48 +first ! 0 +rest ! type ;
caps 48 +first ! 48 +rest ! type ;
select jump rest done done done done done done done done norm cap caps done done done done ;
.S
nextw 1 + dup @ dup
tag f and select .s ;

And the shadow block:

type w display one 32-bit word of text
rest w finish typing a word
done aw drop addr and word and return from stype
norm normal text
cap text starts with a capital
caps all caps
select wt handle word according to tag
.s a display contiguous white text
nextw a get next word and increment address
tag n get tag field from word. used by select.

The usage remains the same. "Hello World" in 2 lines of ColorForth.

126 load hello 0 Hello World, I speak ColorForth
ok show blank text hello .s ;

Note: This will probably be the last version of Typing ColorForth (at least I hope so). It does (almost*) everything I want it to do as is as efficient and readable as I can make it. To the critics (well meaning I'm sure) who don't understand why I was doing this, please look at the rest of the Primary ColorForth tutorial. Doing all of the examples in Starting Forth by looking up codes and "emitting" them would be an unecessary pain in the butt. And yes, I could just type in "Hello World" on a blank screen, but that would not be flexible enough for what I'm doing.

(* There is one other thing I'd like to do. The current version sticks in an extra space before typing anything. Sometimes this throws the formatting off. But I'm going to quibble about that...for now.)

Labels:

Tuesday, May 26, 2009

Typing ColorForth...versions 3.1 and 4.0

Hello again. Here's yet another update to my experiments with unpacking and displaying packed ColorForth text. I know have it to the place where doing the examples from Starting Forth should be easy. First a fix from version 3.0 based on the fact that ColorForth 2.0 enforces Chuck's admonition for yellow variable calls.

s 0 hello , i speak forth
type fffffff0 and unpack if emit type ; then drop drop ;
print dup @ f and -9 + drop if drop then ; dup @ type space 1 + print ;
greet show text s 1 + print ;

However I found a much better version. This version actually handles caps and mixed case. But it also requires the yellow variable call fix.


+first 0 +rest 0
type space fffffff0 and unpack +first @ + emit
rest unpack if +rest @ + emit rest ; then drop drop ;

done drop drop pop drop ;
norm 0 +first ! 0 +rest ! type ;
cap 48 +first ! 0 +rest ! type ;
caps 48 +first ! 48 +rest ! type ;

select jump rest done done done done done done done done norm cap caps done done done done ;
stype 1 + dup @ dup 15 and select stype ;

Here's a slightly different version that uses macros to (IMO) improve readability and includes an example of usage.

+first 0 +rest 0
type space fffffff0 and unpack +first @ + emit
rest unpack if +rest @ + emit rest ; then drop drop ;

done drop drop pop drop ;
norm 0 +first ! 0 +rest ! type ;
cap 48 +first ! 0 +rest ! type ;
caps 48 +first ! 48 +rest ! type ;

select jump rest done done done done done done done done norm cap caps done done done done ; macro
tag 15 and ;
nextw 1 + dup @ dup ; forth
stype nextw tag select stype ;


Here's what this does and why I think it's better. The words "nextw" and "tag" are put in the "macro" dictionary and then inlined because they as "cyan" words. Cyan words allow you to inline. Normally in ColorForth words are factored to save space. Here no space is saved because "nextw" and "tag" are only used once. But "stype" is more readable because it says exactly what it does. Here's the documentation "shadow block".

String Display
type w display one 32-bit word of text
rest w finish typing a word
done aw drop addr and word and return from stype
norm normal text
cap text starts with a capital
caps all caps
select wt handle word according to tag
nextw a get next word and increment address
stype a display contiguous white text


Using the above, here's the solution to problem 1-1 from Starting Forth.

162 load salute 0 Dear friend 0 Stephanie, thank 0 thanks for the gift 0 bookends.
thanks salute stype friend stype thank stype gift stype ;
ok show text blank white thanks keyboard ;

Note that "162 load" assumes that the "String Display" library is in block 162.

Labels:

A ColorForth 2.0 "gotcha".(Windows version anyway)

Hello all.

I pretty much use a Windows version of ColorForth all the time these days. (Usually ColorForth 2.0 from Chuck Moore in Windows mode, but some Roman Pavlyuk's version.). The reason I'm prefacing my remarks is because I have never used the native version of ColorForth 2.0 and I don't know if this "gotcha" only happens under Windows. There is an easily fixable bug that only happens in Roman's Windows version of ColorForth. It uses absolute addressing from blocks as opposed to indirect addressing. So the code:


0 block @


causes it to crash. The fix is easy. Assume the following code in block 162.


ofs 0
foo block ofs 162 block negate + -1 + + ;
block foo ;

Thankfully ColorForth 2.0 for Windows doesn't have that problem. It uses an offset to calculate blocks out of the box. However there is another "gotcha" when using variables. If you try to address a variable using a green word it doesn't work. You may simply not get the results you want or it might crash. Consider the following example taken from Starting Forth chapter 2.


date 0 month 0 year 0
!date date ! month ! year ! ;

5 26 2009 !date


That doesn't get the expected results. But there's a reason I call this a "gotcha" instead of a bug. Long ago Chuck documented that variables really should be used as yellow words (evaluated at compile time) instead of green words (evaluated at run time). When you think about it, this makes sense. A variable is really just an address and for the most part address are constants. So why wait until run time to find the address of a variable? Just find it at compile time and compile the address constant directly into the word. With that in mind the above code becomes:


date 0 month 0 year 0
!date date ! month ! year ! ;

5 26 2009 !date


So if you have old ColorForth code that uses variables as green words you need to change them to yellow words. Your code will be (slightly) faster and it will work on ColorForth 2.0 for Windows (again, I don't know if the native version even has this "gotcha").

Labels: ,

Wednesday, December 27, 2006

Typing ColorForth...version 3.0

Cliche of the day: The third time's a charm

I've now extended my ColorForth text display library to the place where it's as "non-tedious" to use as possible. The first step was to be able to unpack and "type" a word rather than having to look up ColorForth charecter codes and emit them one at a time. The second step was to be able to print multiple words at one shot. That was in version 2.0. But the problem there was that I either had to put the number of words on the stack, or store them in the string variable itself. Now, after some brainstorming on the c4th IRC channel, I've come up with working code that figures out for itself how many words to type. Here it is.

s 0 hello , i speak forth
type fffffff0 and unpack if emit type ; then drop drop ;
nextw dup @ type space 1 + ;
tag f and ;
?ncom tag -9 + drop ;
print 1 +
ploop dup @ ?ncom if drop ; then nextw ploop ;
greet show text s print ;

A few notes here. Due to the way "print" works I couldn't use the old "nxtw" definition. So I modified it and changed the name. Also note, for those obsessing over lines of code (despite the fact that just about everyone knows that's no longer a good measure of program size, complexity or "tediousness") the above can be "compressed" into less lines, though IMO at the cost of readability.

s 0 hello , i speak forth
type fffffff0 and unpack if emit type ; then drop drop ;
print dup @ f and -9 + drop if drop then ; dup @ type space 1 + print ;
greet show text s 1 + print ;

There you have it. Four lines of ColorForth. (Or 3 lines depending upon where you put your variable.)

type fffffff0 and unpack if emit type ; then drop drop ; s 0 hello , i speak forth
print dup @ f and -9 + drop if drop then ; dup @ type space 1 + print ;
greet show text s 1 + print ;

And for the "ultra minimalist" (who doesn't want to bother with the tedium of looking up ColorForth charecter codes) you can do a simple "hello world" in 2 lines.

type fffffff0 and unpack if emit type ; then drop drop ; s 0 hello world
ok show text s dup push 1 + @ type 0 emit pop 2 + @ type ;

But that code isn't very robust. What happens when the string you want to type grows from 2 words to 6 as in "hello world, what a lovely day"? Still, that beats the pants off of emitting each charecter one at a time.

Anyway, this is the last I'm do anything with "hello world" programs for a while. I've got enough now to finish all of the examples in Starting Forth (chapter 1 anyway) with a minimum of tedium. This does remind me of how Chuck Moore answered the question of "hello world" programs on the ColorForth mailing list.
I've noticed the interest people have in getting colorForth to say "Hello
World".

The facility for doing that is extremely simple. Find an empty block. Edit
"Hello World" at the top.

I know that's not quite what they have in mind. But it's the way I'd
generate any sort of display. Format a block with the editor. Fill in
whatever numbers or graphics are required.
Gotta love it! "Hello world" in a single line and no need for tedious charecter code look ups and emits! Honestly though, that's what got me (and others) thinking about the "unpack" method of displaying text. The ColorForth to my understanding works by unpacking and displaying all of the 32 bit words in a block of code. But it's smart enough to understand compile words, macros, comments, numbers ect and choose the correct color and font. Right now the method I'm using only recognizes comments from non comments so it can't properly handle capitalization. But it should be intuitively obvious to the casual observer how to fix that. Perhaps I'll leave that as a "student exercise". :)

Labels:

Typing ColorForth...ver 2.0

Hello folks. Back fresh from the forever flamewars at comp.lang.forth. :) It's funny how some people want to nitpick ColorForth while posting code that the ANS standard calls "dangerous".

Anyway the current "nitpick" is over my stype code. Small confession. I'm not omniscient. ;) When I posted at c.l.f. I was replying to the usual nonsense while thinking about where I was going with PrimaryForth tutorial as opposed to just answering what's possible now. Once I get finished you will be able to do the following code:

s 0 hello , i speak forth
ok show text s stype ;

And get:

hello, i speak forth

as output. Right now you get:

hello

as output. If you want to get the entire phrase you have to put the number of words you want to type on the stack use the "words" word. For example:

ok show text s 5 words ;

I really don't see that as a big deal. You still don't have to do:

hw
show blue screen text 230 350 at red 2a 10 c 1 3 3f 0 2e 3 c c 4 44 13 for 2emit next ; hw

But don't tell the "haters*" that. :) They still want to believe what they want to believe. Still, I've found a way around this. By storing the number of words in the ColorForth string variable (the same as the way ANS Forth stores the number of charecters in the first byte of an ANS Forth string variable) the computer can put the number of words on the stack for you. For example:

s 5 hello , i speak forth
phrase dup @
words for ntxtw next ;

Now with just one small line of ColorForth:

ok show text s phrase ;

You get:

hello , i speak forth

The next step will be to incorporate testing the token color. Comments use the "white" color. So phrase could be programmed to typing words until it hits a word that's not a comment. (Thanks to "tathi" on the c4th IRC channel for kicking this idea around.)

* Note: By "haters" I don't mean the person who actually wrote the ColorForth code I referenced. I mean those who want to insist on using that as "proof" that it's difficult to do something as simple as "hello world" in ColorForth rather than seeing the obvious. ColorForth, like any other Forth, is extensible.

Labels:

Typing ColorForth

I made the following extensions to ColorForth.

s 0 hello , i speak forth

stype 1 + @
type fffffff0 and unpack if emit type ; then drop drop ;

The word "type" takes a packed word and displays it on the screen. Right now it ignores all color tags and just emits charecters using the current foreground color. Note that s is a string variable. Actually it's just a regular variable, but I'm treating it like a string variable. Variables in ColorForth really point directly to block memory. So by adding 1 to the address of s I can get the address of the text for "hello". The word "stype" adds 1 to the address on the stack and then returns data which is treated by "type" as a packed string. So the code:

greet show text s stype ;

Will display "hello" on the screen. Of course that's only part of the phrase. I added a definition to get a word, display it, and add the address for the next word.

nxtw 1 + dup @ type space ;

The word "space" was defined in a previous posting. I then added a word to unpack and display several words of text.

words for nxtw next ;

So the code:

greet show text s 5 words ;

Will display:

hello , i speak forth

I'm looking for better ways to do this. All comments welcome.

Labels: , ,

Thursday, December 21, 2006

Starting Forth chapter 1 examples.

Intro to PrimaryColorForth

The goal here is to simply reproduce all of the examples from chapter 1 of Starting Forth in ColorForth.

Washing Machine Example

washer wash spin rinse spin ;

In ColorForth red words signify the start of a new definition. So "washer" is the new procedure. The ";" represents the call return. The green words are procedures that have already been defined. Let's look at the definition of rinse.

rinse faucets open till-full faucets close ;

The definition includes "things" (faucets) and verbs (open and close). The word "till-full" represents a delay loop. After the faucets "open" the word waits "till-full" before they "close".

Note. Unlike traditional Forth words cannot be defined from the command line. All words must be defined in the editor. Then the block containing the source text must be loaded. For example if you defined some new words in block 22 you would type:

22 load

Putting on a show

Forth was originally designed around a TTY display model. But ColorForth uses a GUI display, albeit one that is MUCH simpler than MS Windows, X-Windows or MacIntosh. So getting things displayed on the screen is a bit tricker than traditional Forth, but simpler than raw programming of most GUI operating system. The ColorForth word "show" creates a display task using the words following it.

Consider this definition.

ok show text 45 emit keyboard ;

This creates a new definition "ok" that draws a "*" at the top left corner of the screen. The word "text" moves the cursor to the top left of the screen and sets the drawing color to white. The word "emit" takes a number off the stack and draws the corresponding charecter. It's the same as "emit" in traditional Forth. Note that the charecter set is different from ASCII. The word "keyboard" redraws the keyboard and stack.

Chapter 1 of Starting Forth builds up an example on how to draw the letter "F" as a large charecter using "ASCII art". Here is a walkthrough of that example using colorForth.

The first word "space" draws a blank space on the screen.

space 0 emit ;

The next word "spaces" draws a certain number of spaces. For instance "5 spaces" would draw 5 spaces. Note that the "for..next" loop will be covered in detail later.

spaces for space next ;

The word "star" is similar to "space" but draws a star.

star 45 emit ;

The word "stars is similar to "spaces" but draws a number of stars.

stars for star next ;

The next words define the "F" using combinations of the above defined words. Note that "cr" stands for "carriage return". That simply moves the cursor to the next line.

side star spaces star ;
margin cr 30 spaces ;
blip margin star ;
bar margin 5 stars ;
f bar blip bar blip blip cr ;
ok show text f keyboard ;

After loading the block containing these words and typing "ok" from the command line a large "F" will be displayed on the screen.

Labels:

Re-starting "Primary Colorforth"

Hello all. Some months ago I announced that I was working on a tutorial for ColorForth called Primary ColorForth. It is a play on words for the Leo Brodie classic Starting Forth. The plan was (and still is) to build a tutorial that follows the "spirit" of Starting Forth while departing from it when necessary to better fit the ColorForth model. I made a little progress. (Actually Jeff Fox made a bigger contribution than I did with his "Editor" chapter.)

However the project got stalled. Part of the problem is that I got waylaid by other projects. But another bigger problem was the classic "chicken and egg" problem. Some of the examples I wanted to do in the first chapter required advanced concepts that I didn't want to cover until other chapters. I was really stuck. Then, in a discussion with Jeff Fox in the USENET group comp.lang.forth about learning VentureForth I got an idea. Jeff suggested that someone learning VentureForth should try to do the examples from Staring Forth in it. I found then (and still find) that a daunting prospect. But I knew I could many of them in ColorForth so I decided to try. Then while reading the first chapter I noticed that Brodie put some advance code in an example and simply said we'll explain how it works in a later chapter. Now why did I think of that?

So I'm restarting my efforts. Things that I need to explain later, I'll just note and explain later. It's good to be back!

I'm going to use the blog to track my progress. While the tutorial will be built here, this won't be the final "polished" version. That will be put at the ColorForth Wiki. I don't want to be slowed down by trying to be "perfect" the first time.

Labels: