0% found this document useful (0 votes)
38 views15 pages

Forth in 100 Steps (Sample)

Uploaded by

Nicolás Carlos
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
38 views15 pages

Forth in 100 Steps (Sample)

Uploaded by

Nicolás Carlos
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 15

0 Stack

00
To know a bit more about the Forth language, let’s Here we go:
launch gforth in a terminal.
gforth ←-
Gforth 0.7.2, Copyright (C) 1995-2008
Free Software Foundation, Inc.
Gforth comes with ABSOLUTELY NO WARRANTY;
for details type ‘license’
Type ‘bye’ to exit

01
Forth uses a Stack as a way to pass parameters to, 42 ←- ok
17 ←- ok
and get results from operations. Entering numbers will
4807 ←- ok
put these numbers on the Stack. Enter two numbers.

02
You can print the number that is currently at the top . ←- 4807 ok
. ←- 17 ok
of the Stack, using the dot symbol: . . ←- 42 ok

03
Printing the number removes it from the Stack. Put
two numbers on the Stack again. You can enter several 47 150 ←- ok
numbers on the same line.

04
You can add the two numbers at the top of the Stack Let’s try:
by entering the + sign.
+ ←- ok
. ←- 197 ok

1
05
Just like numbers, the + and . symbols should be 42 17 +. ←-
:8: Undefined word
separated by space. Try not separating them and see 42 17 >>>+.<<<
what you get. (We don’t need to know about the trace Backtrace:
information for now). $103D82A08 throw
$103D98C90 no.extensions
$103D82CC8 interpreter-notfound1

06
Other arithmetic operations are available as well. 47 150 - . ←- -103 ok
47 150 * . ←- 7050 ok
They all use the Stack as a container for integer values. 150 47 / . ←- 3 ok
Try them. 4807 47 / . ←- 102 ok

07
Enter two numbers on the Stack, add them, then OK.
multiply the result by another number.
4807 3 + 42 * . ←- 202020 ok

08
To get the remainder of a division, use MOD. 4807 42 MOD . ←- 19 ok

09
You can also obtain both quotient and remainder, 4807 7 /MOD ←- ok
using the word /MOD. The quotient will be at the top of . ←- 686 ok
the Stack, and the remainder will be just below the top. . ←- 5 ok

0A
Enter a number, then print its opposite, using 17 NEGATE . ←- -17 ok
NEGATE.

0B
Print 32% of 4807 (approximately). 4807 32 * 100 / . ←- 1538 ok

0C
Give a more precise result (still using integer val-
ues). You can print the integer part and the fractional 480700 32 * 100 / 100 /MOD . . ←- 1538 24
part separately.

0D
Enter two numbers, then print the greatest number, 42 17 MAX . ←- 42 ok
using MAX.

0E
Enter two numbers, then print the smallest number, 42 17 MIN . ←- 17 ok
using MIN.

0F
Enter four numbers on the Stack, and print the 42 17 255 -13 MAX MAX MAX . ←- 255 ok
greatest number.

→ Forth programs are made of numbers and words, separated by space.


→ Numbers are pushed on a data Stack, words are interpreted and executed on the fly.
→ Numbers enter and leave the Stack in a First In, First Out fashion.

→ . , + , etc. are words, as well as MOD or MAX.


→ Words consume their arguments, removing them from the Stack.
→ Forth uses Reverse Polish Notation for all arithmetic expressions; the order of operations determines
the order of evaluation (no need for parentheses).

2
1 Arrange

10
Numbers are usually removed from the Stack by the 42 DUP ←- ok
. . ←- 42 42 ok
words that use them. If you want to keep a number on
the Stack and use it as a parameter for a word, you can . .
42 DUP
duplicate it, with the word DUP.
42 42 42
Draw the successive states of the Stack to better under-
42
stand the way it works.

