Google Translated from:
http://www.ep128.hu/Ep_Util/fig-Forth.htm
fig-forth 1.1g for Z80
Noémi
Adorján: Forth step by step (1990)
Rector: László Csurgai
Technical publisher
Content
Introduction
The FORTH chained-code interpreted language, developed by Charles Moore in
the early 1960s, in solving the management problems of the telescope of the
Kitt Peak Observatory. Like
other programming languages, FORTH also has several "dialects", some of which
are standard. One is FORTH
79, written by Leo Brodie in the great book "Starting Forth".
A later version of the classic
FIG-FORTH 1.1. (aligned with
FORTH 79).
What does FIG mean? FORTH INTEREST
GROUP, PO BOX 1105, SAN CARLOS, CA 94070. This is a company founded for the
promotion, implementation and use of FORTH.
Not only have standard FORTH
recommendations been developed, but with several other useful publications,
the FORTH interpreter source list has been published for 9 different processors
(which is partly in the assembly language of the machine and partly in FORTH).
The 8080 source list can be found in the download package Z80FORTH.Z80 )
and other important information about FORTH (practically free).
With such a manual (FIG-FORTH
INSTALLATION MANUAL) it is no longer difficult to write a FORTH interpreter,
with little exaggeration that anyone can engage in it.
While
playing with FORTH, we will see that everything in FORTH can be.
But not everything is
recommended!
Do not be surprised by the inexperienced programmer (the experienced person)
when experiencing "wild" phenomena.
He may have made a small mistake
and accidentally palmed in the wrong place.
If you do not have a better
idea, you can always reset the machine, refill FORTH in the knowledge that
this has happened to others.
FORTH's most beloved fan can
not say it's easy to learn. Its
benefits are due in particular to the fact that it is a machine-friendly
language (so it is necessary to understand the "soul" of the computer) so
that it can be expanded, transformed (so we need to know how FORTH works),
its small memory requirement (fig-FORTH here it's only 6656 bytes!) and that
much of it is original, witty, but not necessarily easy to understand.
Knowing FORTH does not go without
any effort.
Much of the FORTH itself was written in FORTH. The FORTH source texts of the FORTH basic words serve as an abundant example, from which the author has well deserved. For everyone who has decided to learn FORTH, there is plenty of success and fun!
1. Getting
Started
Fill in and start FORTH. This
can be done after running
IS-DOS
by
running the Z80FORTH.COM file.
Later, we will launch FORTH
differently.
The FORTH interpreter starts running the version number (this is Z80 fig-FORTH
1.1g). The report "No file"
will
be discussed
later .
Then the interpreter waits
for him to give him a command line.
She waits until we finish her
line. How do you know when
we're done? From there, press
ENTER to end the line.
Enter
the ENTER line to FORTH; Until
pressing ENTER, nothing else happens than the FORTH is waiting for
us.
|
This
is worth noting if you do not want to spend a lot of time waiting to implement
our instructions without ENTER.
If we have coated, we can fix
it. Press the ERASE key to
delete the last character from the line - of course just before ENTER is
pressed.
Let's start by finishing it: give a blank command line: just press ENTER
in an empty line. The OK received
as a response means that FORTH has made the statements (in our case, the
big one) completely. After
OK, FORTH waits for our next wish for the beginning of the next line.
A simple word you
understand:
CR
OK
this time it is shown one line down, FORTH has a carriage return and a line
up character.
Those who received an error message instead of OK were ignored and not exactly
the same
in
FORTH, all the instructions to the interpreter must be capitalized
|
To make the effect more spectacular, write the same thing in a row several times. We need to know that
each
word is separated from each other by one line (one or
more)
|
So, if we say:
CR CR CR CR
FORTH prints the four empty lines and rewards the regular job statement with OK. But if we write that
CRCR CR CR
then
FORTH will be violated by the incomprehensible CRCR, and without honoring
us, it will stop it. The two
"good" CRs are not read yet, only one error code is obtained.
Sometimes we get something
like this when we try to know the word FORTH.
(
Declining
DTCs can be found in
Appendix
B.
)
Let's
play more "dumpers":
42 EMIT
The
word EMIT prints the character whose code was given to it;
42 is the star code.
Define a word for astrologers!
: CS 42 EMIT;
We have written our first FORTH program. Now this is the same FORTH word as any other, so it can be run with the description of its name:
CS
In fact, we can use the creation of new words:
: PONT CR CS;
: VONAL CR CS CS CS;
In
the example, we tried every word before we used them in other words.
so it may be (and recommended)
to "be sure". One of the most
attractive attributes of FORTH is this: the building blocks from which the
program finally compiles can be tested separately after they are written.
Most of the FORTH basic words are written in the same way in FORTH, using
other basic words. For example,
SPACE. which writes a space
on the screen, so it is built up:
: SPACE 32 EMIT;
The already known CR means:
: CR 13 EMIT 10 EMIT;
The first step is to mention the last step in using FORTH: from the FORTH interpreter to
BYE
so we can step out properly without losing data.
1.1.
About the
dictionary
What made CS, F, etc.
executable word?
What happens when we type such
a "colon definition"?
FORTH keeps words that can be interpreted in a dictionary.
After loading, the dictionary
has the FORTH basic words. By
creating new words, we will expand the dictionary - or, if you like, the
FORTH language itself.
The names of dictionary words are written to the VLIST (Vocabulary List,
the vocabulary, say: Vocabulary, meaning: dictionary).
You can stop a "word" starting
with VLIST by tapping any key.
If we define our own words
and then look at our vocabulary with VLIST, we see that the most recently
defined words appear first;
after the first operation,
for example, the list of words begins as follows: F LINE POINT
CS
The FORTH interpreter, when you want to interpret a word, first begins to
search it in the dictionary.
The last word defined;
Here you will find information
about where the last word written in front begins, so if you need to continue
searching, and so on. If, then,
in the example, after the definition of F, we write another word
F:
: F70 EMIT;
then the word F is "redefined"; the FORTH warns you of an error message and writes the new word into the dictionary. Let's see what the result is
F
FORTH
found this second F definition.
(70 is the big F code.)
Let's stop for a moment! Good,
it's good that CS, F etc. it
can be executed by being included in the dictionary.
We took it when we were defined.
It may also be true that EMIT
is in it. It's a basic word.
But what do you know about
42 and 70? Are not all the
songs in it? And if there is
something in the dictionary, why does not the interpreter say why he pretends
to be all right?
Principle. The principle is
that what is not a dictionary word is a sure number, so the FORTH interpreter
attempts to interpret the resulting string after a failed search in the
dictionary. If it does not
go (there are "non-numeric" characters), then it's really a mistake.
If it is a number, then this
number will be in the stack.
1.2.
What is a stack?
The stack (the English name stack) is an important part of FORTH.
Each word is "mailed" to each
other. For example, EMIT looks
at the stack in the stack that the character code should be written on the
screen; after knocking it down,
it will destroy it from the stack.
They call it a stack because
there are more things (more than one number in our case) can be kept;
We have only one access to
one of them: the one that has been there for the last time, that is, "upside
down". To get to know this,
we learn a new FORTH basic word.
Let's try it!
65
.
We
put 65 on the stack (first row), we asked "point" (second line).
Back it up!
He also deleted it.
Let's make sure.
Write another point!
We get a bug signal, which
means we wanted to use more batteries than we used to buy.
And if not? It's easy for the
Experiment Reader to do a lot of things to get there.
Maybe there was something in
the stack. The simplest way
to empty the stack is to type a word we know that FORTH does not know.
The "angry" interpreter empties
the vermet; if you then try
some of the above, you will see that this is true.
The method can be useful when
we accidentally put the vermet full of "trash".
(Let's say, in a cycle, forget
to delete something unnecessary.
1 2 3. . .
Which number is to be written first? The one that is on top of the stack, the one that was last in the stack. It will also be deleted at the same time; the next item then writes and deletes the item below it. The answer is 3 2 1 . After each step the stack looks like the following figure.
1.3.
Back to
dictionary
Something else. What if we
focus on our definitions, do not we want to use them further?
For example, we redefined a
word, but we regret it.
The radical solution is the word COLD.
It restores the dictionary,
the vermet, and some other things that have not been reported so far to the
original state of loading. The
dictionary will therefore contain the FORTH basic vocabulary.
The delicious solution is FORGET.
After the FORGET (still in
the same line), enter the name of the word to be forgotten.
For example, if we want to
recall the second F word:
FORGET F
FORGET forgets the given word, plus the words that are defined afterwards (that is, words above "in the dictionary").
What???
Everything we have defined
afterwards?
That's right. In principle,
in any of the words written after the forgotten one, we could use this word
you just want to delete. The
words of the FORTH dictionary are built on one another (it can not be deleted
from the middle only). (You
can, however, keep the words of our words, how it will be, and just want
to calm everyone: you will not have to type everything again because of a
mistake!)
Which F word will oblige FORGET to forget if there are two?
Almost unobtrusive can be said:
from the "top", from the last defined.
Finding words in the dictionary,
for whatever purpose, is always from the top, in that direction you can quickly
look at the vocabulary. In
this example, we dig out the old, star F word,
1.4.
We learn how to calculate -
it's a bit unusual ...
What does FORTH arithmetic consist of?
Of course FORTH words.
Their names are so short that
the more naive they may think of as an action signal.
The four basic operations are:
+, -, *, /. Each one is waiting
for the two numbers at the end of the operation (ie two operands of the
operation); they are also lifted
from the stack and replaced by the result of the operation.
Here is the following.
See example.
(After that step, the data in the stack is drawn.) The
2 3 + 4
*
series described
performs the same calculation
as BASIC
(2 + 3) *
4
(say) .
The latter, more usual markup is called infix, as opposed to the FORTH
(multiplying) postfix. The
names reflect that the operation signal is in the infix spelling between
the two operands, and the postfix in the postfix after the
operands.
To become accustomed to postfix, the following can be crippled:
The
order of the operands in the postfix script is the same as in the infix,
only the position of the operation signal varies.
|
infix | postfix |
1 + 1 | 1 1 + |
2 - 4 | 2 4 - |
6/3 | 6 3 / |
This means that, for example, in the case of subtraction, the word is awaiting the extraction on top of the stack, and below it the minor. This is commonly documented for FORTH programs:
(to be deducted --- difference to be deducted)
We
are writing a lock signal so that the effect of the individual words on the
stack can be indicated in the FORTH source text.
The word "FORTH" means the word "FORTH", its function is "enclosing" the
text that is given to the interpreter, so that the interpreting between the
opening and closing parentheses is not read by the interpreter, so that it
does not execute it. so it can be documented in
FORTH .
( before after )
If
you look at the order of the elements, you just have to imagine how to make
the vermet right.
The base effect of the four basic operations:
+ (sum up to add2 --- amount)
- (to be subtracted to extract --- difference)
* (to multiply1 to multiply2 --- product)
/ (to divide the dividing ratio)
This is how we implemented the basic operations. Even so: there are integers in the stack, FORTH arithmetic is a whole arithmetic. Accordingly, the division is also a division (that is, the whole quotient of the quotient).
1.5.
Rearrange the
stack
The FORTH words are expected to get the bugs in the correct order for the
parameters needed for their operation.
This is not always easy.
At times, the parameters are
generated in the wrong order in the stack, including unnecessary, but it
may even be necessary for one.
The following words are used
to solve such problems:
SWAP | (ab-ba) | replaces the two top elements; |
DUP | (a --- aa) | doubling the top element; |
OVER | ( the baby ) | make a copy of the second item on top of the stack; |
ROT | (abc --- bca) | removing the third element from the bottom and throwing it on the roof; |
DROP | ( the --- ) | removes the top element. |
For example, write a word whose effect on the stack:
(xy --- z); where z = xy- (x + y).
We can not start the thing with an arithmetic operation, since we would lose x and yt on the stack. We have to keep them in some way. Applying this OVER twice is a good catch. In addition to each step, we have indicated what will happen after the step in the stack; this way of writing is very useful until we become a rogue magician of the stack. (Do not be bothered by the fact that the definition is multi-line! FORTH allows this without further notice.)
: XY
OVER
OVER
*
ROT
ROT
+
-
;(xy)
(xyx)
(xyxy)
(xy product)
(x product y)
(product xy)
(product amount)
(z)
1.6.
Useful, but non-standard
words
There are some pile management FORTH words that are not included in the FIG
baseline set
,
but many in FORTH are
listed. The source text of
the words is
7.3.
section
if anyone wants to use them.
DEPTH | (--- n) | (meaning: depth) puts the stack of stacks (before the DEPTH is executed) on the stack. |
.STACK | (---) | the word STACK can be used to spell the stack. .STACK does not change the vermet. |
PICK | (n1 --- n2) | copy the n1th element of the stack to the top of the stack. 2 PICK works the same way as OVER, 1 PICK like DUP. |
ROLL | (n ---) | removes the nth element of the stack and puts it on top of the stack. 3 ROLL is ROT, 2 ROLL is equal to the SWAP word. With the standard marking of the stack, the ROLL function can only be written incorrectly. |
1.7.
One more word of the text of
the notice
of. "Writes words on the screen after the specified text until the next mark.
The closing quotation mark in
."
must
be in a row! For example, write
a word that contains the two numbers found on the vermine, also print their
amount on the screen, in plain text to clarify which number is what.
The spin of the word is: (xy
---).
: LOCSI-FECSI
OVER OVER
CR
. "It was up:". CR
. "This was down:". CR
+
. " amount: " . CR
;(xy ---)
(xyxy)
(xyx)
(xy)
(sum)
Do not forget that you have to enter a space after ". special word. The space bar does not count in the text to be typed.
What was that about?
Summary
of Chapter 1
The
interpreter
works on a query-based basis, one line (to ENTER) takes a "question".
The line is interpreted as "word";
line, you will notice a word
from the space character while it is over.
He is processing such a "formal" word.
that
About
the dictionary:
There are words in it, chained together with "indicators";
the chain begins with the last
word defined and the FORTH basic dictionary is drawn to the end.
There may be a name several times;
by referencing the name, we
call the "topmost", most recently defined word of such names.
We can expand it (we have only learned the definition of the colon), but
it can only be deleted with the word to be deleted all the definitions that
are defined afterwards (no one eye can be collected from the chain, the entire
upper end should be disconnected ).
From
the stack:
There are numbers, from which we always reach the one that was last
reached.
There
are two words that work with text: both (and. "
Both hold the text behind it to a
delimiter .
The delimiter must be in a
row with the word, and one
tends to forget about the space behind them, but do not.
The words learned:
: | (---) | Start a new word definition. |
; | (---) | The double-point word definition is over. |
FORGET | (---) | So we use: FORGET xxx where xxx is a word dictionary. This word will be deleted from the dictionary with the definitions that follow. FORTH basic word can not be deleted. |
VLIST | (---) | Lists the dictionary words on the screen. You can interrupt the list by pressing any key. |
( | (---) | Locks the string up to the closing parenthesis from the interpreter, and the text between the two brackets has no effect (can be used for documentation purposes). The opening and closing brackets must be in a row. |
EMIT | (c ---) | Prints the character corresponding to the code found in the vermin on the screen. |
SPACE | (---) | Writes a space on the screen. |
CR | (---) | A carriage return and a line up character on the screen. |
. " | (---) | Displays the following text on the screen for the closing "The word and the closing" should be in a row. |
. | (n ---) | Prints the number at the top of the stack and a space on the screen. He takes the number from the stake. |
+ | (n1n2 --- n3) | It gives the sum of the two upper elements to the worm. |
- | (n1n2 --- n3) | The n1-n2 gives a difference. |
* | (n1n2 --- n3) | It gives the product of the two top elements. |
/ | (n1n2 --- n3) | Returns the n1 / n2 quotient. |
DUP | (n --- nn) | Doubles the top element of the stack. |
SWAP | (n1 n2 --- n2 n1) | Replaces the two tops in the stack. |
DROP | (n ---) | Removes the top of the stack from the stack. |
OVER | (n1 n2 --- n1 n2 n1) | Make a copy of the second item at the top of the stack. |
ROT | (n1 n2 n3 --- n2 n3 n1) | He removes the third element of the stack from the bottom and throws it to the top. |
COLD | (---) | "Cold Start". The dictionary, the vermet, and many more things will be restored to the original state after loading. |
Words that have not been mentioned but are readily apparent to date:
MIN | (n1 n2 --- min) | It gives the smaller of the two elements. |
MAX | (n1 n2 --- max) | It gives the bigger of the two elements. |
MODE | (n1 n2 --- m) | Returns the remainder of n1 / n2 division. |
/MODE | (n1 n2 --- mh) | The remainder of the n1 / n2 division is also obtained. |
ABS | (n --- n1) | Returns the absolute value of n. |
MINUS | (n --- n1) | The result is -1 times. |
Examples
1.1 What does the interpreter answer to the following lines?
6 2 * 4 /.
Number displayed: 3
6 2 * 4 SWAP /.
The displayed number is 0
19 3 / MOD. .
Numbers appearing: 6 1
1.2. What is the stack for the following words?
: ALUL-DUP OVER SWAP;
: ALUL-DUP
OVER
SWAP
;
(xy)
(xyx)
(xxy)
: DUPLA-DUP OVER OVER;
: DUPLA-DUP
OVER
OVER
;
(xy)
(xyx)
(xy xy)
: 3CSERE ROT ROT SWAP;
: 3CSERE
ROT
ROT
SWAP
;
(xyz)
(yzx)
(zxy)
(zyx)
1.3 / a. Let us write a word having a vertex of y = 5x ^ 2 + 6x + 2
: A DUP DUP * 5 * SWAP 6 * + 2 +;
1.3 / b. Let us write a word with a vertex of y = 6x- (x ^ 2-1)
: B DUP DUP * 1 - SWAP 6 * SWAP -;
1.4. Write a word ** 5 that elevates the top of the stack to the fifth power. Thus, its curve effect is: (x --- x ^ 5)
an auxiliary word that raises the upper element of the stack to a square:: ** 2 DUP *;
using this:
: ** 5 DUP ** 2 ** 2 *;
2. Comparative and logical
operations
How do we compare two numbers in FORTH?
Of course, the first one is
placed on the stack (so since the first operands are given, the comparison
mode is also a postfix). Then
we call up a comparative operation.
These are: <,>, =.
It is important to keep it
in mind
the
order of the operands in the postfix script is the same as in the infix,
only the position of the operation signal varies.
|
THE
2 3 <
For example, a result of an action will be that <a true value is placed on the stack.
2.1.
The
flag
The flag in English is flag to indicate something true or false.
To illustrate these two options
in general, such as FORTH, we use numbers.
FORTH-in:
According
to the agreement, the flag is false if it is 0, and true if anything
else.
|
Comparative
operations provide "well-fed" flags with a value of 0 or 1.
Write a word that tells what the user in the keyboard is thinking about.
Reporting is done with a marker
on the stack. In the spirit
of the user, we have the following question: YES OR NO?
Now, wait until you press any key.
The vermin is given a true
value when the user pressed the large I letter.
To do this, we need to learn
the word that waits for one of the keys to be pressed on the keypad and puts
the key code on the stack. This
is the word a
KEY (--- code)
(The
English word KEY means several things, probably the "key" translation is
most likely.) After KEY everything stops until you press a key.
On the screen, we do not see
what we're typing (does not write it back than usual) except that the interpreter
sends OK. The character code
is in the stack - you can type the character with EMIT.
with your code.
It's a little more comfortable to see you.
what he writes.
Here is a program that, like
KEY, will press a key and put the correct code on the stack, and even type
the character on the screen:
: ECHO (--- code)
KEY DUP EMIT;
After that, the yes-no program (taking into account that code I is 73) is as follows:
: IVN
"Yes or No?"
ECHO
73 =
;
(the marker is
empty)
(the character on the stack)
(then the desired indicator)
2.2.
Data types seen so
far
Two known words:
. | (number ---) | prints the number found on the screen on the screen; |
EMIT | (code ---) | prints the character corresponding to the character code of the worm on the screen. |
Both
use one element from the stack.
An element of the stack is
a 16-bit machine word. (Machine
word: 16-digit, 2-digit - that is, binary number, otherwise a 16-element
series with 0 and 1 values). it
assumes a 16 bit preset number (we will see how to work with longer numbers)
and EMIT a character code that would otherwise fit 1 byte (8 bits).
EMIT simply ignores one of
the bytes of a machine word with 2 bytes!
For example, the bug is 42 (binary, since the stack has only machine numbers).
How do you know which "which"
is 42: a signed number, the * character code, or - we already know this is
possible - is a "true" flag?
In
FORTH, the type of data depends only on what kind of action is performed
on them.
|
Thus,
42 is a character code if EMIT is used and a signed number if a
.
.
For example, + considers the top two elements of the stack as a signed number.
If anyone still forgets the
character code that has been given to KEY, it's the one to take.
When describing the spin of the word, the letters indicating the elements
also indicate the type of elements.
The types seen so
far:
Thus we document the comparative operations:
< | (n1 n2 --- f) | the flag is true if n1 <n2; |
> | (n1 n2 --- f) | the signal is true if n1> n2; |
= | (n1 n2 --- f) | the signal is true if n1 = n2; |
2.3.
Why should a marker be
"well-educated"?
Write a word that tells you that the number found on the stack is between
0 and 9. The name of the word
should be 1 TICKET and its stack is: (n --- f).
We can now examine whether a number is smaller than 10 (it is a whole number,
it is the same as asking for a "no bigger than 9") and whether it is larger
than -1 . From the two indicators,
logical AND operation to see
if the two responses are true at one time.
Logical AND produces a third
of the two logical values: if the two values were true then the result
of the operation is true, otherwise it is false.
The AND operation between the
flags can be implemented with the AND FORTH key word.
(AND in Hungarian:
AND.)
Warning: AND performs the logical "and" operation with each bits of the binary
form of the two operands! If,
for example, the stack was
2 and 1, that is binary
0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 0
and
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1,
then the logical AND result
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0,
that is, 0 will be, since one of the bits of each other is always 0. Whatever is the 2, the 1 is also considered a true value, so AND should have given a true value according to our logic. We need to know about this discomfort (which is another comfort) but at this moment it is unnecessary to worry about it; comparative actions are "well-behaved" with 0 or 1 flags that can not cause the above half-turn.
: 1JEGY
DUP -1>
SWAP 10 <
AND
;
(n-f)
(n f1)
(f1 f2)
Another important operation is the logical OR, which also gives a third of the two logical values. The result will be true if at least one of the two logical values is true. So then and then we get false only if both operaridus were fake. Obviously this OR does not correspond to the Hungarian word OR word. We say in Hungarian:
"Or flame at the old, wild county house,
or here our souls are sitting, submerged"
and
that is to say that the two options exclude each other.
We call the OR or EO to be
distinguished from a negative OR compared to Hungarian OR.
The negative OR gives a true
result if one of the logical values obtained is true and the other is not.
OR, we usually call the permissive
OR if we think of the negative OR, let's say its name.
Accordingly, the two words
FORTH are OR (OR) and XOR (eXclusive OR, Exclude OR).
These also work on bit as the
AND, but it does not make any difference to the "well-raised" signals from
the comparative operations.
Let's look at the counter NEM-1JEGY (n --- f) counterparty 1, which gives
a real signal if the number obtained does not fall between 0 and 9 (i.e.,
less than 0 or greater than 9):
: NEM-1JEGY
DUP 0 <
SWAP 9>
OR
;
Of course, the NEM-1JEGY, which runs counter to 1JEGY, is easier to write than using 1JEGY. An action must be added (negation, complement) that changes the meaning of the signal on the vermouth: it makes 0 from the true signal and 1 from the false, ie 0 value. This word is not included in the standard FIG-FORTH 1.1. but there are many FORTHs, and it's not hard to write:
: NOT 0 =;
So the
: NO-1JEGY 1JEGY NOT;
will work the same as the other NEM-1EGY defined above.
2.4.
Quick
Steps
Most computers have the machine operating instructions quickly, something
to increase by 1 or multiply or distribute, examine the sign of Reduce, 2.
In comparison, the series that
1 + (put on the stack 1, call + word) is slow and cumbersome.
The so-called.
"quick operations" cut off
the unnecessary bends and, without any difficulty, start the right machine
instructions. Quick
Actions:
1+ | (n --- n1) | one increases its n value; |
1- | (n --- n1) | one decreases its n value; |
2+ | (n --- n1) | n doubled; |
2 / | (n --- n1) | n; |
0 = | (n --- f) | f is true if n = 0; |
0 < | (n --- f) | f is true if n <0. |
Obviously,
the words that execute quick operations look the same as the same step-by-step
commands, only one word for the operand with the operative sign;
the word 1 + does the same
thing as the 1 + series, only faster.
A faster version of NOT:
: NOT 0 =;
2.5.
How do we store our programs?
In our attempts so far, it is annoying that the texts of the programs do
not remain, can not be corrected or used again.
We can make the programs not directly handed over to the interpreter, but
to some media, so-called. we
write them in screens; can
be repaired or read at any time with the interpreter.
The screen in the screen means
a screen in the Hungarian, which we will call the abbreviated
shade.
The umbrella is the unit of storing text information.
In a window, there are as many
texts as you can handle at the same time;
this is 16 rows, in a row with
64 characters (that is, 1 sq. can store exactly 1 kbyte information).
All FORTHs are stored in their
own way. The standard FORTH
looks at a disk simply as a set of sectors that it allocates itself to the
clouds (mainly based on older implementations that presume a small disk
capacity). The fig-Forth so-called.
it uses file folders to allow
you to hold other files on the same disk (even multiple file
files).
When we started the FORTH interpreter so far, the "No file" message warned
that we did not select a file, so the interpreter can only be used in
"question-answer" mode. If
you want to load a file, you can do this when starting Forth by specifying
the name of the popup file as a parameter.
Ex .:
Z80FORTH SCREENS.FRT
Once
you have loaded the desired file, you can start editing our program, which
will of course require some kind of word processor.
The fact that the fig-FORTH
interpreter does not include a word editor (editors) is cited by computer
science. The editor of William
F. Ragsdale, attached to fig-FORTH, is also writing in FORTH, which must
be completed in the same way as any other program we wish to run.
Do not even dream about fullscreen
editing; the command line editor needs to be used in the beginning; later
it becomes quite useful. Its
use is described in detail
in the
appendix .
If we have constructed an umbrella, then a
LOAD (n ---)
so
we can pass it on to the interpreter.
The worm must enter the number
of the blind. As a result of
LOAD, it is exactly the same as typing the text on a given number of umbrellas.
If, as is usually the case,
there are definite definitions, the words defined in the dictionary appear
in the dictionary by loading, that is, LOAD.
If we want to load more successive umbrellas (for example, because our program
does not fit into a window), then
->
write the word to the end of the spectators. When loaded, this interpreting is stopped and the next begins to load. THE
S
the
interpreting of the interpreter is interrupted and the interpreter continues
where the LOAD was.
The interpreter almost does not have control over the keypad or receiver
at that particular moment. The
course stream interpreted by the interpreter, English-language literature
as input stream, translates this into an influence.
The text of an umbrella on a
LIST (n ---)
so we can add it to the screen.
By agreement, the top row of each screen contains some reference to the content of the screen. This is used by
INDEX (from to ---)
which
is not standard, but contains many FORTH basics (such as fig-FORTH) and
can be written by anyone after
reading
Chapter
13
(see task 13/2). INDEX lists
the top row of the number of the number of the two numbers that you entered,
giving you a table of contents about our umbrellas.
In the first place we have to mention that a
FLUSH (---)
so you can write the modified blocks to disk.
What was that about?
Summary
of Chapter 2
About
comparative operations:
The worm is waiting for their operands;
their order is the usual, only
the location of the <,>, = "operation marks" (postfix markup mode)
changes.
They make signs on the stack.
About
Flags:
True or False: 0 is false, the other is true.
They may be "well-educated"
- this means that the true flag is always worth 1. Comparative operations
provide such.
About
Types:
FORTH does not know what kind of data the stack is - this is the programmer's
business.
The types and their markings so far:
they all occupy one element in the verme (that is, a 16-bit word).
About
logic operations:
AND is true if both operands are true.
OR is false if both operands are false.
Exclude OR is true if one of the two operands is true and the other is false.
Negation: It's a false one and vice versa.
And
their FORTH implementation:
AND (AND) OR (OR) and XOR (negative OR) performs the corresponding logical
operation bitwise. so if they
are not applied to "well-raised" markers, they may lead you astray.
Negation can be accomplished by the word 0 =.
About
Quick
Actions
:
They are not a new operation, only a more time-consuming and more conservative
version of some of the special cases of the old.
About
the viewers:
Store text on a disc or tape.
You can load LOADs at any time, so the same happens as typing the text on
the screen. Editing programs
are used to write and maintain the umbrellas.
The words learned:
< | (n1 n2 --- f) | f is true if n1 <n2. |
> | (n1 n2 --- f) | f is true if n1> n2. |
= | (n1 n2 --- f) | f is true if n1 = n2. |
AND | (n1 n2 --- f) | Bitwise logical AND. |
GUARD | (n1 n2 --- f) | Bitwise Logical OR. |
XOR | (n1 n2 --- f) | Bitwise logical exclusion OR. |
1+ | (n --- n1) | n increases by 1. |
1- | (n --- n1) | n by 1. |
2 * | (n --- n1) | n by 2. |
2 / | (n --- n1) | n is divided by 2. |
0 = | (n --- n1) | f is true if n = 0. |
0 < | (n --- n1) | f is true if n <0. |
KEY | (--- c) | Expect to press a key on the keypad and enter a keypad corresponding to the key. |
LOAD | (n ---) | Load, "interpret" the specified number of umbrellas. |
-> | (---) | It comes from the interpretation of the given silhouette to the next. |
LIST | (n ---) | List a screen on the screen. |
S | (---) | Completing the interpretation of the shadow. |
Examples
2.1. Write a 3: 0? (n --- f), which gives a true sign if n is divisible by 3.
: 3: 0?
3 MOD
0 =
;
(n --- f)
(in the stack the remainder of the division)
(then "true" is the answer if it is 0)
2.2. We have a box with a length of 100 cm, a width of 65 cm, a height of 10 cm. Write a BELE? , which tells the worm that the length, width, and height of the given length fit into the box? The spin of the word is: (width width height --- f). f is true if the length is <100, width <65 and height <10.
: BELE?
10 <
ROT
100 <
AND
SWAP 65
AND
;
2.3. Write a word 7-E (n --- f) that gives true to the vermin if the last digit 7 in the decimal number of n is the number 7!
: 7-E (n --- f)
ABS (absolute value if negative)
10 MOD (last digit)
7 =
;
2.4. Write the words L-AND and L-OR (f1 f2 --- f), which do not perform the corresponding logical operations bitwise, but between the two flags. So, for example, 1 2 L-AND do not enter 0, but 1 (for two true tokens) 1. Both words are "well-fed".
A word by which we can make a marker "well-educated":: 1EL 0 = 0 =;
For both words, the top 2 elements of the stack should be "well-raised"
: L-AND 1EL SWAP 1EL AND;
: L-OR 1EL SWAP 1EL OR;
3. Conditional
Instructions
We already know how to get an indication of a true or false condition of
a condition. Now we learn how
to use the flags.
3.1.
The IF ...
ENDIF
Function of the IF ... ENDIF structure: the IF will emit the marker at the
top of the stack. If the flag
is true, the IF and ENDIF part will be executed if not, not.
Before we give an example,
let's quickly sketch it:
All
structures that contain control transmission (ie conditional and cycle-forming
commands) can only be used in definition.
|
Write a word that finds a number between 0 and 9 on the worm, and prints it to the screen: COPY. Of course, we use the word 1JEGY (n --- f) as defined in the previous chapter . The font of the new word: (n ---)
: ONE SIZE IF "one-note" ENDIF CR;
The
synonym for ENDIF is THEN.
Other high-level programming
languages make the THEN completely different;
before we let ourselves be
mixed up, it's best to remember: this is different, THEN here is ENDIF!
IF and ENDIF can not be used without each other.
3.2.
ELSE
If we do not only have to fulfill a given condition, but also in the opposite
case, how can we build our program:
IF (here is what to do if the flag is true);
ELSE (here is what to do if not)
ENDIF
For example:
: ONE
ONE "IF" ONE digit "
ELSE" is not a single "
ENDIF CR
;
Sometimes in the ELSE branch there is no other task than removing a duplicate copy of the marker. If you do not need to write an ELSE branch for that, there is a FORTH basic word that only doubles the upper element of the stack if it is not 0.
-DUP (n --- nn, if n <> 0) (n --- nm if n = 0)
3.3.
Nested
be higher, depending on the condition of work to do IF or ELSE branch.
For example, write an EVES-OR (n ---) program that is
answers. For example, the result of 3 EVES VOICES is CHILDREN.
: EVES I AM
DUP
10 <
IF
"child"
DROP
ELSE
20 <
IF "" adolescent "
ELSE" adult "
ENDIF
ENDIF
CR
;
(N ---)
(nn)
(n f 1)
(where n <10)
(work done)
(eyes but remains in the stack)
(n => 10)
(f2)
(if less than 20)
(where no )
Note that the "internal" IF structure is always entirely on the "outer" side. This is the key to which IF, ELSE and ENDIF belong in a FORTH text. If we see a program item like this:
IF A IF B ELSE C IF D ENDIF ENDIF ELSE AND ENDIF
then in order to get it right, look for the innermost IF and we already know that the ENDIFs will soon be his. (Similar to the second innermost IF.) Apparently, the second IF has an ELSE branch:
and the whole second IF is on the very branch of the first one. It is best to write such a series in a bit more detail; something more obvious is the same as the following:
IF
A
IF B
ELSE
C
IF D
ENDIF
ENDIF
ELSE
AND ENDIF
that is, if the IF, ELSE and ENDIF joins each other, they will be executed on the given branch a little bit further.
What was that about?
Summary
of Chapter 3
On
the IF ... ELSE ... ENDIF structure: Use
only in definition.
IF is the only one of the three words that will change the vermen (use a
marker).
ELSE may be omitted.
If the IF is a true marker on the vermin, IF and ELSE (if there is no ELSE,
IF and ENDIF) are executed, if false, then between ELSE and ENDIF (or, in
the absence of ELSE). Execution
in both cases continues after ENDIF.
ENDIF is synonymous with THEN.
These structures can be embedded in any depth.
Even
from a stacker word about -DUP:
If the worm
is 0, it does not do anything,
otherwise it is the same as the DUP.
Examples
3.1. Write a word SN (n1 --- n2) that gives -1 on the vermin if n1 is negative, + 1 if positive and zero if null.
: SN
DUP
IF
DUP ABS /
ENDIF
;
(n1 n2)
(n1 n1)
(if n1 <> 0)
(dividing the number with its own absolute value)
(if n1 was 0, then 0 is in the worm)
3.2. Write a SZOVEGEL (n ---) word that specifies any of the following messages, depending on the value of n: NULL, ONE, MINUS, KETTO, MUST, ONE.
: Text
DUP
IF
DUP
ABS 2>
IF "OTHER" DROP.
ELSE
DUP
0 <IF "minus" ENDIF.
ABS
1 = IF "a."
ELSE "two".
ENDIF
ENDIF
ELSE "zero" DROP.
ENDIF
SPACE
;
3.3. Write an ALPHA (---) word that waits for a character from the keyboard and
The numbers in the numbers are 48 and 57 in capital letters between 65 and 90.
We have to examine twice whether our character is between something and something else. A serious FORTH programmer does not write anything twice, rather write a word.: ELEMENT
ROT SWAP OVER
<ROT ROT
>
OR 0 =
;So it's easy (we also use the word ECHO that was previously made):
: ALPHA
ECHO CR
DUP 48 57 ELEMENTS
IF "DROP
ELSE 65 90 ELEMENTS
IF" grandma "
ENDIF
ENDIF CR
;
3.4. Let's say, which decides from the year that the leap year is? Leap years are: all four are divisible by year, with the exception of one hundred. Leap years, however, are 400 years old. That is, from the turn of the century, only leap years, which can be divided by 400. For the simplest solution, we use the word EXIT as described in 5.1. We'll get to know this chapter .
: LEAP-YEAR? (Ev --- f) (leap year?)
DUP 400 MOD = 0 EXIT ENDIF IF 1 DROP
DUP 100 MOD = 0 EXIT ENDIF IF DROP 0
4 MOD = 0
;
Let's try to interpret the next, more concise solution:
: LEAP-YEAR? (ev --- f) (SPEED)
DUP 4 MOD 0 =
OVER 16 MOD 0 =
ROT 25 MOD 0 =
NOT OR AND
;
3.5. Using the lessons learned so far, we can now calculate with Christian Zeller's algorithm that the given date is the seven-day day.
: WEEKDAY (day
1 to 2 ) (1 week, 2 days, ..., 7 days)
OVER 3 <IF
1 SWAP 12 + SWAP
ENDIF
100 / MOD
DUP 4 / SWAP 2 * -
SWAP DUP 4 / + +
SWAP 1+ 13 5 * / + +
2- 7 MOD 1+
;
Using the word WEEKDAY, you can say the day of the week on either day:
24 12 2000 WEEKDAY.
4.1.
The return
stack
The FORTH interpreter uses two holes.
One is already known: this
is a computation stack or datum, which we mean when we are talking about
a stack. The other one is mainly
used by the interpreter itself, most often to note it: to run a word (jump
to the appropriate address, execute the code found there) after returning.
It is therefore called a return
stack, briefly called virem.
Our vibration programs can be used to temporarily store stack items when
you keep in mind
the
elements of the vire for each word (which does not deliberately and slyly
use the virus to modify the control) should be left in the same way as found;
the state of the vibe may change
only within one word.
|
The word handling words (here as well, like everywhere, we document the stack of stakes for the calculation stack):
> R | (n ---) | moves the top of the stack to the vire. |
R> | (--- n) | the top element of the wine is moved to the stack. |
R | (--- n) | Copies the top element of the wine into the stack; the vial remains unchanged. |
A task that's good for you: Write the largest of the top 4 of the stack on the screen! The stack is ultimately unchanged.
: .MAX
DUP> R
OVER MAX
SWAP> R
> OVER R>
MAX
OVER MAX
. R> R>
;
(n1 n2 n3 n4)
(a viremen: n4)
(m1 m2 m3 max3,4)
(a viremen: n4 n3)
(n1 n2 n1 max3,4)
(n1 n2 max1,3,4 )
(n1 n2 max)
(n1 n2 n3 n4)
4.2.
Staging One
by
One DO ... LOOP is another structure that can only be used in word definition.
Cycle organization;
to repeat the program part
(cycle core) between DO and LOOP.
For example, write 10 times: DO NOT ENABLE.
: HAZI-FEL 10 0 DO CR. "No time to waste" LOOP;
The DO ... LOOP so called. indexed cycle. This means there is a cycle index somewhere - a cindex or cycle counter that counts how many times the cycle nucleus is performed. The starting value of the cindex and the end value called the index limit are given to DO. The DO of the DO: (index limit start value ---). DO does these two values for virem. During the run of the cycle core, the virgin is at the top of the cindex current value, and below it the cycle limit. So, if you want to use the cindex in the cycle core, you can simply pull it out of the vire:
: ABC
CR
. "The ASCII code for the big bet:"
91 65
DO CR
R
DUP EMIT
SPACE
.
LOOP CR
;
(
cycle)
(cycle)
(we put the cindex)
(the current value)
(we write the character)
(followed by a space)
(and then the code itself)
(end of the cycle)
At the first run of the loop core, the cindex value is the given starting value (in our example, 65, the letter A). The LOOP will always increase the cindex one by one and see if it has not reached the cycle limit. When it is reached, the cycle is completed (it clears the two upper values). so that the cycle core lasts when the cindex is less than the index limit. The last letter of the alphabet is ABC, the code of which is 90.
4.3.
With
IFs
The ABC code table would be nice to fit the screen if not just a code, but
10, say, in a row. How can
you only get CR in the loop core when you have already written 10 items?
We will investigate whether
the cindex 10 is divided into 5 residues.
This will be true for the first
time (if the start value is 65) and then for each tenth round.
: ABC
CR. "The ASCII code for the big bet:"
91 65 DO
R 10 MOD 5 =
IF CR ENDIF
R DUP EMIT SPACE. 2 SPACES
LOOP
CR
;
We know that some of the FORTH basic words are written in FORTH, using the words "more basic". This is SPACES (n ---), which writes a number of spaces on the screen. SPACES is essentially a SPACE for DO ... LOOP.
: SPACE
0 MAX
-DUP
IF
0 DO SPACE LOOP
ENDIF
;
(n ---)
(so that the starting value can not be)
(greater than the cycle limit)
(should not be done 0 times?)
(if n is not 0)
Prior to implementation, it is necessary to examine whether there is zero on the vermin because the DO. It follows from the operation of LOOP that
The
DO ... LOOP cycle core will always be executed at least once before the LOOP
conducts the first test.
|
4.4.
Cycles inside each
other
Write a multiplication table!
The board will have 10 rows
and 10 columns. For example,
in the 3rd place in row 3, write the result of 3 x 4
multiplication.
The . it is not suitable for writing a table because it has multiple long and one-digit numbers for a long time. THE
. R (nm ---)
literally n numbers in a width width box, right-aligned (space for spaces to enter the number of characters you are typing). The elements of our table are maximum 3 digits, so if 4. Write them out with R, each with two spaces (except 100), will not "stick together".
Version 1: The nth row of the table is constructed so that 1, 2,. . . , Multiply 10 numbers by n and write the products:
: 1SOR
CR 11 1 DO
R
OVER *
4 .R
LOOP
DROP
;
(--- n)
(n)
(n cindex)
(to burn product)
(notice)
(leaving no garbage)
The table itself is enough to repeat 1SOR with numbers 1, ... 10:
:
TABLE 11 1 DO R 1SOR LOOP CR;
Version 2: Resolve the same in a word with nested DO ... LOOP cycles! (In the example, the cycle boundary is chatted with the outside with k and the inside with b.)
: TABLA
11 1 DO CR
11 1 DO
R> R> R
ROT ROT
> R> R
R * 4 .R
LOOP
LOOP CR
;
(A Virma: chat k cindex's)
(elõássuk cindex-kt the viremrõl)
(the stack: cindex-b chat b cindex b)
(the stack: cindex's cindex-b chat b)
(downgraded to virmet)
(we print the product)
Version 3: The same solution, so that we can take the external cindy in time:
: TABLE
11 1 DO
CR R
11 1 DO
R
OVER *
4 .R
LOOP
DROP
LOOP CR
;
(here is only the outer cycle)
(things are in the virgin)
(cinder-binds)
(cindexs-b)
(beginners tend to spoil it)
(to compress them and to do)
(the cycle core would run second )
(cindexs are lost)
(cindexs do not have to)
In many FORTH, the cindex is I, the outer cindex (the third element of the stack) is J, the even more external cindex (the fifth element of the stack) with K. The stack of all three words (--- n). If I and J are in our FORTH, we can write the TABLA program more easily. In the fig-Forth dictionary, there is only the word I, the pair of the word J is missing, but this is only temporary in the next paragraph of our book so let's look at this solution too!
Version 4: Using the words I and J:
: TABLE
11 1 DO
CR 11 1 DO
IJ *
4 .R
LOOP
LOOP CR
;
4.5.
What is easy to
ruin
Let's see how word I works, and write the missing word J in the fig-Forth
dictionary! With I, we seem
to have a simple task, as doing nothing more than the R word: copy the top
of the vire into the stack. And
yet, the obvious
: IR;
definition is not good for this. When the word I enters the interpreter, it puts the address to which I will return. In addition to the definition of the former I, we would get this title on the vermin instead of the cindex. A good solution puts the second element of wine on the stack:
: I R> R SWAP> R;
Likewise, in the J word, we have to move the third rather than the third element of the vi:
: J
R> R> R> R
SWAP> R
SWAP> R
SWAP> R
;(
stack: vc n2 n1 n)
(stack: vc n2 n)
(stack: vc n)
(stack: n)
(Viread n)
(Viread n n1)
(Viread: n1 n n2)
(Viread n n1 n2 vc)
Anyone tempted not to write the SWAP R> series three times, but to write a word or a cycle, but try - just be careful not to call the new word or the start of the cycle any longer over the viremes!
4.6.
Get out of the
cycle
of a DO ... LOOP cycle can be interrupted at any time so that cindexet and
limit cycles in the Virma "összeigazítjuk".
That's what LEAVE does.
With LEAVE, the nearest LOOP
will find that the cycle must be completed.
For example, write a word BETU (--- n) that waits for characters up to ENTER
(ENTER code 13), but no more than 20 characters.
BETU returns the number of
characters received, except for spaces.
The characters are compressed
and compared in a DO ... LOOP cycle.
During the cycle, there will
be a count on the vermin, giving 1 for each "real" character.
Alphabet
0
20 0 DO
KEY EMIT DUP
DUP 13 =
IF LEAVE
DROP
ELSE
32 -
IF 1+
ENDIF
ENDIF
LOOP
;
(if
this is the counter)
(counter)
(if it was ENTER, the nearest one)
(LOOP)
(was a space?)
(if not, increase the counter)
4.7.
A Different
Walkthrough
Agatha Christie's short abstract of a novel:
10 small indians
9 small indians
small indians
7 small indians
6 small indians
5 small indians
4 small indians
3 small indians
2 small indians
1 small indians
0 small indians
How can this be printed on the screen?
: MONTH
11 0 DO
10 R -
CR 4. R 2 SPACES "small indian"
LOOP CR
;
The same goes even easier if the cindex is not moved by 1, but by -1. This is the DO ... + LOOP structure. The + LOOP from the LOOP differs from that
The above program can be written using DO ... + LOOP as follows:
: MONTH
CR 0 10 DO
R
CR 4. R 2 SPACES "small indian"
-1 + LOOP
CR
;
With the word + LOOP, you can of course walk with any step.
: MESE2
CR 42 2 DO
R DUP
CR 3 .R SPACE "man"
2/3 .R SPACE. "Par"
2 + LOOP
CR
;
What was that about?
Summary
of Chapter 4
From
the return stack, that is, from the vibe:
This will return the interpreter if he skips a word to be executed.
So when a word is over, the vire must be ok.
Viruses are considered to be DO ... LOOP and DO ... + LOOP cycles of the
cindex and the cycle boundary.
When handling vira, you should also pay attention to adding a word to a new
item.
DO
... LOOP, DO ... + LOOP cycles:
Both indexed cycles: a cyclic counter (cycle index, cindex) monitors how
many cycles have run down.
Cindex is a virgin, it can be accessed at any time.
The DO gives the start value of the cycle limit (cindex end value) and the
cindex initial value for the worm.
The LOOP increases the cindex one by one (leaving the vermet in peace), +
adds LOOP an as the worm is given.
You can get out of the loops with the LEAVE word out of the way;
LEAVE aligns the cindex and
the cycle boundary with the viruses so that the nearest LOOP or LOOP will
"feel" that the cycle is over.
DO
... LOOP, DO ... + LOOP, IF ... ELSE ... ENDIF
structures:
Optionally, I can nested.
They can only be used in word definition.
The same is true of the other structures we are still learning.
The words learned:
> R | (n ---) | The top element of the stack is placed on the vire. |
R> | (--- n) | It puts the top element of the wine on the stack. |
R | (--- n) | The top element of the wine is copied to the stack, the vial remains unchanged. |
DO | (n1 n2 ---) | The beginning of the index cycle. n1 is the cycle limit, n2 is the starting value. Use with LOOP or + LOOP. |
LOOP | (---) | End of the cycle of the index cycle. Increases the cindex by one and verifies whether you have reached the cycle limit. If not, he will go back to DO. If so, he gets out of the cycle. |
LOOP + | (n ---) | End of the cycle of the index cycle. For cindex, it gives n and looks for greater (if n> 0) or less (if n <0) than the cycle limit. If not, he will go back to DO. If so, he gets out of the cycle. |
I | (--- n) | DO ... is used for loop cycles. Copy cindex to stack. |
LEAVE | (---) | DO cycle. Corrects the cindex and the cycle boundary to the viruses; this closest LOOP desire + LOOP gets out of the cycle. |
SPACES | (n ---) | n writes space on the screen. |
.R | (nm ---) | n is written in a m width field right aligned. |
Examples
4.1. Write a word TEGLA (nm ---), which writes m. Each of them must be n stars!
: TABLE
0 DO
DUP
CR
0 TO
42 EMIT
LOOP
LOOP
DROP CR
;
(nm ---)
(m line is written)
(n will be needed for every line)
(a n is to be executed)
(the star is written in a cycle)
4.2. Write a "normal" ASCII code table:
The elements are written in 7 columns, the sequential elements are under one another. The first code to be displayed is 32, the last is 126.
: KODOK
14 0 DO
CR R
7 0 DO
32
OVER +
R 14 * +
DUP 127 <IF
DUP 3 .R
SPACE EMIT
3 SPACE
ELSE DROP
ENDIF
LOOP
DROP
LOOP CR
;
(Will be 14 lines)
(TARUN Which row)
(item 7 in a row)
(initial element of the table)
(the first element of the row)
(actual element of the row)
(greater than 126)
(codes not described in)
4.3. Factorial computation: n! = 1 * 2 * 3 *. * n. Write a factorial count F (n --- n!). If a number smaller than 1 is received in the worm, 0 is returned.
: F
DUP 0> IF
1
SWAP 1+
1 DO
R *
LOOP
ELSE DROP 0
ENDIF
;
(n --- n!)
(this will be the series)
(vermen 1 and n + 1)
(the product is the product)
4.4.
The
so-called. Elements of a Fibonacci
Line: 1, 2, 3, 5, 8, ...,
From the third element, each element is the sum of the previous two.
Write a word FIB (n1 --- n2)
that puts the n1th element of the Fibonacci line on the stack!
It is assumed that the number
of vermin is not less than 1.
Try FIB to get the first 16
elements of the line.
: FIB (n1 --- n2)
DUP 3 <IF (if n1 = 1 or 2 then)
(the desired result is equal to n1)
ELSE
1 2 ROT 2 DO
SWAP OVER +
LOOP
SWAP DROP
ENDIF
;: FIBTEST CR 16 0 DO R FIB 5 .R LOOP CR;
4.5.
Write
a PRIM? (n --- f), which gives
a true value if n is the prime number, ie, dc and itself no divisor.
+1, -1 is not a prime.
Write the prime numbers between 1 and 2000.
: PRIM?
ABS
DUP 2> IF
1
OVER 2 / 2+ 2 DO
OVER R
MOD 0 =
IF 0 = LEFT
ENDIF
LOOP
SWAP DROP
ELSE 2 =
ENDIF
;: PRIMTEST
CR 2000 1 DO
I PRIM? IF
I 5 .R
ENDIF
LOOP CR
;
(n-f)
(we do not deal separately)
(with negative numbers)
(if R divisor, rebound)
(the flag)
(unexamined cases)
(only 2 prim)
4.7. Display the first 13 lines of the Pacal triangle. (The Pascal triangle in mathematics is the arrangement of binomial coefficients in triangular form.)
: PASCTRIANGLE (n ---)
CR DUP 0
DO
1 OVER 1- I - 2 *
SPACES
I 1+ 0
DO
DUP 4 .R
JI
- * I 1+ /
LOOP
CR DROP
LOOP
DROP
;
13 PASCTRIANGLE
5.1.
The endless cycle (BEGIN ...
AGAIN)
With BEGIN ... AGAIN you can repeat the
cycle
nuclei BEGIN and AGAIN
indefinitely. In such a BEGIN
... AGAIN cycle, the FORTH interpreter itself runs the FORTH language, the
source of which we will get acquainted with.
(Something like this: BEGIN
Read a line, do it! AGAIN.)
The endless cycle can also be ended.
Let's look at how the following
word works:
: EXIT R> DROP;
for example when it is used:
: BETUK (---)
BEGIN
KEY DUP EMIT
13 = IF CR EXIT ENDIF
AGAIN
;
When
the word BETUK starts to execute, the title on the top of the vibe is where
the interpreter continues to run after the BETUK has been executed.
When you enter EXIT, the address
of the return from EXIT (to BETUK) is at the top of it, but you will not
sit there for a long time because the act of EXIT is just about to drop you
from there. EXIT does not return
to BETUK, but the place where BETUK should be, that is, the word BETUK, so
it can force completion of a word.
EXIT is a basic word in many FORTH versions, but not FIG-FORTH
1.1.
5.2.
Departure at end of cycle (BEGIN
... UNTIL)
BEGIN ... UNTIL repeats the cycle nucleus between two words;
after each run of the cycle
core, UNTIL will eat a marker from the stack, deciding whether to go back
to BEGIN or go on.
UNTIL
(f ---) will continue the cycle if you find a false flag.
|
For example, write prime numbers smaller than 200. We use the 4.7. task PRIM? (n --- f), which tells us whether the number in the vermin is prime.
: PRIMEK
CR 2
BEGIN
DUP 5 .R
BEGIN
1+ DUP PRIM?
UNTIL
DUP 199>
UNTIL
DROP
;
(first prime number)
(print)
(we are looking for further)
(if prime, exit)
(if it is too big)
(exit)
(throw away trash)
5.3.
Outbound in the middle of the
cycle (BEGIN ... WHILE ... REPEAT)
WHILE (f ---) checks the end of the cycle for a stack.
WHILE
(f ---) will continue the cycle if you find a true marker.
|
For the true signal, WHILE will translate the program: the WHILE and REPEAT part of the program will be executed and REPEAT will return to BEGIN (unconditionally). If WHILE finds a false flag, the program continues with REPEAT words. For example:
: TURELMES
BEGIN
CR. "Spray Spenoth (I or N)"KEY DUP EMIT
73 -
WHILE(the answer to the bug)
(code I?)(here we get if I did not have a letter I)
CR. "Incorrect answer, try again!"
(the control goes back to BEGIN)REPEAT (here we get if I was a letter)
CR: "I'm really kidding!" CR
;
What was that about?
Summary
of Chapter 5
The words learned:
BEGIN | (---) | Selects the start of a cycle. Use BEGIN ... UNTIL, BEGIN ... WHILE ... REPEAT and BEGIN ... AGAIN |
AGAIN | (---) | Returns BEGIN without a condition. |
UNTIL | (f ---) | If you receive a false flag, you will return to BEGIN, if not, the program will walk away from the cycle. |
WHILE | (f ---) | If you receive a true signal, the program goes down to REPEAT, then goes back to BEGIN unconditionally. If not, the program will exit REPEAT from the cycle. |
REPEAT | (---) | Returns BEGIN without a condition. |
EXIT | (---) | Returning from one word to the word he calls. |
Structures (IF, Indexed and Indexed Cycles) can be embedded at any depth. Matching the keywords correctly is controlled by the interpreter and does not translate the word if something is wrong.
Examples
5.1. What's the difference between the TURELMES word in chapter 5 and the next version?
: TURELMES
BEGIN
CR. "Spray Spanning? (I or N)"
KEY DUP EMIT
73 = IF EXIT ENDIF
CR. "Incorrectly, try again!"
AGAIN
CR. "That's right!" CR
;We also used EXIT as defined in Chapter 5 on this topic . The cycle here remains with the letter I. But EXIT will not only get out of the loop but also from the word itself: the revelatory post after AGAIN will not appear.
5.2. Write a LOG2 (n1 --- n2) word. If n1 is positive, n2 is a number for which 2 ^ n2 <= n1. If not, n2 be 0.
: LOG2
0 MAX DUP
IF
0> R
1
BEGIN
2 *
R> 1+> R
OVER OVER <
UNTIL
DROP
DROP
R>
1-
ENDIF
;
(n1 --- n2)
(if a positive number is obtained)
(the exponent is generated in
virem ) (the current power will be released ) (vermen
n1 and power)
(next power)
(next exponent)
("exaggerated" n1- et?)
(if so, the end of the cycle)
(not in the power of need)
(n1 not be)
(this is the first exponent from whom)
( "outgrown" the last good)
(if we did not get a positive number)
(the 0 in the grove is just fine)
6.1.
Signal and unsigned
values
Let the interpreter enter the following command line:
65535.
The
answer is: -1
And we did not put -1 on the stack.
Or is it?
On the 65535 16 bits:
1111 1111 1111 1111
The . the number found in the vermine is considered to be signed, ie the first bit is a sign bit, and if it is 1 then the number is negative. Negative numbers are used to represent the sum of the two binary series representing the number and its opposite. This takes 16 bits so that the sum of the numbers -1 and 1 is 2 ^ 16, i.e.,
1 0000 0000 0000 0000
(the high-ranking 1 is already out of sixteen bits, the 0 tickets remain). And really:
1111 1111 1111 1111+ 1 1 0000 0000 0000 0000
or to stay at the more homely tithing number system:
65535 + 1 = 65536 = 2 ^ 16
We can play the same thing backwards; we need to know the word that considers the number at the top of the stack as unsigned, and so write it out.
U. (u ---)
U
is the abbreviation for the "unsigned" word in the name of the word and in
the mark of the stack.
THE
-2 U.
the answer to the command line is 65534. (As 2 is added to 65534 for 2 ^ 16).
6.2.
What about too many numbers?
We can see that 16 bits of 2 ^ 16-1 = 65535 can not exist.
The first digits of the higher
values simply "leak" and are lost.
THE
65536.
response
to the command prompt: 0. (Binary representation: 1 0000 0000 0000 0000).
THE
35537.
response
to the command prompt: 1. (binary representation: 1 0000 0000 0000 0001)
Similarly,
35537 30000 +.
1 is the response. FORTH does not handle overflow, we have to pay attention to ourselves.
6.3.
Duplications
If a number does not fit in one word, it can be represented in two, that
is, in a 32-bit duplicate.
The
duplicate word is located in the worm, with its higher-value word (the "front")
above.
|
So, for example, the
1 0
we put a 1 doubled word in the stack. About this
D. (d ---)
can be verified; it prints the double word on the screen that consists of two top elements of the stack:
1 0 D. (the answer is 1)
-1 -1 D. (the answer is -1)
-1 0 D. (the answer is 65535)
The dictated duplicates are shown binary in the figure below.
In
the name of D. and in the case of the bump effect, the word doubleword is
an abbreviation for the English word, although it could even be the Hungarian
"double word" version.
It can also be foolish to double the dice in the stack.
In fact:
the
numbers that have a decimal point are translated by the interpreter into
a duplicate.
|
For example:
100. D.
10.0 D.
10 D.
431567 D.
We see that
the
doubling value on the stack is not affected by the location of the decimal
point.
|
We
will be able to determine where the decimal point was (11.2).
Double words can be either signatory or unsigned as words.
Marking the unsigned double
word in the description of the stack effect: ud.
In
the description of the dowel effect, a doubling clause, i.e., represents
two elements.
|
At the end of this chapter are the words of double word and mixed arithmetic, here we only mention that a few one-word operations have the duplicate equivalent, which is missing from the fig-forth vocabulary, in the examples we make some.
one word: double word: . D. + D + ABS DABS MINUS DMINUS DUP 2DUP .R DR
6.4.
A disguised duplicate action
Combines the
splitting and division with the following word:
* / (n1 n2 n3 --- n4)
where n4 = (n1 * n2) / n3. The product n1 * n2 is stored in * / doubled, so that multiplication does not result in overflow. It does the same thing
* / MOD (n1 n2 n3 --- residual ratio)
even if we get the dividing quotient.
What was that about?
Summary
of Chapter 6
Words for unsigned, double-word and unsigned double-word values:
U. | (u ---) | Prints the unsigned value found on the screen on the screen, followed by a space. |
U * | (u1 u2 --- ud) | Adds unsigned values on the vermin; double-word, unsigned product. |
U / | (u1 u2 --- u2 u3) | Defines a tuple word with a single value, the returned u2 is the remainder of the division, u3 is the quotient. All values are unsigned. |
U < | (u1 u2 --- f) | Compare unsigned values. f is true if u1 <u2. |
D. | (d ---) | He prints the double word found on the vermin and then a space. |
DR | (dn ---) | Write the double word found in the vermin in a n width field. |
D + | (d1 d2 --- d) | Duplicate words (double-blind). |
DABS | (d --- d1) | Defines the absolute value of a double word. |
DMINUS | (d --- -d) | Deny a double word. |
M * | (n1 n2 --- d) | Multiplies multiple words, giving a double result. |
M / | (d n1 --- n2 n3) | It shares a double word with a single word value; the returned n2 is the remainder of the division, n3 is the quotient. All values are signed. (U / Signed Version.) |
M / MOD | (ud1 u2 --- u3 ud4) | It shares a double word with a single word value; ud4 is the duplicate ratio, u3 is the remainder of the division. |
Symbols in the description of the stack effect:
The latter two mark two elements in the vermin.
Examples
6.1. Write the duplicate version of the stack handling operations:
2DROP (n1 n2 ---) or (d ---) : 2DROP DROP DROP;
2SWAP (n1 n2 n3 n4 --- n3 n4 n1 n2) or (d1 d2 --- d2 d1)
: 2SWAP (n1 n2 n3 n4 n3 n4 --- n1 n2)
> R (n1 n2 n3)
ROT (n1 n2 n3)
ROT (n1 n2 n3)
R> (n1 n2 n3 n4)
ROT (n2 n3 n4 n1)
ROT (n3 n4 n1 n2)
;2OVER (d1 d2 --- d1 d2 d1)
: 2OVER (d1 --- d2 d1 d2 d1)
> R> R (d1)
2DUP (d1 d1)
R> R> (d1 d1 d2)
2SWAP (d1 d2 d1)
;2ROT (d1 d2 d3 --- d2 d3 d1)
: 2ROT (d1 d2 d3 --- d2 d3 d1)
> R> R (d1 d2)
2SWAP (d2 d1)
R> R> (d2 d1 d3)
2SWAP (d2 d3 d1)
;
6.2. Write more duplicate actions using existing ones.
D- (d1 d2 --- d-coefficient): D- DMINUS D +;
D = (d1 d2 --- f), f is true if d1 = d2
: D = DMINUS 0 = SWAP 0 = AND;
or, taking advantage of the OR to give zero only if both operands were 0:
: D = DMINUS OR 0 =;
D < (d1 d2 --- f), f is true if d1 <d2
: D- 0 <SWAP DROP;
Here, let us use the double-word difference to be negative if the sign word 1 is in the upper word, so we can ask this 0 <.
7.1.
Byte
Operations
The computer memory is a sequence of bytes numbered and numbered by them.
The words of the FORTH memory
manager make these bytes freely readable and overwritable, regardless of
whether they are in the middle of the interpreter code, in the stack, or
in a somewhat "gentler" place.
The programmer's job is not
to get in the wrong places. A
good address for skinning, where you can store data temporarily:
pad (pronounced ped).
The pad means a notepad, a
block. The address of the pad
is a
PAD (--- title)
word
provides.
Caution! The pad is above the
dictionary area, at a constant distance from the top of the dictionary (byte
from the last word defined).
Therefore, when new words are
defined or forgotten, the pad position changes.
It is best to use the data
in the pad in the same word that we put it into.
For permanent data retention,
the variables are provided, which
will be discussed in
Chapter
8
.
Words for memory bytes:
C @ | (title --- c) | specify the contents of the byte stored in the title; |
C! | (c title ---) | ac stores the bytes on the title (the contents of the previous byte are lost). |
In
the description of the stack effect, the title means a memory address;
type is a one-word, unsigned
value.
Write a word that waits for characters from the keyboard, right up to ENTER,
and after ENTER, rewrite the resulting string.
The backspace character (whose
code is 8) responds by deleting the last scanned character.
We keep the characters in the
pad while we are writing.
: BACK
PAD
BEGIN
KEY DUP 13 -
WHILE
(
will be the first character)
(vermen is the next character's title)
(it will be false if it was ENTER)(here we get if you have not already ENTER) DUP 8 =
IF DROP
DUP
PAD -
IF 1 ENDIF
ELSE
OVER C!
1 +
ENDIF
REPEAT
(
we do not want to delete more)
(how much is there?)
(if not)
(store the code)
(the next code one after the other)
(we will have to store it)(here comes the effect of ENTER)
(the address code of the vermen)DROP PAD
DO RC @
EMIT LOOP
;(the first character to be entered)
Typing the characters could also be done with the TYPE key word. TYPE, along with other basic words that handle byte series, can be found in the glossary at the end of this chapter. A convenient way to scan character sequences is
EXPECT (max limit ---)
a word that drops the characters scanned from the keyboard from the specified address to the memory. Scanning characters will take up to the first carriageway or the "max" character scans. By the end of the series, binary zeros are stored in the memory. The backspace character deletes the last character in the series.
7.2.
Voice and Dual
Operations
Memory is not only 8-bit, that is, bytes, but also words and doubles.
The words used are:
@ | (cim --- content) | the 2 bytes on the title and the following address, that is, the word on the stack; |
! | (n title ---) | stores the n 16 bit value on the address and the next byte (the previous contents of 2 bytes will be lost); |
2 @ | (title --- d content) | it puts a double word on the title and the next 3 bytes. |
2! | (title d ---) | the DWORD is stored on the title and the next 3 bytes (the previous contents of 4 bytes will be lost). |
So the
0 PAD 2!
the bytes on the PAD, PAD + 1, PAD + 2 and PAD + 3 addresses are reset.
7.3.
Convenient
Stack
Management With the words handling memory, you can "go out of the way" to
the stack as it is ultimately just a memory space.
All you have to do is know
what titles the stack is about.
The
SP @ (--- title)
refers
to the title of the top of the stack (before the execution of SP @), that
is, if the stack is not empty, the title of the top element.
So if the stack is not empty then that
SP @ @
series is equivalent to a DUP operation. If we experiment with a bit with the SP8 and SP @, we soon realize that SP @ gives a smaller title, the more elements in the stack.
The
stack is "down" in the opposite direction to the memory
address.
|
The address of the stack of the stack, the address given by SP @ in an empty stack, FORTH keeps a permanent address; the latter address is placed on the stack by the word S0. The bottom of the stack is therefore
S0 @
. (See the following figure.)
Now we can write the 1.6. stage , non-standard management stack in words (DEPTH, .STACK, PICK and ROLL). You should read the source texts of those who like to learn from other programs; none of the novelties are provided.
: DEPTH
SP @
S0 @
- MINUS
2 /
;
(--- stack depth)
(on the top)
(the bottom)
(that's bytes pt include elements of the stack)
(so many items available)
: STACK (---)
SP @ S0 @ =
IF
CR. "Stack is empty"
ELSE
SP @ S0 @ SWAP (from top to bottom)
DO CR R @ 5 .R 2 + LOOP
ENDIF CR
;
Before we write the words PICK and ROLL, let's wonder: what do we do if someone wants to look too deep in the bottom of the stack? What if someone wants to get the third of the two elements of the stack? Assume that this can only be a programming mistake and protect the programmer from the consequences of his mistake, so stop everything! That's right
QUIT
weave.
Quit interrupts almost everything
at all levels and returns the control to the external interpreter, which
starts to wait for a new command line.
Quit with QUIT is not followed
by OK.
The text of PICK can be followed without much explanation.
: PICK (n --- n1)
DEPTH 1- (with no nullity)
OVER <
IF (if the stack has fewer than n elements)
"PICK error" QUIT
ELSE
SP @
SWAP 2 * (2 * n)
+ @
ENDIF
;
The stack when PICK is started:
The n ROLL (n now refers to the number on the stack) first copies a n-th top element to the top of the stack with a PICK, which is to be "thrown" and then sums up the "old" n- n-1, n-1 to n-2, and so on. Finally, from n-1, all elements are "slid down", and at the top two copies of the n-eds; the excess top is discarded.
: ROLL
DUP> R
PICK
(copy "one copy")
(copy element n to the roof)(Copied in DO ... LOOP cycle) SP @
DUP 2+
SWAP R> 2 * +
DO
R 2- @
R!
-2 + LOOP
DROP
;(the title of
the original item)
(the title of the original item)
(copy the item to be
copied
)
(duplicate) (discard the item n. unnecessary) (copy)
What was that about?
Summary
of Chapter 7
The words taught in Chapter 7:
@ | (title --- n) | The 16-bit content of the title. |
! | (n title ---) | Store n by 2 bytes from the title. |
C @ | (title c ---) | It gives the title 8-bit content. |
C! | (c title ---) | Store in the byte on the address ct. |
PAD | ( --- title ) |
The
address of the memory space for temporary storage.
This title changes when changing
the size of the dictionary (new words are defined, "forgot",
etc.)
|
QUIT | (----) |
Interrupt
the program run. QUIT causes
the interpreting of the interpreter to be interrupted, and the interpreter
waits for a new command line.
|
EXPECT | (max title ---) |
Scan
text from the keyboard to the address.
The last character you entered
can be deleted with the delete character.
Scan to the first carriage
return character or to the "max" character (without the deletions) continues.
In the memory at the end of
the text (one or more) is binary 0.
|
S0 | ( --- title ) | It gives the title of the bottom of the stack. |
SP @ | ( --- title ) | The top of the stack (top of the stack if the stack is not empty) (before the SP @ execution). If the stack is empty, this address is the same as S0 @ . |
Convenient basics to handle Byte series:
TYPE | (title length ---) | Prints the title on the title at the specified length. |
CMOVE | (where to where length ---) | Moving byte series from one title to the next. Transmission starts at lower addresses. |
FILL | (title length character ---) | The memory is filled with long characters from the title. |
ERASE | (title length ---) | The memory is loaded from the address by a long 0 bytes. |
BLANKS | (title length ---) | The memory is filled with long spaces from the title. |
Examples
7.1.a. How to write 2 @ (title-d-content) and 2! (title d ---)?
: 2 @ (title --- d content)
DUP @ (the contents of the first memory word)
SWAP 2+ @ (for the second)
;: 2! (d-content title)
> R (we put the address on the vibe)
R 2 +! (fill the second memory slot first)
R>! (the first one for the second time)
;
7.1.b.
How
to write
TYPE (title length ---)?
FIG version:
: TYPE
-DUP IF
OVER +
SWAP DO
RC @ EMIT
LOOP
ELSE DROP
ENDIF
;
(address length ---)
(if the length is not 0)
(bytes between the two addresses
)
(if it was 0, the address on the vermen is)
7.1.c.
How
to write
CMOVE (from length to length)?
A FORTH solution:
: CMOVE
0 DO
OVER C @
OVER C!
1 + SWAP 1+ SWAP
LOOP
DROP DROP
;
(from the length to ---)
(let's get one byte)
(let's put it to the other location)
(both titles will be added)
(the two titles do not have to)
However, in general (like fig-Forth), CMOVE is not in FORTH but in a machine code.
7.1.d.
How
to write FILL (title length byte ---)?
The FIG solution:
: FILL
SWAP> R
OVER C!
DUP 1+ R> 1-
CMOVE
;
(address length byte ---)
(address byte)
(address)
(address title + 1 length-1)
7.1.e.
How
to write the words
ERASE and
BLANKS ?
FIG version:
: ERASE 0 FILL;
: BLANKS BL FILL;
7.2. Why is not DEPTH so good?
: DEPTH (--- verity)
S0 @ (the bottom)
SP @ (the top)
- 2 /
;The first S0 puts a new element on the stack, SP @ is no longer in the original state. This version is correct:
: DEPTH (--- verity)
S0 @ (the bottom)
SP @ (the top)
- 2 /
1-
;
7. 3. In many FORTH, there is a word S <> (title1 title2 length --- f) that compares the length length beginning with address1 and address 2 but not in fig-Forth. The returned signal is false, ie 0, if the two characters are the same, positive if the first is greater, negative if the second one. (The two equal lengths are the same if their corresponding characters are the same, and if not, then the comparison of the code of the first non-matching pair of characters gives the relationship between the two.) Write the word S <>.
: S <>
0 PAD!(title1 title2 length --- f) (this will be the signal we give back)
(initially assume that the two series)
(same, if not, change it)0 DO
OVER C @ OVER C @
-DUP IF
PAD!
LEAVE
ENDIF
1+ SWAP 1+ SWAP
LOOP
DROP DROP
PAD @
;
(the difference between the two characters)
(if the two characters are different)
(this will be the answer signal)
(and finish the operation)
(move on with the titles)
(titles are no longer needed)
("overwrite"
7.4. If we write a memory area with the words TYPE (title length ---), there are very strange things, since there are all sorts of control characters between them. Write a TYPE2 (title length ---) word that prints the characters between 32 and 126 (punctuation, digit, uppercase, lowercase) and points to the rest.
The program is almost literally the same as TYPE, only the control characters must be replaced by the code of the point (56) before the characters are written:
: TYPE2
-DUP IF
OVER + SWAP DO
RC @
DUP DUP
32 <SWAP 126> OR
IF
DROP 46
ENDIF
EMIT
LOOP
ELSE DROP
ENDIF
;
(title length ---)
(if control character)
(replace)
(write the character)For example, you can try TYPE2 for example:
PAD 6 65 FILL PAD 3 ERASE PAD 6 TYPE2 The answer is: ... AAA
7.5. Write a BOTTOM (--- n) that copies the bottom of the stack to the top of the stack.
: BOTTOM
SP @ S0 @ - IF (there is something on the stack)
S0 @ 2- @
ELSE. "Stack is empty" QUIT
ENDIF
;
8.1.
A sure place: the
variable
There are data that may sometimes be needed (the bottom of the stack, the
title of the dictionary, our own counters), but not always.
We can not keep them in the
vermin, because we would be embarrassed if we had to avoid these even in
the pad, which sometimes changed the title.
There are variables in FORTH
(also), which are word words like words of arithmetic or cycle
organization.
The
FORTH variables work by putting an address on the stack;
you can store the 16-bit data
at this address, the variable being created to preserve it.
|
The FORTH interpreter itself uses variables, such as so-called. System variables.
8.1. Examples of system variables
8.2.0.
S0
The word S0, which
we learned in
7.3 , is a system
variable .
8.2.1.
BASE
A BASE contains the base number of the numeric system used when scanning
and scanning. So far this was
always 10. If we want to work
in the 2-digit system, then the value of this variable is set to
2:
2 BASE (makes the variable address on the stack)
! (which we made with this operation 2)
Let's try and see what life is in the binary system:
1 1 +.
For
example, the 9th digit does not take the "stomach" of the interpreter, since
we are in a two-digit system where it makes no sense.
Surprisingly, however, the
experimental reader finds that numbers 2, 3, which are also "meaningless",
work. This is because the first
few numbers are in the dictionary;
these are often used.
It speeds up the work of the
interpreter by "finding them", without having to convert them.
The most commonly used two numbers are 10 and 16;
these are set to FORTH basic
words. Their operation is clear
from their source text:
: DECIMAL 10 BASE! ;
: HEX 16 BASE! ;
How do I know at what point is my conversion count? It's easy to say, without thinking, you just need to get the base number out of the variable and give it up:
BASE @.
We get 10 responses What do we know about this? That the base number of the numeric system in the given system is represented by a 1 and a 0, that is, it is equal to the base number of the numeric system. We will go further if we write a smaller number:
BASE @ 1-.
From
this answer we know that B, that is, 11 is the smallest one-digit number,
we are in the 12th numerical system.
Now set the default number to 5 and define a new one in the 5th numerical
system:
5 BASE!
: KIIR 10. ;
What
happens if we run the KIIR in the 10-digit system?
5 results are obtained.
There are binary numbers in the dictionary words, with the definition of
0000 0000 0000 0101, this is in the decimal system 5.
8.2.2.
OUT
We know that the FORTH parentheses on the screen write each character with
EMIT. EMIT increases the OUT
content of OUT, so if you reset the OUT then you can always find out how
many characters have been displayed since the reset.
For example, imagine that we want to write the same lines, which consist
of two (unpredictable) numbers;
we want the first number to
start at the 3rd and 3th on the screen, starting at position 13.
We assume the two numbers are
on the vermin. Write the word
that says it as above:
: BALRA-TABULAL
CR 0 OUT!
3 SPACES
.
(n1 n2 ---)
(reset the OUT variable)
(3 spaces)
(print the first number)(the OUT content now: how many characters have been written)
(already in this line)13 OUT @ -
SPACES.
;(
Add 13 to the spelled ) (number of spells, then print)
(the second number)
8.3.
Creating new
variables
Variables can be defined with VARIABLE (n ---).
The expected value of the worm
is the initial value of the variable.
The name of the variable should
be given immediately after VARIABLE:
0 VARIABLE SAJAT
With
this, the word SAJAT appears in our dictionary (as we can confirm with VLIST
at a glance). Function: Changes
the address of the variable to the stack.
For example, imagine creating a list on the printer (by switching the handset
off). How can I not know, one
sure thing: 60 lines should be on one side.
A new line in the listing program
will always start with the CR word.
Define the word CR by rolling
60 cards per line (12 EMITs), and then write down on the tab on how many
cards it is.
Since we do not know what is going on with a stack in a list, and it's simpler,
counting the rows and tabs in a variable:
0 VARIABLE LINE
0 VARIABLE LAPSZ
Both variables will have to be increased by one. To date, we know that the content of a variable would be somewhat increased by 1:
SORSZ @ (we cover the content)
1+
SORSZ! (the returned value will be returned)
FORTH Basic Word Simplifying Adds to Variables (or Any Memory Template) a
+! (n title ---)
which adds n to the one-word value on the title and stores the sum at the address. The +! Could be written in some way if it were not:
: +!
SWAP OVER
@
+
SWAP!
;
(n title ---)
(title n title)
(title n old content)
(title new content)
To increase the content of the SORSZ:
1 SORSZ +!
When calculating rows, tabs, and more, you need to increase variables by just 1. Perhaps it is worth introducing a special word that uses the 1+ action:
: INC (title ---)
DUP @
1+ SWAP!
;
The following things must be done for the printer program after the display of 60 lines:
: LAPDOB
12 EMIT
0 SORSZ!
LAPSZ @.
. "tab" CR
LAPSZ INC
;
(---)
(
countdown)
( resume counting ) (write the number of pages)
(increase the number of counters )
We will start writing the script with just a few clicks; this is the right moment to set the LAPSZ start value:
: ELSO-LAPDOB
1 LAPSZ! LAPDOB
;
The listing program will have to start listing by calling ELSO-LAPDOB. The redefined CR:
: CR
SORSZ INC (increase the count counter)
SORSZ @ 60 = (end of tab?)
IF LAPDOB
ELSE CR
ENDIF
;
8.4.
Constants
If you want to preserve a value in a dictionary that we never change, it
is simpler to use words that give the value not the title but the value itself
to the worm. These are the
constants. For example, the
words 1, 2, 3 contained in the dictionary and the 1, 2, 3 values on the
stack. This is BL, from which
we get the code for the space.
Our own constants a
CONSTANT (n ---)
so we can define it. The thing is quite similar to defining variables. For example:
42 CONSTANT CSIL-COD
we defined this constant word called CSIL-KOD. CSIL-KOD 42 is put on the stack.
What was that about?
Summary
of Chapter 8
The words learned in Chapter 8:
VARIABLE | (n ---) | A
word defining a variable. so
we use: n VARIABLE xxx. This is how we created a word dictionary called xxx. The word xxx works by putting the variable's address on the stack. At this address, when the variable is created, n is the initial value. |
CONSTANT | (n ---) | Constant
definition word. so use:
n CONSTANT yyyy. This is how we created a dictionary word yyyy. The yyyy works by stacking the constant on the stack: this is the value that was given when the constant was created on the worm. |
System Variables:
BASE | ( --- title ) | The numbers are off and on. is the base number of the concurrent versions. |
OUT | ( --- title ) | The value of this variable is increased by EMIT (each character string). So you can use it to monitor and control the number of characters you are typing. |
Other words:
HEX | (---) | The BASE value is set to 16. |
DECIMALIZE | (---) | The BASE value is set to 10. |
+! | (n title ---) | Adds n to the 16-bit content of the address, the result is stored in the address-cn. |
Examples
8.1. THE ? (title ---) source text source:
:? @. ;
Prints the 16-bit, signed value on the title. If, for example, A variable, it isTHE ?
line A is written.
8.2.
Write
a: = (title1 title2 ---) word that copies the 16 bit value on address2 to
address1
(ie if A and B are two variables, then with AB: = action A is B
value).
: = (title1 title2 ---)
@ SWAP!
;
8.3. Write a .BASE (---) word that writes BASE content decimally on the screen, but does not break it! (Or, more accurately, restoring it after it has been corrupted.)
: .BASE)
BASE @ DUP
DECIMAL
.
BASE!
;
(---)
(now
we have broken BASE) (but there is another instance of the original)
(so we can reset it)
9. Where does the variable change? Getting to know the dictionary
9.1.
The word
counter
During the FORTH programming the dictionary size is constantly changing.
When the word "top" of the
dictionary is located, the first free space after the dictionary, where the
following dictionary will be used, is interpreted by the interpreter DP
(Dictionary Pointer, say: dictator pointer).
The value of the DP variable
is used a lot, so we have a separate word for reading:
: HERE (--- title)
DP @;
A 7.1. it was a section that the pad was at a constant distance from the top of the dictionary. This phenomenon is explained by the source text of the word PAD:
: PAD HERE 68 +;
9.2.
What's in the dictionary?
A dictionary element consists of the following parts:
The parameter field - wholly arbitrarily abbreviated - is physically at the very end of the word. so after changing its definition, the word markers point exactly behind the new variable. If the value of the word counter is then set to 1, 2, etc. we increase this by multiplying the variables of the variable 1, 2, and so on. bytes. The basic word for increasing the word probe, ALLOT's source text:
: ALLOT (n ---)
DP +! ;
9.3.
Long
Variables
This hand has the option of defining double or longer
variables.
87 VARIABLE DOUBLE
88 HERE!
2 ALLOT
DUPLA
is therefore two words, the first word is the initial value of 87, and the
second the 88th.
The initial values stored in the parser and the "broadening" of the parter
are the following basic words:
:, (n ---)
HERE!
2 ALLOT
;: C, (c ---)
HERE C!
1 ALLOT
;
The following series could have been written:
87 VARIABLE DUPLA 88,
Now
we can define vectors, longer datasets.
It is important to know that
there are more convenient tools for FORTH -
we will meet them in
Chapter
15
- here we define a vector to better understand FORTH's operation (such as
Chapter 15).
For example, define a 10-element "word" vector.
Its parsing will be 20 bytes;
the
0 VARIABLE VECTOR
defined by VECTOR 2 bytes of the VECTOR by 18 bytes:
18 ALLOT
The vector is worth something if its elements can be referred to separately. Thus, we write the word IK-ELEM (n --- address) waiting for the index of the element (serial number) of the element and return its address:
: IK-ELEM
2 *
VECTOR +
2 -
;
(n-address)
(one element is 2 bytes)
(the element with 1 index at the address)
(starts with the VECTOR)
What was that about?
Summary
of Chapter 9
The words learned in Chapter 9:
DP | ( --- title ) | Changing the system. The interpreter keeps the title of the "top" of the dictionary, the first free byte after the dictionary. |
HERE | ( --- title ) | Specifies the value of the DP system variable. |
ALLOT | (n ---) | DP gives it n. |
. | (n ---) | Store n at HERE, in a word, increase the value of the word mark (DP) by 2. |
C | (c ---) | Store n at HERE by 1 byte, increasing the value of the word counter (DP) by 1. |
Examples
9.1. Write a pencil registration system! The system has three types of pencils:
0 CONSTANT RED
1 CONSTANT KEK
2 CONSTANT ZOLD
Create a 3-element variable in which each pen count can be kept. The pen count counters have an initial value of 0. Next, write the following words:
A description of the "long variable" for pencil counting:0 VARIABLE CK 0, 0,
Define a SZLO (color-tag) word that produces the pen-numbering pen for the color from the color code:
: SZLO
2 *
CK +
;
(color address)
(color code multiplied by 2)
(counters are worded)
(first counters address)
From here we have a simple business:
: CERUZA-BE (n color ---)
SZLO +!
;: CERUZA-OFF (n color ---)
SZLO
OVER OVER @
> IF "There is not enough"
DROP DROP
ELSE
SWAP MINUS SWAP +!
ENDIF
;: CERUZAK (color ---)
SZLO @.
;
9.2. Write a NULL (n ---) word that n sets the byte of 0 with the predefined variable parser. So, for example, the
0 VARIABLE HUSZ 18 NO
command line generates a variable with 20 bytes parsing; of which 2 bytes are VARIABLE, and 18 bytes 0 start bytes are NULL.
: NULL (n ---)
0 DO 0 C, LOOP;
10. The FORTH Garland and WORD
10.1.
FORTH
curtains Texts and numbers that are scanned or scribed form the character
logs in the memory. (The string
of characters in English is string, say: string.) We can work with such a
string if we know its starting address and its length.
Frequent storage in FORTH is
the so-called " start with
the length of the string containing the length of the string and then the
character codes. The so-called
FORTH is called a FORTH garland.
Let's learn about the COUNT
basic word that produces the first character's address and the length of
the string (that is, the parameters needed to call the TYPE test word) from
the FORTH garland title.
Bytees of the FORTH rope of the word "LOVE":
The COUNT word source:
: COUNT (ff address --- title length)
DUP 1+ (first character address)
SWAP C @ (the length byte content)
;
The word FORTH is in the shape of a FORTH interpreter, the word WORD.
WORD (c ---)
(pronounced:
vord, meaning: word) breaks my influence based on the delimiter character
specified on the worm. That
is, WORD reads the characters of my influence all the way to the delimiter,
changes the appropriate system variables (that the closest WORD begins reading
where it is finished), and the scanned text is put into the HERE address
as FORTH. WORD feels the end
of the line boundaries.
Caution: in the viewers (see
section
2.5
), the end of the line is quite different;
we say (say) 64 lines of lines,
but the end of them is not indicated in the memory by a special character
than the lines in the terminal!
An example of using WORD is LEVEL, which can be used in this
way:
Let's see the realization:
: LEVEL
BL (constant code for the space)
WORD (reads the name given after LEVEL)
(in the form of the first space and in the form of a FORTH)
(put it in the HERE address)CR CR
. " Dear "
HERE COUNT
3 - TYPE
. ", Halalomig imadlak!"
CR 20 SPACES
. "Pityu" CR
;(start new line)
(name, length)
("no", "no")
I can see, with my spiritual eyes, the reckless look of the Elders, the Sisters, the Elements, not to mention the Eve and Annas. Why should Pityuk's life be easy? WORD can be called twice in one word; you can also change the name of the sender:
: .NEV (read, write)
(recipient and sender name)
BL WORD
HERE COUNT 3 -
TYPE
;: LEVEL
CR CE
"Dear" .NEV
. "Halalomig imadlak"
CR 20 SPACES .NEV CR
;
Using the word:
LEVEL JENONEK LUJZATOL
The Experiment Reader may try the following:
BL WORD ABRAKADABRA HERE COUNT TYPE
and waits for the ABRADADRA word to be answered in response to the WORD. Instead, you will get the TYPE word as the interpreter uses the WORD itself to parse the lines, so when TYPE is executed, the last executed WORD put it on the HERE address.
10.3.
How do you know him?
(
Basic Words
) In WORD, it is unusual not only to take
data from the stack, but also from the background, from the input and from
the input. We have already
encountered this phenomenon in some of the FORTH core words;
these words are called WORDs.
The simplest such basic word
is
( with which we also get acquainted with
the source:
: (41 WORD;
(41
is the code of the closing parenthesis).
The opening parenthesis reads
what you find behind it, up to the closing brace (or the end of the line).
WORD converts the appropriate
system variables so that the interpreter reads the next closing parenthesis;
so the part of my influence
between the two brackets simply does not kick.
A (
there will still be a note
in
Chapter 16.
We
'll get to know
the full source of the other basic word later (also in
Chapter
16
), here we can only see a reduced version:
:. "34 WORD HERE COUNT TYPE;
(34
is the code of the quotation mark).
WORD reads my influence to
the quotation mark and puts it in the form of FORTH garland at HERE;
From here you can place a COUNT
TYPE series.
How much more do you know the real
" word" The difference is when the word is
meant to be used inside the definition
.
specify
the text specified in the definition, the version here reads the text to
be written when the word is defined.
WORD
reads the name of the word being forgotten with FORGET as well.
WORD works inside any word that can be used to define other words:
VARIABLE,
CONSTANT:
Specifically, the word CREATE creates the new dictionary element; CREATE
and WORD read the name of the dictionary element to be created.
What was that about?
Summary
of Chapter 10
The words learned:
WORD | (c ---) | Read the influence to the delimiter character c; the scanned text is put into the HERE address in the form of FORTH. |
COUNT | (ff title --- title length) | Creates the title and length of the string in the starting address of the FORTH rope. |
Examples
10.1. Write a PELDANY (n ---) word that reads the text you specified after the end of the line and writes the scanned line as many times as we have given it to the worm! For example:
4 PELDANY HULL IS HERE
If WORD has a delimiter character that can not occur in my influence, WORD will read the end of the line. For example, code 1 (not character code):: PELDANY (n ---)
1 WORD
0 DO CR HERE COUNT TYPE LOOP
;
10.2. Write an ORD (--- c) word that says the code you entered afterwards (and adds a space-filled letter to the stack, for example:
ORD C.
: ORD (--- c)
BL WORD HERE 1+ (avoiding the counter)
C @
;
11.1.
Appropriate shrinkage
for
the
correct
type
.
.R D.
is
uniquely based on one or two digit generators.
With the same basic words,
we can write similar words at any time, which in some form print out the
value of a given type of verme.
The binary value on the worm
can be converted into digits that can be written into digits,
and the
#
# word starts and
#> ends.
You
can run the words that have been converted (
#, #S, HOLD,
SIGN
) after calling
<# before
the
#> call.
|
As you can see, there are several FORTH words in the # character. To avoid spending too much time searching for this character, note one important thing:
There
are no # characters on English keyboard machines, and we always have to use
£.
|
During
conversion, the memory creates a set of converted tickets and additional
symbols, whose title and length is #> placed on the stack (so you can
type it with TYPE).
Anyone who has tried to transcribe a number from one number system to another
can know that it only goes backwards, starting with the last one.
Conversion words are
"backward":
the
goblet of characters to be written is made from the back.
The last byte of the rope is
the first byte of the pad.
|
(Do
not be surprised, therefore, when converting words ruin your data stored
on the bench at the beginning!)
The
# (ud1 --- ud2)
word
inserts the (next) ticket to the garter.
Function: distributes ud1 unmarked doubling with BASE content.
The ud2 queue is placed on
the stack so the conversion can continue;
calculate the code of the
corresponding numeric code from the remainder and enter it into the cluster.
THE
#S
converts
the unmarked duplicate word on the vermin to the number of tickets that are
needed (so worthless, leading zeroes).
The worm remains a double-blind
0.
Source #S otherwise:
: #S (ud --- double-0)
BEGIN
# (one ticket)
2DUP OR 0 = (
Dweller Word 0?) UNTIL (if not 0 was the last double word, continue)
;
The DWORD in which the partial results of the conversion were kept, a
#>
throw it off the stack.
The
# , so the
#S also produces the corresponding number
BASE systemic tickets.
THE
HOLD (c ---)
word
will enter the received c character in front of the converted tickets.
For example, if you want to include a double-digit, unsigned number so that
the last two digits are displayed as decimal places:
: 2THE
<#
# #
46 HOLD
#S
#>
TYPE
;
(ud ---)
(start of conversion)
(the last two tickets have been generated)
(decimal point)
(additional tickets)
(end of conversion)
Or, if we want to give you the number of decimals you want in the worm:
: TJE
<#
0 DO # LOOP
46 HOLD
#S
#>
TYPE
;
(decimal places ---)
(start of conversion)
(decimals)
(decimal point)
(and others)
(end of conversion)
If you want to write an unmarked, one-word value, it is no problem either. We can easily make a double word, because (as a positive number) the higher value of the double word value is 0, simply this should be done only on the stack. One possible source for U. is, for example:
: U.
0
<# #S #>
TYPE SPACE
;
(ud ---)
(start of conversion)
(the last two tickets have been generated)
(decimal point)
(additional tickets)
(end of conversion)
Mostly, however, we work with signatures. To do this we need to get acquainted with
SIGN (nd-d)
so that is also used between <# and #>. SIGN sets the converted sequence with a minus sign or not, depending on the sign of n (ie the third element of the stack). For example, a . a possible source:
:.
DUP ABS
0
<# #S SIGN #>
TYPE SPACE
;
(n ---)
(the upper instance has no sign)
(easy without sign)
(make a duplicate)
Finally,
a witty example from Leo Brodie, STARTING FORTH:
Let's say that the doubling of the bug is the number of seconds, and what
time is the minute: minute: we want to post this time in seconds.
We have to work between the
10 and 6 number systems.
: SEXTAL
6 BASE! ;:: OO
#
SEXTAL
#
DECIMAL
58 HOLD
;
(transition to number 6)
(making a decimal ticket)
(making a "tick" ticket)
(colon)
The above program, if you think about it, is the remainder of the division with the 60, in a decimal system. (The quotient is passed on to the vermin.) So we can easily write the word you want:
: SEC (ud ---)
<#: OO: OO #S #> TYPE SPACE
;
11.2.
What do we get from NUMBER?
We know in the
first
chapter
that the interpreter will search the words received for the first time in
the dictionary and if he can not find it, he tries to interpret the number.
The latter is a
NUMBER (title --- d)
calling.
NUMBER will try to produce
the corresponding double word from the FORTH font specified by BASE (BASE).
If it does not go, it gets
"missed" with the error message, ie it quits the queue by quitting the queue.
If, on the other hand, the
girth is a sign, and possibly a decimal point, it consists of a sign that
can be interpreted in that particular numeric system, it places the double
binary value (calculated without taking a decimal point) into the stack;
Additionally, the DPL sets
the decimals number in the system variable.
If there was no decimal point,
the DPL is -1. (The interpreter,
when analyzing the numbers found in my influence, drops the higher value
of the converted doubling word by DPL -1, which we see as a single value.)
Example: "prefix" multiplication taking into account the decimal
point."*" can be used in this way:
"*" 1.2 -0.2
Read the numbers with the WORD and analyze them with NUMBER:
: "*"
2 0 DO
BL WORD
HERE NUMBER
DROP
DPL @
0 MAX
LOOP
(---)
(read on two numbers)
(FORTH string at HERE)
(conversion double talk)
(then considered a)
(number of decimals)
(DPL -1 if it was not)
(decimal)(the vermin: value 1 dpl1 value 2 dpl2) > R SWAP> R
M *
> R DUP R> DABS
R> R> +
<# -DUP IF
0 DO # LOOP
46 HOLD
ENDIF
#S SIGN #>
TYPE SPACE
;(value1 value 2)
(double-word product)
(preparation for conversion)
(number of decimal places)
What was that about?
Summary
of Chapter 11
The words learned:
<# | (---) | Conversion of numbers from binary to character. |
# | (ud1 --- ud2) |
Generates
the following character code in the output string.
The duplicate value added must
be used to generate additional characters (this is the fraction of the division
with the BASE content, and the character code is generated from the remainder).
You can use the words <#
and #>.
|
#S | (ud1 --- duplaszavas-0) |
Generates
numeric codes in the output string until the value of the duplicate value
to be converted runs out during the distribution;
that is, in the converted string,
the valuable ones (and only those) are displayed.
You can use the words <#
and #>.
|
MOON | (c ---) | Inserts ac in the output string. You can use the words <# and #>. |
SIGN | (nd-d) | One - adds a signal to the output string if n is negative. You can use the words <# and #>. |
#> | (ud --- length) | Complete Conversion. Drops the doubler used during the conversion from the stack, instead replaces the title and length of the converted string on the stack. |
NUMBER | (title --- d) |
For
FORTH that begins with the title, convert it to an ad doubling doubling,
according to the BASE value. If
the FORTH hanger to be converted includes a decimal point, then the number
of digits to the right of the decimal point is placed in the DPL system variable;
if not, the DPL will be -1.
If the conversion can not be
completed, the program run will be canceled with an error
message.
|
DPL | ( --- title ) | Changing the system. NUMBER sets the number of decimal places. |
Examples
11.1. Write a word T (n decimal places ---) that specifies the signed, one-word n value with the specified decimal number.
: T (N decimal places ---)
> R DUP ABS
0 (sign ud value)
<# R> (number of decimals)
-DUP IF (if decimal)
0 DO # LOOP 46 HOLD
ENDIF
#S SIGN
#> TYPE
;
11.2. Write a .L (n field width --- word), which sets the n value to the left in the width field, ie if the series to be written is shorter, multiplies the required number of spaces, if it is longer, cut off low-value tickets.
:. L
> R DUP ABS 0
<# # S SIGN #>
R MIN
SWAP OVER
TYPE
R> SWAP -
SPACES
;
(Field width n ---)
(stack of the converted sequence)
(length and address)
(if need be, cut off the excess)
(the stack: the longitudinal length of the title)
(the stack: length)
(if necessary, spaces)
11.3. Write a% (percentage) --- word, which takes the percentage base from the bottom of it and prints the percentage with the required number of decimal places! We assume that the percentages of the precious digits fit in a word, and that the percentage basis is given by a decimal point. For example:
50% 24.4
12% 3.
For Forbes: Percentage = Percentage Base * Percentage / 100.
:%
BL WORD
HERE NUMBER
DROP M *
SWAP OVER DABS
<# DPL @
2+
0 DO # LOOP
46 HOLD #S SIGN
#> TYPE SPACE
;
(N ---)
(% basic character charge)
(% base conversion)
(double word is the% value)
(preparation dump)
(that was corporal% base)
(the division by 100 in)
(decimal point tologatásával)
(indicated)
11.4.
What
can be the SIGN source?
The FIG solution:
: SIGN
ROT 0 <IF 45 HOLD ENDIF;
12.1.
Chaining the Dictionary
Element
As shown in
Section 9.2.
this
section
has already been mentioned, all the elements of the dictionary have a chain
of fields, this combines the words of the dictionary.
The chain field contains a
pointer to the name field of the previous word, or 0 (for the "lower" element
of the dictionary). If we know
the title of a word field in a word, the corresponding FORTH parentheses
can also be used to generate the addresses of other fields:
PFA | (ncím --- pcím) | generates the title of the parser from the name field of a dictionary element; |
NFA | (pcím --- ncím) | enter the address of the search field from the title of the parser; |
CFA | (title pm) | enter the address of the code field from the title of the parser; |
LFA | (pcim --- address) | enter the address of the chain field from the heading address. |
The title field of a word thus obtains the title of the name field of the word defined before:
PFA (Parameter Address)
LFA (chain field address)
@ (chain field content = address field of the previous word)
We can therefore move on the chain; another word to find the front of the chain:
LATEST | (--- ncím) | The address field of the last defined dictionary dictionary. |
In the name field, the word "almost" is in the form of a FORTH garland; the difference is that the first three bits of the length of the bytes area do not belong to the length, and contain other information. So we do not write the word with COUNT TYPE, but with a special word:
ID. | (ncím ---) | it prints the name of the word whose name field is found in the vermin. |
The following is the name of the last word defined:
: TODAY LATEST ID. ;
Now we can even list our dictionary:
: VLIST2
80 OUT!
LATEST
BEGIN
OUT @
70> IF
CR 0 OUT!
ENDIF
DUP ID.
SPACE SPACE
PFA LFA @
DUP 0 =
UNTIL
DROP
;
(the list begins with a new line)
(the worm: address)
(do not write over lines in a row?)
(name
spelling)
( next name field address) (if the chain field is 0, end)
(the dictionary)
How does this differ from your well-known VLIST? First, it does not stop when you press a key on the keypad. We can easily help you with this
? TERMINAL (--- f)
we must know the word; this will give you a true flag when you press a key on the keyboard (we have not handled it with KEY). Second, it does not list the same vocabulary that VLIST. How should this be understood? It turns out in the next section.
12.2.
Search and Chain Dictionary
It is
embarrassing to distinguish between the meaning of two words that are equally
translated into "vocabulary".
One is dictionary dictionary
(eg, DP: Dictionary Pointer system name), which is a "physical" vocabulary,
the other is vocabulary (known as VLIST, Vocabulary List), which is " logical
"vocabulary, with a list of terms with indices.
In FORTH, a "physical" dictionary
can contain more "logic"; In
addition to the FORTH dictionary, there are mostly EDITOR and ASSEMBLER
dictionaries. By default, we
are in the FORTH dictionary;
then, for example,
the words of the EDITOR dictionary
are simply not found or recognized by the interpreter.
To use the words in the EDITOR dictionary, the EDITOR should be used as a
search dictionary. (The "search
dictionary" is quite a free translation of the original "context vocabulary",
contextual dictionary expression.) At a given moment dictionaries can be
a single search dictionary.
Two logical chains, physically mixed
The
interpreter searches the words to interpret in the search context.
The dictionary name makes the
given dictionary a search dictionary.
|
So, for example, the
EDITOR
with the command prompt, you can see the words in the EDITOR dictionary (if loaded before). It is unnecessary to worry about how to get in EDITOR without the FORTH basic vocabulary:
The
words of any dictionary in which the given dictionary is defined are chained
to the words of the dictionary.
|
Ultimately, this means that
the
words of the FORTH dictionary appear from every search
dictionary.
|
We
see this if we do a VLIST after the word EDITOR is executed.
Standard VLIST lists the search
dictionary. We can also make
sure that our VLIST2 program does not do this, as it does not write the words
in the EDITOR dictionary. The
word LATEST with which our program starts starts is not the title of the
top word of the chaining dictionary, but the search engine.
The chaining (originally current) dictionary is just one at a given
moment.
Newly
defined words are added to the chaining dictionary.
|
With the name of the dictionary, only the search dictionary will be changed; if you want the chaining dictionary to be the same, then a
DEFINITIONS
use
the word that aligns the chaining dictionary to the search engine, the two
will agree.
In reverse, the two dictionaries are aligned with the definitions
: word: this changes the viewfinder to match
the chain.
An old acquaintance, a new feature of FORGET: works only if the search and
chaining dictionary is the same, otherwise it is broken by
error.
12.3.
Our own
dictionaries
We can also separate one of the vocabulary from the other, we can create
their own dictionaries.
Defining the
dictionary
Vocabulary
you have to enter the name of the new dictionary (as we have seen in the definitions). After defining a dictionary, you also use the word IMMEDIATE, which we will later discuss (see section 16 ). For example, if you write a user program, but do not want to know the user's nose, what are the auxiliary words written during the program buildup, you can lock these auxiliary words into a separate dictionary:
VOCRBULRRY REJTETT IMMEDIATE
When we write the words "hidden" we will do this as a search and chaining dictionary:
HIDDEN (this made him search)
DEFINITIONS (from a chaining)
If we are ready to write the auxiliary words, we want to create the final result in the FORTH dictionary:
FORTH DEFINITIONS
: VEGSO (but you want to use it in the program)
( READY words)
HIDDEN
(here comes the text of the program)
;
The
fact that the REJTETT word is performed while compiling and not running VEGSO
is the result of IMMEDIATE.
Since
:
you
stop the search dictionary, if you want to define another word using the
READER words, you will need to redefine the search dictionary after the next
colon:
: VEGSO2 REJTETT
(here comes the text of the program)
;
What was that about?
Summary
of Chapter 12
The words learned:
PFA | (ncím --- pcím) | It generates a parsing address from the name field of a dictionary element. |
NFA | (pcím --- ncím) | Enter the name of the search field from the title of the parser. |
LFA | (pcim --- address) | Enter the address of the chain field from the parsing address. |
CFA | (pcs. | Enter the address of the code field from the title of the parser. |
LATEST | (--- ncím) | Returns the name field of the top element of the linking dictionary. |
ID. | (ncím ---) | Specifies the name of the dictionary element whose name field was found in the verme. |
FORTH | (---) | Dictionaries. Their name can be used to search for them. |
EDITOR | (---) | Dictionaries. Their name can be used to search for them. |
ASSEMBLER | (---) | Dictionaries. Their name can be used to search for them. |
?TERMINAL | (--- f) | The returned indicator is true when you press a key on the keypad. |
DEFINITIONS | (---) | The chaining dictionary is aligned to the search dictionary. |
Vocabulary | (---) | Defining word, so we use: VOCABULARY xxx We created a dictionary called xxx. |
Examples
12.1. Write in section 12.1. section of a VLIST2 section that will stop the listing by pressing any key!
: VLIST
80 OUT!
LATEST
BEGIN
OUT @
70> IF
CR 0 OUT!
ENDIF
DUP ID.
SPACE SPACE
PFA LFA @
DUP 0 =
? TERMINAL OR
UNTIL
DROP
;
12.2. Write the names in the dictionary that start with an opening lock, so that it is tabulated so that the number of characters that can be entered can be divisible by 13. If there are more than 51 characters in a row, the next name is written in a new line.
: LIST
80 OUT!
LATEST
BEGIN
DUP 1+
C @
40 = IF(---)
(crossing the lengthbyte)
(this is the first character of the name)
(if parenthesis)OUT @ 51> IF
CR 0 OUT!
ENDIF
DUP ID.
13 OUT @ 13 MOD - SPACE
ENDIF
PFA LFA @
DUP 0 =
UNTIL
DROP
;
13.1.
Basics
By the time you get there, the Reader has probably written a lot of programs.
Much of them have been edited
on a umbrella to improve them (see
Section
2.5
).
The spectators are so called.
they are in virtual memory.
Virtual memory is a memory
that is complemented with a diskette file.
The virtual word here is apparent.
The virtual memory name reflects
that the virtual memory blocks - although they are on a data carrier - are
programmed to appear as if they were in memory.
This is because we see it
because
BLOCK (block number --- memory address)
word
ensures that the block you are referring to is scanned into memory if it
has not been there; from the
recovered address we find the contents of the block in the memory.
The block here is the physical
unity of reading and writing, usually (as a disc) of a sector.
The AB / BUF system constant specifies how many blocks the block is.
If we assume that there are
text data in the virtual memory, it is possible to output the contents of
a given block of numbers:
: BTYPE (block number ---)
BLOCK (address)
B / BUF (block address block)
TYPE
;
Looking
at the BTYPE word usually shows that the blocks contain a set of jewels;
around the 4th round there
are error messages (see section
13.3 ).
The word BLOCK:
|
In
the latter case, we do not turn to the disc;
saving time without having
to pay attention to programming when writing.
The virtual memory blocks are interpreted by the interpreter as a so-called
memory. in his block robots.
BLOCK looks at whether there
is any block in one of the block buffers;
if found, then we get the block
buffer address, if not, then scan, but in which buffer?
The answer is simple if there is an empty block buffer.
However, block buffers are
few in comparison to virtual memory blocks.
Mostly, one of the blocked
buffer blocks must be overwritten.
What happens to the buffer
for the puff? Are you discouraged
or rewritten on the media?
This is what we decide for ourselves.
If we do nothing, the contents
of the buffer will not be restored, so just read the virtual memory.
We want to rewrite a given
block, after the block reference (BLOCK)
UPDATE (---)
so we announce it. This block will be "updated", so it will be modified. Words are a bit misleading; the contents of the block buffer will then be modified, and the media blocks will be later, when the buffer is needed, or whenever the modified buffer is reverted.
UPDATE
always refers to the block that was last referred to as BLOCK.
|
(This
simply happens that BLOCK puts the block number in the PREV system variable
and UPDATE finds it there).
All modified blocks are a
FLUSH (---)
so we can write it out (for example, when we stand up from the machine). But if we want to do all that we have mixed in the block buffers, that is
EMPTY-BUFFERS (---)
we
can start with a clean sheet;
the EMPTY BUFFERS does not
delete the buffers, but write the buffers' records.)
To make the texts stored in the virtual memory executable in the same way
as the interpreter, the interpreter
will consider all the block buffer buffers without having to rewrite (or
modify the actual contents of the block buffers)
such as the keypad, it depends
(among others) that the interpreter always passes the word WORD to the next
word to be interpreted. WORD
works depending on the contents of the BLK system variable:
WORD
records the IN system variable in the command buffer or in the block that
is being recorded. After reading
a word, the IN content increases with the word length so the WORD next will
look for the next word.
BLOCK, UPDATE, FLUSH and EMPTY-BUFFERS are the basics of virtual memory
management. The rest of this
chapter will show how to use them through the FORTH basic words and the most
basic words of a word processor.
13.2.
Lightweight Basic
Words
The size of the hoods is not the same as the block length;
more than one block is usually
needed to store a watch. How
much is that in the given FORTH, that is the B / SCR system constant.
In Fig-Forth, 8 blocks out
of an umbrella. The blinds
are on a continuous, sequential number block.
The number of screens, blocks and queues starts from 0.
Let's
look at how LINE is the basic word that gives the title and length of the
specified number of lines of the specified number of frames.
So, for example,
0 2 (LINE) TYPE is the 0th
digit of the 2nd screen, ie, it writes the top line of the screen.
To calculate the address of the line you are looking for (or be sure you
are in the memory), we need to know which block it is in.
The number of the first block of the row containing the row:
B / SCR * number of
frames
(because in the virtual memory it is preceded by an "umbrella" piece, each
of which is a B / SCR block).
The row is preceded by a
row number *
number
within the umbrella , so there
are as many blocks as it can fit.
That is: a
(line length * serial number) / block length
quantifies
how many blocks from the beginning of the screen precedes the block containing
our line and the remaining number of characters in the block.
The line length is given by
the C / L system constant.
After that the text of the program is:
: (LINE)
> R
C / L
B / BUF
* / MOD
(Ref kernyõsz --- Address Length)
(number)
(Ref queue length)
(serial queue length block length)
(the remainder: the line within the block)(number of preventive characters)
(the quotient: the
number of blocks preceding the block)R>
B / SCR *
+
BLOCK
+
C / L
;(number of blocks)
(the starting point of
the row containing the line
)
(row starting line)
(row start
)
If
we look at it better, (LINE) works even if the specified line is not on the
specified umbrella (for example, if the 16 slots are looking for row 18 of
our umbrellas and 0. quill, we get the same as the 1st window 2. ).
The LIST basic word list is the
.LINE (serial no. Number ---)
built on words; it prints the specified line. The .LINE call has not yet been learned
-TRAILING (title length --- address length2)
Basic word. A -TRAILING cuts off the spaces from the end of the string with its title and length; it changes the length so that the space element does not understand.
: .LINE (line number lane ---)
(LINE)
-TRAILING (to avoid having no excess)
TYPE
;
FORTH editors often consist of operations for a current queue line. The number of the current screen is contained in the SCR system variable. For example, the LIST (see Section 2.5 ) also makes the listener visible in real time, ie places its number in the SCR variable.
: LIST
DECIMAL CR
DUP SCR! (we made the elephant accurately)
. "SCR #". (write the number of the queue)
16 0 DO (may be the queues)
CR R 3 .R SPACE (line number)
R SCR @ .LINE (row content)
LOOP
CR
;
13.3.
Standard error
handling
The FORTH parentheses start the ERROR word when the error is detected and
the bug is waiting for the error number.
ERROR's activity can vary depending
on the value of the WARNING system variable:
We
will learn to define our own interrupt procedure later (see
chapter
14.4.3
).
In all three cases, ERROR drains the vermet and incorporates the contents
of the IN and BLK system variables.
The error counts can be found
in the
appendix .
Most of our programs are
? ERROR (indicator error number)
is used for error reporting. The indicator indicates whether a specified number error has occurred. The ERROR source text:
: ERROR
SWAP IF ERROR
ELSE DROP
ENDIF
;
Those who are interested in seeing many examples of what have been studied so far should read the source of the most important words of ERROR and ERROR:
: ERROR
WARNING @
0 <IF
(ABORT)
ENDIF
(error line --- in blk)
(user interruption)(here we can only get WARNING)
(not negative)HERE COUNT
TYPE
. "?"
MESSAGE
SP!
IN @ BLK @
QUIT
;(we write the word that WORD)
(last read)
(this word writes the error message)
(this word drains the vermet)
: (ABORT)
ABORT
;
(user interruption)
The error message is MESSAGE:
: MESSAGE
WARNING @
IF
-DUP IF
4 .LINE SPACE
ENDIF
ELSE
"MSG £".
ENDIF
;(
if WARNING is not 0)
(if the error string is not 0)
(if WARNING 0)
13.4.
Excerpts from a
Editor
We will get to know one part of the editor, William F. Ragsdale, attached
to fig-FORTH; as much as it
is uncomfortable, but enough for the maintenance of the umbrellas.
The editor's description
can be found in
Appendix C.
Here
we mainly deal with the construction of the words, the source text.
First of all, creating a dictionary containing the words of the editor is
our job.
VOCABULARY IMMEDIATE EDITOR
This will be the search and chaining dictionary:
EDITOR DEFINITIONS
When writing the editor's words, we work in sixteen numerical systems:
HEX
The pad serves as a temporary storage of the text of the lines. Our first word, TEXT, reads a string of words from the spell and makes it into the pile in the form of a FORTH rope. The worm waits for the delimiter character of the text.
: TEXT
HERE C / L 1+
BLANKS
WORD(c ---)
(over the dictionary)
(upload with spaces)
(read the text of the given)
(with delimiter characters, transfer to PAD)
(text, data to be provided to CMOVE)HERE
PAD
C / L 1+
CMOVE
;(where)
(where)
( where )
Our
next building block is LINE, which tells you which row of the current queen
is where it is. A viewer is
current because its number is in the SCR variable.
The LINE checks whether the number received is between 0 and 15.
Meanwhile, of course, he says
that a watch is 16 rows.
: LINE
DUP
FFF0 AND(serial number --- address)
(one number falls between 0 and 15)
(if its hexadecimal shape is one-digit)
(this gives the AND 0 bit per bit)17? ERROR
SCR @
(LINE)
DROP
;(if you do not get 0, you will get away)
(the program)
(line title)
(and length)
It is built on this
-MOVE (title line ---)which copies a line from the specified address to the specified number of rows of the current quilt:
: -MOVE (address line ---)
LINE (the address where we move)
C / L CMOVE
UPDATE
;
The first user word of the editor is E (erase), which overwrites the specified number of lines with spaces:
: E (line ---)
LINE (the address of the line to be deleted)
C / L BLANKS
UPDATE
;
With the word S (spread), the specified line can be dumped by lowering the contents below the rows below and filling the space with spaces. The last line of the umbrella is lost.
: S
DUP 1-
0E
DO
R LINE
R 1+
-MOVE
-1 + LOOP
E
;
(No. ---)
(the first line, which does not require)
(move)
(the last line, which is moved)
(the cycle progresses from behind)
(moved row)
(write this line)
(A copy of the serial number on the stack )
(left)
(deleting a line with spaces)
AH (hold) retrieves the specified number of lines of the current umbrella into the pad, in the form of FORTH.
: H
LINE
PAD 1+
C / L
DUP PAD C!
CMOVE
;
(sort ---)
(the title from which
we copied)
(duplicate ) (lengthwise to the beginning of the pad)
AD (delete; delete) will delete the specified number of lines; the umbrellas underneath are moving up one up, and the last row is overwritten. The deleted line remains in the pad.
: D
DUP H
0F DOUBLE
ROT
DO
R 1+
LINE
R -MOVE
LOOP
E
;
(
the line goes to the pad)
(last row number)
(
the row is on the top of the stack) (this row goes up)
(the stack has a copy of 0F)
(deleting the last line with spaces)
R (replace) replaces the specified frame with the text stored in the pad.
: R (
sort ---) PAD 1+ SWAP -MOVE;
AP (put; place) overwrites the specified search string with the text that is written after P (end of the line):
: P
1
TEXT
R
;
(No. ---)
(1 character code is not on your keyboard)
(TEXT will read until the end of the line)
(TEXT read the pew, R copy here)
The word I (insert) inserts the text in the pad just as in R, but pushes the line down with the underside before overwriting.
: I (sort ---)
DUP SR;
Another word that handles the entire screen: CLEAR (ornate number), this clears the specified umbrella.
: CLEAR
SCR!
10 0 DO
FORTH
R
EDITOR
E
LOOP
;
( row = )
(the screen becomes actual)
(row 16)
(word R from the FORTH dictionary)
(should be taken)
What was that about?
Summary
of Chapter 13
The words learned:
BLOCK | (n --- address) |
Returns
the memory address of the block buffer containing the nth block.
If the block is not in the
memory, it will be read in the block buffer that was last mentioned last.
If you have edited a revised
puff, it will first copy the content to the virtual memory.
|
UPDATE | (---) |
Modified
indicates the block that was last referred to as BLOCK (the block number
is found in the PREV system variable).
This means that the interpreter
will rewrite the block into the virtual memory before using the block buffer
containing it.
|
FLUSH | (---) | Write the modified blocks in the virtual memory. |
EMPTY-BUFFERS | (---) |
Changes
the register of block buffers;
all of them are considered
blank (without modifying the modified blocks in the virtual
memory).
|
PREV | ( --- title ) | In this system variable, the number of the block that BLOCK has last referenced is retained. |
B / BUF | (--- n) | Constant system; the block length bytes. |
The system variables used by the WORD:
BLK | ( --- title ) |
The
number of the block from which the WORD reads the influence.
If 0, then my influence comes
from the terminal, WORD reads from the command buffer.
|
TIB | ( --- title ) | A system variable with the command buffer address. |
TENDON | ( --- title ) | Shows the WORD where the block buffer or command buffer contains the closest read. |
Kernyõkezelés:
B / SCR | (--- n) | System constant: the number of blocks in a single window. |
C / L | (--- n) | System Constance: the length of the grid rows. |
(LINE) | (row nose --- title length) | Specifies the memory address and length of the specified row of specified number of umbrellas. |
.lin | (row nose ---) | Write the specified line. |
SCR | ( --- title ) | System variable; the editors use to store the current number of people. |
Error handling:
ERROR | (error-blk in) |
Procedure
to be followed when a given number of errors are detected.
If the value of the WARNING
variable is 1, it writes an error number from the beginning of the fourth
memory of the virtual memory as a diagnostic error.
(The sequence number may be
negative or you can move beyond the 4th floor.) If WARNING is 0, the error
is only identified with the number of the error message.
If WARNING is -1, the word
(ABORT) is executed, which we can modify ourselves (see section
14.4.3 ).
We get the contents of the
BLK and IN variables on the vermin to identify the error.
Fault management ends with
QUIT.
|
(ABORT) |
"User
Defined Interruption", see
14.4.3.
chapter
. If you do not define an interrupt
procedure, the word ABORT will be executed.
|
|
WARNING | ( --- title ) | System variable; contains information on how to handle error handling (see ERROR). |
? ERROR | (error f --- ---) | If f is true, it starts the error handling procedure for the specified serial number. |
MESSAGE | (n ---) |
In
response to the WARNING value, the error message is output to the specified
serial number: if WARNING is 0, the serial number, if not, is the nth row
of row 4 of line 4.
|
Other words:
-TRAILING | (title length --- address length2) |
Change
the length of the string with its title and length so as not to include the
spaces at the end of the text.
|
ABORT |
Empties
the vermes, the search and the chaining dictionary to FORTH, and sets the
conversion count to 10.
Interrupting the line or bracket
that is being interpreted will wait for a new command line.
|
|
SP! | Emptying the stack. |
The editor's words, see Appendix C .
Examples
Before trying out task solutions, you might want to put a virtual memory off of a virtual memory. So people are experimenting more courageously.
13.1. (After Leo Brodie, freely). There are ladies in the 25th virtual memory, one on each line.
At the beginning of the line, the lady's name, starting from the 21st character, is the color of her, starting with the 40th character, her eye color (so all three fields are 20 characters long). Write a LEVEL (n ---) word waiting for the line number on the vermen and print the following letter:
Dear <name>!
Lazba jovok, if you remember <eye color>
your eyes, <hair color> your hair. Come tomorrow,
pick up your clothes, so you're gonna have a pretty
eye on
Leo
For example:
The letter writer may be somewhat instable: it changes the starting position of the eye, intends to start the lines of the letter or does not want to use the 25th cap. Therefore, highlighting the name, hair color and eye color is emphasized in one word; we also discuss the starting address of the line containing the lady. So it will be easy to change when someone remembers you.
0 VARIABLE LIN
: SOR (--- LINE) LIN @ 25 (LINE) DROP;
: .NEV SOR 20 -TRAILING TYPE;
: .HAJ SOR 20 + 20 -TRAILING TYPE;
: SEM 40 + 20 -TRAILING TYPE;
: UJSOR CR 10 SPACES;In addition to filling in the mail, the main program should provide the LIN variable upload:
: LEVEL
LIN!
CR UJSOR 5 SPACES
"Dear" .NEV. "!"
CR UJSOR "Lazba jovok, if you remember me" I'm UJSOR
"your eyes," .HAY "your hair, come tomorrow,"
UJSOR. "Pick up" I AM ", clothes so"
UJSOR. " "
UJSOR 7 SPACES. "Leo" CR
;
13.2. How to write the word INDEX (from ig ---), which lists the row 0 (including "umbrella" and "up") between the two specified borders. Keep in mind if you press a key on your keyboard.
: INDEX (tol ig ---)
1 + SWAP DO
CR 0 R (LINE) -TRAILING TYPE
? TERMINAL IF LEAVE ENDIF
LOOP
;
13.3.
What
can be the source of -TRAILING?
The FIG solution:
: -TRAILING
DUP 0 DO
2DUP +
1- C @
BL - IF
LEAVE
ELSE
1-
ENDIF
LOOP
;
(Title length --- Address hossz1)
(a stack of address length)
(after the title string)
(last character of the string)
(No spaces,)
(We are ready for slaughter)
(if space bar)
(further abbreviated)
14. Dictionary and title interpreter
14.1.
Colloidal
Words
The most basic feature of FORTH programming is to build words that are already
existing for words that are closer to our goal so that we can build them
later on. Such words, compiled
in other words, contain indicators for the words that make up their own;
the essence of their operation
is the implementation of the words that make up them based on the indicators.
This kind of evaluation of
the indicators is a small, fast program, the so-called.
an internal interpreter or
an interpreter. (Much depends
on the title interpreter to be fast because it is executed when executing
FORTH words.)
If we start a word definition with a colon, then we'll tell you that the
new word will be rebuilt from older words.
Thus, since the operation of
dictionary words is determined by the contents of the code
field,
all
encoded fields in the colon have the address interpreter
address.
|
The
metrics on which the titleinterpreter has to go is in the parsing of the
colon-words; these are the
code addresses of the words that make up the word.
Example of a colon definition:
: .PAD PAD C @. ;
The generated element:
Name field: .PAD Chain Field: name field of the previous word code field: address interpreter parameter field: PAD code field address C @ code field address . kódmezõcíme ; S code field address
In the parsing of the colon words, the last code address is : S ; this word returns the title interpreter to the caller word. (The S word in section 2.5. Have been met. Kerny interpretation of the result is complete) The S kódmezõcímét of ; the word is enchanted in the parable of the new word.
14.2.
Primitives
The majority of the words FORTH are thus run by the title interpreter: he
goes to the addresses where the indicators found in the parsing word are
sent. There may be newer metrics
to go on. Many of the messaging
needs to end once: sooner or later, any word you have called has to figure
out what to do. These final
words, which therefore do not contain other indicative terms but executable
machine codes, are called primitives.
In the code field of the
primitives, the pointer points to the primitiva's own parser.
The parser has a machine code,
this is executed when the primitive is run.
The existence of primitives
is based on the following statement:
What
can be on a machine can be in the FORTH running on it.
|
Primitives
can also be used to call routines of the operating system, so you can integrate
the file system or any other feature of that operating system.
Of course, a machine-independent
CP / M programmer can not do this for all existing machine types, which we
should do to the machine we use.
If you want to better use the
capabilities of your ENTERPRISE operating system, machine
- specific
IS-FORTH
is the right choice.
To create primitives, the words of the ASSEMBLER dictionary serve to make
use of mnemonics instead of machine codes so that we can have assembler
programming for control structures and so on.
14.3.
Variables and
constants
All variables work in the same way: the stack is the address where the variable
value is. so maybe it's not
surprising that the code fields of our variables all contain the same address.
More surprisingly, system variables
(BLK, IN, DPL, etc.) are not the same.
Such special
variables:
HLD | R # | CSP | FLD | DPL |
BASE | STATEMENT | CURRENT | CONTEXT | SCR |
OUT | TENDON | BLK | VOC-LINK | DP |
FENCE | WARNING | WIDTH | TIB | R0 |
S0 |
The
system variables (USER, say: variables variables) are in a table.
A part of the table is loaded
with the word COLD (start of cold start) with the initial values,
(with the other key data needed
for the operation of the interpreter, so that the original state of the
dictionary is returned after COLD, which is usually the deletion of our
definitions.Users
can be defined with the word USER, described at the end of the chapter, although
it does not matter much to the writers of this "field" user program. USER
variables, as we have seen, are the same as ordinary variables, but there
is a difference only behind the scenes.
The constants' code field is also the same: it points to the code that puts
the parsing content on the stack.
Thus, we can conclude from
the code field of a dictionary that it is about colon, primitive, or the
like.
14.4.
Tricky
Runs
The usual way to
execute a word is by referring to its name, and
the interpreter will know what to do with it.
However, a word can be done
on the basis of its code title, ultimately the interpreter also does.
In order to enjoy the fun of
it, we must first know how to create a code field (or any other) of a dictionary
word. That's
right
-FIND
word that tries to find the next word of my influence in the dictionary. If you find it, it returns the parsing address of the word, the longitude marker and a true marker from the name field. If not, it only gives a false sign.
14.4.1.
EXECUTE
The
EXECUTE (code field title ---)
is
the word that executes another word in the code field specified in the vermin.
Let's say that we only want to write the words of such or somehow characteristic
words (primitives, USER variables, etc.).
The structure of such list-creation
programs is exactly the same - all goes through the dictionary chain and
decides whether or not to write that word.
This decision is the only detail
that changes when we want to list constants instead of primitives.
Let's make this decision a
separate "decisive word", and we will list the listener on which final word
to list.
We assume that the decisive word is waiting for a mark on the vermen and
gives a marker that is true for the words to be pronounced, the others will
be false. For example, to decrypt
the words starting with the closing sign, the decisive word is:
: (WORD (pm address --- f)
NFA (name field address)
1+ C @ (first character of the name)
40 =
;
We write the soloist EZEK-A, after which I will only give the name of the decisive word in my influence, somehow:
EZEK-A (WORD
We will make it easier for us to introduce a variable to store the parsing address of the decisive word:
0 VARIABLE DONTO-PMC
because the DONTO-PMC already contains the prime address of the decisive word, then you can choose one word to write:
: DOES-E (pm title --- f)
DONTO-PMC @ CFA
EXECUTE (execute the word "decisive")
;
Writing a word
: OUTPUT (OUTPUT ---)
OUT @ 35> (lines should not be too long)
IF CR 0 OUT!
ENDIF
NFA ID.
;
The program itself:
: EZEK-A
80 OUT!
-FIND 0 = 5?
DROP DONTO-PMC ERROR !
LATEST
BEGIN
PFA DUP DUP KELL
-E
IF KIIR
ELSE DROP
ENDIF
LFA @
DUP 0 = UNTIL
DROP CR
;
(---)
(the Chamber immediately start a new line)
( "fly away" if there is no final word)
(word name in the top box title)
(next word address field name)
(pmcím pmcím pmcím)
(pmcím pmcím indicator)
(proceed)
14.4.2.
Variations for
-FIND
Let's say that the former EZEK-A word is a word VALCULE (pmc --- f), which
gives a true flag if the given address is a (VARIABLE-defined) variable.
We know that the code fields
of the variables all contain the same address, but we just do not know which
address this is. But we can
find out that a single variable is enough:
0 VARIABLE A
In its code field a
-FIND A DROP DROP CFA @
address; if we've been fascinated somehow on the stack, we can build it in a constant way to use it:
CONSTANT A-CIM
So we have easy things to do:
: VALIDES (pm address --- f)
CFA @ A-CIM =;
The constant introduction of A-CIM can be floated using the word ' word ' . The 'gives the prime word of the next word of my influence, so it works in the same way as -FIND, only:
If
you use
' word definition
' , you will find the word in the definition
for the word whose title is searched;
and finds the found address
of the find in the definition.
|
(This
will be more fully understood in
Chapter
16.
)
Thus, at the moment of definition, you decide whether or not there is such
a word; the
' does not even give a tell-tale (otherwise
the length band). If we did
not search for a dictionary, it simply stops (
calling the ERROR word known
in
section
13.3
).
The other version of VALTOZOK for which the A-CIM constant is not to be
introduced:
: VALTOZOK (pm address --- f)
CFA @
'A CFA @
=
;
If we do not want to look at the top of the dictionary or do not want to enter the name of the word to search,
(FIND)
which can be found in the appendix .
14.4.3.
User-defined
Interruption
With the term title, see
Section 13.3.
section
, we encountered standard error handling.
If the value of the WARNING
variable is -1, then ERROR will give the command word ABORT, which, if nothing
is done, executes the word ABORT.
We already know this means
that the (ABORT) parter has the ABORT code field address.
If you want another interrupt
procedure, we'll write a word for it, for example:
: SAJAT CR. "En mar nemsokara bucsuzom" ABORT;
and place this code address in the (ABORT) partition:
'SAJAT CFA' (ABORT)!
What was that about?
Summary
of Chapter 14
The words learned:
-FIND | (--- pmc longitude warning)
or (--- false signal) |
It
reads the next word of my influence (up to the space) and searches the
dictionary. Once you find it,
the parsing address of the word is given by its length field and its true
marker. If not, we only get
a false sign.
|
' | (--- pmc) | It gives the title of the next word of my influence. In definition, the word to be searched is taken from the definition text, translates the address into the definition. |
EXECUTE | (code title ---) | Executes the word the code field address of which was given in the worm. |
HAUSER | (relay ---) |
Definition
word. The so-called.
USER variables are in a table;
the relative address given
at the time of defining specifies the location of the variable USER in the
table. This relative address
is in the parameter of the USER variables.
USER variables are used in
the same way as VARIABLE; they
also put the variable's address on the stack.
|
S | (---) | The word whose execution finishes the running of the colon words. |
Examples
14.1. Create a list of USER variables. (Such a list can be found at the beginning of this chapter.)
: USEREK (pm address --- f)
CFA @
'IN CFA @ =
;Then the list is populated:
THESE ARE THE USERS
14.2. Make a list of primitives!
Similarly to the previous task, just write the final word. Primitives can be learned from the point where the pointer points to their own parame- ters:
: PRIMITIVAK (pmcím --- f)
DUP CFA @ =;Then the list is populated:
EZEK-A PRIMITIVAK
14.3. Write a DRAWING (---) word to draw graphs of functions. The functions (x --- y) are vertebrates; if the name of such a word is given after the DRAWING, the DRAW shows us the function between -10 and 10 points. For example:
DRAWING 2 /
or
: F1 DUP * 6/6 - MINUS;
DRAWING F1
To make our life more comfortable, we create a variable for the code field of the function:0 VARIABLE KMCI
If KMCI already contains the code field address of the function, a function call is in this form:
: FHIV (n1 --- n2)
KMCI @ EXECUTE;The function drawing is between the minimum and maximum values recorded between -10 and 10. The program of a line of the graph (the worm waits for the function value corresponding to the line):
: 1SOR (n ---)
CR DUP 3 .R 2 SPACES
11 -10 DO
R FHIV OVER =
IF 42 (if the value fv is correct for the line)
ELSE
DUP 0 = IF (if in line 0)
45 (horizontal line)
ELSE R 0 = IF (if in column 0)
124 (vertical line)
ELSE BL ENDIF
ENDIF
ENDIF
EMIT
LOOP DROP
;The main program is to execute 1SOR for values for the minimum and maximum function values.
: DRAWING (---)
CR -FIND
IF
DROP CFA KMCI!
0 DUP (minimum and maximum starting value)
11 -10 DO
R FHIV MAX
SWAP R FHIV MIN SWAP
LOOP
DO R 1SOR -1 + LOOP
ELSE "There is no such thing "
ENDIF
;
15. Defined words of self-made
words
Whoever does not want a variety of data structures provided by the FORTH
basic words, that is, they want words that define not only single-word variables
and constants but also words that define a vector, a matrix, a double or
a three-sphere variables. For
example, suppose a person uses vectors consisting of 2 bytes of elements.
It would be good if the vectors
somehow would automatically know what to do if they wanted access to one
of their elements.
We know about variables and constants that their value is stored in their
parsers. This will not be the
case with data structures of their own imagination;
the elements of the vector
are kept in the parsing of the word defined as vector.
The vectors, similarly to the
variables and constants, work equally: the code index is the same as the
code field of each vector.
Definition words contain two methods:
Accordingly, the definition words are written in two actions:
<builds
(first act: we make it when defining).
When
defining a word counter, it points to the beginning of the parame- ter of
the word to be defined.
|
DOES>
(second act: this is done by the words defined).
At
the beginning of the DOES> procedure, the title of the word defined is
on the worm.
|
For example, write the word 2CONSTANT (d ---), which defines double-constant constants. When defining, the expected value in the worm is the constant value; this will be the definition of the word on the stack. So, for example, the
3.1415926 2CONSTANT PI
you will create a double-level constant called PI:
PI D.
Let's see the definition of 2CONSTANT:
: 2CONSTANT
<BUILDS
HERE 2!
4 ALLOT
DOES>
2 @
;
(d ---)
(store the double word in the parame- ter)
(drag the dictionary pointer over)
(the parame- ter address in the parame- ter)
Let's get to the vectors! Write the word VECTOR (n ---) defining the number of elements of the vector (16 bit) waiting for the worm; in the parser of the vector, it allocates 2 bytes to each element. The words defined with the VECTOR will then calculate the title of the index element from the stack index and return it to the verme.
: VECTOR (n ---)
<BUILDS
2 * ALLOT
DOES>
SWAP
1- (starting with 1, not 0)
2 * +
;
Thus, for example, we define a 10-element vector:
10 VECTOR TIZ
The font of the word TIZ: (index --- element title). The vectors thus defined work fine until good indexes are given to them; it is only a little misleading, so it is easy to get rid of it in the dictionary. Precaution dictates that vectors check the index obtained and stop if it does not match their scaling. For this, we need to store the size of the vector somewhere, and since we can not hold it somewhere else, we need to use the parser as well. In this case, when the data structure parser contains several data, it is best to design the parser before writing the word (or write it down because it has something else to do with programming).
Then we will start programming:
: VECTOR
<BUILDS
DUP,
2 * ALLOT
DOES
>> R
(store the element number of the vector)
(space for the elements)
(put the title of the parameut)
(the index will remain in the vermen )
DUP 1 <OVER R @> OR
IF. "Bad index!" QUIT
ELSE 2 * R> +
ENDIF
;
Finally, we write a defining word with which we can create text-writing words. The word will be .TEXT; When defining it, you must enter the name of the word to be written. For example the
.TEXT PLD MY SYSTEM OF KETTES, I AM THE TETTES
line
with the word PLD (---); it
outputs the text that we specified to it at the time of definition (up to
the end of the line).
The text to be written in FORTH will be kept in the parody of the
word:
: .TEXT
<BUILDS
1 WORD
(this is the FORTH thread just in HERE)(to the address, ie to the new word) HERE C @
1 +
ALLOT
DOES
COUNT TYPE
;(length of text)
(along with longitude)
(dictionary pointer behind the text)
(set)
We write a word that tells you how much the length of the text that is written in a word defined with a .TEXT. The word SHOCK (--- n) can be used as follows:
SZHOSSZ PLD.
: HOWTO (--- n)
-FIND (find the word in the dictionary)
IF DROP
2+
C @
ELSE. "No such" QUIT
ENDIF
;
The paramex given from -FIND is not the same as the word found on the word; the first two bytes of the parser are used by the FORTH interpreter.
Examples
15.1. Write a 2VARIABLE (d ---) definition word that defines double-blind variables with the initial value of the bug. The variables put the starting address of their parser on the stack.
: 2VARIABLE (d ---)
<BUILDS 2! 4 ALLOT DOES>;
16.1.
When the interpreter
translates
The word
introducing the colon
word
definitions
: creates the name, code and chain fields
of the new word, then so-called.
translates the interpreter
into a translation state. This
means that the interpreter does not execute the terms of his or her influence,
but searches for their code address and stores them in the HERE address (in
the parser of the word that is being created).
Whether
the words found in my influence are performed or translated by the interpreter
depends on the value of the system variable USATE (USER variable).
If the value of the STATE is
not 0, the words of my influence are translated.
|
Accordingly,
if STATE 0 is an execution, if not, translation state.
The value of the STATE (including) the definitions: and the finishing;
word says.
16.2.
When the interpreter does not
translate
Let's look at a fairly common definition:
: COUNT DUP 1+ SWAP C @;
With the above and 14.1. section , the COUNT parter looks like this:
DUP field address 1+ code domain name SWAP code field C @ code field address ; S code field address
Now add the same definition to a comment:
: COUNT (ff-cim --- length length) DUP 1+ SWAP C @;
From the above, it will appear in the second COUNT parse of the (word code field name (since the word STATE is not 0, the system is in translation state.) Common sense, however, suggests that the results of the two definitions should be the same if they only differ in a single comment, the common sense is correct: not all words are translated in the translation state, but exceptions to the rule are instant (immediate, immediate) words.
Immediate
words are not even translated when the interpreter is in translation;
every time the interpreter
finds them, they are executed immediately.
|
A (an instant word, we can write words immediately; we just have to add the word fresh after word definition
IMMEDIATE
so make it straightforward:
: JELENT (---)
CR LATEST ID. "defines started"
; IMMEDIATE
If JELENT is used in a colon word definition, the meaning is written during the definition, but the whole thing has no effect on the resulting new word. Here is the third definition that creates exactly the same parsing as the previous two:
: COUNT3 JELENT DUP 1+ SWAP C @;
The instantaneous or non-immediate word of a word is the second bit of the length field of the name field, so-called. precedence bit. IMMEDIATE simply sets the last bit of the last word defined to 1.
16.3.
When we pay instead of the
interpreter (Compile)
How Does
.
"
Word when used definition? Taking the value to be printed by definition,
so immediately it has to be (so you can text only to read the definition
at compile time). Should , but to have a word that is actually translated
into the parsing of the word that is being generated, otherwise there is
no one who writes the text during the run time.
(. ")
"Compiling
word" is the name of the immediate words that make the code field for another
word (the "running word") and the data for the running word work (field
parameters) in the parser.
|
In
our case
.
"
The word translator, the
(.
')
Running words, the text is kiíratandó edge of the field parameters.
If there is a definition in which the
word
"." Was used:
: RENDBEN. "OK";
then its paramount:
The word "." Does make sure that the FORTH hanger on it goes to the device and that the title interpreter does not attempt to interpret the byte of the hanger as a code address to use it for its operation the virgin finds his / her own return address, which is exactly the title of the font that you want to point out: from here, type the text and then manipulate the virus to point the return address after the string.
: (. ")
R COUNT
DUP 1+
R> +> R
TYPE
;
(the length and the title of the string in
the worm)
( add the total length to a) (return address)
If you want an instant word to translate another (running) word, then a
COMPILE
we have to use word. For example, "
COMPILE (. ")
cheating
in the series
(
".)
kódmezõcímét the paramzõbe.
The word translates the word COMPILE behind it, that places the
kódmezõcímét at HERE.
A. " Checks for a translation state:
:. "
34 (the" delimiter character code ")
STATE @ IF
COMPILE (.)
WORD
HERE C @ (the dictionary pointer is the string)
1+ ALLOT (behind it)
ELSE (no translation, execution)
WORD HERE COUNT TYPE
ENDIF
;
16.4.
Literals
Literals are the numbers that are given in the definition;
these interpreters enter the
parser. The running word handling
the literals a
LIT
For example the
: .HAT 6. ;
literally the 6 is a literal. The parable of the word looks like this:
LIT code field address 6 . kódmezõcíme ; S code field address
LIT
makes sure that when running .HAT, you get 6 on the stack and also that the
address interpreter does not look at the 6 as the execution address.
The value to be used in the word definition may be the result of an operation;
say, we want to use the number
of minutes per day 60 * 24.
This can be anticipated, but
you do not see what this was and how it was calculated;
the multiplication can be written
in the definition text, but it is executed at each run, which is a waste
of time. Instead, we can also
make the translation state a
[
so we eliminate it, produce the desired value in the vermin and a
]
so we return to the translation state. The value on the bug will be translated into the parser by literal literal LITERAL:
: PERCEK [60 24 *] LITERAL. "one minute a day";
The
word LITERAL is, of course, immediate.
If used in the definition,
the LIT running word translates, behind, the value in the box as the field
parameter. If not used in a
definition, LITERAL does not do anything.
The source of the last three words learned:
HEX : [0 STATE! ; IMMEDIATE
:] 192 STATE! ; IMMEDIATE
; LITERAL
STATE @ IF COMPILE LIT, ENDIF
; IMMEDIATE
16.5.
Postpone Instant Words (on
[COMPILE])
How does 'word' work? It should
be an instant word, as it searches for the word behind the word in the dictionary
when translating. The title
then (if used in 'definition') appears as literal in the parsing.
There is nothing in it that we can not write:
: '
-FIND
0 = 0? ERROR (if there is no such thing,
flush) DROP (Parameter Address on the Vermont)
STATE @ IF
COMPILE LIT,
ENDIF
; IMMEDIATE
If someone compares the end of the program with the LITERAL source text, you see that they are completely identical. However, LITERAL can not be included in the 'text: LITERAL is immediate and we do not want it to be' under the definition. Instead, we want you to use all 'immediate' activities when you use it. This is made possible by
[COMPILE]
, which eliminates the immediate behavior of the word behind it for this one occasion. The word 'original' is FIG:
: '
-FIND
0 = 0? ERROR (if there is no word left)
DROP
[COMPILE] LITERAL
ENDIF
; IMMEDIATE
Now let's get acquainted with the LITERAL double-word version of DLITERAL:
: DLITERAL
STATE @ IF (translation status)
SWAP (the bottom element must be placed on the stack first)
[COMPILE] LITERAL [COMPILE] LITERAL
ENDIF
; IMMEDIATE
What was that about?
Summary
of Chapter 16
The words learned:
STATEMENT | ( --- title ) |
USER
variable. If it is 0, the
interpreter will execute it if not, then translate the words to be interpreted
(execution and translation status).
|
IMMEDIATE |
The
last word defined is immediate (sets the so-called precedent bit to 1).
This means that the word is
not translated even in translation;
if you want to translate it,
you should use the word [COMPILE].
|
|
[COMPILE] | For a single occasion it eliminates the immediate behavior of the word behind it. This way you can translate the words immediately. | |
COMPILE | Use it in immediate words. Translates the word behind it. | |
[ | Turns the system into a translation state. | |
] | Enables the system to take effect. | |
LIT | (--- n) | A running word that makes the one-word field parameter behind it on the stack. |
liter | (n
---) during the translated word: (--- n) when executing: (n --- n) In translation state translates the value found in the vermont literal, ie: translates the running word LIT into a single word field parameter n et. Thus, at run time, n is on the stack. In execution state no effect. |
|
DLITERAL | when
translating: (d ---) during the translated word: (d) when executing: (d --- d) In translation state translates the double word value found in the vermont literally, which is translated into the stack when the compiled word runs. In execution state no effect. |
|
(. ") | A. " Translated Run Word Prints to the outboard for FORTH that is behind the parade. |
Examples
16.1. Make a list of the immediate words of the dictionary!
The second bits of the length words of the immediate words 1. Thus, if this longitude bent is placed on the stack and the logical AND result of binary
0000 0000 0100 0000
ie hexadecimal 40, we get the corresponding flag:
: AZONNALIAK (pmmark --- flag)
NFA C @
[HEX 40 DECIMAL] LITERAL AND
;Using the word EZEK-A known in Chapter 14, it is easy to finish:
THESE ARE THE IMMEDIATE
16.2. Write a KNYO (---) word, which if used in the definition, the word defined defines how the definition is in a quake. So if, for example, the
: HOL-VAN KNYO;
HOL-VAN is in operation, it says: "I was 12 months old"
: KNYO
[BLK @ B / SCR /] LITERAL
. "I was in a hurry";
;
16.3. Write a "" word that can be used in the same definition as the "" word, but the translated word begins before the text is written.
:. ""
COMPILE CR [COMPILE] "
; IMMEDIATE
16.4. Define such a; word to indicate the termination of the definition with text.
:;
LATEST ID. (the name of the last word defined)
. "definicio vege"
[COMPILE]; (normal finish)
; IMMEDIATE
16.5. What can be the source of [COMPILE]?
: [COMPILE]
-FIND 0 = 0? ERROR DROP CFA
,; IMMEDIATE
17. How is the control structure made?
In this chapter, we discard some of the already familiar control structures
and get acquainted with a non-standard, but commonly-running, CASE source.
(Solution of CASE FORTH under
the name of Charles Eaker came to immortality.) It is recommended to read
this chapter to those who want to get intimate acquaintance with translating
words or control structures.
Those who do not, they can
enter the description of the operation of the CASE (see 17.5.1).
you can use CASE keywords whenever
you need them without full understanding.
17.1.
Running
words
The controls work with a conditional and unconditional branch.
Both are behind you, in the
parser, looking for the branch address (this is the field field parameter).
Branching addresses are relative
to the address of the field parameter (so say how many bytes of the parameter
should jump). This is good
because the jumping parameterization does not depend on the title of the
jump at the memory.
The two words:
BRANCH | (---) |
unconditional
jump to the (relative) address as field parameter;
|
0BRANCH | (---) | if the received flag is false, it will skip to the (relative) address as field parameter. |
An example makes it easier to understand. Let's say, so we define a word:
: PELDA BEGIN A KETTO AGIN;
(here,
ONE and KETTO are defined, not immediate words).
Let's say the PELDA parter starts at 2000.
At:
BRANCH
must go back to the 2000 absolute address.
In the field parameter, this
address is relative to the parameter address (2006), so the field parameter
value will be 2000-2006 = -6.
After the BRANCH, the value of the parameter will be -6 even if the EXAMPLE
parameter does not start at 2000 but at any other address.
Therefore, relative addressing
is good.
The parser is closed by the code field of the word S (in this case at the
2008 address); this will finish
the title interpreter to interpret the word.
Let's look at a parody of a known word:
Source #S:
: ERROR SWAP IF ERROR ELSE DROP ENDIF;
paramezõje:
In addition to the parameters of BRANCH and 0BRANCH, it is also worth noting that some words (BEGIN, ENDIF) do not include any code field addresses in the parsing, their task is only to indicate where to jump from UNTIL or ELSE.
17.2.
Checks
The check words are called "ERROR", which interrupts all QUITs in error (see
section
13.3 ).
In addition to the error indicator,
the ERROR should also specify a fault number that reflects the nature of
the error. There are the
corresponding error messages in the ranks of the reader's 4th queue.
The word COMP checks whether the control structures are actually used in
translation mode.
source:
:? COMP (---)
STATE @ 0 = 17? ERROR;
To match the keywords correctly, make sure that the opening keyword (say BEGIN) puts a number on the stack, your business name (BEGIN eg 1), and AGAIN is only willing to compile if the vermen finds 1 . Pairing Word:
:? PAIRS (n ---)
- 19? ERROR;
The translation words at the end of the translation must be left in the same way as they found it. To control this, a separate system variable, CSP, is used. The instantaneous value of the pointer is a
! CSP (---)
so we can do it in the variable; the
? CSP (---)
so you can check that the stack is the same as the CSP position. The source of the two words:
: CSP SP @ CSP! ; :? CSP SP @ CSP @ - 20? ERROR;
The! CSP : the? CSP ; call it; at CASE we will see that they may be useful at other times.
17.3.
BEGIN, AGAIN, and
UNTIL
A BEGIN do not translate anything into the parsing;
it is his job to put the words
he paired with him into where to jump.
Thus, the essence of BEGIN's
action: when translating it, it makes the value of the word puncture on the
stack; this is the title where
the first word of the cycle nucleus will be translated, so it will have to
jump back. The stack is still
worth 1, this is BEGIN's business card.
: BEGIN
? COMP
HERE
1
; IMMEDIATE
(
if you do not use it while translating)
(BEGIN "skips")
(jumper address)
(contact)
The relative address of the jumpback is entered by the word BACK:
: BACK
HERE
-
,
;
(skip title ---)
(this is the parameter)
(deducted from the address on the vermin , so)
(we get a relative address)
(the received address is stored in the parameter)
So AGAIN:
: AGAIN
1? PAIRS
COMPILE BRANCH
BACK
; IMMEDIATE
(jumper contact ---) (translation)
(was BEGIN?)
(translating the jumping word)
(skip title translation)
UNTIL differs from AGAIN only in that return jump is conditional.
: UNTIL
1? PAIRS
COMPILE 0BRANCH
BACK
; IMMEDIATE
(jumper contact ---) (translation)
(was BEGIN?)
(translating the jumping word)
(skip title translation)
17.4.
IF, ELSE, and
ENDIF
IF translates the word 0BRANCH into the parser, which jumps to the ELSE branch
or ENDIF after the false signal.
However, when IF is compiling,
you still do not know where the ELSE branch or ENDIF will be, the 0BRANCH
parameter will be entered later.
At the IF moment, we can only
help ourselves to note the vermin where it will have to go to the jump
title:
: IF
(--- parameter address contact) (when translating)
COMPILE 0BRANCH (conditional jump) HERE
0,
2
; IMMEDIATE(parameter address)
(leave the parameter location)
(contact)
If there is no ELSE, ENDIF places the relative bounce address in the specified parameters:
: ENDIF
? COMP
2? PAIRS
HERE
OVER -
SWAP!
; IMMEDIATE
(--- parameter address contact) (at translation)
(this is the absolute jump address)
(now relative to)
(we have reset the parameter)
If ELSE is present, the situation is more complicated:
In the IF then the ELSE will enter the jump address, "literally" in the same way as ENDIF. And ENDIF receives the address from the ELSE where the jump address should be.
: ENDIF
2? PAIRS(par address1 contact --- par address2 contacts)
(translation)COMPILE BRANCH (end of true branch) HERE
0,(this address is given further)
(location of the jump address)(now shows the word counter for the beginning of the false branch) SWAP 2 (the worm: par.cim2 par. title 1 2) [COMPILE] ENDIF (Address Relative to Parent Address 1) 2
; IMMEDIATE(contact)
17.5. A non-standard structure: CASE
17.5.1.
How to use it?
The CASE structure is to handle different things depending on a value (called
this branch value). The word
CASE waits for the grove to run the truncation value at which the action
depends. Each branch is described
between words OF and ENDOF;
such OF branches may be any.
When running, the OF at the
worm is given to determine the branching value of the given OF branch.
If the branch value assigned
to CASE does not deliver the program to any of the OF branches, then the
last ENDOF and the ENDCASE ending the end of the structure will be executed.
The splitting value is dropped
by the real OF from the stack, so if the other part runs, it is on top of
the stack and ENDCASE will remove it.
For example, if German-speaking users are G, English is E, French is indicated
by letter F, this may be a saying:
:
CASE
71 OF (letter G)
"auf Wiedersehen"
ENDOF
69 OF (letter E)
"good bye"
ENDOF
70 OF (letter F)
"au revoir"
ENDOF
(other)
. " what to do with you? "
ENDCASE
;
17.5.2.
Source of
Keywords
As far as we are concerned, the novelty is that the CASE structure has an
ever-repeating element, the OF ... ENDOF branch.
After each ENDOF you have to
go to ENDCASE, but of course (when translating) you do not even know where
it is. Thus ENDCASE should
enter the jump addresses on the stack of parameter addresses;
how many places you need to
call the CSP variable to calculate it.
Endcases and ENDOFs postpone
jump addresses for ENDOFs and ENDOFs.
the OFs generated jumps.
Since this post-entry is done
by ENDIF, if you get the parameter address and a 2-denominate contact, ENDCASE
and ENDOF will mobilize it for this task.
: CASE
? COMP
CSP @
! CSP
4
; IMMEDIATE
(
for example, CSP
is corrupted , fits) (preserve the eedeti value)
(CSP is the current value of the pointer)
(contact): OF
4? PAIRS
(contact name --- parameter address contact)
(when translating)
(was CASE?)COMPILE OVER (comparing the branch value to)
COMPILE = (with the value)
COMPILE 0BRANCH (if not = after ENDOF)HERE
0,
(here comes the jump address)
(location of the jump address)COMPILE DROP (if this is the true OF, the branching)
5
; IMMEDIATE
(No longer required)
(About OF): ENDOF
5? PAIRS(par. address1 contact1 --- par.cím2 contacts2)
(translation)
(was OF?)COMPILE BRANCH (end of OF branch to ENDCASE)
HERE
0,
SWAP 2(we go)
(par address2)
(parameter location)
(preparing for ENDIF)[COMPILE] ENDIF 4
; IMMEDIATE(contact2)
If the last OF branch is not real, then the program will go after the last ENDOF. There is no further question here: what is there, it is accomplished. During the branching value the vermin will be forgotten - ENDCASE will be discarded.
: ENDCASE
4? PAIRSCOMPILE DROP (this will get you running at a)
BEGIN
SP @ CSP
@ = 0 =
WHILE
2(program if none of the OFs was the real one)
(and left the branching value)
(ENDOF jumpers)
(until ENDOFs had been sold)
(the stack on the stack)
(contact with ENDIF )[COMPILE] ENDIF REPEAT
CSP!
; IMMEDIATE
(so we kept the CSP on the bug)
(original value)
18. Another FORTH program: the
textinterpreter
As a summary of what has been learned so far, we will look at how the FORTH
interpreter works.
After loading, the control is given to the word COLD (cold start).
COLD clears block buffers,
sets virtual memory and terminal data, some USER variables are called so
called. fill parameters with
standard initial values. Then
call ABORT. ABORT's text speaks
for itself:
: ABORT
SP! (The primitive pit emptying)
DECIMAL
? STACK
CR .CPU (fill out the processor type)
"FORTH fig- 1.1g."
FORTH
DEFINITIOS
QUIT
;
The textinterpreter is mobilized by QUIT. QUIT after initializing the corresponding variables reads rows from the terminal in cycle and passes them to the word INTERPRET. Scanning is done by QUERY. QUERY calls EXPECT, configuring to place the line read from the keyboard into the command buffer; In addition, it sets IN to 0:
: QUERY
TIB @
80
EXPECT
0 IN!
;
(the title to which EXPECT will be scanned)
(text)
(maximum text length for EXPECT)
In addition to QUERY and INTERPRET, the RP! primitives; it restores the virus to its initial, empty state.
: QUIT
0 BLK!
[COMPILE] [
BEGIN PR
CR
QUERY
INTERPRET
STATE @
(read from the terminal)
(enter the execution state
)
(new line)
(command line scanning)
(command line execution)0 = IF "ok" ENDIF (if not in the middle of the fdefinition) ; (there is a row, the reason may be)
The
textinterpreter is roughly the same as the word INTERPRET.
1NTERPRET processes the influence
I speak of (spoken by BLK and IN system variables).
Of course, WORD makes wording,
which is included in the INTERPRET text in -FIND.
If -FIND successfully searches for the dictionary, the interpreter must decide
whether or not to execute or translate the dictionary word.
This decision (if the possible
values of the STATE are cleverly chosen) can be compressed into a single
comparison: the length of the word field of the word is compared to the STATE
values.
If you are interested in "bits": STATE, if not 0 (ie not executing state),
is hexadecimal C0, binary 1100 0000. In the length of the word field of the
words, the first bit is always 1. Thus, in executing state, the STATE value
is always smaller will be like longitude byte.
In the translation state, the
value of the STATE will be less than the length of the immediate words length
(the second bits of the longitude bit, the precedence bit 1).
So the word should be executed
if the STATE value is less than the length of the word.
If the word is not found in the dictionary, NUMBER will handle it, so try
to convert it. If it does not go, the NUMBER will be flown with 0 ERROR (going
back to QUIT). After a successful
conversion, you only have to decide whether it is a one-word or double-count
value (whether it was a decimal point), so LITERAL or DLITERAL gets the job.
Both do nothing if they are
in translation.
INTERPRET checks the word "STACK" to see if we have not used more items than
we used to stack or did not stack the stack (because it is finite).
In both cases, STACK causes
an error message and goes back to QUIT.
: INTERPRET
BEGIN
-FIND
IF
STATE @ <
IF
CFA,
ELSE
(the tag
is false)
(the word is FALSE if STATE 0,) (or the word is immediate)
( translate )
(put the start address to HERE)
(execution)CFA EXECUTE ENDIF
? STACK
ALWAYS
HERE NUMBER
DPL @ 1+
IF
(there is no element with this name)
(conversion)
(here we get when the conversion is
successful ) (NUMER has failed)
(DPL is not -1, it was a decimal point)[COMPILE] DLITERAL ELSE
DROP(one-word value) [COMPILE] LITERAL ENDIF
? STACK
ENDIF
AGAIN
;
What happens if the text to be interpreted brings you from the command buffer to translate a shadow? The LOAD text will give you the answer:
: LOAD
BLK @> R
IN @> R
0 IN!
B / SCR *
BLK!
INTERPRET
R> IN!
R> BLK!
;
(the queue number)
(note where we left)
(the text containing the LOAD
)
(begin with the beginning of the block)
(the first block of the screen)
So a LOAD calls another INTERPRET, that is, a new BEGIN ... AGAIN cycle (this time the word blocks starts from the blocks of blocks). Whichever (external, internal, or even more) BEGIN ... AGAIN cycle is concerned, one must once complete the interpretation of all the nodes and command lines. The term word is null (its name is used in dictionary lists and documentation x), which is called a single binary zero byte. Therefore, it is good that EXPECT (that is QUIT called QUERY) will cause binary zero or zero after the scanned text; therefore (although not so far) is also binary at the end of the block buffers. Binary 0 (in addition to always delimiting the WORD) is a dictionary word.
Null is a term not only for interpretation but also for this book. Good luck and good work for FORTH!
Appendix
A
FIG-FORTH 1.1.
Glossary
The glossary is given in FIG-FORTH 1.1.
Based on the Installation Manual
glossary. We have seen many
words in the text, this is indicated by chapter numbers or assignments in
brackets, without any further explanation, eg:
Other
references refer to the original text of the glossary and to the words of
the glossary.
There are words whose stack is not marked.
They either do not have a toggle
(FORGET), or they can not be labeled with this technique (for example, COLD
evacuates the vermet). Markings
used to describe the stack effect:
b bytes, c character (so also a byte value), n one word, signed value, u one-word, unsigned value, d double word, signed value (ie 2 elements in the stack), ud double word, unsigned value (2 elements), f indicator, true true value flag, false counterfeit indicator, title one-word, unsigned value, ! (n title ---)
Store the 16-bit n value at address ( 7.2 ).CSP
The CSP sets the current value of the pointer ( 17.2 )# (ud1 --- ud2)
When converting numbers to strings, we use the word <# and #>. Generates the following character code in the output string. The duplicate value added is required to produce additional characters (this is a fraction of the division with BASE content and the character code is generated from the remainder). ( 11.1. )#> (ud-tag length)
Completion of converting numbers into strings. The title string and the length of the output string are placed on the stack, so this can be typed immediately with the TYPE word ( 11.1 ).#S (ud1 --- ud2)
When converting numbers into strings, we use the word <# and #>. Repeating the # word generates character codes in the output string as long as it has a precious value, that is, until the ratio for the additional conversion is 0. ( 11.1 ).' (--- title)
So we use
' nnnn.
The nnnn vocabulary word gives the parsing address of the verme. If used in the definition, the title is translated literally into the word that is defined. If there is no such dictionary word, the line is interrupted by the corresponding error message ( 14 4.2 and 16.5 ).( (---)
So we use:
(cccc)
A) to the delimiter comment is ignored. A) The delimiter must be (in words, it must be in a row!), It can be used in the same way as in executing state, do not forget the (after the word spacing space ( 1.4 , 10.3 , 16.2 )(. ") (---)
A. " is a translated word running, which writes the following (prominent) text ( 16.3 ).(; CODE) (---)
A; CODE is a running word that sets the pointer to the code stored in the parser in the last code of the word that is defined in the last word (CODE).(+ LOOP) (n ---)
A + LOOP is a running word that increases cindex by n and checks whether the cycle has ended.(ABORT)
Interruption defined by the user executing -1 of the WARNING variable. If you do not change it, call ABORT ( 13.3 , 14.4.3 ).(DO) (n1 n2 ---)
The DO is translated by the DO, which makes the cindex start value and the cycle bound for the vire.(
Title1 title2 --- pmmath length byte is true) or
(title1 title2 --- false)
Title2 searches for the name given in the dictionary by the title FORTH. If you find it, it will give you the paramname, the length of the search field and a true flag, if not, only a false sign. FIND calls.(LINE) (n1 n2 --- title length)
Displays the disc buffer address and total line length of the n1th line of the n2 th row ( 13.2 ).(LOOP)
A word translated by LOOP that increases the cindex and checks whether the cycle is over.(NUMBER) (d1 title1 --- d2 address2)
Returns the string starting with address1 + 1 in a doubling to BASE according to BASE and adding it to the d1 received in the vermin to get d2. address2 is the first non-convertible character address. NUMBER calls.[
Used in a double-point definition.
: xxxx [other words];
Pausing the translation. The words after [are not translated, but are executed until]. See LITERAL,] ( 16.4 ).[COMPILE]
Translates the immediate word behind it (which would not be translated without [COMPILE], but would be executed) ( 16.5 ).]
Restore the translation state. See] ( 16.4 ).* (n1 n2 --- product)
Indicates the sign of two signatures ( 1.4 ).* / (N1 n2 n3 n4 ---)
of n4 = (n1 * n2) / n3 enter quotient. All numbers are signed. The n1 * n2 product is stored in duplicate, allowing for greater precision than n1 n2 * n3 / series ( 6.4 ).* / MOD (n1 n2 n3 n4 n5 ---)
to (n1 * n2) / n3 enter division ratio n5 and n4 residue thereof. Store the product n1 * n2 in a duplicate. All values are signed ( 6.4 ).+ (n1 n2 --- sum)
Indicates the signed amount of two signed numbers ( 1.4 ).+! (n title ---)
Enter the signed n number at the 16-bit value on the address and store the amount in the address ( 8.3 ).+ - (n1 n2 --- n3)
If n1 is negative, n3 = -n2 if not, n3 = n2 .+ BUF (title1 --- address2 f)
Displays the title of the next disk buffer2 from the cim1 disk buffer. The returned flag is false if title2 is the address of the buffer stored in the PREV variable.+ LOOP
(n1 ---) (at run time)
(title n2 ---) (translation) In the
double-point definition, use the following form:
DO ... n1 + LOOP
When running, the + LOOP decides whether the control retracts DO respectively. add n1 to the cindex and compare the amount, that is, the new cindex to the cycle limit. (The cindex and the cycle limit are viruses during the cycle.) Returns to the DO until the new cindex is greater than or equal to the cycle limit (n1> 0) is less than or equal to (n1 <0). At exit from the cycle, the cindex and the cycle boundary are removed from the vire ( 4.7.). When translating, the word running (+ LOOP) and the address made by DO on the stack compile a relative bounce address relative to the dictionary dial. The n2 value is used for error checking during translation.+ ORIGIN (n --- address)
The address obtained is the address of the field of the load parameters, increasing by n., (n ---)
The value of n is stored in the place shown by the word counter; increases the value of the word counter with 2 ( 9.3 ).- (n1 n2 --- difference)
gives n1-n2 a difference ( 1.4 ).-> (---)
The interpretation of the shadow goes to ( 2.5 ).-DUP
(n1 --- n1) (if n1 = 0)
(n1 --- n1 n1) (if n1 <> 0)
n1 is doubled only if n1 <> 0. Usually it is used directly before IF to save the single ELSE branch containing the single DROP ( 3.2 ).-FIND
(--- pmcím length-byte true) (if found)
(--- false) (but)
Looks for the next word of my influence (space-bounded) in the dictionary. Once you find it, it will give you the title, the length of the name field and a true marker. If not, we only get a false sign ( 14.4 ).-TRAILING (title n1 --- address n2)
Changes the length of n1 in the title string so that the spaces at the end of the series are not comprehensible ( 13.2 ).. (n ---)
Prints n, converted to BASE, followed by a space ( 1.2 ).. " (---)
Used as follows:.
" cccc "
If used in the definition, it will translate the cccc text into the new word together with a running word that outputs the text to run on a run when running. Using a definition, the cccc text is immediately written ( 1.7 , 10.3 , 16.3 )..CPU (---)
Specifies the type of processor, that is, it gives us the message Z80.. LINE (Line Render ---)
Enter the specified line of the specified number of jets (without the end-of-space) on the device ( 13.2 )..R (n1 n2 ---)
Write the number n1 in a n2 length field aligned to the right ( 4.4 )./ (n1 n2 --- quotient)
The n1 / n2 indicates the vermin ( 1.4 )./ MOD (n1 n2 --- residual quotient)
Returns the remainder of the n1 / n2 division and its subscript ratio. The rest has the same sign as the dealer.0
1
2
3 (--- n)
Frequently used numbers, which are therefore constant in the dictionary ( 8.2.1 , 8.4 ).0 < (n --- f)
The signal obtained is true if n <0 ( 2.4 ).0 = (n --- f)
The signal obtained is true if n = 0 ( 2.4 ).0BRANCH (f ---)
The contingent running word running. If f is false, then with the parameter field after 0BRANCH, the address where the title interpreter continues to work (the parameter can be negative, this means the backward jump) increases. IF, UNTIL, WHILE are translated (among others) ( 17.1 ).1- (n1 --- n2)
n1 is reduced by 1 ( 2.4 ).
Increases 1+ (n1 --- n2) n1 to 1 ( 2.4 ).2- (n1 --- n2)
n1 to 2 ( 2.4 ).2+ (n1 --- n2) increases
n1 to 2 ( 2.4 ).2 * (n1 --- n2)
n1 is multiplied by 2.2 / (n1 --- n2)
n1 is divided by 2.2! (Title d ---)
The double word is stored on the title and the next 3 bytes (the previous contents of 4 bytes will be lost).2 @ (title --- d content)
puts a double word on the address and the next 3 bytes.2DUP (n1 n2 --- n1 n2 n1 n2) Copies the duplicate word
at the top of the stack to the top of the stack.: We use the
so called double-point words.
: cccc. ;
Creates a dictionary element named cccc into which the next FORTH words are translated; or CODE. The textinterpreter translates until the STATE status value is 0. The CONTEXT dictionary is the same as CURRENT ( 1.1 ).;
Completion of the colon word definition. Stops translation; translates the running word S ( 1.1 ).; CODE
So we use
: cccc ....; CODE assembler mnemonics
Stops the translation, finishes the new word cccc defining the word (; CODE). Converts the CONTEXT vocabulary to ASSEMBLER which translates mnemonics after CODE into machine code. If then defined by cccc, cccc nnnn, then the word nnnn will execute the machine code given after cccc. In cccc, there must be a definitive word before CODE.; S (---)
Stops the interpretation of an umbrella ( 2.5 ). By the end of the double-point definitions, this running word translates the; word ( 14.1 ).< (n1 n2 --- f)
Returned signal is true if n1 <n2 ( 2. ).<#
Convert numbers to strings. Conversion works on a double word, producing text at the pad ( 11.1 ).<BUILDS Used in a
double-point definition, such as:
cccc <BUILDS ... DOES> ...;
The created cccc word will be a definable word; when running, <BUILDS creates a new dictionary element:
cccc nnnn
The nnnn vocabulary element that you create calls in the definition of cccc, the procedure described after DOES>. When the word nnnn starts to run, it finds its own parsing address in the verme ( 15 ).= (n1 n2 --- f)
The signal obtained is true if n1 = n2 ( 2. ).> (n1 n2 --- f)
The signal obtained is true if n1> n2 ( 2.2 ).> R (n ---)
Displays the top element of the stack. Usually, we use the equation R> in equation ( 4.1 ).? (title ---)
Write the 16-bit number on the title to the device ( Task 8.1 ).? COMP With an
error message it interrupts the run if it is not called a translation state ( 17.2 ). CSP is
suspended by error message if the value of the pointer differs from the value stored in the CSP variable ( 17.2 ).? ERROR (f error row ---)
With an error message with the specified number, it interrupts the run if the flag is true ( 13.3 ). EXEC With
error message, it interrupts run when called in translation mode.? LOADING
An error message interrupts the run if it is not called a caller.? PAIRS (n1 n2 ---)
An error message interrupts the run if n1 <> n2. The error message indicates a bad match between the control structure keywords ( 17.2 ). STACK
An error message stops running if the stack is under or overflowed ( 18 ).? TERMINAL (--- f)
Checks whether the terminal has been interrupted (most of the time, if any key is pressed). ( 12.1. ).@ (title ---- n)
Returns the 16-bit content of the address ( 7.2 ).ABORT
Empties the dam, the virus, and the execution state. Provides control to the terminal; install-dependent message ( 13.3 ).ABS (n --- u)
Returns the absolute value of n number ( 1 ).AGAIN (address n ---) (translation)
Definition:
BEGIN ... AGAIN
When running, AGAIN gives control to BEGIN. The vermet remains unchanged. The cycle does not end (unless an R> DROP is executed at a call level below) ( 5.1 ).
When translating, the word BRANCH is translated, from the HERE to the address given to the worm. It is for error checking under translation ( 17. 3. ).ALLOT (n ---)
Displays the nominal number n for DP marking. We use it for booking, to organize memory ( 9.3 ).AND (n1 n2 --- n)
Performs bitwise AND operation between n1 and n2 ( 2.3 ).B / BUF (--- n)
Constant; the length of the disk buffers, the length at which BLOCK reads the virtual memory ( 13.1 ).B / SCR (--- n)
Constants, it specifies the number of blocks that each piece contains. According to the convention, the size of the screens is 1024 bytes, 16 by 64 characters ( 13.2 ).BACK (title ---)
The relative address is calculated from the HERE to jump to the given address in the verme. The calculated address is translated into the dictionary ( 17.3 ).BASE (--- address)
User variable; the base number of input and output conversions ( 8.2.1 ).BDOS ( parm fcode --- dircode)
where parm stands for the parameter passed to the BDOS in the DE register pair, and fcode is the BDOS function number. Dircode is the directory code returned by the BDOS. This enables you to access CP/M files using high level definitions.BEGIN (title --- n) (translation)
Definition:
BEGIN ... UNTIL,
BEGIN ... AGAIN,
BEGIN ... WHILE ... REPEAT
When running, BEGIN indicates the beginning of the cycle core, this return point is the corresponding UNTIL , AGAIN or REPEAT. UNTIL returns to BEGIN if the flag found on the stack is false, AGAIN and REPEAT always return ( 5.1 , 5.2 , 5.3 ). When translating, BEGIN leaves the return address and n (for serving for translation-proof error) n to the bug ( 17.3 ).BL (--- c)
The constant of the space code ( 8.4 ).BLANKS (Title Length ---) Spans
the length of the long memory area starting with the title ( Task 7.1 ).BLK (--- address)
User variable contains the number of the block that is being interpreted. If 0 is the interpreter works from the command buffer ( 13.1 ).BLOCK (n --- address) Returns the address of the disc buffer containing the nth block. If the block is not in memory, it will be scanned in the buffer that was the last one to refer to last. If the buffer was modified to read the block in a modified block then it will be released to the disk first. See also BUFFER, UPDATE, FLUSH ( 13.1 ).
BRANCH
The unconditional branching running word. The next field parameter increases the address where the interpreter performs his job (the parameter may be negative, which indicates a backward jump). The ELSE, AGAIN and REPEAT translations ( 17.1 ).BUFFER (n --- address)
Stores the next disc buffer as n-th block. If the previous contents of the buffer were modified, it will be written to the disc. The nth block is not read. The received address is the buffer for the first data storage address.BYE
Exits the FORTH interpreter. The modified blocks are written before exiting (the word FLUSH is executed), but no confirmation is expected.C! (b title ---)
The b bit of b is stored at the specified address ( 7.1 ).C, (b ---)
The b bit of b is stored in the next free byte of the dictionary, increasing the value of the word counter ( 9.3 ).C / L (--- b)
System constant. It gives the length of the queue lines (in characters), that is, fig-Forth 64 ( 13.2 ).C @ (title --- b)
Returns the title of the title to 8 bit ( 7.1 ).CFA (pmc --- code field address)
Produces the code field address ( 12.1 ) from the parameter field address of a dictionary word .CMOVE (where to where ---)
Moves the specified number of bytes from where the address is moved to. The byte at the lower address is first transmitted ( task 7.1.c ).COLD
The so-called. cold start. Set the dictionary to the minimum standard and restart it with ABORT. You can call from Terminal, delete our programs and restart the system ( 1.3 , 18 ).COMPILE
When the word containing the COMPILE is executed, the code field address of the word after the COMPILE is translated into the dictionary. We can handle some special translation situations ( 16.3 ).CONSTANT (n ---)
Defining word, like this:
n CONSTANT cccc
There is a n number in the parsed word cccc. If after this the word cccc is executed, the value n is placed on the stack ( 8.4 ).CONTEXT (--- address)
User variable; contains a pointer to the search dictionary.COUNT (Title1 --- Title2 Length)
The title of the text (which is no title other than title1 + 1) and the length of the text (the content of the length of the title1) begins with the title 1. COUNT is typically used before TYPE ( 10.1 ).CR (---)
Returns a carriage return and a line output character to the output device ( 1 ).CREATE Definition word
:
CREATE cccc
The code field of the cccc created word contains the parsing address of the word, the parser is empty (can be uploaded to CREATE afterwards). The new word is created in the chaining dictionary. The definition of; so we can close it down.CURRENT
CSP (--- address)
User variable to temporarily store the tax rate. Used for error checking under translation ( 17.2 ).D + (d1 d2 --- d sum)
Doubles the sum of the two double-blind values ( 6 ).D + - (d1 n --- d2)
If n is negative, d2 = -d1, if not, d2 = d1.D. (d ---)
Displays the doubling value for the output device, followed by a space. The upper part of the stack is the larger part of the stack. The conversion is done according to the BASE value ( 6.3 ).DR (dn ---)
Displays a double-blind value in a n-length field right-aligned ( 6.3 ).DABS (d-ud)
Returns the absolute value of d doubling ud ( 6.3 ).DECIMAL (---) Sets
the BASE value to 10 (so the numbers are written and scanned in a decimal system) ( 8.2.1 ).DEFINITIONS
We use:
cccc DEFINITIONS
Adjusts the chaining dictionary to the search dictionary. Executing the cccc dictionary name will make cccc a search dictionary, and after the DEFINITIONS the chaining dictionary will be cccc ( 12.2 ).DIGIT
(c n1 --- n2 true) (successful conversion)
(c n1 --- false) (unsuccessful conversion)
The c character code is converted to the binary equivalent of n2 by the base number n1. If the conversion succeeds, it will give a true flag. If conversion is not possible, we only get a false flag.DIGIT (--- b)
System variable. Indicates the result of the last disc operation. There was no error in 0.DISK-ERROR
DLITERAL
(d --- d) (in execution state)
(d ---) (at translation) When
translated, the double-word value found on the vermin translates to double-liter literals. The translated word will run on the stack when it runs. No effect at execution stage ( 16.4 ).DMINUS (d1 --- d2)
Returns duplicate d1 (duplicate) 1 times ( 6 ).DO
(n1 n2 ---) (running)
(--- address n) (translation) In the
definition of a double-point,
DO .. LOOP
DO ... + LOOP
When running, the DO launches an index cycle with a cycle limit of n1, the starting value of the cindex while n2. DO removes these values from the stack. When the program reaches the LOOP, the cindex increases by one. The program will always go back to DO after the LOOP until the cindex reaches or does not exceed the cycle limit. The cutoff of the cycle also means removing the cindex and the cycle limit, n1 and n2 must be given at run, which may be the result of other operations. Within the loop core, the actual value of the cindex can be copied to the stack by the word I. See I, LOOP, + LOOP. LEAVE ( 4.2 ,4.7. ).
When translating (DO), the word running at the start of the cycle core and the n value for the translation error checking are left on the worm.DOES>
Used together with <BUILDS. See <BUILDS ( 15. ).DP (--- title)
User variable, the word counter. Displays the first free memory address above the dictionary. Its value is read with the word HERE and can be changed with ALLOT ( 9.1 ).DPL (--- address)
User variable contains the number of digits after the decimal point of NUMBER last reading. If there was no decimal point, its value is - 1. ( 11.2 ).DR0
DR1
DROP (n ---)
Removes the top of the stack ( 1.5 ).DUP (n --- nn)
Duplicates the top element of the stack ( 1.5 ).ELSE (address1 n1 --- address2 n2) (translation) In the
definition of a double-point definition:
IF ... ELSE ... ENDIF.
When running, ELSE indicates the end of a true line after IF. The end of the true branch goes to ENDIF. There is no need for a drum ( 3.2 ). When translating the word BRANCH, it places the jump address, leaves the address of the fake branch2 and the n2 number for translation error checking. IF's translated jump address is calculated from address1 and HERE and stores the relative address on address1 ( 17.4 ).EMIT (c ---)
Write the character c to the output device ( 1 ). The value of the OUT variable is increased by one (see 8.2.2 ).EMPTY-BUFFERS
All blocks buffer is blank, possibly without changing its contents. Modified blocks are not written out. It also serves as the initial initialization procedure for the disc ( 13.1 ).ENCLOSE (title1 c --- title1 n1 n2 n3)
The WORD is a text analyzer primitiva. The vermen gets ca delimiter, title1 is the start address of the text to be analyzed. Returned addresses n1, n2, n3 are relative to address1, n1 is the first character of the first character after the address1, n2 is the first delimiter character after n1, n3 is the first non-analyzed character. Binary zero is considered bounded by irons regardless of the ac value.END is
the synonym for UNTIL.ENDIF (title n ---) (translation)
Use in a double-point definition:
IF ... ENDIF
IF ... ELSE ... ENDIF
When executing, ENDIF selects the IF or ELSE jumps. THEN is the synonym for ENDIF. See also IF and ELSE ( 3.1 ). When translating, ENDIF calculates the relative address of the heading to the HERE from the address and stores it in the address. The n number serves for error-checking during translation ( 17.4 ).ERASE (title n ---) Resets
n bytes from address ( task 7.1.e ).ERROR (n --- in blk)
Indicates a fault and restarts the system. The procedure performed depends on the value of WARNING. If WARNING 1 is the nth line counted from the 0th line of the fourth screen, an error message. (N may be negative too, but it may show too much on Screen 4.) If WARNING is 0, n is output as an error message (no virtual memory). If WARNING -1, the word (ABORT) is executed, which calls ABORT. The (ABORT) function can be changed by the programmer ( 14.4.3 ). The values of the IN and BLK system variables are stored on the stack so the error can be localized. The system is restarted with QUIT. ( 13.3. )EXECUTE (title ---)
Performs the word whose code field is in the worm ( 14.4.1 ).EXPECT (Address Character) - It
reads characters from the terminal to the title to the carriage curb or access to the specified character. At the end of the text one or more binary 0 ( 7.1 ) is added.EXTEND ( n ---)
extends (sic!) the logged in screens file by n blocks, as long as disc space permits. You could start by SAVE-ing a 0-size file at CCP level and then expand it after you logged in same file at the time you invoke FORTH (e.g. FORTH D:SCREENS.FRT).FCB (--- address)
leaves the address of the current file control block on the stack.FENCE (--- address)
User variable. It contains the address at which a lower address can not be deleted by FORGET (the dictionary is protected).FILL (address length b ---)
The memory is filled by the byte of the length of the memory by title (length 7.1.d ).FIRST (--- n)
Constant; the first block buffer address.FLD (--- address)
User variable; FIG-FORTH does not use it.FLUSH
Displays all modified blocks on disk.FORGET
This is how we use:
FORGET cccc
Deletes the word element cccc together with all the above. If the search and chaining dictionary does not match, we get an error message. ( 1.3. )FORTH
The name of the primary dictionary. Implementing FORTH as a search engine. The word FORTH is immediate, so it is executed at translation. ( 12.2. )HERE (--- address)
Returns the first free byte address above the dictionary ( 9.1 ).HEX (---)
Adjusts the conversion count to 16 (hexadecimal) ( 8.2.1 ).HLD (- address)
User variable. When converting numbers into strings, it contains the title of the last converted character.HOLD (c ---)
When converting numbers into strings, we use the word <# and #>. In the output string enter the ac code character; eg. 2E HOLD is a decimal point ( 11.1 ).I (--- n)
DO ... LOOP cycle; the cindex is placed on the stack ( 4.1 , 4.4 ).ID. (title ---)
Displays the name of the dictionary element whose name field is in the vermin ( 12.1 ).IF
(f ---) (run)
(--- title n) (translation)
Use in a double-point definition:
IF (true part) ... ENDIF IF (true part) ... ELSE (false part) ENDIF
IF based on the signal received, decides that the true or the false part will be executed. If the signal received is true, the true part is run, if not, the false part after the ELSE (if any). In both cases, the program continues after ENDIF. If the ELSE part is missing and the signal received is false, then control (END , 3.1 , 3.2 ) goes directly from IF to ENDIF . When translating, 0BRANCH is translated and leaves the jump address. The title and n will be used for later insertion of the jump address. ( 17.4 ).IMMEDIATE
Immediately defines the last word defined (sets its precedent). This means that if used in the instant word definition, it will be performed at translation and will not be translated into the new word. Instant words can be translated with the word [COMPILE]. ( 16.2. )IN (--- address)
User variable; it contains the title of the text relative to the beginning of the command buffer or block buffer that the WORD will read next. The IN value is used and set by the WORD ( 13.1 ).INDEX (tó --- ---) Between
the two borders, it lists the first lines of the viewers (which, according to the convention, are the comments about the content of the umbrella) ( 2.5 ).INTERPRET
An external textinterpreter that executes or translates words from my terminal (terminals or disks) to STATE. If the word
can not be found in the dictionary, it converts it into the BASE value. If that does not work, we get an error signal. Text is tagged by WORD. If a number contains a decimal point, it converts it into a double slice; the decimal point has no other effect (see NUMBER). ( 18 )KEY (--- c)
Displays the key code key on the terminal ( 2.1 ).LATEST (title)
Specifies the name of the top element of the linking dictionary ( 12.1 ).LEAVE
DO ... LOOP or DO ... + LOOP cycle. The cycle limit is adjusted to the cindex, reaching the end of the loop at the nearest LOOP or + LOOP. The value of the cindex remains unchanged ( 4.6 ).LFA (pmc --- chain address)
Displays the chain address address of a dictionary element ( 12.1 ).LIMIT (--- title)
Constant; the last available memory buffer for the disc buffer. In general, this is the highest memory address for the system.LIST (n ---)
Displays the text of the n-th screen for the device. The SCR variable will contain after the LIST the number of the numbered listener ( 2.5 , 13.2 ).LIT (--- n) In a
double-point definition, the translator translates LIT before compiling a 16-bit number. When running, LIT puts the field parameter behind it on the stack ( 16.4 ).LITERAL
(n ---) (translation)
(n --- n) (in execution state) When
translated, the value found in the vermin is translated into 16-bit literals. (The word is immediate, so it will be translated.) Typical use is the following.
: xxxx [calculations] LITERAL ...;
(The translation is suspended during calculations.) No effect is in effect ( 16.4 ).LOAD (n ---)
Starts the nth capsule to interpret. Interpretation (loading the umbrella) ends at the end of the umbrella or ends with the word S. See S and - ( 2.5 , 18 ).LOOP (address n ---) (when translating)
Use in a double-point definition:
DO ... LOOP
When running, the LOOP determines whether the control returns to DO by the cindex and its cycle limit value. Increase cindex by 1 and compare it with the cycle limit. It will go back to DO until the cindex reaches or does not exceed the cycle limit. Once it reaches the cindex and throws the cycle boundary, the program is moved ( 4.2 ). When translating the word (LOOP), it uses the address to calculate the address of the back to DO. It serves a turn-by-turn error check.M * (n1 n2 --- d)
Mixed action: multiplies the double-word multiplier ( 6 ).M / (d n1 --- n2 n3)
Blended operation: gives the n2 residues and n3 quotients of the ad / n1 divisional sign (6 ).M / MOD (ud1 u2 --- u3 ud4)
Unsigned mixed operation: gives ud1 / u2 division u3 residues and ud4 double-blind quotients ( 6 ).MAX (n1 n2 --- max)
Returns the two digits ( 1. )MESSAGE (n ---)
Displays the nth number of nurses (n can be negative) from the 0th row of the fourth screen. If WARNING 0 (because there is no virtual memory, for example), just type n ( 13.3 ).MIN (n1 n2 --- min)
The smaller of the two numbers ( 1. ).MINUS (n1 --- n2)
n2 = -n1 ( 1. ).MOD (n1 n2 --- mod)
Returns the remainder of n1 / n2, with the sign n1.NFA (pmname ---
name field ) Displays the address field name of a dictionary element ( 12.1 ).NOOP (---)
No operation (empty word).NUMBER (Title --- d)
Converts the FORTH item that starts with the title to a signed double-word value (corresponding to the BASE value). If the text contains a decimal point, its position is preserved in the DPL variable, but the decimal point has no other effect. If conversion is not possible, we will get an error message ( 11.2 ).OFFSET (--- title)
OR (n1 n2 --- or)
Bit-by-lease or logical operation ( 2.3 ).OUT (--- address)
User variable, EMIT increases. The programmer can change or examine the control format ( 8.2.2 ).OVER (n1 n2 --- n1 n2 n1)
Copy the second element of the stack to the top of the stack ( 1.5 ).P! (b b2 ---)
b1 to the b2 port Z80.P @ (b1 --- b2)
b1 of the Z80 port is read into b2.PAD (--- address)
Enter the address of the buffer used for text storage; this buffer is at a constant distance from HERE ( 7.1 , 9.1 ).PFA (name field name --- point name)
Returns the field name of a dictionary word ( 12.1 ).PREV (--- title)
Variable; contains the last reference block buffer number. The UPDATE command will mark this buffer as modified ( 13.1 ).QUERY
Scans a line from the terminal until ENTER is pressed, but up to 80 characters. The text is placed in the address provided by TIB and the IN variable is set to 0 ( 18 ).QUIT
Empty the virus, stop the translation and return the control to the terminal ( 7.3 , 18 ).R (--- n)
Copies the top element of the wine onto the stack ( 4.1 ).R / W
R # (--- address)
User variable is used by editors to store the cursor position.R> (--- n)
The top element of the vibe is placed on the stack. See> R and R ( 4.1 ).R0 (--- address)
User variable contains the initial value of the vibration index.REC# pushes the corresponding record count address onto the stack.
REPEAT (address n ---) (compile-time)
used specifically Dual definition:
BEGIN ... WHILE ... REPEAT
Running When control returns without BEGIN REPEAT condition beyond ( 5.3. ).ROT (n1 n2 n3 --- n2 n3 n1)
The third element of the stack is over ( 1.5 ).RP!
The vibration indicator is initialized by the variable R0.RP @ (--- address)
Returns the memory heading at which the vibration indicator is currently pointing.S-> D (n --- d)
Returns the duplicate equivalent of the signed number n.S0 (--- address)
User variable contains the initial value of the pointer (see SP!) ( 7.3 ).SCR (--- address)
User variable; ( 13.2 , 13.4 ) of the current (the last listed LIST ).SIGN (nd --- d)
When converting numbers to strings, we use the words <# and #>. If n is negative then inserts a - signal into the output string. Removes n from the stack, but leave the duplicate above it in peace ( 11.1 ).SMUDGE
The so-called. "smudge bit" is used. The "smudge bit" in the word field of the words is the length of the longitudinal bits. This allows you to validate the words at the end of the definition, so the unfinished definitions are invalid, and the interpreter does not even find them.SP!
Initializes the pointer with the value stored in S0.SP @ (--- address)
Returns the decimal point (before executing SP @) (eg 1 2 SP @ @ result: 2 2 1) ( 7.3 ).SPACE Write
a space on the device ( 1 ).SPACES (n ---)
n writes space for the device ( 4.3 ).STATE (--- address)
User variable indicates the system's translation or execution state. The non-0 value translates ( 16.1 ).SWAP (n1 n2 --- n2 n1)
Replaces the top two elements of the stack ( 1.5 ).TASK
Blank word, used for separating individual applications. If you translate the TASK before your own words, we can delete your words (application) at once by forgetting TASK FORGET.THEN is
the synonym for ENDIF.TIB (--- address)
User variable, contains the command buffer address ( 13.1 ).TOGGLE (title b ---)
Complements the title content by ab bit pattern.TRAVERSE (address1 n --- address2)
Passes the word field of a FORTH word. Title1 is the address of the longitude or last letter of the name field. If n = 1, from the beginning to the end of the name field, if n = -1, we move from the end to the beginning. Returned address2 is the address of the other end of the domain.TRIAD (listener)
lists 3 screens on the device: these include the specified number, and the first number is divisible by 3. You can interrupt the list of individual screens by pressing any key.TYPE (title character)
From the title, it outputs the specified number of characters to the device ( task 7.1 , task 7.1 ).U * (u1 u2 --- ud)
Denotes double unsigned, unmarked numbers of two unsigned numbers ( 6 ).U. (u ---)
Displays the unsigned value found on the screen, followed by a space ( 6.1 ).U / (ud u1 --- u2 u3)
The ud / u1 divide the u2 residues and u3 quotients. All values are unsigned, ud duplicate ( 6. ).U < (u1 u2 --- f)
Compares the unsigned value found on two worms. f is true if u1 <u2.UNTIL
(f ---) (at run time)
(title n ---) (translation) In the
definition of a double-point, use:
BEGIN ... UNTIL
When running, UNTIL returns the control to BEGIN conditionally (false value of the received flag); if the signal received is true, it will go further ( 5.2 ). When translating, it translates the 0BRANCH and the address from the HERE to the address to the address. It serves for error checking under translation (page 17.3 ).UPDATE
The last referenced block (the number of which is in the PREV variable) is denoted as modified. If the buffer containing the block then needs to store another block then the block is written to disk ( 13.1 ).USE (--- title)
Variable. It contains the number of block buffer to use (which is the last one in the buffer).USER (n ---)
Defining word, so use:
n USER cccc
This creates a cccc user variable. The cccc parity is n; the relative address of the user variable relative to the beginning of the table of user variables. If cccc is executed after that, the variable's address (the title of the table and the sum of n) is placed on the stack ( 14.3 ).VARIABLE (n ---)
Defining word, so use:
n VARIABLE cccc
VARIABLE creates a cccc word whose parser is initialized to n. If after these cccc is executed, the parame- ter is placed on the stack. This way we can read or change the value of the variable ( 8.3 ).VLIST
Lists the names of the search engine dictionary. Press any key) to stop the listing ( 1.1 , 12.1 ).VOC-LINK (--- address)
User variable contains a pointer for the last dictionary defined. Dictionary names are chained.VOCABULARY Defining
word is used:
VOCABULARY cccc
This creates a cccc dictionary, executing cccc as a search dictionary itself, and makes the
cccc DEFINITIONS
series a cccc-linking dictionary. Cccc contains the words in which the cccc was created. so all the dictionaries contain the words of the FORTH dictionary. Dictionary names are defined as immediate. ( 12.3. )WARM
The so-called. hot start. All blocks are blank, and the modified blocks are not written out. It drains the vermet and the virus and then enters the execution state.WARNING (--- address)
User variable controls the output of error messages. If the value is 1 and there is a virtual memory, the error messages are from the beginning of the fourth screen. If 0, the error message only identifies the error with its number. If -1, the word (ABORT) is executed (user defined interrupt, 14.4.3 ). See MESSAGE, ERROR ( 13.3 ).WHILE
(f ---) (running)
(address1 n1 --- address1 n1 address2 n2) (translation)
Used in a double-point definition.
BEGIN ... WHILE ... REPEAT
When running, WHILE's action depends on the signal received. If the flag is true, it will transfer the program to the true part of the REPEAT. REPEAT returns the control to BEGIN. If the signal is false, the control is output after REPEAT. When translating, WHILE translates 0BRANCH and places the address of the jump address address2 on the stack. This will enable REPEAT to swap the bounce address.WIDTH (--- address)
User variable contains the maximum word length. It can be between 1 and 31; if we do nothing, it is worth 31.WORD (c ---)
Reads the next portion of the string to be interpreted to the delimiter character c. The scanned part is made in the form of a FORTH garland to the HERE address. Add one or more spaces at the end of the text. C characters before the text to be scanned are ignored. If the BLK is 0, the text is taken from the command buffer, if not, from the block number stored in the BLK. See BLK, IN ( 10 ; 13.1 ).XOR (n1 n2 --- xor)
Returns the result of the bit-by-bit error OR between the two values (2.3 ).
The words of the Forth Extensions add-on:
2DROP (d ---)
Removes the double word at the top of the stack ( task 6.1 ).2OVER (d1 d2 --- d1 d2 d1)
Copy the second duplex word on the stack to the top of the stack ( task 6.1 ).2ROT (d1 d2 d3 --- d2 d3 d1)
The third double stack of the stack is top ( task 6.1 ).2SWAP (d1 d2 --- d2 d1)
Replaces the top two doubles of the stack ( task 6.1 )..STACK (---)
Lists the contents of the stack. .STACK does not change the vermet ( 1.6 , 7.3 )CASE ... OF ... ENDOF ... ENDCASE
A value-dependent control structure ( 17.5. )CLS (---)
Clears the screen. (Sends a 12 character code to the outboard).D- (d1 d2 --- d-coefficient
) Returns the difference d1 and d2 d1 to d2 (d1-d2) ( task 6.2 ).D = (d1 d2 --- f)
The signal obtained is true if the d1 and d2 doubling equals are equal ( task 6.2 ).D < (d1 d2 --- f)
The signal obtained is true if d2 doubling is greater than d1 doubling ( task 6.2 ).DEPTH (--- n)
Displays the stack elements (before DEPTH is executed) on the stack ( 1.6 , 7.3 )FREE (---)
Displays the amount of available memory available in bytes.INK (b ---)
Adjusts the color of the ink according to its b value (see IS-DOS User's Guide ).J (--- n)
The external cindex is placed on the stack ( 4.4 , 4.5 ).PICK (n1 --- n2)
Copy the stack n1 to the top of the stack ( 1.6 , 7.3 )ROLL (n ---)
Sends the nth element of the stack to the stack ( 1.6 , 7.3 ).SN (n1 --- n2)
-1 gives the worm if n1 is negative, + 1 is positive and 0 is zero.
error Number | error Message | |
December | hex | |
1 | 1 | empty
stack The stack is empty. |
2 | 2 | dictionary
full There is no more space in the dictionary. |
3 | 3 | has
incorrect address mode Wrong addressing mode. |
4 | 4 | is
not unique There is such a name in the dictionary. |
5 | 5 | |
6 | 6 | disc
range? There is no such block in virtual memory. |
7 | 7 | full
stack The stack is full. |
8 | 8 | disc
error! Disk error. |
9 | 9 | |
10 | THE | |
11 | B | |
12 | C | |
13 | D | |
14 | E | |
15 | F | |
16 | 10 | |
17 | 11 | compilation
only, use in definition Used in definition only. |
18 | 12 | execution
only Can be used in execution only . |
19 | 13 | conditionals
not paired Pairing of control structure keywords is incorrect. |
20 | 14 | definition
not finished Unfinished Definition. |
21 | 15 | in
protected dictionary is in the protected part of the dictionary. |
22 | 16 | use
only when loading Only used when printing. |
23 | 17 | off
current editing screen There is no current screen . |
24 | 18 | declare vocabulary |
There is no error message for error number 0, which we get if we try a word that is not in the dictionary and can not be interpreted as a number.
C) Appendix
The
text editor (editor)
The Ragsdale ditor itself is written in FORTH so you have to download it from the virtual memory before using it. The editor - according to the conventions - starts with the 7th wrap, and the editor's 2.0 version occupies 5 frames. So loading a
7 LOAD
with
instructions. The editor first
loads the FORTH Extensions plugin (whose words are described at the end of
Appendix A), creates its own dictionary, defines the editor's words, and
then sets the WARNING system variable to 1 (triggers the display of error
messages.) (Note: FORTH Extensions- you can use it without loading the editor,
so you will need to load it from the 17th.)
The words of the editor:
TEXT (c ---)
To c border character c reads the text of the influence and places it in the previously filled pad.LINE (n --- address)
Returns the title of the nth row of the current node.WHERE (blk in ---)
Using the parameters left by the ERROR, prints the number of the grid and row containing the error and the wrong line.#LOCATE (--- divide row) Displays
the current character position data: the number of the character row (row) and the number of characters within the row (spoz).#LEAD (--- line item extension) Displays
the current character position data: the memory address of the character containing the character and the number of characters within the line.#LAG (--- title
line length) Specifies the number of characters (line length) of the character address (character address ) of the current character position and of the character to the end of the line that contains the character.-MOVE (title line ---)
The line in the title is entered in the specified number of rows of the current quilt.
The words given so far are used by the other words in the editor, the user is not advised to use them. The words "user" of the editor:
B (---)
The current character position is retracted with the length of the text in the pad.C (---)
After entering the current character position, the text in the next line of my influence is entered.D (
Sort ---) Deletes the specified number of lines from the current pointer, but keeps the text in the pad (so you can move it elsewhere).E (
Sort ---) Displays a specified number of lines in the current window with spaces.F (---)
Looks for the next line of my influence in the current umbrella.H (
Sort ---) Copies the specified number of lines of the current window into the pad.I (
sort ---) Insert the line in the row with the specified number of rows (push the other rows below).L (---)
Lists the current screen. After the list, print out the current line again.M (n ---)
Increases the current character position with n, writes the line containing the new position.N (---)
Looks for the next occurrence of the FORTH garland in the pad; prints the line containing the new character position.P (
sort ---) Replaces the specified number of lines with the next line of my influence.R (
sort ---) Replaces the specified number of lines with the line in the pad.S (
Sort ---) Moves the rows of the current viewer down from the rows, and fills the nth line with space.T (sort ---)
The current character position will be the beginning of the specified number of lines; prints the line with the new position.X (---)
Finds the text in the next line of my influence in the current screen and deletes it.CLEAR (Number of nicks ---) Places
the number of umbrellas filled with space and makes it real.COPY (number1 number2 ---)
Copies the contents of the first screen to the second.DELETE (n ---)
Deletes the n characters before the current character position; fills the end of the line with space.FIND (---)
Looks for the text with the FORTH string in the pad in the current queue. If you can not find it, it will give you an error message and the beginning of the screen will have the current character position. If you find it, the current character position will be the end of the text.TILL (---)
Finds the text entered in the next row of its influence in the current character position row and deletes the part between the cursor and the end of the text.TOP (---)
The current character position will be the first character of the umbrella.TS (---)
Lists the current screen.1LINE (--- f)
In the current character position row of the current screen, after the current character position, searches for the text with the FORTH string in the pad, f will be true if found; the current character position will end with the text found. If you did not find it, f is false, and the current character position is the end of the line.
Note: A node is current because the SCR variable contains its serial number. The character position within the umbrella (cursor position) is actual from the fact that the variable R £ contains its serial number (relative to the front of the umbrella).
Practical
advice for editing an umbrella:
First, with INDEX, look for a (blank) umbrella for us.
If the content of an earlier
screen has become redundant and you want to enter a new program, you can
clear it with the CLEAR command.
Before using the editor's words,
remember to use the word EDITOR to make its dictionary default.
If you have a set of shades, you must first make it realistic, so use the
LIST word to find the actual content.
Then we have enough to use
the editor L word for the current list.
You can use the P command to
enter the current queue rows.
Example of using
it:
0 P: TABLA (multiplier)
1 P 11 1 DO
2 P CR 11 1 DO
3 P IJ * 4 .R
4 P LOOP
5 P LOOP CR
6 P;
Of
course, lines are not mandatory to start inside, or even write words in a
row up to 64 characters long.
The end of longer lines is
lost, we have to pay attention to that!
AP also means that you have
to leave a space, but this does not count in the length of the line.
The lines are, of course, not
required to be in ascending order and leave blank lines for clarity.
If you want to insert a line somewhere in the back, it is worth doing the
S word. You can also copy a
line by using the H and I words sequentially.
To move the row, the words
D and I can be used sequentially.
We can not just move / copy
within a window, but we also need to switch between the two words (preferably
using the LIST word).
D) Appendix
A
fig-Forth memory allocation