home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
love
/
chap06.doc
< prev
next >
Wrap
Text File
|
1993-04-11
|
7KB
|
209 lines
Chapter6 L_O_V_E FORTH
6.0 Concept
-------
In constructing Forth application programs, words are defined by
using previously defined words as building blocks. This bottom-up process
precludes the use of forward referencing or mutual recursion, but is
normally sufficient to build quite complex software. There are many
occasions though, when the ability to reference a word before it has been
defined or, for example, when the action of a low level word needs to be
changed dynamically (ie. during program execution), that a portable and
convenient method to do this becomes necessary.
6.1 Definition of Terms
-------------------
Redefine: A word is redefined when its action is changed after its
definition has been compiled. Redefinition can occur
dynamically at run-time, but is generally used to
permanently change the the action of a word.
Revector: Revectoring a word refers to the changing of the action
of a Forth word at run-time. This is the prefered method
for changing a word's action many times at run-time.
Vector: A vector is the information necessary to execute a word
as if it had been compiled into a definition, or typed on
the command line. The vector information is system
specific, but should be hidden from the programmer so
that code which uses redefinitions, or allows run-time
revectoring, can be ported to other systems or computer
architectures. The vector is kept in a location called a
vector field, known to the dynamic word.
6.2 Reasons for Redefining and Revectoring
--------------------------------------
(1) To change the action of a low-level word that is the foundation
for many other higher-level words when it is inconvenient to
recompile the entire system.
(2) To allow mutual recursion or forward referencing. This is
accomplished by first defining a dummy word, and then later
redefining it to perform its correct action.
(3) To dynamically redirect input or output within an application,
while allowing higher-level words to be device independant.
(4) To develop and test an application interactively, and then change
the action of hardware specific words before committing the code
to EPROM.
(5) To chain abort handlers or other error handlers together, to
accomplish application specified actions on run-time execution
errors.
6.3 Word List
---------
REDEFINE ( -- )
Used in the form:
Redefine <word1> <word2>
and can be read as "redefine <word1> do the same thing as
<word2>".
RESTORE ( -- )
Used in the form:
RESTORE <word>
where <word> has been previously redefined, RESTORE will restore
the original function of <word>.
MAKE_DYNAMIC ( -- )
Used in the form:
MAKE_DYNAMIC <word>
to make <word> dynamically revectorable.
This allots space in the dictionary for a vector field, extracts the
vector from <word>, stores the vector into the vector field and
alters the code field address of <word> so that when <word>
executes it finds the vector in its vector field and executes it.
REVECTOR ( -- )
An immediate word used in the form:
REVECTOR <word1> <word2>
where <word1> is a dynamically revectorable word. <word2> is any
other Forth word. Revector changes the vector field at <word1> by
storing the vector extracted from <word2>.
VECTOR_FROM ( -- )(compiling)
( -- cfa, contents_of_cfa )(executing)
An immediate word used in the form:
VECTOR_FROM <word>
From the next word in the input stream extract the cfa and the
contents of the cfa . If the state is compiling, then the vector
is compiled as a dliteral. This word operates on any Forth word.
EXECUTE_VECTOR ( cfa, contents_of_cfa -- )
Executes the word specified by the two-part vector on the
stack.
GETVECTOR ( -- )( compiling )
( -- cfa, cfa_contents )( executing )
An immediate word used in the form:
GETVECTOR <word>
where <word> is a dynamically revectorable word. If the state
is compiling then GETVECTOR compiles the cfa of <word> as a
literal followed by <GETVECTOR>. This word is used to
retrieve the vector from the vector field of <word>, to be
stored in a variable, passed to EXECUTE_VECTOR or operated on
later with SETVECTOR.
SETVECTOR ( cfa1, cfa1_contents -- )(executing)
( -- )(compiling)
An immediate word used in the form:
SETVECTOR <word>
where <word> is a dynamically revectorable word. When
compiling, SETVECTOR compiles the cfa of <word> as a literal
followed by SETVECTOR>. This word is used to store the
vector that is on the stack at run-time into the vector field
of <word>.
6.4 Examples
--------
Forward Referencing:
: second_word ; ( make a dummy )
( a word which executes another word that is define later )
: first_word ( -- )
second_word ;
( the second word executes the previously defined word)
: <second_word> ( -- )
first_word ;
( now complete the circle by making second_word execute )
( something useful )
redefine second_word <second_word>
Input and Output Redirection:
make_dynamic emit ( make emit dynamically revectorable )
( output a character in textmode to the LCD Display )
: LCD_text_EMIT ( c -- )
dup bl <
if
case
7 of beep endof
8 of do_backspace endof
9 of do_tab endof
10 of do_linefeed endof
13 of do_return endof
endcase
else
LCDwrite lcd! ( write the char )
1 #out +!
1 cursor_addr +!
#out @ chars/line = ( is cursor past last column? )
if do_return
do_linefeed
then
then
;
\ Later ...
: app_word ( n1 n2 -- )
...
revector emit LCD_text_EMIT
... ;
Chaining error handlers and abort handlers:
( a new abort that executes the old abort afterwards )
: <locals_abort> ( -- )
LP! ( initialize the local stack )
<cleanup_locals> ( restore all pointers and flags )
vector_from abort execute_vector ; ( execute previous abort)
( chain the special abort handler before abort )
redefine abort <locals_abort>