11
Find a sequence of words that computes the square 42 DUP * . ←- 1764 ok
-7 DUP * . ←- 49 ok
of a number without typing the number twice. Try your
sequence on several values. .
42 DUP *
42 42 1764
42

12
Ask gforth to compute the value of 24 and 28 . 2 DUP DUP DUP * * * . ←- 16 ok

2 DUP DUP DUP * * * .


2 2 2 2 4 8 16
2 2 2 2 2
2 2 2
2

2 DUP * DUP * DUP * . ←- 256 ok

2 DUP * DUP * DUP * .


2 2 4 4 16 16 256
2 4 16

3
13
When you want a copy of the number just below the 42 17 OVER . . . ←- 42 17 42 ok
top instead of a copy of the top, use OVER. Try it.
42 17 OVER . . .
42 17 42 17 42
42 17 42
42

14
Find a sequence of words that given two numbers a 42 17 OVER + . . ←- 59 42 ok
and b, leaves the Stack with the numbers a, a + b.
42 17 OVER + . .
(Remember that repeating . will print the stack content
in reverse order). 42 17 42 59 42
42 17 42
42

100 99 OVER + . . ←- 199 100 ok

100 99 OVER + . .
100 99 100 199 100
100 99 100
100

15
Sometimes you need to exchange the top of the 42 17 SWAP . . ←- 42 17 ok
Stack with the number just below. That’s when you
42 17 SWAP . .
use the word SWAP.
42 17 42 17
42 17

16
Find a sequence of words that given two numbers a 42 17 SWAP 100 * SWAP / . ←- 247 ok
and b, will compute (approximately) 100a
b .
42 17 SWAP 100 * SWAP / .
42 17 42 100 4200 17 247
42 17 42 17 4200
17

17 42 SWAP 100 * SWAP / . ←- 40 ok

17 42 SWAP 100 * SWAP / .


17 42 17 100 1700 42 40
17 42 17 42 1700
42

3 9 SWAP 100 * SWAP / . ←- 33 ok

3 9 SWAP 100 * SWAP / .


3 9 3 100 300 9 33
3 9 3 9 300
9

4
17
You can also move the value that is in the third po- 1 2 3 ROT . . . ←- 1 3 2 ok
sition to the top of the Stack using ROT.
1 2 3 rot . . .
1 2 3 1 3 2
1 2 3 2
1 2

42 17 4807 ROT . . . ←- 42 4807 17 ok

42 17 4807 ROT . . .
42 17 4807 42 4807 17
42 17 4807 17
42 17

18
Using OVER twice duplicates the two numbers at the 42 17 OVER OVER ←- ok
. . . . ←- 17 42 17 42 ok
top of the Stack1 .
42 17 OVER OVER . . . .
42 17 42 17 42 17 42
42 17 42 17 42
42 17 42
42

19
Using ROT twice rotates the number at the top of the Ok
Stack under the number just below the top2 .
1 2 3 ROT ROT . . . ←- 2 1 3 ok

1 2 3 ROT ROT . . .
1 2 3 1 2 1 3
1 2 3 1 3
1 2 3

42 17 4807 ROT ROT . . . ←- 17 42 4807 ok

42 17 4807 ROT ROT . . .


42 17 4807 42 17 42 4807
42 17 4807 42 4807
42 17 4807

1A
Enter three numbers, then print them in the order Easy:
they were entered. 1 2 3 SWAP ROT . . . ←- 1 2 3 ok

1 2 3 SWAP ROT . . .
1 2 3 2 1 2 3
1 2 3 2 3
1 1 3

42 17 4807 SWAP ROT . . . ←- 42 17 4807

42 17 4807 SWAP ROT . . .


42 17 4807 17 42 17 4807
42 17 4807 17 4807
42 42 4807

1 The word 2DUP is a faster equivalent of OVER OVER.


2 The word -ROT is a faster equivalent of ROT ROT.

