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