-
Notifications
You must be signed in to change notification settings - Fork 1
/
tutorial.txt
executable file
·437 lines (345 loc) · 17.8 KB
/
tutorial.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
[ Note, April, 2007. I have left this article mostly unchanged from
the original, written many years earlier. I have corrected the url
for the Forth Interest Group. Although it seems to be gone now, the
web site is still there and the links to the regional FIGs etc. may be
of some use. References to diskettes and bulletin boards are obsolete
and the Internet and comp.lang.forth and other news groups and mailing
lists (e.g. armforth) and Google have taken their place. Google for
gmane for an easy way to read various mailing lists as if they were
newsgroups.]
Introductory Pygmy Forth Tutorial
Foot in the Door
There is a _lot_ of information available about Forth in books,
magazines, diskettes, and bulletin board messages. Much of this
material is available through the Forth Interest Group
(http://www.forth.org). You should join, or at least
get their list of publications, and read as much as possible. At
the very least you should study the book _Starting Forth_ by Leo
Brodie and you should read the Pygmy Forth manual (the file
PYGMY.TXT) and study its source code blocks and their shadows.
Do the Exercises
If you are a beginner, or if you are "stuck" somewhere in your
study of Forth, please study this tutorial and actually do the
practice exercises, no matter how silly they sound.
Disclaimer
This is a tutorial on Forth, specifically Pygmy Forth for
MS/PC-DOS computers. It does not include information about how
to use DOS or how to turn on your computer or warn you that you
need to type a carriage return at the end of a command or explain
what an .EXE or .COM or .BAT file is or how you can find the
executable files on a disk or how to browse through ASCII
textfiles or what ASCII means.
------------------------
To Over Simplify and Exaggerate:
To master Forth you only need:
A. a few broad, simple concepts
B. a "cookbook" collection of examples
C. a lifetime's worth of evaluating what you
are doing and why
----------------------
A. A Few Broad, Simple Concepts
Forth is modular.
We do our work in little pieces and pyramid them into simple,
powerful, hierarchical structures. We should all adopt Rob
Chapman's slogan "It's so simple it has to work." Our job is to
_make_ it that simple and _keep_ it that simple.
Forth is interactive.
We build a little piece and test it immediately from the
keyboard. The more we test early the less we are bitten later.
Forth is not a religion.
Unlike some languages I might mention, Forth is so simple we do
not need to take it on faith. We can see it and test it, rather
than having to "believe" and "hope" and "trust." We can inspect
and modify any part of the system. Full source code is included,
and is small enough, and modularly organized enough, to be
manageable.
I want to go over this point again because it is so radical it
might be missed: Pygmy Forth includes _all_ of its own source
code. You can actually understand it. You can study and modify
the system. You can examine any part of the system you are
curious about. This is virtually unheard of with any language
except Forth. [Times have changed since I wrote the above
originally. With the GNU project and other free software
efforts, many huge systems do come with full source code --
whether it is small enough to be understandable is still a
factor, though.]
Forth has an explicit data stack.
Take a stack of magazines and put them on the floor one at a
time, one on top of the other. Which is the easiest to get to
(the one on top)? Empty the stack and put one magazine down,
saying "3" then put another magazine on top of it, saying "5."
Ok, what's on the stack (3 and 5)? Which number is on top (5)?
Now pretend you are the + (i.e. "plus" or addition) operator. It
is your job to take two numbers off the stack, add them, and put
the sum back onto the stack. Go ahead do it, take the 5 and 3
off the stack, add them to get 8, and put the 8 back on the
stack. How many items are on the stack now (one) and what is it
(8)? (Notice the "subliminal" hints in the previous questions,
in case you are having trouble answering.)
Forth has active operators.
In the previous example, + _did_ something; it wasn't a mere
symbol to tell something else to do something. Forth words are
active! They go to the stack to get the materials (numbers) they
need, they do their work, then they place their results on the
stack.
Forth must be practiced
Ok, you know enough now to start practicing with the computer. I
hope you have printed out a hard copy of this file so you can
read along while you run Pygmy on the computer. Go ahead, bring
up Pygmy.
Put some numbers on the stack by typing 1 3 5 7 9 followed
by the carriage return (which I am never going to mention
again!). What is on the stack? What is on top? Type .S to
display the contents of the stack and check to see if your
answers were correct. Now type . and see what happens. Type
.S and see if the stack is different. The dot removes the top
item from the stack and prints it as a number. Play with putting
numbers on the stack and removing them.
Forth uses postfix notation.
This should not surprise you since it is how + worked several
paragraphs back. Postfix means you type the operator _after_
typing its operands. Try out these examples (and use . or .S
to see the results):
multiply 3 by 5 by typing 3 5 *
subtract 7 from 9 by typing 9 7 -
divide 27 by 3 by typeing 27 3 /
Note, the order of operands is exactly the same as you are used
to in "infix", i.e. 3*5 or 9-7; the only difference is the
operator goes after its operands instead of between them. Ok,
continue.
(3+5)*(6+2) by typing 3 5 + 6 2 + *
3+5 * 6+2 by typing 3 5 6 * + 2 +
Postfix is simple, direct, doesn't require precedence rules,
doesn't require parentheses. You'll get the hang of it in no
time. Notice even in these complex examples that the order of
the operands (the numbers) is the same in both the infix and the
postfix versions. The last example above, due to the higher
precedence of the infix multiply operator, is _not_ the
equivalent of 8*8, but of 3+30+2.
Forth uses one or more blanks to separate words in the input
stream.
A word is a group of non-blank characters. Generally speaking,
the only things you feed Forth are words. Each word is one of
three things:
1. A word already known to Forth (i.e. it is in Forth's
dictionary), in which case Forth executes the word.
2. A word not in Forth's dictionary, but one that can be
interpreted as a valid number (e.g. 75), in which case
Forth does interpret it a number and pushes it to the
stack.
3. Neither of the above, in which case Forth reports an error.
Please re-read that. Isn't that simple? Isn't that pretty?
Like the shark is a feeding machine, Forth is an executing
machine. It gobbles input, pushing numbers to the stack,
executing words which exist in the dictionary, and choking on
anything else.
It makes no difference whether you separate words with one space
or 50, whether you put several words on one line or spread them
across several lines.
_You_ can add words to the dictionary.
And, they are full citizens with equal standing to all the other
words in the dictionary. To use this power responsibly, remember
to add little words and not great big unmanageable words. I do
not mean a word's name should be short, but that its function
should be simple, obvious, straightforward. We "divide and
conquer" at the beginning rather than trying to debug a hopeless
mess at the end. Do not make a word a jack of all trades. Make
it a master of one.
This process of adding a word to the dictionary is called
defining a word. Several different types of words can be
defined, but for now we will study a single type. This one type
can be used for everything you need at first. This type of
definition is called a colon definition, because the colon starts
the definition, e.g.
: SEVENTEEN 17 ;
Type that in and see what happens. Nothing? Well, not nothing
exactly, as you did get the "ok" prompt to indicate Forth gobbled
it up with no complaints. The new word SEVENTEEN is now in the
dictionary. Type SEVENTEEN and see what happens (use . or
.S). So, what else would you expect it to do? It puts the
number 17 on the stack. The definition begins with the word :
which is followed by a blank because the colon is not a _symbol_
but an active word. You are used to numbers preceding a word
that uses them (so they will be waiting on the stack). On the
other hand, strings often follow the word that uses them. In
this case : expects to find a string in the input stream, and
it uses this string as the name of the new word it creates. Then
colon collects all the other words up to the ; and stores them
in the body of the new word. The semicolon is a special word in
that it ends the definition. Try defining and executing the
following until you get the hang of it:
: 3* ( n - 3*n) 3 * ;
17 3* .
2 3* .
2 3* 3* 3* .
: FEET ( feet - inches) 12 * ;
6 FEET .
5 FEET .
: STAR ( -) ." *" ;
STAR
STAR STAR STAR
: STARS ( # -) FOR STAR NEXT ;
0 STARS
1 STARS
2 STARS
200 STARS
: DIGITS ( -) 0 10 FOR DUP . 1+ NEXT DROP ;
DIGITS
: DIGITS ( -) CR CR CR DIGITS CR CR CR ;
Notice the comments in parentheses inside every definition such
as ( n -). Notice how the left parenthesis is followed by a
space. As you must be getting used to by now, the left
parenthesis is a word, although one that is executed during the
defining process. What does it do? It skips the input stream up
through the ending parenthesis. Why do we put in comments?
Several reasons. First, it is our minimum specification of what
the word is intended to do. It shows what should be on the stack
before and after the word executes. We need to know what the
word should do as we write it and as we test it. For example,
DIGITS takes nothing from the stack and places nothing on the
stack. We call this comment a "stack comment" or a "stack
picture". Get in the habit of putting this in every word you
define. Notice the use of Forth's print statement in STAR. The
." (i.e. dot-quote) is a word, so it is followed by a space, then
by whatever characters you want to display, then by an ending
quote mark. FOR ... NEXT should be obvious. DUP copies the top
of the stack, i.e. its stack comment would be ( n - n n). DROP
drops the top item from the stack, i.e. ( n -). CR outputs a
carriage return.
Next, you try defining a word that prints your name. Then use
that word in the definition of another word. Here's an example:
: ME ( -) ." FRANK" ;
(be sure to test it before you continue!) then
: WHO? ( -) ME ." , THAT'S WHO!" CR ;
Forth is case-sensitive.
At least Pygmy and many others are case-sensitive. To test it
try typing the following four lines to see which of them Forth
executes and which it chokes on.
CR
cr
cR
Cr
Review
Where are words looked up (the dictionary)? Where do numbers go
(the stack)? How long should a definition be (not very)? When
should you test (immediately upon defining each word)? How do
you find out how a particular Forth word works (look at its
source and experiment with it from the keyboard)?
There you have it. Those are the concepts you need. Everything
else is simply a matter of asking "How do I do such and such?"
and finding a cookbook example to copy, or better, to study and
possibly modify.
---------------------
The Cookbook
Where do you find examples, and how do you answer questions about
the Forth system? Type WORDS and see what happens. This
displays the words in the dictionary. Did they scroll by too
fast? Try it again and press any key to make it halt, and then
press a key again to let it continue. When you see a word that
interests you, such as EXPECT type
VIEW EXPECT
Bang, you are popped into the editor at the definition of EXPECT.
You can read its definition, especially its stack comment. You
can then use PgUp and PgDn to browse through nearby blocks of
source code. If you have the shadow blocks for Pygmy you can
press Ctrl-A to alternate between the block EXPECT is defined on,
and its shadow block that gives more information.
Speaking of the editor, type .FILES and see what happens. This
shows the files that are currently available, the beginning and
ending block numbers for each file, and each file's DOS handle
number. (If the handle number is shown as -1 then the file is
not available.) Notice that PYGMY.SCR begins at block zero, so
type
0 EDIT
This file holds _all_ the source code for Pygmy. Browse through
it with PgUp, PgDn, (and switch to and from the shadow file with
Ctrl-A, if the shadow file is available). Do not worry too much
about learning all the details of what you see. Right now you
are just taking a tour to see what's where. Go ahead, browse
awhile. Notice that the definitions of words usually have stack
comments. Press Esc to get out of the editor.
By using WORDS EDIT and VIEW you should be able to locate
the source code for any word in the dictionary. Now here's where
the Cookbook comes in: get into the editor at the first block or
so (e.g. 1 EDIT) and then use F3 (i.e. the function key F3) and
F10 keys to set up a search string for the word of interest and
then search across blocks for it. This way you can find examples
of how that word has been used within other definitions.
You can learn a lot from doing that. Plus you will get more
comfortable with Pygmy as a whole. However, until you are
comfortable, until you are familiar with just how it works, you
can refer to the following list of How-do-I-do-such-and-such
questions to get going.
Q: I am tired of defining words and having them scroll off the
screen where I can no longer see the stack comment you made me
write. Ditto for retyping the definition every time I restart
Pygmy from DOS.
A: You are now ready to use the editor to save and change the
source code you write. An entire file is set up just for your
own code. It is named YOURFILE.SCR. You can see it listed when
you type .FILES. Note that it starts at block 2000. Type 2000
EDIT and browse through it with PgDn and PgUp. All the blocks
are blank, probably, unless you have already put stuff in them.
See the documentation file PYGMY.TXT for instructions on using
the editor, or use the quick reference reminder list on the
status line at the top of the display, and experiment. Type away
to enter your source code. Then, to compile your source code,
say from block 2002, get out of the editor by pressing Esc and
type 2002 LOAD. To get back into the editor, you can type 2002
EDIT or you can just type ED to return to the last block
edited. When you exit from Pygmy with BYE the words you've
loaded will vanish from the dictionary, but their definitions
will still be on block 2002. Next time you run Pygmy, you can
reload those definitions without retyping them just by saying
2002 LOAD.
Q: I'm tired of typing 2002 LOAD to reload my favorite little
additions every time I run Pygmy. Isn't there a way to avoid
that step?
A: Yes, there is a way. After you have loaded your favorite
words, type
SAVE A5.COM
That creates an executable file similar to the one you started up
Pygmy from, but named A5.COM. Of course you are free to invent a
more meaningful file name. But, the file extension should always
be .COM. Next time you want to run Pygmy, run it by typing A5
from DOS. The dictionary will contain all your goodies.
Q: How do I create a file in Pygmy?
A: You already have a file for your source code blocks, i.e.
YOURFILE.SCR. Just use it!
Q: But it's full. It only has eight blocks and I've used them
all up.
A: Oh, well, that's simple. Get into the editor and move to the
block where you want more room. Press the F9 key. The editor
will ask you how many. Enter a number, such as 20. The editor
will spread open the file at that point and insert 20 blank
blocks right after the current block.
Q: But, what if I want to use a _different_ file for some of my
code?
A: There are several ways to do it. Just get out to DOS and type
COPY YOURFILE.SCR NEWFILE.SCR
then get back into Pygmy and type
" NEWFILE.SCR" 4 OPEN
SAVE A6.COM
or, from within Pygmy you can create a new file by loading the
definition of NEWFILE from block 142 and using it to create
the new file, e.g.
" NEWFILE.SCR" NEWFILE
Well, that gives you the idea, I'm sure.
Q: Can Pygmy load from textfiles? I'm more comfortable with them
and with my favorite editor.
A: Nonsense! Just practice with Pygmy's block editor until you
become comfortable with _it_. But, the answer is yes, you can
load textfiles with FLOAD or with INCLUDE. I'll leave it as an
exercise for you to look up those words in PYGMY.SCR and/or to
look up the discussion of textfile loading in the manual
PYGMY.TXT. However, block files have a lot to offer over
textfiles, such as their instant availability with the built-in
editor, and their inherent modularity. You _are_ writing very
small definitions, aren't you?
Q: But I've seen some of _your_ source code and sometimes a
single word damn near overflows an entire block.
A: Don't do what I do; do what I say.
Conclusion
Do you feel oriented and comfortable yet (yes, I sure do, you've
opened my eyes to the power and beauty of Forth!)?
THE END