5
1B
Enter two numbers, then print them in ascending 42 17 OVER OVER MAX ROT ROT MIN ←- ok
. . ←- 17 42 ok
order. Test your sequence by entering the numbers in a
different order.
42 17 OVER OVER MAX ROT ROT MIN
42 17 42 17 42 42 17 17
42 17 42 17 42 42 42
42 17 42 17 42
42

17 42 OVER OVER MAX ROT ROT MIN ←- ok


. . ←- 17 42 ok

17 42 OVER OVER MAX ROT ROT MIN


17 42 17 42 42 17 42 17
17 42 17 42 42 17 42
17 42 17 42 42
17

1C
In your last test, replace the sequences OVER OVER 42 17 2DUP MAX -ROT MIN ←- ok
. . ←- 17 42 ok
and ROT ROT with faster words 2DUP and -ROT.
42 17 2DUP MAX -ROT MIN
42 17 17 42 17 17
42 42 17 42 42
17 42 42
42

17 42 2DUP MAX -ROT MIN ←- ok


. . ←- 17 42 ok

17 42 2DUP MAX -ROT MIN


17 42 42 42 42 17
17 17 42 17 42
42 17 42
17

1D
Enter three numbers, then print them in ascending 42 17 4807 ←- ok
2DUP MAX -ROT MIN ( 42,4807,17 ) ←- ok
order, using the sequence for sorting two numbers. ROT ( 4807,17,42 ) ←- ok
You can use ( and ) to comment on what happens on 2DUP MAX -ROT MIN ( 4807,42,17 ) ←- ok
the Stack3 . -ROT ( 17,4807,42 ) ←- ok
2DUP MAX -ROT MIN ( 17,4807,42 ) ←- ok
ROT ( 4807,42,17 ) ←- ok
. . . ←- 17 42 4807 ok

42 17 4807 2DUP MAX -ROT MIN ROT 2DUP MAX -ROT MIN -ROT 2DUP MAX -ROT MIN ROT
42 17 4807 4807 4807 4807 17 42 42 42 42 17 42 42 4807 42 42 17
42 17 17 4807 17 4807 17 17 42 17 42 4807 4807 42 4807 4807 42
42 4807 17 4807 42 4807 42 17 42 4807 17 42 4807 4807 17 4807
17 42 42 17 4807 4807 4807 17 17
42 4807 17

There must be less tedious ways to do this!

