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.

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").