Article View: net.lang.forth
Article #140CREATE <BUILDS
From: Harold Carr
Date: Fri, 12 Oct 1984 18:10
Date: Fri, 12 Oct 1984 18:10
106 lines
4626 bytes
4626 bytes
Could someone enlighten me on why one would use CREATE ... DOES> in
some instances and <BUILDS .. DOES> in others? Also, I am very interested
in Forth's meta-defining words and would appreciate examples of interesting
and powerful ways of using them.
Here are a couple of examples of using <BUILDS and CREATE. They are
both written in Bill's VAXFORTH. This first example creates an
"execution array" to contain words to be executed when accessed:
: xeq-array ( number-of-slots -- )
<builds ( Executing xeq-array in the form: )
( 10 xeq-array keys )
( uses <BUILDS to create a dictionary entry for KEYS. )
2* 2* dup here swap 0 fill allot ( Make a vector initialized to zero)
does> ( index -- )
( DOES> alters the code field and first parameter of )
( word defined by <BUILDS to execute the sequence of )
( words following DOES>. When the DOES> part executes )
( it begins with the address of the first parameter of )
( the new word on the stack. )
swap 2* 2* + @ execute ; ( Execute the function in the indexed slot. )
<BUILDS will take a word from the input stream and create a dictionary
header for it. Then the code up to DOES> is run. In this case, the
code allocates space in the new word for a vector initialized to zeros.
The DOES> part defines the run-time words for the newly created word.
When the new word is run its parameter field address is pushed on Forth's
parameter stack (the user has already pushed an index before it). The
parameter address is the base of the vector. It swaps these two items,
leaving the index on top, which is then multiplied by four to create
a thirty-two bit word index. This index is then added to the base.
The @ operator gets the contents of the indexed slot and leaves it
on the stack. The contents should be the address of another executable
word. Execute simply executes the word whose address is on the top
of the stack.
By defining the following auxilary words (shown without comment):
: put
[compile] ' ;
: offset-in
2* 2* [compile] ' + ! ;
We can create a key-stroke dispatch table:
26 xeq-array control-keys
...
put backward 2 offset-in control-keys
put forward 6 offset-in control-keys
put next 14 offset-in control-keys
put previous 21 offset-in control-keys
...
This creates an execution array for control keys. Then we install
the functions associated with each key. Note, that by using the
execution array rather than a case statement, we can dynamically
redefine the keys. To run any of the functions in the array we simply
do:
14 control-keys
Control-keys takes its index from the stack, fetches the function and
executes it. A simple loop will now listen to the keyboard:
: keys
begin
key
dup 27 <=
if
control-keys
else
regular-keys
then
again ;
A second example (sent to me by Mitch Bradley) uses CREATE to create
an automatically indexed byte array:
: carray ( array-size --name)
create ( Create a dictionary entry for the next word in
the input stream, without allocating any parameter
field memory. )
allot ( Add array-size bytes to the parameter field of the
most recently defined word. )
does> ( index -- byte-address )
( Marks the termination of the defining part of a high-level
defining word and begins the definition of the run-time
actions. On execution of words defined with CARRAY, the
sequence of words between DOES> and ; will be executed,
with the address of the word's parameter field on the stack. )
+ ; ( Add index to base. )
I am still not sure why one would use CREATE rather than DOES> here.
I'll be waiting to hear from you.
Forth programmers remind me of Lisp
hackers: fearless, creative and free - The environment is so open
and powerful (no secret black boxes called compilers), we just can't
wait to get our hands on it an change it!
Harold Carr arpa: CARR@UTAH-20 uucp: harpo!utah-cs!carr
Technical Details
Message-ID:
<3068@utah-cs.UUCP>Path:
arc1-ca.pugleaf.net!utzoo!linus!philabs!cmcl2!seismo!utah-cs!carrShow Full Headers
Complete Article Headers
Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Posting-Version: version B 2.10.1 6/24/83; site utah-cs.UUCP Path: arc1-ca.pugleaf.net!utzoo!linus!philabs!cmcl2!seismo!utah-cs!carr From: carr@utah-cs.UUCP (Harold Carr) Newsgroups: net.lang.forth Subject: CREATE <BUILDS Message-ID: <3068@utah-cs.UUCP> Date: Fri, 12-Oct-84 14:10:42 EDT Article-I.D.: utah-cs.3068 Posted: Fri Oct 12 14:10:42 1984 Date-Received: Sat, 13-Oct-84 06:44:13 EDT Organization: Univ of Utah CS Dept Lines: 106