3 Be careful: ( is a Forth word, i.e. it must be separated from the first word of comment by a space.

6
1E
When you don’t need a number on the Stack any 42 17 DROP . ←- 42 ok
more, you can get rid of it with DROP.

1F
The word 2DROP is a faster way to execute
DROP DROP in order to eliminate 2 values from the 42 17 23 2DROP . ←- 42 ok
Stack.

→ Values on the Stack can be duplicated, exchanged or removed.


→ DUP ( n -- n,n ) : duplicates the top of the Stack.

→ DROP ( n -- ) : removes a number from the top of the Stack.


→ OVER ( a,b -- a,b,a ) : copies the value under the top of the Stack.
→ SWAP ( a,b -- b,a ) : exchanges the top of the Stack with the value below the top.

→ ROT ( a,b,c -- b,c,a ) : rotates the value in the third position to the top of the Stack.
→ -ROT ( a,b,c -- c,b,a ) : rotates the top of the Stack to the third position.
→ 2DUP ( a,b -- a,b,a,b ) : duplicates the two values at the top of the Stack.
→ 2DROP ( a,b -- ) : removes two numbers from the top of the Stack.

7
2 Display

20
We can display characters instead of numbers. The 65 EMIT ←- A ok
word EMIT consumes the value at the top of the Stack
and prints the corresponding character on the terminal.

21
We will use the following ASCII codes to represent 35 EMIT ←- # ok
36 EMIT ←- $ ok
the elements of the puzzle. Try them if you want.
42 EMIT ←- * ok
wall : 35 crate : 36 43 EMIT ←- + ok
filled goal : 42 worker on goal : 43 46 EMIT ←- . ok
64 EMIT ←- @ ok
goal : 46 worker : 64

22
The code for space (or Blank) is frequently used, so BL . ←- 32 ok
there is a word for it: BL, and even an equivalent of the SPACE SPACE SPACE ←- ok
sequence BL EMIT, called SPACE.

23
The word CR sends a Carriage Return on the termi- CR CR CR ←-
nal, forcing the display to start on a new line.

ok

CHAR N ←- ok
24
One way to put a character on the Stack is to enter CHAR A ←- ok
its ASCII code, if you know that code. Another way is CHAR B ←- ok
to use the word CHAR. CHAR reads the following word CHAR O ←- ok
CHAR K ←- ok
on the entry as the litteral char you want to have on the CHAR O ←- ok
Stack. Try it!. CHAR S ←- ok
Display the word SOKOBAN on the terminal. CR EMIT EMIT EMIT EMIT EMIT EMIT EMIT ←- ok
SOKOBAN ok
This takes some work!

8
25
Here is a faster way to display characters: use the ." SOKOBAN" ←- SOKOBAN ok
." Foo Bar" ←- Foo Bar ok
word .", and all the following non space characters in
the flow of entry will be printed until a " is met.
Don’t forget that ." is a word in itself and must be sep-
arated from the rest of the entry.

26
The terminal can do other actions than just display CR 9 EMIT 9 EMIT 35 EMIT ←-
characters. For example, the character with code 7 will # ok
ring a bell, and 9 will send a tabulation.

27
Some complex actions on the terminal are initiated
by the character with code 27 (ESC), followed by a [
27 EMIT ." [2J" ←-
and a command.
For example, to clear the entire screen, display the es-
cape character followed by the string [2J.

ok

28
Another terminal escape command allows you to 27 EMIT ." [5;3H" 42 EMIT ←-
select the column and row of the terminal where you
want to display the next characters. Try the escape
* ok
command 5;3H for example.

29
The gforth vocabulary includes special words that PAGE 2 2 AT-XY 46 EMIT 5 3 AT-XY 42 EMIT ←-
use terminal escape commands: PAGE will clean the
screen; AT-XY will take two numbers on the Stack and
.
use them as the x and y coordinates of the next thing to * ok
be displayed.

2A
The gforth word ESC[ is doing the same as the se- ESC[ ." 4m" ." Foo" ESC[ ." 0m" ." Bar" ←-
FooBar ok
quence: 27 EMIT 91 EMIT would: it sends these con-
trol characters to the terminal.
For example try to print words using underlined (4m)
mode, and then get back to normal mode (0m).

2B
The terminal can also print characters in color. Just
ESC[ ." 31mFoo" ←- Foo ok
print the escape sequence, then the color number, for CR ESC[ ." 32mFoo" ←- Foo ok
instance 31, for red, followed by m. CR ESC[ ." 34mBar" ←- Bar ok
Try to print lines using different colors.

2C
To reset all the terminal display attributes, use the CR ESC[ ." 0mQux" ←-
Qux ok
word ESC[ then print the string 0m.

34 ESC[ . CHAR m EMIT ."Foo" ←- Foo


2D
Find a sequence of words that given a color code
on the Stack, like 34 for example, changes the terminal That doesn’t work, because in the sequence
color. Your sequence should start with ESC[, then print 34 . CHAR m EMIT ←- 34 m ok
the number, then a m. the . word inserts a space after printing the number.

9
2E
Try with the word .R (dot-R). This word takes two
numbers n, w and prints n aligned on the right on w 4807 10 .R ←- 4807 ok
42 2 .R 17 2 .R ←- 4217 ok
columns. If w columns are not enough to print the num-
32 0 .R CHAR m EMIT ←- 32m ok
ber, .R will display the whole number anyway. The
important thing is that it will do it without adding a
trailing space like . does. I see.

2F
Try again this time using 0 .R in your sequence. 34 ESC[ 0 .R 109 EMIT ." Foo" ←- Foo ok
35 ESC[ 0 .R CHAR m EMIT ." Foo" ←- Foo ok
32 ESC[ 0 .R CHAR m EMIT ." Foo" ←- Foo ok
0 ESC[ 0 .R CHAR m EMIT ." Foo" ←- Foo ok

→ EMIT ( c -- ) : displays a character on the terminal.


→ CHAR {c} ( -- c ) : reads a character on the entry and puts its ASCII code on the Stack.
→ ." {CCCCC"} : reads a sequence of characters on the entry flow until ", then prints the string.

→ PAGE : clears the screen.


→ AT-XY ( x,y -- ) : sets the position x,y for the next display on the terminal.
→ ESC[ : starts an escape sequence on the terminal.

→ .R ( n,w -- ) : prints the number n aligned on the right on w columns, with no trailing space.

10
3 Define

30
Forth lets you define your ow words. Cool!
Here’s how to create a new word:
: STAR 42 EMIT ; ←- ok
→ start with : (colon), a space, and the name you STAR ←- * ok
want to give to your new word, STAR STAR STAR ←- *** ok

→ write all the Forth words that this definition


should execute,
→ finish the definition with ; (semicolon).
Let’s try! Define a word called STAR that will display
the character with the code 42.

31
Create a definition for a word called SQUARE that Ok!
takes a number n on the top of the Stack and replaces it
: SQUARE DUP * ; ←- ok
with n2 . 42 SQUARE . ←- 1764 ok
Then create a word called CUBE that takes a number n -7 SQUARE . ←- 49 ok
on the top of the Stack and replaces it with n3 . Use the
: CUBE DUP SQUARE * ; ←- ok
previous word you just created.
42 CUBE . ←- 74088 ok
Try your definition with several examples. -3 CUBE . ←- -27 ok

32
Create a word named SORT2 that given 2 values on : SORT2 2DUP MAX -ROT MIN ; ←- ok
42 17 SORT2 . . ←- 17 42 ok
the Stack, sorts them so that the greater value is below
17 42 SORT2 . . ←- 17 42 ok
the top, and the smaller value is at the top.

33
Create a word named SORT3 that given 3 values on
: SORT3 SORT2 ROT SORT2 -ROT SORT2 ROT ; ←-
the Stack sorts them so that the greatest value is below 42 17 4807 SORT3 . . . ←- 17 42 4807 ok
the two others on the Stack, and the smallest is at the 243 39 -55 SORT3 . . . ←- -55 39 243 ok
top.

11
34
Create a word named MODE that given a number, That is the sequence I defined some time ago:
sends an escape command to the terminal with that
: MODE ESC[ 0 .R CHAR m EMIT ; ←- ok
number. :23: Undefined word
Try your word with different modes. : MODE ESC[ 0 .R CHAR >>>m<<< EMIT ;

Hey! What’s happening?

35
Oh. I forgot to mention that CHAR cannot be used OK.
inside a definition4 . Use [CHAR] instead.
: MODE ESC[ 0 .R [CHAR] m EMIT ; ←- ok
31 MODE ←- ok
34 MODE ←- ok
35 MODE ←- ok
0 MODE ←- ok
CR 4 MODE ." Foo" 0 MODE ." Bar" ←-
FooBar ok

That is better!

36
Create a word BLUE that switches the display color Easy:
to red, and a word NORMAL that restores all display at-
: BLUE 34 MODE ; ←- ok
tributes to normal. : NORMAL 0 MODE ; ←- ok

CR BLUE STAR SPACE NORMAL STAR ←-


** ok

37
You can keep your programs in script files. When That’s cool, now I can write a program!
gforth is launched with the name of a script file as an : MODE ESC[ 0 .R [CHAR] m EMIT ;
argument, the words in the file are automatically exe-
cuted as gforth starts. : BLUE 34 MODE ;
Edit a Forth script file called Sokoban.fs. Enter your
definitions, and execute a simple sequence of actions : NORMAL 0 MODE ;
using these definitions. Note that ending the file script
with the word BYE will tell gforth to quit right after BLUE CHAR @ EMIT NORMAL CR BYE
executing the last word, giving us a stand-alone Forth Sokoban.fs
program. Try it!
gforth Sokoban.fs ←-
@

It works!

38
Comments can be entered after the word \ or be- Ok.
tween ( and ). Stack comments, like in this instance \ Sokoban.fs A Game of Sokoban in Forth!!
: NIP ( a,b -- b )
SWAP DROP ; : MODE ESC[ 0 .R [CHAR] m EMIT ;
are very usual.
: BLUE 34 MODE ;

BLUE CHAR @ ( col,chr -- )


EMIT ( col -- )
NORMAL ( -- )
CR BYE

4 Here’s the reason: CHAR reads the entry flow, looking for the next word, and then puts the char value on the Stack, while [CHAR] reads the

entry flow, looking for the next word, and then compiles the char value in the definition that is currently going on. CHAR used inside a definition,
is inactive. Thus the following item in the entry, m causes an Undefined word error.

12
39
You should keep your definitions small and elegant. Ok.
For that purpose, you can always create some helper \ Sokoban.fs A Game of Sokoban in Forth!!
words. For example:
→ replace [CHAR] m EMIT with a word called .M : .M [CHAR] m EMIT ;

→ replace 0 .R with a word called .N : .N 0 .R ; \ n -- print n w/o trailing space


Note that the gforth vocabulary already includes the
: MODE ESC[ .N .M ; \ N -- print Esc Nm
word .N. When executing your script file, gforth will
simply emit a warning and make the new definition re-
place the existing one.

3A : RED 31 MODE ;
Create new words to display the elements of the
: GREEN 32 MODE ;
game. Here they are:
: YELLOW 33 MODE ;
: BLUE 34 MODE ;
element display mode : NORMAL 0 MODE ;
empty space 0 : DISPLAY-EMPTY NORMAL BL EMIT ;
: DISPLAY-WORKER BLUE [CHAR] @ EMIT ;
worker @ 34
: DISPLAY-ONGOAL BLUE [CHAR] + EMIT ;
worker on goal + 34
: DISPLAY-CRATE GREEN [CHAR] $ EMIT ;
walls # 31 : DISPLAY-WALL RED [CHAR] # EMIT ;
crates $ 32 : DISPLAY-GOAL GREEN [CHAR] . EMIT ;
goal . 32 : DISPLAY-FILLED YELLOW [CHAR] * EMIT ;
filled goal * 33 \ testing
DISPLAY-WORKER DISPLAY-CRATE
DISPLAY-WALL DISPLAY-EMPTY
DISPLAY-GOAL DISPLAY-FILLED
DISPLAY-ONGOAL BYE

gforth Sokoban.fs ←-
@$# .*+

It works!

3B
Your program can be made simpler. Do you see all Ok.
these repeated patterns in the definitions? Instead, we : DISPLAY MODE EMIT ; \ chr,col --
can define one general word: DISPLAY that given an
ascii code and a color number, will display that charac-
ter in that color.

3C : DISPLAY MODE EMIT ; \ chr,col --


Then you can change your DISPLAY-xxx defini-
: DISPLAY-EMPTY BL 0 DISPLAY ;
tions so that they call this word.
: DISPLAY-WORKER [CHAR] @ 34 DISPLAY ;
: DISPLAY-ONGOAL [CHAR] + 34 DISPLAY ;
: DISPLAY-WALL [CHAR] # 31 DISPLAY ;
: DISPLAY-CRATE [CHAR] $ 33 DISPLAY ;
: DISPLAY-GOAL [CHAR] . 32 DISPLAY ;
: DISPLAY-FILLED [CHAR] * 35 DISPLAY ;
\ testing
DISPLAY-WORKER DISPLAY-CRATE
DISPLAY-WALL DISPLAY-EMPTY
DISPLAY-GOAL DISPLAY-FILLED
DISPLAY-ONGOAL BYE

gforth Sokoban.fs ←-
@$# .*+

13
3D
We can simplify the code a bit more. All these Ok.
DISPLAY-xxx have the same structure. We can define \ Sokoban.fs A Game of Sokoban in Forth!!
specialized words, and use them by combining them
with DISPLAY. : .M [CHAR] m EMIT ;
Create words WORKER, ONGOAL, WALL, etc. that will
push the right codes on the Stack. : .N 0 .R ; \ n -- print n w/o trailing space

: MODE ESC[ .N .M ; \ N -- print Esc Nm

: DISPLAY MODE EMIT ; \ chr,col --

: WORKER [CHAR] @ 34 ;
: ONGOAL [CHAR] + 34 ;
: WALL [CHAR] # 31 ;
: CRATE [CHAR] $ 33 ;
: GOAL [CHAR] . 32 ;
: FILLED [CHAR] * 35 ;
: EMPTY BL 0 ;

\ testing
WORKER DISPLAY CRATE DISPLAY
WALL DISPLAY EMPTY DISPLAY
GOAL DISPLAY FILLED DISPLAY
ONGOAL DISPLAY BYE

That is much simpler! But having words like RED,


BLUE, etc. instead of numbers would be better.

3E
Words like RED, BLUE, etc. that just push a number 42 CONSTANT ASTERISK ←-
ASTERISK EMIT ←- * ok
on the Stack can be declared as constants rather than
colon definitions. I see.
The word CONSTANT takes a number on the Stack, and
creates a new definition with the name that follows. Try
it with gforth .

3F \ Sokoban.fs A Game of Sokoban in Forth!!


Since Forth uses space as a delimiter in order to
31 CONSTANT RED 32 CONSTANT GREEN
separate words in the entry, you can use any other sym-
33 CONSTANT YELLOW 34 CONSTANT BLUE
bol to define your words. For instance 34YP! makes a 0 CONSTANT NORMAL
valid Forth word, albeit not a very clearly named one.
Define all the constants you need in the Sokoban. Place : M 109 EMIT ;
them at the beginning of the program. : .N 0 .R ; \ n -- print n w/o trailing space
: MODE ESC[ .N M ; \ N -- print Esc Nm
: DISPLAY \ c,m -- display c c in mode m
MODE EMIT ;

: WORKER [CHAR] @ BLUE ;


: ONGOAL [CHAR] + BLUE ;
: WALL [CHAR] # RED ;
: CRATE [CHAR] $ GREEN ;
: GOAL [CHAR] . GREEN ;
: FILLED [CHAR] * YELLOW ;
: EMPTY BL NORMAL ;

\ testing
WORKER DISPLAY CRATE DISPLAY
WALL DISPLAY EMPTY DISPLAY
GOAL DISPLAY FILLED DISPLAY
ONGOAL DISPLAY BYE

14
→ Forth lets you create new words that can be used just like existing words.
→ : ( {XXX ... ;} ) : creates a new definition named XXX for the following sequence.

→ At run time, a word created with : will execute the words contained in its definition.
→ ; : ends a colon definition.
→ You can redefine words simply by writing their new definition with : and ;.
→ [CHAR] {X} ) : inside a colon definition, reads the next character on the entry and compiles its
ASCII code in the definition.
→ CONSTANT ( {XXX} n -- ) : defines a constant named XXX for the value n.
→ At run time, a word created with CONSTANT will put its value on the Stack.
→ Invoking gforth with a script name executes all the words in the script file.

→ BYE : leaves gforth .


→ Create and combine together simple specialized words to avoid big repetitive ones.

15

You might also like