[net.lang.forth] vforth--a VAX forth

valencia@vger.UUCP (05/28/85)

	It seems that a fair number of users on this group
do not receive net.sources, as my offer of VFORTH has met with
a fairly large number of requests. What I propose, therefore,
is to post the source to vforth to this net group (net.lang.forth).
I know this isn't quite kosher, so I'll hold off on the actual
posting for a couple days, and see how hot the flames get.

	For those of you who HAVE seen vforth before, let me
add that a couple bugs have been fixed, the numeric input routines
tightened, and several things longword aligned (resulting in a nominal
10% perfomance improvement).  The dictionary free space now uses
".comm" so that a 1Mb dictionary no longer results in a 1Mb
executable file (whew). Finally, the bit shift operations ala "C"
have been added ("<<" and ">>").

				Keep the faith,
				Andy Valencia

valencia@vger.UUCP (05/28/85)

	Vforth is a 32-bit Threaded Interpretive Language for the VAX
minicomputer. It uses a combination of subroutine-threading and in-line
code generation to provide significant execution speed improvement. It
was developed for the express purpose of running a graphics which was
developed under JHU forth. As such, it only follows the FIG model to
the extent required to allow the JHU forth code to run with minimal
modification. This code is the sole property of Hewlett-Packard company,
but is put into the public domain for non-profit use only. No support
whatsoever is implied for this code--you're on your own!

	Now that we have the "heavy" stuff out of the way, I may proceed
to describe exactly what we have here. Vforth's internals are unique, but
its external behavior closely mimics FIG-forth for those words provided;
the set of words chosen was mostly driven by the graphics package written
originally for JHU forth. This file, "vforth.doc", is a brief description
of the internal structure of vforth; the set of words implemented is in
the file "glossary".

	The classic approach in forth is to have a register (the Interpretive
Pointer) which points to successive words. Each word points to the CFA (Code
Field Address) of another word. By jumping via the CFA, one invokes the word
indicated by the word the IP points to. The central code which chases all these
pointers is called "NEXT"; its speed is crucial in providing a fast forth
interpreter.

	Vforth takes this one step further by generating a subroutine call
in front of each address. By doing this, the code may be executed in-line;
no time is used executing auxiliary code. Thus, the invokation of a word
occurs at the full speed of the machine's subroutine-call facility. A word's
definition ends with a subroutine return opcode, again saving time over
explicit execution of code.

	The header of a Vforth assembly language word is:

	LFA - longword
	CFA - longword
	SFP - word
	SFA - word
	"name\0" - array of char
	<start of executable code>

	LFA is the Link Field Address and is the "usual"--it points to the
previous word's LFA. CFA always points to the start of the executable code.
SFP (Status Field Parameter) is special and is associated with one of
the bits in SFA. SFA (Status Field Address) contains bits which tell about
the word. In particular, there are bits for a Priority word, for a Smudged
word, and for a Primitive word. "Priority" and "Smudge" are just what one
expects; "Primitive" is unique to Vforth. During compilation, a word whose
SFA has the Primitive bit set will have its executable code copied in-line
to the function being compiled. The number of bytes copied is in SFP. Thus,
the definition for the addition word might be:

	.long	prev_fun,temp
	.word	3,Primitive
	.asciz	"+"
temp:	addl2	(R11)+,(R11)
	rsb

	The "addl2" line takes three bytes; these are the three copied
during compilation. If one is not currently compiling, the code is executed
directly; thus, the trailing "rsb" is needed for interpretive use, although
not for compiling.

	Thus, the Vforth system tends to generate code in-line for those
words whose definitions are (1) short and (2) position independent, and
to thread (via "jsb"s) to those routine which are not. Here at HP we have
observed a 4-5 times speed increase in speed over JHU forth. Because the
increase was sufficient for our needs, no code tuning was done; if you
find a good "tune", please send it along to us!

	The I/O system is very bare-bones indeed. The words "input" and
"output" will take the next word in the input stream and open it as a file,
then use it for input or output (respectively). There is a "stack" of units
for both input and output, so both may be nested. An "abort" will restore
I/O to the console, but will not close the file descriptors--I'm not yet
sure whether this is a feature or a bug. I/O is almost unbuffered on output,
and buffered to 1K blocks on input. The resultant amount of I/O traffic to
UNIX does not slow things down enough for me to be interested in changing it.

	Floating numbers are mostly used for fractional accuracy; no support
is provided for exponential numeric formats. INTERP recognizes a floating
point number as one with a decimal point. Thus, "23" would be a 32-bit
integer, but "23.0" would be a floating point number. The classic use of
the decimal point to mark double-word numbers is superseded in Vforth as
ALL integers are already 32 bits.

					Andy Valencia
					...!ucbvax!hpda!vandys