home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
forth
/
compiler
/
love
/
chap17.doc
< prev
next >
Wrap
Text File
|
1993-04-11
|
7KB
|
168 lines
Local Variables in L.O.V.E. Forth
=================================
Stack Manipulation
------------------
Forth source code has been criticized by many as unreadable. This
is due to the traditional use of stack manipulation operators (such as
swap, dup, rot, pick, roll etc... ) rather than the reverse polish syntax.
Incorrect manipulation of the parameter stack in Forth is such a frequent
source of logical bugs that experienced Forth programmers habitually insert
'stack diagrams' beside their phrases to document the net effect on the
stack. The problem of ordering data items on the stack is compounded by the
use of double and quad length items to represent pointers of different
sizes, large valued integers and floating point numbers. In an attempt to
remedy this, many versions of local variables and named parameters have
been implemented by Forth programmers. The implementation for L.O.V.E.
Forth has a syntax modelled after that used in a Forth-83 system for the
Apple Macintosh called MACH-2 by Palo Alto Shipping Company.
Benefits
--------
Local variables and named input parameters are an addition to the
L.O.V.E. Forth compiler that improves the readability of source code and
allows the programmer to spend less time thinking about the order and sizes
of data items on Forth's parameter stack. An additional and significant
benefit is increased execution speed and decreased object code size. Local
variables and named input parameters insulate the implementation of a
definition from changes to the order and data types of the input
parameters, are used at the programmers discretion and are entirely
optional. This implementation of local variables allows the programmer to
write completely re-entrant code and recursive definitions with ease.
Usage
-----
The syntax used replaces the traditional stack diagram after the
name of the new definition.
Local variables and named input parameters have a structure
following this general form:
: aname { [type] n1 [type] n2 ... [type] n? | [type] L1 ... [type] L? -- comment }
... ;
where:
'{' is an immediate word that precedes a locxal variable specification
list and parses this information up to the first '}' and must be used
immediately after the name of the new definition.
[type] is a built in type specifier that tells the parser how to compile
object code for the local variable name following it in the local
variable specification.
Available types are:
word: -- a two byte (word length) integer
long: -- a four byte (long word length) integer
quad: -- an eight byte (quad word length) integer
float: -- a four byte (single precision) floating point value
in IEEE single precision format
double: -- an eight byte (double precision) floating point
value in IEEE double precision format
ext: -- a ten byte (extended precision) floating point
value in IEEE extended precision format
fbcd: -- a ten byte (binary coded decimal) floating point
value in 80x87 BCD format
** NOTE : If a local variable name appears without a type specifier
the parser assumes that it is a 'word:' type. This allows
the programmer to write simple definitions using mostly word
length items without always specifying the 'word:' type.
n1 n2 n3 ... are named input parameters from the stack where n1 is
deepest in the stack and n? is on the top of the
parameter stack.
| (bar) is a separator character that terminates the input variable
list and signals that a local variable list will begin.
L1 L2 L3 ... is the list of local variable names used in this
definition.
-- specifies that a comment begins, a comment string follows,
usually used to document what the definition leaves on the
stack. May not contain '}' .
Notes:
(1) Named parameters, temporary local variables and the comment are all
optional. A definition with no input parameters can have local
variables for temporary results.
(2) In the V1.24 implementation a local variable stack frame can contain up
to 128 bytes of named input parameters and temporary local variables
(one local frame per definition).
(3) Local names can be any space delimited string up to 31 characters
long but must not be named '|' (bar) or '--' (comment) or '}' (left
brace) or given a name that is identical to a type specifier .
Examples
--------
: <a_word> { arg1 arg2 arg3 | temp -- result }
...............
............... ;
The named arguments 'arg1', 'arg2' and 'arg3' are initialized values on the
parameter stack with 'arg3' on the top and 'arg1' deepest on the stack. The
local variable 'temp' is an uninitialized temporary value.
: <b_word> { word: arg1 long: arg2 | ext: temp -- result }
...............
............... ;
The named arguments 'arg1', 'arg2' are initialized values on the
parameter stack with long word length 'arg2' on the top and word length 'arg1'
deepest on the stack. The local variable 'temp' is an uninitialized extended
precision floating point temporary value.
Operations with Local Variables
-------------------------------
There are 4 basic operations with local variables and the possibility of
adding more operations in the future.
These operations are:
local_name -- the default action of a local variable is to fetch
the contents of the local variable to the top
of the stack.
-> local_name -- stores the top of stack into the location specified by
local_name in the format specified by the type of
local_name.
+> local_name -- adds the top of stack to the contents of the location
specified by local_name in the format specified by the
type of local_name.
& local_name -- returns the segment and offset of the contents of
local_name.
All operations with local variables are immediate words that determine at
compile time what type of data will be operated upon and then compile the
correct object code.