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
;