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

Source:
Z80FORTH.ASM

DISCIO.ASM
CONPRTIO.ASM

Introduction
1. Getting Started
1.1. About dictionary
1.2. What is a stack?
1.3. Back to dictionary
1.4. We learn to count - it will be a bit unusual ...
1.5. Rearranging the stack
1.6. Useful but not standard words
1.7. One more word about writing
What was it about?

2. Comparative and logical operations
2.1. Indicator
2.2. Types of data so far seen
2.3. Why should a marker be "well-educated"?
2.4. Quick Actions
2.5. How do we store our programs?
What was it about?

3. Conditional instruction
3.1. IF ... ENDIF
3.2. The ELSE
3.3. Written in a row
What was it about?

4. Indexed Cycles
4.1. The return stack
4.2. Scrambling with each other
4.3. With IFs
4.4. Cycles inside each other
4.5. What is easy to ruin
4.6. Departure from the cycle
4.7. Different Walking
What was it about?

5. Cycles without index
5.1. The endless cycle (BEGIN ... AGAIN)
5.2. Departure at end of cycle (BEGIN ... UNTIL)
5.3. Outbound in the middle of the cycle (BEGIN ... WHILE ... REPEAT)
What was it about?

6. Additional Data Types
6.1. Signal and unsigned values
6.2. What about too many numbers?
6.3. Doubles
6.4. A disguised duplicate operation
What was it about?

7. Getting to know the memory
7.1. Byte Operations
7.2. Voice and Doubt Operations
7.3. Convenient stack handling
What was it about?

8. Variables and constants
8.1. A sure place: the variable
8.2. Examples of system
variables 8.3. Create new variables
8.4. Constants
What was it about?

9. Where does the variable change? Getting to know the dictionary
9.1. The word mark
9.2. What's in the dictionary?
9.3. Long Variables
What was it about?

10. The FORTH garland and the WORD
10.1. The FORTH curtains
10.2. WORD
10.3. How do you know him? (Basic Words )
What was it about?

11. Conversions
11.1. Suitability for the appropriate type
11.2. What do we get from NUMBER?
What was it about?

12. Dictionaries
12.1. Chaining of dictionary elements
12.2. Search and chaining dictionary
12.3. Our own dictionaries
What was it about?

13. Virtual Memory
13.1. Funds
13.2. Basic Thin Handling Principles
13.3. Standard error handling
13.4. Excerpts from an Editor
What was it about?

14. The dictionary and the title interpreter
14.1. Colloidal words
14.2. Primitives
14.3. Variables and constants
14.4. Tricky Runes
What was it about?

15. Own-made definitions

16. Immediate words
16.1. When translator translates
16.2. When the interpreter does not turn
16.3. When we translate instead of the interpreter (the COMPILE)
16.4. Literals
16.5. Postpone Instant Words (by [COMPILE])
What was it about?

17. How is the control structure made?
17.1. Running words
17.2. Checks
17.3. BEGIN, AGAIN and UNTIL
17.4. IF, ELSE and ENDIF
17.5. A non-standard structure: CASE

18. Another FORTH program: the textinterpreter

Appendix
A FIG-FORTH 1.1. Glossary
Error Messages
The editor
of Fig-Forth


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. Indexed Cycles

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. Indexless cycles

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. More data types

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. Getting to know the memory

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. Variables and constants

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 is

THE ?

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:

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.

10.2. A WORD
A

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. Count conversions

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. Dictionaries

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. Virtual Memory

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:

  • scans the block with the specified number in the memory and returns the address of the scanned block;
  • or if the block is already in the memory due to a previous scan, it will search for it and enter its address.

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>;

Immediate words

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? PAIRS
 
  COMPILE 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

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.

B) Appendix
Error Messages

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

Back to Util

Back to books