summaryrefslogtreecommitdiff
path: root/doc/source
diff options
context:
space:
mode:
Diffstat (limited to 'doc/source')
-rw-r--r--doc/source/api.ht250
-rw-r--r--doc/source/debugger.ht157
-rw-r--r--doc/source/dpans.ht589
-rw-r--r--doc/source/ficl.ht1257
-rw-r--r--doc/source/generate.py244
-rw-r--r--doc/source/index.ht244
-rw-r--r--doc/source/license.ht47
-rw-r--r--doc/source/links.ht156
-rw-r--r--doc/source/locals.ht133
-rw-r--r--doc/source/oop.ht1224
-rw-r--r--doc/source/parsesteps.ht234
-rw-r--r--doc/source/releases.ht1003
-rw-r--r--doc/source/upgrading.ht349
13 files changed, 5887 insertions, 0 deletions
diff --git a/doc/source/api.ht b/doc/source/api.ht
new file mode 100644
index 000000000000..599ba9e16b14
--- /dev/null
+++ b/doc/source/api.ht
@@ -0,0 +1,250 @@
+<?
+ficlPageHeader("ficl api")
+
+ficlAddToNavBarAs("API")
+
+
+def entrypoint(prototype):
+ print "<p><dt>\n" + "<code>" + prototype + "</code>\n<dd>\n"
+?>
+
+
+
+<? ficlHeader1("Quick Ficl Programming Concepts Overview") ?>
+
+
+A Ficl <i>dictionary</i> is equivalent to the FORTH "dictionary"; it is where words are stored.
+A single dictionary has a single <code>HERE</code> pointer.
+<p>
+
+A Ficl <i>system information</i> structure is used to change default values used
+in initializing a Ficl <i>system</i>.
+<p>
+
+A Ficl <i>system</i> contains a single <i>dictionary</i>, and one or more <i>virtual machines</i>.
+<p>
+
+A Ficl <i>stack</i> is equivalent to a FORTH "stack". Ficl has three stacks:
+<ul>
+
+<li>
+The <i>data</i> stack, where integer arguments are stored.
+
+<li>
+The <i>return</i> stack, where locals and return addresses for subroutine returns are stored.
+
+<li>
+The <i>float</i> stack, where floating-point arguments are stored. (This stack
+is only enabled when <code>FICL_WANT_FLOAT</code> is nonzero.)
+</ul>
+
+<p>
+
+A Ficl <i>virtual machine</i> (or <i>vm</i>) represents a single running instance of the Ficl interpreter.
+All virtual machines in a single Ficl system see the same dictionary.
+<p>
+
+<? ficlHeader2("Quick Ficl Programming Tutorial") ?>
+
+Though Ficl's API offers a great deal of flexibility, most programs
+incorporating Ficl simply use it as follows:
+
+<ol>
+
+<li>
+Create a single <code>ficlSystem</code> using <code>ficlSystemCreate(NULL)</code>.
+
+<li>
+Add native functions as necessary with <code>ficlDictionarySetPrimitive()</code>.
+
+<li>
+Add constants as necessary with <code>ficlDictionarySetConstant()</code>.
+
+<li>
+Create one (or more) virtual machine(s) with <code>ficlSystemCreateVm()</code>.
+
+<li>
+Add one or more scripted functions with <code>ficlVmEvaluate()</code>.
+
+<li>
+Execute code in a Ficl virtual machine, usually with <code>ficlVmEvaluate()</code>,
+but perhaps with <code>ficlVmExecuteXT()</code>.
+
+<li>
+At shutdown, call <code>ficlSystemDestroy()</code> on the single Ficl system.
+
+</ol>
+
+
+<? ficlHeader1("Ficl Application Programming Interface") ?>
+
+The following is a partial listing of functions that interface your
+system or program to Ficl. For a complete listing, see <code>ficl.h</code>
+(which is heavily commented). For a simple example, see <code>main.c</code>.
+<p>
+
+Note that as of Ficl 4, the API is internally consistent.
+<i>Every</i> external entry point starts with the word
+<code>ficl</code>, and the word after that also corresponds
+with the first argument. For instance, a word that operates
+on a <code>ficlSystem *</code> will be called <code>ficlSystem<i>Something</i>()</code>.
+
+
+
+
+<dl>
+
+<? entrypoint("void ficlSystemInformationInitialize(ficlSystemInformation *fsi)") ?>
+
+Resets a <code>ficlSystemInformation</code> structure to all zeros.
+(Actually implemented as a macro.) Use this to initialize a <code>ficlSystemInformation</code>
+structure before initializing its members and passing it
+into <code>ficlSystemCreate()</code> (below).
+
+<? entrypoint("ficlSystem *ficlSystemCreate(ficlSystemInformation *fsi)") ?>
+
+Initializes Ficl's shared system data structures, and creates the
+dictionary allocating the specified number of cells from the heap
+(by a call to <code>ficlMalloc()</code>). If you pass in a <code>NULL</code>
+pointer, you will recieve a <code>ficlSystem</code> using the default
+sizes for the dictionary and stacks.
+
+
+<? entrypoint("void ficlSystemDestroy(ficlSystem *system)") ?>
+
+Reclaims memory allocated for the Ficl system including all
+dictionaries and all virtual machines created by
+<code>ficlSystemCreateVm()</code>. Note that this will <i>not</i>
+automatically free memory allocated by the FORTH memory allocation
+words (<code>ALLOCATE</code> and <code>RESIZE</code>).
+
+<? entrypoint("ficlWord *ficlDictionarySetPrimitive(ficlDictionary *dictionary, char *name, ficlCode code, ficlUnsigned8 flags)") ?>
+
+Adds a new word to the dictionary with the given
+name, code pointer, and flags. To add
+<p>
+
+The <code>flags</code> parameter is a bitfield. The valid
+flags are:<ul>
+
+<li>
+FICL_WORD_IMMEDIATE
+<li>
+FICL_WORD_COMPILE_ONLY
+<li>
+FICL_WORD_SMUDGED
+<li>
+FICL_WORD_OBJECT
+<li>
+FICL_WORD_INSTRUCTION
+
+</ul>
+
+For more information on these flags, see <code>ficl.h</code>.
+
+
+<? entrypoint("ficlVm *ficlSystemCreateVm(ficlSystem *system)") ?>
+
+Creates a new virtual machine in the specified system.
+
+
+<? entrypoint("int ficlVmEvaluate(ficlVm *vm, char *text)") ?>
+
+ the specified C string (zero-terminated) to the given
+virtual machine for evaluation. Returns various exception codes (VM_XXXX
+in ficl.h) to indicate the reason for returning. Normal exit
+condition is VM_OUTOFTEXT, indicating that the VM consumed the string
+successfully and is back for more. Calls to <code>ficlVmEvaluate()</code>
+can be nested, and
+the function itself is re-entrant, but note that a VM is
+static, so you have to take reasonable precautions (for example, use one
+VM per thread in a multithreaded system if you want multiple threads to
+be able to execute commands).
+
+
+<? entrypoint("int ficlVmExecuteXT(ficlVm *vm, ficlWord *pFW)") ?>
+
+Same as ficlExec, but takes a pointer to a ficlWord instead of a
+string. Executes the word and returns after it has finished. If
+executing the word results in an exception, this function will
+re-throw the same code if it is nested under another ficlExec family
+function, or return the exception code directly if not. This function
+is useful if you need to execute the same word repeatedly&mdash;you
+save the dictionary search and outer interpreter overhead.
+
+<? entrypoint("void ficlFreeVM(ficlVm *vm)") ?>
+
+Removes the VM in question from the system VM list and deletes
+the memory allocated to it. This is an optional call, since
+ficlTermSystem will do this cleanup for you. This function is
+handy if you're going to do a lot of dynamic creation of VMs.
+
+<? entrypoint("ficlVm *ficlNewVM(ficlSystem *system)") ?>
+
+Create, initialize, and return a VM from the heap using
+ficlMalloc. Links the VM into the system VM list for later reclamation
+by ficlTermSystem.
+
+<? entrypoint("ficlWord *ficlSystemLookup(ficlSystem *system, char *name)") ?>
+
+Returns the address of the specified word in the main dictionary.
+If no such word is found, it returns <code>NULL</code>.
+The address is also a valid execution token, and can be used in a call to <code>ficlVmExecuteXT()</code>.
+
+<? entrypoint("ficlDictionary *ficlSystemGetDictionary(ficlSystem *system)<br>ficlDictionary *ficlVmGetDictionary(ficlVm *system)") ?>
+
+Returns a pointer to the main system dictionary.
+
+
+<? entrypoint("ficlDictionary *ficlSystemGetEnvironment(ficlSystem *system)") ?>
+
+Returns a pointer to the environment dictionary. This dictionary
+stores information that describes this implementation as required by the
+Standard.
+
+
+
+
+<? entrypoint("ficlDictionary *ficlSystemGetLocals(ficlSystem *system)") ?>
+
+Returns a pointer to the locals dictionary. This function is
+defined only if <code>FICL_WANT_LOCALS</code> is non-zero (see <code>ficl.h</code>).
+The locals dictionary is the symbol table for
+<a href="locals.html">local variables</a>.
+
+
+</dl>
+
+
+<? ficlHeader1("Ficl Compile-Time Constants") ?>
+
+There are a lot of preprocessor constants you can set at compile-time
+to modify Ficl's runtime behavior. Some are required, such as telling
+Ficl whether or not the local platform supports double-width integers
+(<code>FICL_PLATFORM_HAS_2INTEGER</code>);
+some are optional, such as telling Ficl whether or not to use the
+extended set of "prefixes" (<code>FICL_WANT_EXTENDED_PREFIXES</code>).
+<p>
+
+The best way to find out more about these constants is to read <code>ficl.h</code>
+yourself. The settings that turn on or off Ficl modules all start with
+<code>FICL_WANT</code>. The settings relating to functionality available
+on the current platform all start with <code>FICL_PLATFORM</code>.
+<p>
+
+
+
+<? ficlHeader2("<code>ficllocal.h</code>") ?>
+
+One more note about constants. Ficl now ships with a standard place for
+you to tweak the Ficl compile-time preprocessor constants.
+It's a file called <code>ficllocal.h</code>, and we guarantee that it
+will always ship empty (or with only comments). We suggest that you
+put all your local changes there, rather than editing <code>ficl.h</code>
+or editing the makefile. That should make it much easier to integrate
+future Ficl releases into your product&mdash;all you need do is preserve
+your tweaked copy of <code>ficllocal.h</code> and replace the rest.
+
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/debugger.ht b/doc/source/debugger.ht
new file mode 100644
index 000000000000..e2187f9b2670
--- /dev/null
+++ b/doc/source/debugger.ht
@@ -0,0 +1,157 @@
+<?
+ficlPageHeader("ficl debugger")
+
+ficlAddToNavBarAs("Debugger")
+
+?>
+
+<p>Ficl includes a simple step debugger for colon definitions
+and <code>DOES></code> words.
+
+
+<? ficlHeader1("Using The Ficl Debugger") ?>
+
+
+To debug a word, set up the stack with any parameters the word requires,
+then execute:
+<pre><b>DEBUG <i>your-word-name-here</i></b></pre>
+<p>
+
+If the word is unnamed, or all you have is an execution token,
+you can instead use <code>DEBUG-XT</code></b>
+<p>
+
+The debugger invokes <tt>SEE</tt> on the word which prints a crude source
+listing. It then stops at the first instruction of the definition. There are
+six (case insensitive) commands you can use from here onwards:
+
+<dl>
+
+<dt>
+<b>I</b> (step <b>I</b>n)
+<dd>If the next instruction is a colon defintion or does> word, steps into
+that word's code. If the word is a primitive, simply executes the word.
+
+<dt>
+<b>O</b> (step <b>O</b>ver)
+<dd>
+Executes the next instruction in its entirety.
+
+<dt>
+<b>G</b> (<b>G</b>o)
+<dd>
+Run the word to completion and exit the debugger.
+
+<dt>
+<b>L</b> (<b>L</b>ist)
+<dd>
+Lists the source code of the word presently being stepped.
+
+<dt>
+<b>Q</b> (<b>Q</b>uit)
+<dd>
+Abort the word and exit the debugger, clearing the stacks.
+
+<dt>
+<b>X</b> (e<b>X</b>ecute)
+<dd>
+Interpret the remainder of the line as Ficl words. Any change
+they make to the stacks will be preserved when the debugged word
+continues execution.
+Any errors will abort the debug session and reset the VM. Usage example:
+<pre>
+X DROP 3 \ change top argument on stack to 3
+</pre>
+
+</dl>
+
+
+Any other character will prints a list of available debugger commands.
+
+
+<? ficlHeader2("The <code>ON-STEP</code> Event") ?>
+
+If there is a defined word named <code>ON-STEP</code> when the debugger starts, that
+word will be executed before every step. Its intended use is to display the stacks
+and any other VM state you find interesting. The default <code>ON-STEP</code> is:
+<p>
+
+<pre>
+: ON-STEP ." S: " .S-SIMPLE CR ;
+</pre>
+
+If you redefine <code>ON-STEP</code>, we recommend you ensure the word has no
+side-effects (for instance, adding or removing values from any stack).
+
+
+
+<? ficlHeader3("Other Useful Words For Debugging And <code>ON-STEP</code>") ?>
+
+<dl>
+
+<dt>
+<code>.ENV ( -- )</code>
+<dd>
+Prints all environment settings non-destructively.
+
+<dt>
+<code>.S ( -- )</code>
+<dd>
+Prints the parameter stack non-destructively in a verbose format.
+
+<dt>
+<code>.S-SIMPLE ( -- )</code>
+<dd>
+Prints the parameter stack non-destructively in a simple single-line format.
+
+<dt>
+<code>F.S ( -- )</code>
+<dd>
+Prints the float stack non-destructively (only available if <code>FICL_WANT_FLOAT</code> is enabled).
+
+<dt>
+<code>R.S ( -- )</code>
+<dd>
+Prints a represention of the state of the return stack non-destructively.
+
+
+
+</dl>
+
+<? ficlHeader1("Debugger Internals") ?>
+
+<p>
+The debugger words are mostly located in source file <code>tools.c</code>. There are
+supporting words (<code>DEBUG</code> and <code>ON-STEP</code>) in <code>softcore.fr</code> as well.
+There are two main words that make the debugger go: <code>debug-xt</code> and <code>step-break</code>.
+<code>debug-xt</code> takes the execution token of a word to debug (as returned by <code>'</code> for example) ,
+checks to see if it is debuggable (not a primitive), sets a breakpoint at its
+first instruction, and runs <code>see</code> on it. To set a breakpoint,
+<code>debug-xt</code>
+replaces the instruction at the breakpoint with the execution token of <code>step-break</code>, and
+stores the original instruction and its address in a static breakpoint
+record. To clear the breakpoint, <code>step-break</code> simply replaces the original
+instruction and adjusts the target virtual machine's instruction pointer
+to run it.
+
+<p>
+
+<code>step-break</code> is responsible for processing debugger commands and setting
+breakpoints at subsequent instructions.
+
+
+<? ficlHeader1("Future Enhancements") ?>
+
+<dl>
+
+<li>
+The debugger needs to exit automatically when it encounters the end of the word
+it was asked to debug. (Perhaps this could be a special kind of breakpoint?)
+
+<li>Add user-set breakpoints.
+
+<li>Add "step out" command.
+</dl>
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/dpans.ht b/doc/source/dpans.ht
new file mode 100644
index 000000000000..cfd957e269a6
--- /dev/null
+++ b/doc/source/dpans.ht
@@ -0,0 +1,589 @@
+<?
+ficlPageHeader("ficl standards compliance")
+
+ficlHeader1("ANS Required Information")
+
+ficlAddToNavBarAs("ANS")
+
+?>
+
+
+The following documentation is necessary to comply for Ficl
+to comply with the DPANS94 standard. It describes what areas
+of the standard Ficl implements, what areas it does not, and
+how it behaves in areas undefined by the standard.
+
+<blockquote>
+
+<? ficlHeader2("ANS Forth System") ?>
+
+<b>
+
+Providing names from the Core Extensions word set
+<br>
+
+Providing names from the Double-Number word set
+<br>
+
+Providing the Exception word set
+<br>
+
+Providing the Exception Extensions word set
+<br>
+
+Providing the File-Access word set
+<br>
+
+Providing the File-Access Extensions word set
+<br>
+
+Providing names from the Floating-Point word set
+<br>
+
+Providing the Locals word set
+<br>
+
+Providing the Locals Extensions word set
+<br>
+
+Providing the Memory Allocation word set
+<br>
+
+Providing the Programming-Tools word set
+<br>
+
+Providing names from the Programming-Tools Extensions word set
+<br>
+
+Providing the Search-Order word set
+<br>
+
+Providing the Search-Order Extensions word set
+<br>
+
+Providing names from the String Extensions word set
+<br>
+
+</b>
+
+
+<?
+def entry(heading):
+ print "<dt><b>\n" + heading + "\n</b><dd>\n"
+
+?>
+
+
+<? ficlHeader2("Implementation-defined Options") ?>
+
+The implementation-defined items in the following list represent
+characteristics and choices left to the discretion of the implementor,
+provided that the requirements of the Standard are met. A system shall
+document the values for, or behaviors of, each item.
+
+<dl>
+
+<? entry("aligned address requirements (3.1.3.3 Addresses)") ?>
+
+System dependent. You can change the default address alignment by
+defining <code>FICL_ALIGN</code> on your compiler's command line,
+or in <code>platform.h</code>.
+The default value is set to 2 in <code>ficl.h</code>.
+This causes dictionary entries and <code>ALIGN</code> and
+<code>ALIGNED</code> to align on 4 byte
+boundaries. To align on 2<b><sup>n</sup></b> byte boundaries,
+set <code>FICL_ALIGN</code> to <b>n</b>.
+
+
+<? entry("behavior of 6.1.1320 EMIT for non-graphic characters") ?>
+
+Depends on target system, C runtime library, and your
+implementation of <code>ficlTextOut()</code>.
+
+
+<? entry("character editing of 6.1.0695 ACCEPT and 6.2.1390 EXPECT") ?>
+
+None implemented in the versions supplied in <code>primitives.c</code>.
+Because <code>ficlEvaluate()</code> is supplied a text buffer
+externally, it's up to your system to define how that buffer will
+be obtained.
+
+
+<? entry("character set (3.1.2 Character types, 6.1.1320 EMIT, 6.1.1750 KEY)") ?>
+
+Depends on target system and implementation of <code>ficlTextOut()</code>.
+
+
+<? entry("character-aligned address requirements (3.1.3.3 Addresses)") ?>
+
+Ficl characters are one byte each. There are no alignment requirements.
+
+
+<? entry("character-set-extensions matching characteristics (3.4.2 Finding definition names)") ?>
+
+No special processing is performed on characters beyond case-folding. Therefore,
+extended characters will not match their unaccented counterparts.
+
+
+<? entry("conditions under which control characters match a space delimiter (3.4.1.1 Delimiters)") ?>
+
+Ficl uses the Standard C function <code>isspace()</code> to distinguish space characters.
+
+
+<? entry("format of the control-flow stack (3.2.3.2 Control-flow stack)") ?>
+
+Uses the data stack.
+
+
+<? entry("conversion of digits larger than thirty-five (3.2.1.2 Digit conversion)") ?>
+
+The maximum supported value of <code>BASE</code> is 36.
+Ficl will fail via assertion in function <code>ltoa()</code> of <code>utility.c</code>
+if the base is found to be larger than 36 or smaller than 2. There will be no effect
+if <code>NDEBUG</code> is defined, however, other than possibly unexpected behavior.
+
+
+<? entry("display after input terminates in 6.1.0695 ACCEPT and 6.2.1390 EXPECT") ?>
+
+Target system dependent.
+
+
+<? entry("exception abort sequence (as in 6.1.0680 ABORT\")") ?>
+
+Calls <tt>ABORT</tt> to exit.
+
+
+<? entry("input line terminator (3.2.4.1 User input device)") ?>
+
+Target system dependent (implementation of outer loop that calls <code>ficlEvaluate()</code>).
+
+
+<? entry("maximum size of a counted string, in characters (3.1.3.4 Counted strings, 6.1.2450 WORD)") ?>
+
+Counted strings are limited to 255 characters.
+
+
+<? entry("maximum size of a parsed string (3.4.1 Parsing)") ?>
+
+Limited by available memory and the maximum unsigned value that can fit in a cell (2<sup>32</sup>-1).
+
+
+<? entry("maximum size of a definition name, in characters (3.3.1.2 Definition names)") ?>
+
+Ficl stores the first 31 characters of a definition name.
+
+
+<? entry("maximum string length for 6.1.1345 ENVIRONMENT?, in characters") ?>
+
+Same as maximum definition name length.
+
+
+<? entry("method of selecting 3.2.4.1 User input device") ?>
+
+None supported. This is up to the target system.
+
+
+<? entry("method of selecting 3.2.4.2 User output device") ?>
+
+None supported. This is up to the target system.
+
+
+<? entry("methods of dictionary compilation (3.3 The Forth dictionary)") ?>
+
+Okay, we don't know what this means. If you understand what they're asking for here,
+please call the home office.
+
+
+<? entry("number of bits in one address unit (3.1.3.3 Addresses)") ?>
+
+Target system dependent, either 32 or 64 bits.
+
+
+<? entry("number representation and arithmetic (3.2.1.1 Internal number representation)") ?>
+
+System dependent. Ficl represents a CELL internally as a union that can hold a <code>ficlInteger32</code>
+(a signed 32 bit scalar value), a <code>ficlUnsigned32</code> (32 bits unsigned),
+and an untyped pointer. No specific byte ordering is assumed.
+
+
+<? entry("ranges for n, +n, u, d, +d, and ud (3.1.3 Single-cell types, 3.1.4 Cell-pair types)") ?>
+
+System dependent.
+Assuming a 32 bit implementation, range for signed single-cell values is [-2<sup>31</sup>, 2<sup>31</sup>-1].
+Range for unsigned single cell values is [0, 2<sup>32</sup>-1].
+Range for signed double-cell values is [-2<sup>63</sup>, 2<sup>63</sup>-1].
+Range for unsigned double cell values is [0, 2<sup>64</sup>-1].
+
+
+<? entry("read-only data-space regions (3.3.3 Data space)") ?>
+
+None.
+
+
+<? entry("size of buffer at 6.1.2450 WORD (3.3.3.6 Other transient regions)") ?>
+
+Default is 255. Depends on the setting of <code>FICL_PAD_SIZE</code> in <code>ficl.h</code>.
+
+
+<? entry("size of one cell in address units (3.1.3 Single-cell types)") ?>
+
+System dependent, generally 4.
+
+
+<? entry("size of one character in address units (3.1.2 Character types)") ?>
+
+System dependent, generally 1.
+
+
+<? entry("size of the keyboard terminal input buffer (3.3.3.5 Input buffers)") ?>
+
+This buffer is supplied by the host program. Ficl imposes no practical limit.
+
+
+<? entry("size of the pictured numeric output string buffer (3.3.3.6 Other transient regions)") ?>
+
+Default is 255. Depends on the setting of <code>FICL_PAD_SIZE</code> in <code>ficl.h</code>.
+
+
+<? entry("size of the scratch area whose address is returned by 6.2.2000 PAD (3.3.3.6 Other transient regions)") ?>
+
+Default is 255. Depends on the setting of <code>FICL_PAD_SIZE</code> in <code>ficl.h</code>.
+
+
+<? entry("system case-sensitivity characteristics (3.4.2 Finding definition names)") ?>
+
+The Ficl dictionary is not case-sensitive.
+
+
+<? entry("system prompt (3.4 The Forth text interpreter, 6.1.2050 QUIT)") ?>
+
+<code>ok&gt;</code>
+
+
+<? entry("type of division rounding (3.2.2.1 Integer division, 6.1.0100 */, 6.1.0110 */MOD, 6.1.0230 /, 6.1.0240 /MOD, 6.1.1890 MOD)") ?>
+
+Symmetric.
+
+
+<? entry("values of 6.1.2250 STATE when true") ?>
+
+1.
+
+
+<? entry("values returned after arithmetic overflow (3.2.2.2 Other integer operations)") ?>
+
+System dependent. Ficl makes no special checks for overflow.
+
+
+<? entry("whether the current definition can be found after 6.1.1250 DOES&gt; (6.1.0450 :)") ?>
+No. Definitions are unsmudged after ; only, and only then if no control structure matching problems have been detected.
+
+</dl>
+
+
+<? ficlHeader2("Ambiguous Conditions") ?>
+
+<dl>
+
+<? entry("a name is neither a valid definition name nor a valid number during text interpretation (3.4 The Forth text interpreter)") ?>
+
+Ficl calls <code>ABORT</code> then prints the name followed by <code>not found</code>.
+
+
+<? entry("a definition name exceeded the maximum length allowed (3.3.1.2 Definition names)") ?>
+
+Ficl stores the first 31 characters of the definition name, and uses all characters of the name
+in computing its hash code. The actual length of the name, up to 255 characters, is stored in
+the definition's length field.
+
+
+<? entry("addressing a region not listed in 3.3.3 Data Space") ?>
+
+No problem: all addresses in Ficl are absolute. You can reach any 32 bit address in Ficl's address space.
+
+
+<? entry("argument type incompatible with specified input parameter, e.g., passing a flag to a word expecting an n (3.1 Data types)") ?>
+
+Ficl makes no check for argument type compatibility. Effects of a mismatch vary widely depending on the specific problem and operands.
+
+
+<? entry("attempting to obtain the execution token, (e.g., with 6.1.0070 ', 6.1.1550 FIND, etc.) of a definition with undefined interpretation semantics") ?>
+
+Ficl returns a valid token, but the result of executing that token while interpreting may be undesirable.
+
+
+<? entry("dividing by zero (6.1.0100 */, 6.1.0110 */MOD, 6.1.0230 /, 6.1.0240 /MOD, 6.1.1561 FM/MOD, 6.1.1890 MOD, 6.1.2214 SM/REM, 6.1.2370 UM/MOD, 8.6.1.1820 M*/)") ?>
+
+Results are target procesor dependent. Generally, Ficl makes no check for divide-by-zero. The target processor will probably throw an exception.
+
+
+<? entry("insufficient data-stack space or return-stack space (stack overflow)") ?>
+
+With <code>FICL_ROBUST</code> (defined in <code>ficl.h</code>) set to a value of 2 or greater,
+most data, float, and return stack operations are checked for underflow and overflow.
+
+
+<? entry("insufficient space for loop-control parameters") ?>
+
+This is not checked, and bad things will happen.
+
+
+<? entry("insufficient space in the dictionary") ?>
+
+Ficl generates an error message if the dictionary is too full to create
+a definition header. It checks <code>ALLOT</code> as well, but it is possible
+to make an unchecked allocation request that will overflow the dictionary.
+
+
+<? entry("interpreting a word with undefined interpretation semantics") ?>
+
+Ficl protects all ANS Forth words with undefined interpretation semantics from being executed while in interpret state.
+It is possible to defeat this protection using ' (tick) and <code>EXECUTE</code> though.
+
+
+<? entry("modifying the contents of the input buffer or a string literal (3.3.3.4 Text-literal regions, 3.3.3.5 Input buffers)") ?>
+
+Varies depending on the nature of the buffer. The input buffer is supplied by ficl's host function, and may reside
+in read-only memory. If so, writing the input buffer can ganerate an exception.
+String literals are stored in the dictionary, and are writable.
+
+
+<? entry("overflow of a pictured numeric output string") ?>
+
+In the unlikely event you are able to construct a pictured numeric string of more
+than <code>FICL_PAD_LENGTH</code> characters, the system will be corrupted unpredictably.
+The buffer area that holds pictured numeric output is at the end of the virtual machine.
+Whatever is mapped after the offending VM in memory will be trashed, along with the heap
+structures that contain it.
+
+
+<? entry("parsed string overflow") ?>
+
+Ficl does not copy parsed strings unless asked to. Ordinarily, a string parsed from the input buffer during
+normal interpretation is left in-place, so there is no possibility of overflow.
+If you ask to parse a string into the dictionary, as in <code>SLITERAL</code>, you need to have enough
+room for the string, otherwise bad things may happen. This is usually not a problem.
+
+
+<? entry("producing a result out of range, e.g., multiplication (using *) results in a value too big to be represented by a single-cell integer (6.1.0090 *, 6.1.0100 */, 6.1.0110 */MOD, 6.1.0570, &gt;NUMBER, 6.1.1561 FM/MOD, 6.1.2214 SM/REM, 6.1.2370 UM/MOD, 6.2.0970 CONVERT, 8.6.1.1820 M*/)") ?>
+
+Value will be truncated.
+
+
+<? entry("reading from an empty data stack or return stack (stack underflow)") ?>
+
+Most stack underflows are detected and prevented if <code>FICL_ROBUST</code> (defined in <code>sysdep.h</code>) is set to 2 or greater.
+Otherwise, the stack pointer and size are likely to be trashed.
+
+
+<? entry("unexpected end of input buffer, resulting in an attempt to use a zero-length string as a name") ?>
+
+Ficl returns for a new input buffer until a non-empty one is supplied.
+
+
+</dl>
+
+
+The following specific ambiguous conditions are noted in the glossary entries of the relevant words:
+
+<dl>
+
+<? entry("&gt;IN greater than size of input buffer (3.4.1 Parsing)") ?>
+
+Memory corruption will occur&mdash;the exact behavior is unpredictable
+because the input buffer is supplied by the host program's outer loop.
+
+
+<? entry("6.1.2120 RECURSE appears after 6.1.1250 DOES&gt;") ?>
+
+It finds the address of the definition before <code>DOES&gt;</code>
+
+
+<? entry("argument input source different than current input source for 6.2.2148 RESTORE-INPUT") ?>
+
+Not implemented.
+
+
+<? entry("data space containing definitions is de-allocated (3.3.3.2 Contiguous regions)") ?>
+
+This is okay until the cells are overwritten with something else.
+The dictionary maintains a hash table, and the table must be updated
+in order to de-allocate words without corruption.
+
+
+<? entry("data space read/write with incorrect alignment (3.3.3.1 Address alignment)") ?>
+
+Target processor dependent. Consequences include: none (Intel), address error exception (68K).
+
+
+<? entry("data-space pointer not properly aligned (6.1.0150 ,, 6.1.0860 C,)") ?>
+
+See above on data space read/write alignment.
+
+<? entry("less than u+2 stack items (6.2.2030 PICK, 6.2.2150 ROLL)") ?>
+
+If <code>FICL_ROBUST</code> is two or larger, Ficl will detect a stack underflow, report it, and execute <code>ABORT</code> to
+exit execution. Otherwise the error will not be detected, and memory corruption will occur.
+
+
+<? entry("loop-control parameters not available ( 6.1.0140 +LOOP, 6.1.1680 I, 6.1.1730 J, 6.1.1760 LEAVE, 6.1.1800 LOOP, 6.1.2380 UNLOOP)") ?>
+
+Loop initiation words are responsible for checking the stack and guaranteeing that the control parameters are pushed.
+Any underflows will be detected early if <code>FICL_ROBUST</code> is set to 2 or greater.
+Note however that Ficl only checks for return stack underflows at the end of each line of text.
+
+<? entry("most recent definition does not have a name (6.1.1710 IMMEDIATE)") ?>
+
+No problem.
+
+
+<? entry("name not defined by 6.2.2405 VALUE used by 6.2.2295 TO") ?>
+
+Ficl's version of <code>TO</code> works correctly with words defined with:
+<ul>
+
+<li> <code>VALUE</code>
+<li> <code>2VALUE</code>
+<li> <code>FVALUE</code>
+<li> <code>F2VALUE</code>
+<li> <code>CONSTANT</code>
+<li> <code>FCONSTANT</code>
+<li> <code>2CONSTANT</code>
+<li> <code>F2CONSTANT</code>
+<li> <code>VARIABLE</code>
+<li> <code>2VARIABLE</code>
+</ul>
+as well as with all "local" variables.
+
+<? entry("name not found (6.1.0070 ', 6.1.2033 POSTPONE, 6.1.2510 ['], 6.2.2530 [COMPILE])") ?>
+
+Ficl prints an error message and executes <code>ABORT</code>
+
+<? entry("parameters are not of the same type (6.1.1240 DO, 6.2.0620 ?DO, 6.2.2440 WITHIN)") ?>
+
+Not detected. Results vary depending on the specific problem.
+
+
+<? entry("6.1.2033 POSTPONE or 6.2.2530 [COMPILE] applied to 6.2.2295 TO") ?>
+
+The word is postponed correctly.
+
+
+<? entry("string longer than a counted string returned by 6.1.2450 WORD") ?>
+
+Ficl stores the first <code>FICL_COUNTED_STRING_MAX</code> - 1 characters in the
+destination buffer.
+(The extra character is the trailing space required by the standard. Yuck.)
+
+<? entry("u greater than or equal to the number of bits in a cell (6.1.1805 LSHIFT, 6.1.2162 RSHIFT)") ?>
+
+Depends on target process or and C runtime library implementations of the &lt;&lt; and &gt;&gt; operators
+on unsigned values. For I386, the processor appears to shift modulo the number of bits in a cell.
+
+<? entry("word not defined via 6.1.1000 CREATE (6.1.0550 &gt;BODY, 6.1.1250 DOES&gt;)") ?>
+
+<? entry("words improperly used outside 6.1.0490 &lt;# and 6.1.0040 #&gt; (6.1.0030 #, 6.1.0050 #S, 6.1.1670 HOLD, 6.1.2210 SIGN)") ?>
+
+Undefined. <code>CREATE</code> reserves a field in words it builds for <code>DOES&gt;</code> to fill in.
+If you use <code>DOES&gt;</code> on a word not made by <code>CREATE</code> it will overwrite the first
+cell of its parameter area. That's probably not what you want. Likewise, pictured numeric words
+assume that there is a string under construction in the VM's scratch buffer. If that's not the case,
+results may be unpleasant.
+
+
+</dl>
+
+<? ficlHeader2("Locals Implementation-Defined Options") ?>
+
+<dl>
+
+<? entry("maximum number of locals in a definition (13.3.3 Processing locals, 13.6.2.1795 LOCALS|)") ?>
+
+Default is 64&mdash;unused locals are cheap. Change by redefining <code>FICL_MAX_LOCALS</code> (defined in <code>ficl.h</code>).
+
+</dl>
+
+
+<? ficlHeader2("Locals Ambiguous conditions") ?>
+
+<dl>
+
+<? entry("executing a named local while in interpretation state (13.6.1.0086 (LOCAL))") ?>
+
+Locals can be found in interpretation state while in the context of a definition under
+construction. Under these circumstances, locals behave correctly. Locals are not visible
+at all outside the scope of a definition.
+
+<? entry("name not defined by VALUE or LOCAL (13.6.1.2295 TO)") ?>
+
+See the CORE ambiguous conditions, above (no change).
+
+</dl>
+
+
+<? ficlHeader2("Programming Tools Implementation-Defined Options") ?>
+
+
+<dl>
+
+<? entry("source and format of display by 15.6.1.2194 SEE") ?>
+
+<code>SEE</code> de-compiles definitions from the dictionary. Ficl words are stored as a combination
+of things:
+<ol>
+
+<li>bytecodes (identified as "instructions"),
+<li>addresses of native Ficl functions, and
+<li>arguments to both of the above.
+
+</ol>
+Colon definitions are decompiled. Branching instructions indicate their destination,
+but target labels are not reconstructed.
+Literals and string literals are so noted, and their contents displayed.
+
+</dl>
+
+
+<? ficlHeader2("Search Order Implementation-Defined Options") ?>
+
+
+<dl>
+
+<? entry("maximum number of word lists in the search order (16.3.3 Finding definition names, 16.6.1.2197 SET-ORDER)") ?>
+
+Defaults to 16. Can be changed by redefining <code>FICL_MAX_WORDLISTS</code> (declared in <code>ficl.h</code>).
+
+
+<? entry("minimum search order (16.6.1.2197 SET-ORDER, 16.6.2.1965 ONLY)") ?>
+
+Equivalent to <code>FORTH-WORDLIST 1 SET-ORDER</code>
+
+</dl>
+
+
+
+<? ficlHeader2("Search Order Ambiguous Conditions") ?>
+
+
+<dl>
+<? entry("changing the compilation word list (16.3.3 Finding definition names)") ?>
+
+Ficl stores a link to the current definition independently of the compile wordlist while
+it is being defined, and links it into the compile wordlist only after the definition completes
+successfully. Changing the compile wordlist mid-definition will cause the definition to link
+into the <i>new</i> compile wordlist.
+
+
+<? entry("search order empty (16.6.2.2037 PREVIOUS)") ?>
+
+Ficl prints an error message if the search order underflows, and resets the order to its default state.
+
+
+<? entry("too many word lists in search order (16.6.2.0715 ALSO)") ?>
+
+Ficl prints an error message if the search order overflows, and resets the order to its default state.
+
+</dl>
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/ficl.ht b/doc/source/ficl.ht
new file mode 100644
index 000000000000..faa49e7a7cff
--- /dev/null
+++ b/doc/source/ficl.ht
@@ -0,0 +1,1257 @@
+<!DOCTYPE html PUBLIC "-//w3c//dtd html 4.0 transitional//en">
+
+<html>
+<head>
+ <meta name="Author" content="john sadler">
+ <meta name="Description" content="Ficl - embedded scripting with object oriented programming">
+ <meta name="Keywords" content="scripting prototyping tcl OOP Forth interpreter C">
+ <link rel="SHORTCUT ICON" href="favicon.ico">
+ <title>Ficl - Embedded Scripting</title>
+</head>
+
+<body>
+
+<h1>Ficl Documentation</h1>
+
+<script language="javascript" src="ficlheader.js" type="text/javascript">
+</script>
+
+<h1><a name="whatis">What is Ficl?</a></h1>
+Ficl is a complete programming language interpreter designed to be
+embedded into other systems (including firmware based ones) as a
+command, macro, and development prototype language. Unlike other
+scripting interpreters, Ficl:
+
+<ul>
+
+<li>
+typically takes under 2 hours to port to a new system&mdash;much
+less if the target operating system is one of several already supported
+(Win32, Linux, FreeBSD, RiscOS, and more)
+
+<li>
+has a small memory footprint: a fully featured Win32 console
+version takes less than 100K of memory, and a minimal version is less
+than half that
+
+<li>
+is relatively quick thanks to its "switch-threaded" virtual
+machine design and just in time compiling
+
+<li>
+is a complete and powerful programming language
+
+<li>
+is interactive
+
+<li>
+has object oriented programming features that can be used to wrap
+data structures or classes of the host system without altering them&#151;even
+if the host is mainly written in a non-OO language
+
+</ul>
+
+<p>
+
+Ficl syntax is based on ANS Forth and the code is ANSI C. See
+below for examples of <a href="#includesficl">software and products
+that include ficl</a>. Ficl stands for "Forth inspired command language".
+
+
+<h3>Ficl Versus Other Forth Interpreters</h3>
+
+Where most Forths view themselves as the center of the system and
+expect the rest of the system to be coded in Forth, Ficl acts as a
+component of the system. It is easy to export code written in C or
+ASM to Ficl in the style of TCL, or to invoke Ficl code from a compiled
+module. This allows you to do incremental development in a way that
+combines the best features of threaded languages (rapid
+development, quick code/test/debug cycle, reasonably fast) with the best
+features of C (everyone knows it, easier to support large blocks of
+code, efficient, type checking). In addition, Ficl provides a simple
+and powerful object model that can act as an object oriented <i>adapter</i>
+for code written in C (or asm, Forth, C++...).
+
+
+<h3>Ficl Design Goals</h3>
+<ul>
+
+<li>
+Target 32- and 64-bit processors
+
+<li>
+Scripting, prototyping, and extension language for systems
+written also in C
+
+<li>
+Supportable&mdash;code is as transparent as I can make it
+
+<li>
+Interface to functions written in C
+
+<li>
+Conformant to the 1994 ANSI Standard for Forth (DPANS94)
+
+<li>
+Minimize porting effort&mdash;require an ANSI C runtime environment
+and minimal glue code
+
+<li>
+Provide object oriented extensions
+
+</ul>
+
+<hr>
+
+<h2><a name="download">Download</a></h2>
+
+<ul>
+
+<li> <b><a href="http://sourceforge.net/project/showfiles.php?group_id=24441">Download Ficl (latest release)</a></b>
+
+</ul>
+
+<h2><a name="links">More information on Ficl and Forth</a></h2>
+
+<ul>
+
+<li>
+<a href="http://ficl.sourceforge.net">Web home of Ficl</a>
+
+<li>
+<a href="http://ficl.sourceforge.net/pdf/Forth_Primer.pdf">
+An excellent Forth Primer by Hans Bezemer
+</a>
+
+<li>
+<a href="ficlddj.pdf">
+Manuscript of Ficl article for January 1999 Dr. Dobb's Journal
+</a>
+
+<li>
+<a href="jwsforml.pdf">
+1998 FORML Conference paper&mdash;OO Programming in Ficl
+</a>
+
+<li>
+<a href="http://www.taygeta.com/forth_intro/stackflo.html">
+An Introduction to Forth using Stack Flow
+</a>
+(start here if you're new to Forth)
+
+<li>
+<a href="http://www.softsynth.com/pforth/pf_tut.htm">
+Phil Burk's Forth Tutorial
+</a>
+
+<li>
+<a href="http://www.complang.tuwien.ac.at/forth/threaded-code.html">
+Anton Ertl's description of Threaded Code
+</a>
+(Ficl now uses what he calls "switch threading")
+
+<li>
+<a href="http://ficl.sourceforge.net/dpans/dpans.htm">
+Draft Proposed American National Standard for Forth
+</a>
+(quite readable, actually)
+
+<li>
+<a href="http://www.taygeta.com/forthlit.html">
+Forth literature index on Taygeta
+</a>
+
+<li>
+<a href="http://www.forth.org">
+Forth Interest Group
+</a>
+
+</ul>
+
+<h2><a name="includesficl">Some software that uses Ficl</a></h2>
+
+<ul>
+<li>
+The <a href="http://www.freebsd.org/">FreeBSD</a> boot loader
+(Daniel Sobral, Jordan Hubbard)
+
+<li>
+<a href="http://www.chipcenter.com/networking/images/prod/prod158a.pdf">
+SwitchCore
+</a>
+Gigabit Ethernet switches (&Ouml;rjan Gustavsson )
+
+<li>
+<a href="http://debuffer.sourceforge.net/">
+Palm Pilot Debuffer
+</a>
+(Eric Sessoms) Also see ficlx, a C++ interface to ficl, on the same site
+
+<li>
+<a href="http://www.swcp.com/%7Ejchavez/osmond.html">
+Osmond PC Board Layout tool
+</a>
+
+<li>
+<a href="http://www.netcomsystems.com">
+NetCom Systems
+</a>
+ML7710
+
+<li>
+<a href="http://www.parview.com/ds/homepage.html">
+ParView
+</a>
+GPS system
+
+<li>
+<a href="http://www.thekompany.com/products/powerplant/software/Languages/Embedded.php3">
+PowerPlant Software
+</a>
+Development Environment for Linux
+
+<li>
+<a href="http://www.vyyo.com/products/architecture_v3000.html">
+Vyyo V3000 Broadband Wireless Hub
+</a>
+
+<li>
+<a href="mailto:john_sadler@alum.mit.edu">
+<i>Your Product Name Here!!!</i>
+</a>
+
+</ul>
+
+
+<hr>
+<h2><a name="lawyerbait">License And Disclaimer</a></h2>
+
+Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
+<br>
+All rights reserved.
+<p>
+
+<b>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+<ol>
+
+<li>
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+<li>
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+</ol>
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+</b>
+<p>
+
+I am interested in hearing from anyone who uses Ficl. If you have a
+problem, a success story, a defect, an enhancement request, or if
+you would like to contribute to the ficl release, please
+<a href="mailto:john_sadler@alum.mit.edu">send me email</a>.
+<p>
+
+
+<h2><a name="features">Ficl Features</a></h2>
+
+<ul>
+
+<li>
+Simple to integrate into existing systems: the sample
+implementation requires three Ficl function calls (see the example
+program in <b>main.c</b>).
+
+<li>
+Written in ANSI C for portability.
+
+<li>
+Standard: Implements the ANS Forth CORE word set, part of the
+CORE EXT word set, SEARCH and SEARCH EXT, TOOLS and part of TOOLS EXT,
+LOCAL and LOCAL EXT, EXCEPTION, MEMORY, and various extras.
+
+<li>
+Extensible: you can export code written in Forth, C, or ASM in a
+straightforward way. Ficl provides open facilities for extending the
+language in an application specific way. You can even add new
+control structures (not surprising if you're familiar with Forth)
+
+<li>
+Ficl and C/C++ can interact in two ways: Ficl can wrap C code,
+and C functions can invoke Ficl code.
+
+<li>
+Ficl code is thread safe and re-entrant: your program can have one or more
+Ficl "systems", and each "system" can have one or Ficl virtual machines.
+Each Ficl virtual machine has an otherwise complete state, and each can
+be bound to a separate I/O channel (or none at all).
+An optional function called ficlLockDictionary() can control
+exclusive dictionary access. This function is stubbed out by
+default (See FICL_MULTITHREAD in sysdep.h). As long as there is only
+one "session" that can compile words into the dictionary, you do not
+need exclusive dictionary access for multithreading.
+<b>Note</b>:
+while the code is re-entrant, there are still restrictions on how you
+can use it safely in a multithreaded system. Specifically, the VM
+itself maintains state, so you generally need a VM per thread in a
+multithreaded system. If interrupt service routines make calls into Ficl
+code that alters VM state, then these generally need their
+own VM as well. Alternatively, you could provide a mutual exclusion
+mechanism to serialize access to a VM from multiple threads.
+
+<li>
+ROMable: Ficl is designed to work in RAM based and ROM code / RAM
+data environments. It does require somewhat more memory than a pure ROM
+implementation because it builds its system dictionary in RAM
+at startup time.
+
+<li>
+Written in ANSI C to be as simple as I can make it to understand,
+support, debug, and port. Compiles without complaint at <code>/Az /W4</code> (require
+ANSI C, max. warnings) under Microsoft Visual C++, and <code>-ansi</code>
+under GCC. Ports to several other toolchains and operating systems
+(notably FreeBSD and Linux flavors) exist.
+
+<li> Does full 32 bit math (but you need to implement two mixed
+precision math primitives (see sysdep.c)) </li>
+
+</ul>
+
+<hr>
+
+<h2><a name="porting">Porting Ficl</a></h2>
+
+To install Ficl on your target system, you need an ANSI C compiler and
+its runtime library. Inspect the system dependent macros and functions
+in <b>sysdep.h</tt> and <tt>sysdep.c</tt> and edit them to suit
+your system. For example, <tt>INT16</tt> is a <tt>short</tt> on some
+compilers and an <tt>int</tt> on others. Check the default <tt>CELL</tt>
+alignment controlled by <tt> FICL_ALIGN</tt>. If necessary, add new
+definitions of <tt>ficlMalloc, ficlFree, ficlRealloc</tt>, and <tt>ficlTextOut</tt>
+to work with your operating system. Finally, use <tt>testmain.c</tt> as
+a guide to installing the ficl system and one or more virtual machines
+into your code. You do not need to include <tt>testmain.c</tt> in your
+build.
+<p>
+Note: ficlLockDictionary can be left unimplemented in most
+multithreaded implementations - it's only necessary if you expect to
+have more than one thread modifying the dictionary at the same
+time. If you do decide to implement it, make sure calls to
+ficlLockDictionary can nest properly (see the comments in sysdep.h). You
+need to keep count of nested locks and unlocks and do the right
+thing.
+<p>
+
+Feel free to stub out the double precision math functions (which are
+presently implemented as inline assembly because it's so easy on many 32
+bit processors) with kludge code that only goes to 32 bit
+precision. In most applications, you won't notice the difference. If
+you're doing a lot of number crunching, consider implementing them
+correctly.
+
+
+<h3>Build Controls</h3>
+
+The file sysdep.h contains default values for build controls. Most of
+these are written such that if you define them on the compiler command
+line, the defaults are overridden. I suggest you take the defaults
+on everything below the "build controls" section until you're confident
+of your port. Beware of declaring too small a dictionary, for example.
+You need about 3200 cells for a full system, about 2000 if you
+strip out most of the "soft" words.
+
+<h3>Softcore</h3>
+Many words from all the supported wordsets are written in Forth, and
+stored as a big string that Ficl compiles when it starts. The sources
+for all of these words are in directory <b>softcore</b>. There is a
+.bat file (softcore.bat) and a PERL 5 script (softcore.pl) that convert
+Forth files into the file softcore.c, so softcore.c is really dependent
+on the Forth sources. This is not reflected in the Visual C++ project
+database. For the time being, it's a manual step. You can edit
+<b>make.bat</b> to change the list of files that contribute to
+<b>softcore.c</b>.
+
+<h3>To-Do List (target system dependent words)</h3>
+
+<ul>
+
+<li>
+Unimplemented system dependent <tt>CORE</tt> word: <tt>KEY</tt>
+(implement this yourself if you need it)
+
+<li>
+Kludged <tt>CORE</tt> word: <tt>ACCEPT</tt> (implement this
+better if you need to)
+
+</ul>
+
+<h2><a name="api">Application Programming Interface</a></h2>
+
+The following is a partial listing of functions that interface your
+system or program to Ficl. For a complete listing, see <b>ficl.h</b>
+(which is heavily commented). For examples, see <b>main.c</b> and the
+FiclWin sources (<a href="#download">below</a>).
+
+<dl>
+ <dt> <b>FICL_SYSTEM *ficlInitSystem(int nDictCells)</b> </dt>
+ <dd> Initializes Ficl's shared system data structures, and creates the
+dictionary allocating the specified number of CELLs from the heap (by a
+call to ficlMalloc) </dd>
+ <dt> <b>void ficlTermSystem(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Reclaims memory allocated for the ficl system including all
+dictionaries and all virtual machines created by vmCreate. Any uses of
+the memory allocation words (allocate and resize) are your
+problem. </dd>
+ <dt> <b>int ficlBuild(FICL_SYSTEM *pSys, char *name, FICL_CODE code,
+char flags)</b> </dt>
+ <dd> Create a primitive word in ficl's main dictionary with the given
+name, code pointer, and properties (immediate, compile only, etc) as
+described by the flags (see ficl.h for flag descriptions of
+the form FW_XXXX) </dd>
+ <dt> <b>int ficlExec(FICL_VM *pVM, char *text)</b> </dt>
+ <dd> Feed the specified C string ('\0' terminated) to the given
+virtual machine for evaluation. Returns various exception codes (VM_XXXX
+in ficl.h) to indicate the reason for returning. Normal exit
+condition is VM_OUTOFTEXT, indicating that the VM consumed the string
+successfully and is back for more. ficlExec calls can be nested, and
+the function itself is re-entrant, but note that a VM is
+static, so you have to take reasonable precautions (for example, use one
+VM per thread in a multithreaded system if you want multiple threads to
+be able to execute commands). </dd>
+ <dt> <b>int ficlExecC(FICL_VM *pVM, char *text, int nChars)</b> </dt>
+ <dd> Same as ficlExec, but takes a count indicating the length of the
+supplied string. Setting nChars to -1 is equivalent to ficlExec (expects
+'\0' termination). </dd>
+ <dt> <b>int ficlExecXT(FICL_VM *pVM, FICL_WORD *pFW)</b> </dt>
+ <dd> Same as ficlExec, but takes a pointer to a FICL_WORD instead of a
+string. Executes the word and returns after it has finished. If
+executing the word results in an exception, this function will
+re-throw the same code if it is nested under another ficlExec family
+function, or return the exception code directly if not. This function
+is useful if you need to execute the same word repeatedly -
+you save the dictionary search and outer interpreter overhead. </dd>
+ <dt> <b>void ficlFreeVM(FICL_VM *pVM)</b> </dt>
+ <dd> Removes the VM in question from the system VM list and deletes
+the&nbsp; memory allocated to it. This is an optional call, since
+ficlTermSystem will do this cleanup for you. This function is
+handy if you're going to do a lot of dynamic creation of VMs. </dd>
+ <dt> <b>FICL_VM *ficlNewVM(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Create, initialize, and return a VM from the heap using
+ficlMalloc. Links the VM into the system VM list for later reclamation
+by ficlTermSystem. </dd>
+ <dt> <b>FICL_WORD *ficlLookup(FICL_SYSTEM *pSys, char *name)</b> </dt>
+ <dd> Returns the address (also known as an XT in this case) of the
+specified word in the main dictionary. If not found, returns NULL. The
+address can be used in a call to ficlExecXT. </dd>
+ <dt> <b>FICL_DICT *ficlGetDict(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Returns a pointer to the main system dictionary, or NULL if the
+system is uninitialized. </dd>
+ <dt> <b>FICL_DICT *ficlGetEnv(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Returns a pointer to the environment dictionary. This dictionary
+stores information that describes this implementation as required by the
+Standard. </dd>
+ <dt> <b>void ficlSetEnv(FICL_SYSTEM *pSys, char *name, UNS32 value)</b> </dt>
+ <dd> Enters a new constant into the environment dictionary, with the
+specified name and value. </dd>
+ <dt> <b>void ficlSetEnvD(FICL_SYSTEM *pSys, char *name, UNS32 hi,
+UNS32 lo)</b> </dt>
+ <dd> Enters a new double-cell constant into the environment dictionary
+with the specified name and value. </dd>
+ <dt> <b>FICL_DICT *ficlGetLoc(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Returns a pointer to the locals dictionary. This function is
+defined only if FICL_WANT_LOCALS is #defined as non-zero (see sysdep.h).
+The locals dictionary is the symbol table for <a href="ficl_loc.html">local
+variables</a>. </dd>
+ <dt> <b>void ficlCompileCore(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Defined in words.c, this function builds ficl's primitives.&nbsp;
+ </dd>
+ <dt> <b>void ficlCompileSoftCore(FICL_SYSTEM *pSys)</b> </dt>
+ <dd> Defined in softcore.c, this function builds ANS required words
+and ficl extras by evaluating a text string (think of it as a memory
+mapped file ;-) ). The string itself is built from files in
+the softwords directory by PERL script softcore.pl.&nbsp; </dd>
+</dl>
+<hr>
+<table border="0" cellspacing="5" cols="2">
+ <tbody>
+ <tr>
+ <td colspan="2">
+ <h2> <a name="manifest"></a>Ficl Source Files </h2>
+ </td>
+ </tr>
+ <tr>
+ <td> <b>ficl.h</b> </td>
+ <td> Declares most public functions and all data structures.
+Includes sysdep.h and math.h </td>
+ </tr>
+ <tr>
+ <td> <b>sysdep.h</b> </td>
+ <td> Declares system dependent functions and contains build
+control macros. Edit this file to port to another system. </td>
+ </tr>
+ <tr>
+ <td> <b>math.h</b> </td>
+ <td> Declares functions for 64 bit math </td>
+ </tr>
+ <tr>
+ <td> <b>dict.c</b> </td>
+ <td> Dictionary </td>
+ </tr>
+ <tr>
+ <td> <b>ficl.c</b> </td>
+ <td> System initialization, termination, and ficlExec </td>
+ </tr>
+ <tr>
+ <td> <b>float.c</b> </td>
+ <td> Adds precompiled definitions from the optional FLOAT word
+set. Most of the file is conditioned on FICL_WANT_FLOAT </td>
+ </tr>
+ <tr>
+ <td> <b>math64.c</b> </td>
+ <td> Implementation of 64 bit math words (except the two unsigned
+primitives declared in sysdep.h and implemented in sysdep.c) </td>
+ </tr>
+ <tr>
+ <td> <b>prefix.c</b> </td>
+ <td> The optional prefix parse step (conditioned on
+FICL_EXTENDED_PREFIX). This parse step handles numeric constructs like
+0xa100, for example. See the release notes for more on parse steps. </td>
+ </tr>
+ <tr>
+ <td> <b>search.c</b> </td>
+ <td> Contains C implementations of several of the SEARCH and
+SEARCH EXT words </td>
+ </tr>
+ <tr>
+ <td> <b>softcore.c</b> </td>
+ <td> Contains all of the "soft" words - those written in Forth and
+compiled by Ficl at startup time. Sources for these words are in the
+softwords directory. The files softwords/softcore.bat and
+softwords/softcore.pl generate softcore.c from the .fr sources. </td>
+ </tr>
+ <tr>
+ <td> <b>softwords/</b> </td>
+ <td> Directory contains sources and translation scripts for the
+words defined in softcore.c. Softcore.c depends on most of the files in
+this directory. See softcore.bat for the actual list of
+files that contribute to softcore.c. This is where you'll find source
+code for the object oriented extensions. PERL script softcore.pl
+converts the .fr files into softcore.c. </td>
+ </tr>
+ <tr>
+ <td> <b>stack.c</b> </td>
+ <td> Stack methods </td>
+ </tr>
+ <tr>
+ <td> <b>sysdep.c</b> </td>
+ <td> Implementation of system dependent functions declared in
+sysdep.h </td>
+ </tr>
+ <tr>
+ <td> <b>testmain.c</b> </td>
+ <td> The main() function for unix/linux/win32 console applications
+- use this as an example to integrate ficl into your system. Also
+contains some definitions for testing - also useful in
+unix/linux/win32 land. </td>
+ </tr>
+ <tr>
+ <td> <b>tools.c</b> </td>
+ <td> Contains C implementations of TOOLS and TOOLS EXT words, the
+debugger, and debugger support words. </td>
+ </tr>
+ <tr>
+ <td> <b>vm.c</b> </td>
+ <td> Virtual Machine methods </td>
+ </tr>
+ <tr>
+ <td> <b>win32.c &amp; unix.c</b> </td>
+ <td> Platform extensions words loaded in ficl.c by
+ficlCompilePlatform() - conditioned on FICL_WANT_PLATFORM </td>
+ </tr>
+ <tr>
+ <td> <b>words.c</b> </td>
+ <td> Exports ficlCompileCore(), the run-time dictionary builder,
+and contains most precompiled CORE and CORE-EXT words. </td>
+ </tr>
+ </tbody>
+</table>
+<hr>
+<h2> <a name="extras"></a>Ficl extras </h2>
+<h3> <a name="exnumber"></a>Number syntax </h3>
+You can precede a number with "0x", as in C, and it will be interpreted
+as a hex value regardless of the value of <code>BASE</code>. Likewise,
+numbers prefixed with "0d" will be interpreted as decimal values.
+Example:
+<pre>ok&gt; decimal 123 . cr<br>123<br>ok&gt; 0x123 . cr<br>291<br>ok&gt; 0x123 x. cr<br>123<br></pre>
+Note: ficl2.05 and later - this behavior is controlled by the <a
+ href="ficl_parse.html">prefix parser</a> defined in <code>prefix.c</code>.
+You can add other prefixes by defining handlers for them in ficl
+or C.
+<h3> <a name="exsearch"></a> The <code>SEARCH</code> wordset and Ficl
+extensions </h3>
+<p> Ficl implements many of the search order words in terms of two
+primitives called <code><a href="#tosearch">&gt;SEARCH</a></code> and <code><a
+ href="#searchfrom">SEARCH&gt;</a></code>. As their names
+suggest (assuming you're familiar with Forth), they push and pop the
+search order stack. </p>
+<p> The standard does not appear to specify any conditions under which
+the search order is reset to a sane state. Ficl resets the search order
+to its default state whenever <tt>ABORT</tt> happens. This includes
+stack underflows and overflows. <tt>QUIT</tt> does not affect the search
+order. The minimum search order (set by <tt>ONLY</tt>) is equivalent
+to </p>
+<pre>FORTH-WORDLIST 1 SET-ORDER<br></pre>
+<p> There is a default maximum of 16 wordlists in the search order. This
+can be changed by redefining FICL_DEFAULT_VOCS (declared in sysdep.h). </p>
+<p> <b>Note</b>: Ficl resets the search order whenever it does <tt>ABORT</tt>.
+If you don't like this behavior, just comment out the
+dictResetSearchOrder() lines in ficlExec(). </p>
+<dl>
+ <dt> <a name="tosearch"></a><code>&gt;search ( wid -- )</code> </dt>
+ <dd> Push <tt>wid</tt> onto the search order. Many of the other search
+order words are written in terms of the <tt>SEARCH&gt;</tt> and <tt>&gt;SEARCH</tt>
+primitives. This word can be defined in ANS Forth as follows </dd>
+ <dd> <tt>: &gt;search&nbsp;&nbsp; &gt;r get-order 1+ r&gt; swap
+set-order ;</tt> </dd>
+ <dt> <a name="searchfrom"></a><tt>search&gt;&nbsp;&nbsp; ( -- wid )</tt> </dt>
+ <dd> Pop <tt>wid</tt> off the search order (can be coded in ANS Forth
+as&nbsp;<tt>: search&gt;&nbsp; get-order nip 1- set-order ;</tt> ) </dd>
+ <dt> <a name="ficlsetcurrent"></a><tt>ficl-set-current&nbsp;&nbsp; (
+wid -- old-wid )</tt> </dt>
+ <dd> Set wid as compile wordlist, leaving the previous compile
+wordlist on the stack </dd>
+ <dt> <a name="ficlvocabulary"></a><tt>ficl-vocabulary&nbsp;&nbsp; (
+nBins "name" -- )</tt> </dt>
+ <dd> Creates a <tt>ficl-wordlist</tt> with the specified number of
+hash table bins, binds it to the name, and associates the semantics of <tt>vocabulary</tt>
+with it (replaces the top wid in the search order list with
+its own wid when executed) </dd>
+ <dt> <a name="ficlwordlist"></a><tt>ficl-wordlist&nbsp;&nbsp; ( nBins
+-- wid )</tt> </dt>
+ <dd> Creates a wordlist with the specified number of hash table bins,
+and leaves the address of the wordlist on the stack. A <tt>ficl-wordlist</tt>
+behaves exactly as a regular wordlist, but it may search
+faster depending on the number of bins chosen and the number of words it
+contains at search time. As implemented in ficl, a wordlist is single
+threaded by default. <tt> ficl-named-wordlist</tt> takes a name for the
+wordlist and creates a word that pushes the <tt>wid</tt>. This is by
+contrast to <tt>VOCABULARY</tt>, which also has a name, but replaces
+the top of the search order with its <tt>wid</tt>. </dd>
+ <dt> <a name="ficlforgetwid"></a><tt>forget-wid&nbsp;&nbsp; ( wid -- )</tt> </dt>
+ <dd> Iterates through the specified wordlist and unlinks all
+definitions whose xt addresses are greater than or equal to the value of <tt>HERE</tt>,
+the dictionary fill pointer.&nbsp; </dd>
+ <dt> <a name="ficlhide"></a><tt>hide&nbsp;&nbsp; ( -- current-wid-was
+)</tt> </dt>
+ <dd> Push the <tt>hidden</tt> wordlist onto the search order, and set
+it as the current compile wordlist (unsing <tt>ficl-set-current</tt>).
+Leaves the previous compile wordlist ID. I use this word to
+hide implementation factor words that have low reuse potential so that
+they don't clutter the default wordlist. To undo the effect of hide,
+execute&nbsp; <b><tt>previous set-current</tt></b> </dd>
+ <dt> <a name="ficlhidden"></a><tt>hidden&nbsp;&nbsp; ( -- wid )</tt> </dt>
+ <dd> Wordlist for storing implementation factors of ficl provided
+words. To see what's in there, try:&nbsp; <b><tt>hide words previous
+set-current</tt></b> </dd>
+ <dt> <a name="wid-get-name"></a><tt>wid-get-name&nbsp;&nbsp; ( wid --
+c-addr u )</tt> </dt>
+ <dd> Ficl wordlists (2.05 and later) have a name property that can be
+assigned. This is used by <tt>ORDER</tt> to list the names of wordlists
+in the search order.&nbsp; </dd>
+ <dt> <a name="wid-set-name"></a><tt>wid-set-name&nbsp;&nbsp; ( c-addr
+wid -- )</tt> </dt>
+ <dd> Ficl wordlists (2.05 and later) have a name property that can be
+assigned. This is used by <tt>ORDER</tt> to list the names of wordlists
+in the search order. The name is assumed to be a \0 terminated
+string (C style), which conveniently is how Ficl stores word
+names.&nbsp; See softwords/softcore.fr definition of <tt>brand-wordlist</tt>&nbsp;</dd>
+ <dt> <a name="wid-set-super"></a><tt>wid-set-super&nbsp;&nbsp; ( wid
+-- )</tt> </dt>
+ <dd> Ficl wordlists have a parent wordlist pointer that is not
+specified in standard Forth. Ficl initializes this pointer to NULL
+whenever it creates a wordlist, so it ordinarily has no effect.
+This word sets the parent pointer to the wordlist specified on the top
+of the stack. Ficl's implementation of <tt>SEARCH-WORDLIST</tt> will
+chain backward through the parent link of the wordlist when
+searching. This simplifies Ficl's object model in that the search order
+does not need to reflect an object's class hierarchy when searching for
+a method. It is possible to implement Ficl object syntax in
+strict ANS Forth, but method finders need to manipulate the search order
+explicitly. </dd>
+</dl>
+<h3> <a name="exuser"></a>User variables </h3>
+<dl>
+ <dt> <tt>user&nbsp;&nbsp; ( -- ) name</tt> </dt>
+ <dd> Create a user variable with the given name. User variables are
+virtual machine local. Each VM allocates a fixed amount of storage for
+them. You can change the maximum number of user variables
+allowed by defining FICL_USER_CELLS on your compiiler's command line.
+Default is 16 user cells. User variables behave like <tt>VARIABLE</tt>s
+in all other respects (you use @ and ! on them, for example).
+Example: </dd>
+ <dd>
+ <dl>
+ <dd> <tt>user current-class</tt> </dd>
+ <dd> <tt>0 current-class !</tt> </dd>
+ </dl>
+ </dd>
+</dl>
+<h3> <a name="exmisc"></a>Miscellaneous </h3>
+<dl>
+ <dt> <tt>-roll&nbsp;&nbsp; ( xu xu-1 ... x0 u -- x0 xu-1 ... x1
+)&nbsp;</tt> </dt>
+ <dd> Rotate u+1 items on top of the stack after removing u. Rotation
+is in the opposite sense to <tt>ROLL</tt> </dd>
+</dl>
+<dl>
+ <dt> <a name="minusrot"></a><tt>-rot&nbsp;&nbsp; ( a b c -- c a b )</tt> </dt>
+ <dd> Rotate the top three stack entries, moving the top of stack to
+third place. I like to think of this as <tt>1<sup>1</sup>/<sub>2</sub>swap</tt>
+because it's good for tucking a single cell value behind a
+cell-pair (like an object).&nbsp; </dd>
+</dl>
+<dl>
+ <dt> <tt>.env&nbsp;&nbsp; ( -- )</tt> </dt>
+ <dd> List all environment variables of the system </dd>
+ <dt> <tt>.hash&nbsp;&nbsp; ( -- )</tt> </dt>
+ <dd> List hash table performance statistics of the wordlist that's
+first in the search order </dd>
+ <dt> <tt>.ver&nbsp;&nbsp; ( -- )</tt> </dt>
+ <dd> Display ficl version ID </dd>
+ <dt> <tt>&gt;name&nbsp;&nbsp; ( xt -- c-addr u )</tt> </dt>
+ <dd> Convert a word's execution token into the address and length of
+its name </dd>
+ <dt> <tt>body&gt;&nbsp;&nbsp; ( a-addr -- xt )</tt> </dt>
+ <dd> Reverses the effect of <tt>CORE</tt> word <tt>&gt;body</tt>
+(converts a parameter field address to an execution token) </dd>
+ <dt> <tt>compile-only</tt> </dt>
+ <dd> Mark the most recently defined word as being executable only
+while in compile state. Many <tt>immediate</tt> words have this
+property. </dd>
+ <dt> <tt>empty&nbsp;&nbsp; ( -- )</tt>&nbsp; </dt>
+ <dd> Empty the parameter stack </dd>
+ <dt> <tt>endif</tt> </dt>
+ <dd> Synonym for <tt>THEN</tt> </dd>
+ <dt> <a name="last-word"></a><tt>last-word&nbsp;&nbsp; ( -- xt )</tt> </dt>
+ <dd> Pushes the xt address of the most recently defined word. This
+applies to colon definitions, constants, variables, and words that use <tt>create</tt>.
+You can print the name of the most recently defined word
+with&nbsp; </dd>
+ <dd> <b><tt>last-word &gt;name type</tt>&nbsp;</b> </dd>
+ <dt> <tt>parse-word&nbsp;&nbsp; ( &lt;spaces&gt;name -- c-addr u )</tt> </dt>
+ <dd> Skip leading spaces and parse name delimited by a space. c-addr
+is the address within the input buffer and u is the length of the
+selected string. If the parse area is empty, the resulting
+string has a zero length. (From the Standard) </dd>
+ <dt> <a name="qfetch"></a><tt>q@&nbsp;&nbsp; ( addr -- x )</tt> </dt>
+ <dd> Fetch a 32 bit quantity from the specified address </dd>
+ <dt> <a name="qbang"></a><tt>q!&nbsp;&nbsp; ( x addr -- )</tt> </dt>
+ <dd> Store a 32 bit quantity to the specified address&nbsp; </dd>
+ <dt> <tt>w@&nbsp;&nbsp; ( addr -- x )</tt> </dt>
+ <dd> Fetch a 16 bit quantity from the specified address </dd>
+ <dt> <tt>w!&nbsp;&nbsp; ( x addr -- )</tt> </dt>
+ <dd> Store a 16 bit quantity to the specified address (the low 16 bits
+of the given value) </dd>
+ <dt> <a name="xdot"></a><tt>x.&nbsp;&nbsp; ( x -- )</tt> </dt>
+ <dd> Pop and display the value in hex format, regardless of the
+current value of <tt>BASE</tt> </dd>
+</dl>
+<h3> <a name="exficlwin"></a>Extra words defined in testmain.c (Win32
+and POSIX versions) </h3>
+<dl>
+ <dt> <tt>break&nbsp;&nbsp; ( -- )</tt> </dt>
+ <dd> Does nothing - just a handy place to set a debugger breakpoint </dd>
+ <dt> <tt>cd&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (
+"directory-name&lt;newline&gt;" -- )</tt> </dt>
+ <dd> Executes the Win32 chdir() function, changing the program's
+logged directory. </dd>
+ <dt> <a name="clock"></a><tt>clock&nbsp;&nbsp; ( -- now )</tt> </dt>
+ <dd> Wrapper for the ANSI C clock() function. Returns the number of
+clock ticks elapsed since process start. </dd>
+ <dt> <a name="clockspersec"></a><tt>clocks/sec&nbsp;&nbsp; ( --
+clocks_per_sec )</tt> </dt>
+ <dd> Pushes the number of ticks in a second as returned by <tt>clock</tt> </dd>
+ <dt> <a name="ficlload"></a><tt>load&nbsp;&nbsp;&nbsp; (
+"filename&lt;newline&gt;" -- )</tt> </dt>
+ <dd> Opens the Forth source file specified and loads it one line at a
+time, like <tt>INCLUDED (FILE)</tt> </dd>
+ <dt> <tt>pwd&nbsp;&nbsp;&nbsp;&nbsp; ( -- )</tt> </dt>
+ <dd> Prints the current working directory as set by <tt>cd</tt> </dd>
+ <dt> <tt>system&nbsp; ( "command&lt;newline&gt;" -- )</tt> </dt>
+ <dd> Issues a command to a shell; implemented with the Win32 system()
+call. </dd>
+ <dt> <tt>spewhash&nbsp;&nbsp; ( "filename&lt;newline&gt;" -- )</tt> </dt>
+ <dd> Dumps all threads of the current compilation wordlist to the
+specified text file. This was useful when I thought there might be some
+point in attempting to optimize the hash function. I no longer
+harbor those illusions. </dd>
+</dl>
+<h3> Words defined in FiclWin only </h3>
+<dl>
+ <dt> <tt>!oreg&nbsp;&nbsp; ( c -- )</tt> </dt>
+ <dd> Set the value of the simulated LED register as specified (0..255)
+ </dd>
+ <dt> <tt>@ireg&nbsp;&nbsp; ( -- c )</tt> </dt>
+ <dd> Gets the value of the simulated switch block (0..255) </dd>
+ <dt> <tt>!dac&nbsp;&nbsp;&nbsp; ( c -- )</tt> </dt>
+ <dd> Sets the value of the bargraph control as specified. Valid values
+range from 0..255 </dd>
+ <dt> <tt>@adc&nbsp;&nbsp;&nbsp; ( -- c )</tt> </dt>
+ <dd> Fetches the current position of the slider control. Range is
+0..255 </dd>
+ <dt> <tt>status"&nbsp;&nbsp; ( "ccc&lt;quote&gt;" -- )</tt> </dt>
+ <dd> Set the mainframe window's status line to the text specified, up
+to the first trailing quote character. </dd>
+ <dt> <a name="ficlms"></a><tt><a
+ href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905">ms</a>&nbsp;&nbsp;
+( u -- )</tt> </dt>
+ <dd> Causes the running virtual machine to sleep() for the number of
+milliseconds specified by the top-of-stack value. </dd>
+</dl>
+<hr>
+<h2> <a name="ansinfo"></a>ANS Required Information </h2>
+<b>ANS Forth System</b><br>
+<b>Providing names from the Core Extensions word set&nbsp;</b><br>
+<b>Providing the Exception word set</b><br>
+<b>Providing names from the Exception Extensions word set</b><br>
+<b>Providing the Locals word set&nbsp;</b><br>
+<b>Providing the Locals Extensions word set&nbsp;</b><br>
+<b>Providing the Memory Allocation word set</b><br>
+<b>Providing the Programming-Tools word set</b><br>
+<b>Providing names from the Programming-Tools Extensions word set</b><br>
+<b>Providing the Search-Order word set</b><br>
+<b>Providing the Search-Order Extensions word set</b>
+<h3> Implementation-defined Options </h3>
+The implementation-defined items in the following list represent
+characteristics and choices left to the discretion of the implementor,
+provided that the requirements of the Standard are met. A system
+shall document the values for, or behaviors of, each item.&nbsp;
+<ul>
+ <li> <b>aligned address requirements (3.1.3.3 Addresses);</b>&nbsp; </li>
+ <li> <br>
+ <font color="#000000">System dependent. You can change the default
+address alignment by defining FICL_ALIGN on your compiler's command
+line. The default value is set to 2 in sysdep.h. This causes
+dictionary entries and <tt>ALIGN</tt> and <tt>ALIGNED</tt> to align on 4
+byte boundaries. To align on <b>2<sup>n</sup></b> byte boundaries, set
+FICL_ALIGN to <b>n</b>.&nbsp;</font> </li>
+ <li> <b>behavior of 6.1.1320 EMIT for non-graphic characters</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Depends on target system, C runtime library,
+and your implementation of ficlTextOut().</font> </li>
+ <li> <b>character editing of 6.1.0695 ACCEPT and 6.2.1390 EXPECT</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">None implemented in the versions supplied in
+words.c. Because ficlExec() is supplied a text buffer externally, it's
+up to your system to define how that buffer will be obtained.</font> </li>
+ <li> <b>character set (3.1.2 Character types, 6.1.1320 EMIT, 6.1.1750
+KEY)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Depends on target system and implementation
+of ficlTextOut()</font> </li>
+ <li> <b>character-aligned address requirements (3.1.3.3 Addresses)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Ficl characters are one byte each. There are
+no alignment requirements.</font> </li>
+ <li> <b>character-set-extensions matching characteristics (3.4.2
+Finding definition n<font color="#000000">ames)</font></b><font
+ color="#000000">;&nbsp;</font> </li>
+ <li> <br>
+ <font color="#000000">No special processing is performed on
+characters beyond case-folding. Therefore, extended characters will not
+match their unaccented counterparts.</font> </li>
+ <li> <b>conditions under which control characters match a space
+delimiter (3.4.1.1 Delimiters)</b>;<font color="#ff6666">&nbsp;</font> </li>
+ <li> <br>
+ <font color="#000000">Ficl uses the Standard C function isspace()
+to distinguish space characters. The rest is up to your library vendor.</font> </li>
+ <li> <b>format of the control-flow stack (3.2.3.2 Control-flow stack)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Uses the data stack</font> </li>
+ <li> <b>conversion of digits larger than thirty-five (3.2.1.2 Digit
+conversion)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">The maximum supported value of <tt>BASE</tt>
+is 36. Ficl will assertion fail in function ltoa of vm.c if the base is
+found to be larger than 36 or smaller than 2. There will be no
+effect if NDEBUG is defined</font>, however, other than possibly
+unexpected behavior.&nbsp; </li>
+ <li> <b>display after input terminates in 6.1.0695 ACCEPT and
+6.2.1390 EXPECT</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Target system dependent</font> </li>
+ <li> <b>exception abort sequence (as in 6.1.0680 ABORT")</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Does <tt>ABORT</tt></font> </li>
+ <li> <b>input line terminator (3.2.4.1 User input device)</b>;<font
+ color="#ff0000">&nbsp;</font> </li>
+ <li> <br>
+ <font color="#000000">Target system dependent (implementation of
+outer loop that calls ficlExec)</font> </li>
+ <li> <b>maximum size of a counted string, in characters (3.1.3.4
+Counted strings, 6.1.2450 WORD)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">255</font> </li>
+ <li> <b>maximum size of a parsed string (3.4.1 Parsing)</b>;&nbsp; </li>
+ <li> <br>
+Limited by available memory and the maximum unsigned value that can fit
+in a CELL (2<sup>32</sup>-1).&nbsp; </li>
+ <li> <b>maximum size of a definition name, in characters (3.3.1.2
+Definition names)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl stores the first 31 characters of a
+definition name.</font> </li>
+ <li> <b>maximum string length for 6.1.1345 ENVIRONMENT?, in characters</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Same as maximum definition name length</font> </li>
+ <li> <b>method of selecting 3.2.4.1 User input device</b>;&nbsp; </li>
+ <li> <br>
+None supported. This is up to the target system&nbsp; </li>
+ <li> <b>method of selecting 3.2.4.2 User output device</b>;&nbsp; </li>
+ <li> <br>
+None supported. This is up to the target system&nbsp; </li>
+ <li> <b>methods of dictionary compilation (3.3 The Forth dictionary)</b>;&nbsp;</li>
+ <li> <b>number of bits in one address unit (3.1.3.3 Addresses)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Target system dependent. Ficl generally
+supports processors that can address 8 bit quantities, but there is no
+dependency that I'm aware of.</font> </li>
+ <li> <b>number representation and arithmetic (3.2.1.1 Internal number
+representation)</b>;&nbsp; </li>
+ <li> <br>
+System dependent. Ficl represents a CELL internally as a union that can
+hold INT32 (a signed 32 bit scalar value), UNS32 (32 bits unsigned), and
+an untyped pointer. No specific byte ordering is
+assumed.&nbsp; </li>
+ <li> <b>ranges for n, +n, u, d, +d, and ud (3.1.3 Single-cell types,
+3.1.4 Cell-pair types)</b>;&nbsp; </li>
+ <li> <br>
+Assuming a 32 bit implementation, range for signed single-cell values
+is -2<sup>31</sup>..2<sup>31</sup>-1. Range for unsigned single cell
+values is 0..2<sup>32</sup>-1. Range for signed double-cell
+values is -2<sup>63</sup>..2<sup>63</sup>-1. Range for unsigned single
+cell values is 0..2<sup>64</sup>-1.&nbsp; </li>
+ <li> <b>read-only data-space regions (3.3.3 Data space)</b>; </li>
+ <li> <br>
+None&nbsp; </li>
+ <li> <b>size of buffer at 6.1.2450 WORD (3.3.3.6 Other transient
+regions)</b>;&nbsp; </li>
+ <li> <br>
+Default is 255. Depends on the setting of nPAD in ficl.h.&nbsp; </li>
+ <li> <b>size of one cell in address units (3.1.3 Single-cell types)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">System dependent, generally four.</font> </li>
+ <li> <b>size of one character in address units (3.1.2 Character types)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">System dependent, generally one.</font> </li>
+ <li> <b>size of the keyboard terminal input buffer (3.3.3.5 Input
+buffers)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">This buffer is supplied by the host program.
+Ficl imposes no practical limit.</font> </li>
+ <li> <b>size of the pictured numeric output string buffer (3.3.3.6
+Other transient regions)</b>;&nbsp; </li>
+ <li> <br>
+Default is 255 characters. Depends on the setting of nPAD in
+ficl.h.&nbsp; </li>
+ <li> <b>size of the scratch area whose address is returned by
+6.2.2000 PAD (3.3.3.6 Other transient regions)</b>;&nbsp; </li>
+ <li> <br>
+Not presently supported&nbsp; </li>
+ <li> <b>system case-sensitivity characteristics (3.4.2 Finding
+definition names)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl is not case sensitive</font> </li>
+ <li> <b>system prompt (3.4 The Forth text interpreter, 6.1.2050 QUIT)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">"ok&gt;"</font> </li>
+ <li> <b>type of division rounding (3.2.2.1 Integer division, 6.1.0100
+*/, 6.1.0110 */MOD, 6.1.0230 /, 6.1.0240 /MOD, 6.1.1890 MOD)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Symmetric</font> </li>
+ <li> <b>values of 6.1.2250 STATE when true</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">One (no others)</font> </li>
+ <li> <b>values returned after arithmetic overflow (3.2.2.2 Other
+integer operations)</b>;&nbsp; </li>
+ <li> <br>
+System dependent. Ficl makes no special checks for overflow.&nbsp; </li>
+ <li> <b>whether the current definition can be found after 6.1.1250
+DOES&gt; (6.1.0450 :)</b>.&nbsp; </li>
+ <li> <br>
+ <font color="#000000">No. Definitions are unsmudged after ; only,
+and only then if no control structure matching problems have been
+detected.</font> </li>
+</ul>
+<h3> Ambiguous Conditions </h3>
+A system shall document the system action taken upon each of the
+general or specific ambiguous conditions identified in this Standard.
+See 3.4.4 Possible actions on an ambiguous condition.&nbsp;
+<p> The following general ambiguous conditions could occur because of a
+combination of factors:&nbsp; </p>
+<ul>
+ <li> <b>a name is neither a valid definition name nor a valid number
+during text interpretation (3.4 The Forth text interpreter)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl does <tt>ABORT</tt> and prints the name
+followed by " not found".</font> </li>
+ <li> <b>a definition name exceeded the maximum length allowed
+(3.3.1.2 Definition names)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl stores the first 31 characters of the
+definition name, and uses all characters of the name in computing its
+hash code. The actual length of the name, up to 255
+characters, is stored in the definition's length field.</font> </li>
+ <li> <b>addressing a region not listed in 3.3.3 Data Space</b>;&nbsp;
+ </li>
+ <li> <br>
+ <font color="#000000">No problem: all addresses in ficl are
+absolute. You can reach any 32 bit address in Ficl's address space.</font> </li>
+ <li> <b>argument type incompatible with specified input parameter,
+e.g., passing a flag to a word expecting an n (3.1 Data types)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Ficl makes no check for argument type
+compatibility. Effects of a mismatch vary widely depending on the
+specific problem and operands.</font> </li>
+ <li> <b>attempting to obtain the execution token, (e.g., with
+6.1.0070 ', 6.1.1550 FIND, etc.) of a definition with undefined
+interpretation semantics</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl returns a valid token, but the result of
+executing that token while interpreting may be undesirable.</font> </li>
+ <li> <b>dividing by zero (6.1.0100 */, 6.1.0110 */MOD, 6.1.0230 /,
+6.1.0240 /MOD, 6.1.1561 FM/MOD, 6.1.1890 MOD, 6.1.2214 SM/REM, 6.1.2370
+UM/MOD, 8.6.1.1820 M*/)</b>; </li>
+ <li> <br>
+ <font color="#000000">Results are target procesor dependent.
+Generally, Ficl makes no check for divide-by-zero. The target processor
+will probably throw an exception.</font> </li>
+ <li> <b>insufficient data-stack space or return-stack space (stack
+overflow)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">With FICL_ROBUST (sysdep.h) set &gt;= 2, most
+parameter stack operations are checked for underflow and overflow. Ficl
+does not check the return stack.</font> </li>
+ <li> <b>insufficient space for loop-control parameters</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">No check - Evil results.</font> </li>
+ <li> <b>insufficient space in the dictionary</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl generates an error message if the
+dictionary is too full to create a definition header. It checks <tt>ALLOT</tt>
+as well, but it is possible to make an unchecked allocation
+request that overflows the dictionary.</font> </li>
+ <li> <b>interpreting a word with undefined interpretation semantics</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Ficl protects all ANS Forth words with
+undefined interpretation semantics from being executed while in
+interpret state. It is possible to defeat this protection using
+' (tick) and <tt>EXECUTE</tt>, though.</font> </li>
+ <li> <b>modifying the contents of the input buffer or a string
+literal (3.3.3.4 Text-literal regions, 3.3.3.5 Input buffers)</b>;&nbsp;</li>
+ <li> <br>
+ <font color="#000000">Varies depending on the nature of the buffer.
+The input buffer is supplied by ficl's host function, and may reside in
+read-only memory. If so, writing the input buffer can ganerate
+an exception. String literals are stored in the dictionary, and are
+writable.</font> </li>
+ <li> <b>overflow of a pictured numeric output string</b>; </li>
+ <li> <br>
+In the unlikely event you are able to construct a pictured numeric
+string of more than 255 characters, the system will be corrupted
+unpredictably. The buffer area that holds pictured numeric
+output is at the end of the virtual machine. Whatever is mapped after
+the offending VM in memory will be trashed, along with the heap
+structures that contain it.&nbsp; </li>
+ <li> <b>parsed string overflow</b>; </li>
+ <li> <br>
+Ficl does not copy parsed strings unless asked to. Ordinarily, a string
+parsed from the input buffer during normal interpretation is left
+in-place, so there is no possibility of overflow. If you ask
+to parse a string into the dictionary, as in <tt>SLITERAL</tt>, you
+need to have enough room for the string, otherwise bad things may
+happen. This is not usually a problem.&nbsp; </li>
+ <li> <b>producing a result out of range, e.g., multiplication (using
+*) results in a value too big to be represented by a single-cell integer
+(6.1.0090 *, 6.1.0100 */, 6.1.0110 */MOD, 6.1.0570
+&gt;NUMBER, 6.1.1561 FM/MOD, 6.1.2214 SM/REM, 6.1.2370 UM/MOD, 6.2.0970
+CONVERT, 8.6.1.1820 M*/)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Value will be truncated</font> </li>
+ <li> <b>reading from an empty data stack or return stack (stack
+underflow)</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Most stack underflows are detected and
+prevented if FICL_ROBUST (sysdep.h) is set to 2 or greater. Otherwise,
+the stack pointer and size are likely to be trashed.</font> </li>
+ <li> <b>unexpected end of input buffer, resulting in an attempt to
+use a zero-length string as a name</b>;&nbsp; </li>
+ <li> <br>
+ <font color="#000000">Ficl returns for a new input buffer until a
+non-empty one is supplied.</font> </li>
+</ul>
+The following specific ambiguous conditions are noted in the glossary
+entries of the relevant words:&nbsp;
+<ul>
+ <li> <b>&gt;IN greater than size of input buffer (3.4.1 Parsing)</b> </li>
+ <li> <br>
+Bad Things occur - unpredictable bacause the input buffer is supplied
+by the host program's outer loop.&nbsp; </li>
+ <li> <b>6.1.2120 RECURSE appears after 6.1.1250 DOES&gt;</b> </li>
+ <li> <br>
+It finds the address of the definition before <tt>DOES&gt;</tt> </li>
+ <li> <b>argument input source different than current input source for
+6.2.2148 RESTORE-INPUT</b> </li>
+ <li> <br>
+Not implemented&nbsp; </li>
+ <li> <b>data space containing definitions is de-allocated (3.3.3.2
+Contiguous regions)</b> </li>
+ <li> <br>
+This is OK until the cells are overwritten with something else. The
+dictionary maintains a hash table, and the table must be updated in
+order to de-allocate words without corruption.&nbsp; </li>
+ <li> <b>data space read/write with incorrect alignment (3.3.3.1
+Address alignment)</b> </li>
+ <li> <br>
+Target processor dependent. Consequences include: none (Intel), address
+error exception (68K).&nbsp; </li>
+ <li> <b>data-space pointer not properly aligned (6.1.0150 ,, 6.1.0860
+C,)</b> </li>
+ <li> <br>
+See above on data space read/write alignment&nbsp; </li>
+ <li> <b>less than u+2 stack items (6.2.2030 PICK, 6.2.2150 ROLL)</b> </li>
+ <li> <br>
+Ficl detects a stack underflow and reports it, executing <tt>ABORT,</tt>
+as long as FICL_ROBUST is two or larger.&nbsp; </li>
+ <li> <b>loop-control parameters not available ( 6.1.0140 +LOOP,
+6.1.1680 I, 6.1.1730 J, 6.1.1760 LEAVE, 6.1.1800 LOOP, 6.1.2380 UNLOOP)</b> </li>
+ <li> <br>
+Loop initiation words are responsible for checking the stack and
+guaranteeing that the control parameters are pushed. Any underflows will
+be detected early if FICL_ROBUST is set to two or greater.
+Note however that Ficl only checks for return stack underflows at the
+end of each line of text.&nbsp; </li>
+ <li> <b>most recent definition does not have a name (6.1.1710
+IMMEDIATE)</b> </li>
+ <li> <br>
+No problem.&nbsp; </li>
+ <li> <b>name not defined by 6.2.2405 VALUE used by 6.2.2295 TO</b> </li>
+ <li> <br>
+Ficl's version of <tt>TO</tt> works correctly with <tt>VALUE</tt>s, <tt>CONSTANT</tt>s
+and <tt>VARIABLE</tt>s.&nbsp; </li>
+ <li> <b>name not found (6.1.0070 ', 6.1.2033 POSTPONE, 6.1.2510 ['],
+6.2.2530 [COMPILE])</b> </li>
+ <li> <br>
+Ficl prints an error message and does <tt>ABORT</tt> </li>
+ <li> <b>parameters are not of the same type (6.1.1240 DO, 6.2.0620
+?DO, 6.2.2440 WITHIN)</b> </li>
+ <li> <br>
+No check. Results vary depending on the specific problem.&nbsp; </li>
+ <li> <b>6.1.2033 POSTPONE or 6.2.2530 [COMPILE] applied to 6.2.2295 TO</b> </li>
+ <li> <br>
+The word is postponed correctly.&nbsp; </li>
+ <li> <b>string longer than a counted string returned by 6.1.2450 WORD</b> </li>
+ <li> <br>
+Ficl stores the first FICL_STRING_MAX-1 chars in the destination
+buffer. (The extra character is the trailing space required by the
+standard. Yuck.)&nbsp; </li>
+ <li> <b>u greater than or equal to the number of bits in a cell
+(6.1.1805 LSHIFT, 6.1.2162 RSHIFT)</b> </li>
+ <li> <br>
+Depends on target process or and C runtime library implementations of
+the &lt;&lt; and &gt;&gt; operators on unsigned values. For I386, the
+processor appears to shift modulo the number of bits in a
+cell.&nbsp; </li>
+ <li> <b>word not defined via 6.1.1000 CREATE (6.1.0550 &gt;BODY,
+6.1.1250 DOES&gt;)</b> </li>
+ <li> <br>
+ <b>words improperly used outside 6.1.0490 &lt;# and 6.1.0040 #&gt;
+(6.1.0030 #, 6.1.0050 #S, 6.1.1670 HOLD, 6.1.2210 SIGN)</b><br>
+Don't. <tt>CREATE</tt> reserves a field in words it builds for <tt>DOES&gt;</tt>to
+fill in. If you use <tt>DOES&gt;</tt> on a word not made by <tt>CREATE</tt>,
+it will overwrite the first cell of its parameter area.
+That's probably not what you want. Likewise, pictured numeric words
+assume that there is a string under construction in the VM's scratch
+buffer. If that's not the case, results may be unpleasant. </li>
+</ul>
+<h3> Locals Implementation-defined options </h3>
+<ul>
+ <li> <b>maximum number of locals in a definition (13.3.3 Processing
+locals, 13.6.2.1795 LOCALS|)</b> </li>
+ <li> <br>
+Default is 16. Change by redefining FICL_MAX_LOCALS, defined in
+sysdep.h </li>
+</ul>
+<h3> Locals Ambiguous conditions </h3>
+<ul>
+ <li> <b>executing a named local while in interpretation state
+(13.6.1.0086 (LOCAL))</b> </li>
+ <li> <br>
+Locals can be found in interpretation state while in the context of a
+definition under construction. Under these circumstances, locals behave
+correctly. Locals are not visible at all outside the scope of
+a definition.&nbsp; </li>
+ <li> <b>name not defined by VALUE or LOCAL (13.6.1.2295 TO)</b> </li>
+ <li> <br>
+See the CORE ambiguous conditions, above (no change) </li>
+</ul>
+<h3> Programming Tools Implementation-defined options </h3>
+<ul>
+ <li> <b>source and format of display by 15.6.1.2194 SEE</b> </li>
+ <li> <br>
+SEE de-compiles definitions from the dictionary. Because Ficl words are
+threaded by their header addresses, it is very straightforward to print
+the name and other characteristics of words in a definition.
+Primitives are so noted. Colon definitions are decompiled, but branch
+target labels are not reconstructed. Literals and string literals are so
+noted, and their contents displayed. </li>
+</ul>
+<h3> Search Order Implementation-defined options </h3>
+<ul>
+ <li> <b>maximum number of word lists in the search order (16.3.3
+Finding definition names, 16.6.1.2197 SET-ORDER)</b>&nbsp; </li>
+ <li> <br>
+Defaults to 16. Can be changed by redefining FICL_DEFAULT_VOCS,
+declared in sysdep.h&nbsp; </li>
+ <li> <b>minimum search order (16.6.1.2197 SET-ORDER, 16.6.2.1965 ONLY)</b>&nbsp;</li>
+ <li> <br>
+Equivalent to <tt>FORTH-WORDLIST 1 SET-ORDER</tt> </li>
+</ul>
+<h3> Search Order Ambiguous conditions </h3>
+<ul>
+ <li> <b>changing the compilation word list (16.3.3 Finding definition
+names)</b> </li>
+ <li> <br>
+Ficl stores a link to the current definition independently of the
+compile wordlist while it is being defined, and links it into the
+compile wordlist only after the definition completes
+successfully. Changing the compile wordlist mid-definition will cause
+the definition to link into the <i>new</i> compile wordlist.&nbsp; </li>
+ <li> <b>search order empty (16.6.2.2037 PREVIOUS)</b> </li>
+ <li> <br>
+Ficl prints an error message if the search order underflows, and resets
+the order to its default state.&nbsp; </li>
+ <li> <b>too many word lists in search order (16.6.2.0715 ALSO)</b> </li>
+ <li> <br>
+Ficl prints an error message if the search order overflows, and resets
+the order to its default state. </li>
+</ul>
+</div>
+</body>
+</html>
diff --git a/doc/source/generate.py b/doc/source/generate.py
new file mode 100644
index 000000000000..36a4406320ad
--- /dev/null
+++ b/doc/source/generate.py
@@ -0,0 +1,244 @@
+import cStringIO
+import os
+import re
+import shutil
+import string
+import sys
+
+
+outputStart = None
+navBarEntries = {}
+
+
+
+def ficlLinkEntry(file, title):
+ print("<a href=" + file + ".html><font color=white>" + title + "</font></a><p>\n")
+
+
+
+currentNavBarName = None
+
+def ficlAddToNavBarAs(name):
+ global currentNavBarName
+ currentNavBarName = name
+
+
+def ficlPageHeader(heading):
+ outputStart.write("""<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<HTML>
+<HEAD>
+<META name='Description' content='Ficl - embedded scripting with object oriented programming'>
+<META name='Keywords' content='scripting prototyping tcl OOP Forth interpreter C'>
+<LINK rel='SHORTCUT ICON' href='ficl.ico'>
+<TITLE>""" + heading + """</TITLE>
+<style>\n
+blockquote { margin-left: 1em }\n
+</style>\n
+</HEAD>
+<BODY>
+
+<table border=0 cellspacing=0 width=100%%><tr>\n
+
+<td width=112 bgcolor=#004968 colspan=3>
+<img src=graphics/ficl.4.96.jpg height=96 width=96>
+</td>
+
+<td bgcolor=#004968>
+<font face=arial,helvetica color=white size=7><b><i>
+""" + heading + """
+</i></b></font>
+</td></tr>
+
+\n<tr>
+<td bgcolor=#004968 width=10></td>
+<td bgcolor=#004968 valign=top>
+<br><p>
+<a href=index.html><font face=arial,helvetica color=white><b>Index</b></font></a><p>
+""")
+
+ print("</td><td bgcolor=#004968 width=5></td><td valign=top><blockquote><p>\n")
+
+
+
+def ficlPageFooter():
+ print("\n</blockquote><p></td></tr></table></body></html>\n")
+
+
+
+sizeArray = [7, 5, 4, 3, 2]
+indentLevel = 0
+sections = None
+
+def ficlHeader(level, color, bgcolor, heading):
+ global sizeArray
+ size = str(sizeArray[level])
+
+ global indentLevel
+ global sections
+ while (indentLevel < level):
+ indentLevel += 1
+# sys.stderr.write("adding 1 to indentLevel, it's now " + str(indentLevel) + "\n\n")
+ sections.append([])
+ while (indentLevel > level):
+ indentLevel -= 1
+ subheadings = sections.pop()
+# sys.stderr.write("indentLevel is " + str(indentLevel) + ", subheadings is " + str(subheadings) + ", len(sections) is " + str(len(sections)) + ", sections is " + str(sections) + "\n\n")
+ sections[indentLevel - 1][-1][1] = subheadings
+ entry = [heading, [] ]
+# sys.stderr.write("indentLevel is " + str(indentLevel) + ", len(sections) is " + str(len(sections)) + ", sections is " + str(sections) + "\n\n")
+# sys.stderr.flush()
+ sections[indentLevel - 1].append(entry)
+
+ print("""
+<p>
+</blockquote><table border=0 bgcolor=""" + bgcolor + """ width=100%><tr>
+
+<td width=1em></td>
+<td>
+<font face=arial,helvetica color=""" + color + " size=" + size + "><b><i>")
+ print("<a name='" + collapse(heading) + "'>")
+ print(heading)
+ print("</a></i></b></font></td></tr></table><p><blockquote>\n")
+
+
+def ficlHeader1(heading):
+ ficlHeader(1, "#004968", "#a0a0a0", heading)
+
+def ficlHeader2(heading):
+ ficlHeader(2, "#004968", "#b8b8b8", heading)
+
+def ficlHeader3(heading):
+ ficlHeader(3, "#004968", "#d0d0d0", heading)
+
+def ficlHeader4(heading):
+ ficlHeader(4, "#004968", "#e8e8e8", heading)
+
+
+def collapse(s):
+ return string.join(s.split(), "").replace("'", "").replace("&", "").replace('"', "").replace('<', "").replace('>', "").replace('.', "").replace('?', "")
+
+def dump(f, sections):
+ for section in sections:
+ sys.stderr.write("sections is " + str(section) + "\n")
+ name = section[0]
+ f.write("<li><a href=#" + collapse(name) + "><font color=white>" + name + "</font></a>\n")
+ if len(section[1]) != 0:
+ f.write("<ul>\n")
+ dump(f, section[1])
+ f.write("</ul>\n")
+
+def process(inputfilename, outputfilename):
+ print "generating " + inputfilename
+ global indentLevel
+ indentLevel = 0
+ global sections
+ sections = []
+ global currentNavBarName
+
+ input = open(inputfilename, "r")
+ data = input.read().replace("\r", "")
+ input.close()
+ chunks = data.split("<?")
+
+ output = cStringIO.StringIO()
+
+ global outputStart
+ outputStart = cStringIO.StringIO()
+
+ stdout = sys.stdout
+
+ fauxGlobals = { }
+ fauxGlobals.update(globals())
+ fauxGlobals['__name__'] = '__ficlDocs__'
+ fauxGlobals['__doc__'] = inputfilename
+ fauxGlobals['outputStart'] = outputStart
+
+ sys.stdout = output
+ if (chunks[0] != None):
+ output.write(chunks[0])
+ for chunk in chunks[1:]:
+ (code, verbatim) = chunk.split("?>")
+ code = code.lstrip()
+ if (code[0] == "="):
+ execution = "eval"
+ code = code[1:].lstrip()
+ else:
+ execution = "exec"
+ compiled = compile(code, "[unknown]", execution)
+ if (execution == "eval"):
+ output.write(str(eval(compiled)))
+ else:
+ exec compiled
+ output.write(verbatim)
+
+ sys.stdout = stdout
+
+
+ f = open(outputfilename, "w")
+ f.write(outputStart.getvalue())
+ f.write("<p><br>\n")
+ keys = navBarEntries.keys()
+ keys.sort()
+ for name in keys:
+ filename = navBarEntries[name]
+ f.write("<a href=" + filename + ">")
+ name = name.replace(" ", "&nbsp;")
+ f.write("<font face=arial,helvetica color=white><b>" + name + "</b></font>")
+ f.write("</a><br>\n")
+# This doesn't look as pretty as I wanted, so I'm turning it off. --lch
+# if (name == currentNavBarName) and (len(sections) > 0):
+# f.write("<ul>\n")
+# dump(f, sections[0])
+# f.write("</ul>\n")
+
+ f.write(output.getvalue())
+ f.close()
+
+
+
+##
+## First, find all the documents in the current directory,
+## and look for their navBar entry.
+##
+
+for filename in os.listdir("."):
+ if filename[-3:] == ".ht":
+ file = open(filename, "rb")
+ for line in file.readlines():
+ navBar = "ficlAddToNavBarAs(\""
+ if line.strip().startswith(navBar):
+ (a, name, b) = line.split('"')
+ navBarEntries[name] = filename + "ml"
+ break
+ file.close()
+
+navBarEntries["Download"] = "http://sourceforge.net/project/showfiles.php?group_id=24441"
+
+ignored = re.compile("^((.*\.pyc?)|(.*\.zip)|\.|(\.\.))$")
+
+##
+## Second, build the doc tree (in ..), processing as necessary.
+##
+def visit(unused, directory, names):
+ for file in names:
+ if ignored.search(file):
+ continue
+ input = directory + "/" + file
+ output = "../" + input
+ if input[-3:].lower() == ".ht":
+ process(input, output + "ml")
+ elif os.path.isdir(input):
+ if not os.path.isdir(output):
+ os.mkdir(output)
+ else:
+ try:
+ shutil.copy2(input, output)
+ except IOError:
+ ## Ignore file-copy errors. It's probably
+ ## a read-only file that doesn't change.
+ ## Lazy, I know. --lch
+ None
+
+os.path.walk(".", visit, None)
+
+
diff --git a/doc/source/index.ht b/doc/source/index.ht
new file mode 100644
index 000000000000..1c66a2ed992d
--- /dev/null
+++ b/doc/source/index.ht
@@ -0,0 +1,244 @@
+<?
+ficlPageHeader("ficl")
+
+def feature(preamble, keyfeature, postscript = ""):
+ print "<p><dt>\n" + preamble + " <b><i>" + keyfeature + "</i></b> " + postscript + "\n<dd>\n"
+
+?>
+
+
+<? ficlHeader1("What is Ficl?") ?>
+
+
+Ficl is a programming language interpreter designed to be embedded
+into other systems as a command, macro, and development prototyping
+language.
+<p>
+
+Ficl is an acronym for "Forth Inspired Command Language".
+
+
+<? ficlHeader1("Ficl Features") ?>
+
+<dl>
+
+
+<? feature("Ficl is", "easy to port.") ?>
+
+<ul>
+
+<li>
+It typically takes under 2 hours to port to a new platform.
+
+<li>
+Ficl is written in strict ANSI C.
+
+<li>
+Ficl can run natively on 32- and 64-bit processors.
+
+</ul>
+
+
+
+<? feature("Ficl has a", "small memory footprint.") ?>
+
+A fully featured Win32 console version takes less than 100K
+of memory, and a minimal version is less
+than half that.
+
+
+
+<? feature("Ficl is ", "easy to integrate", "into your program.") ?>
+
+Where most Forths view themselves as the center of the system and
+expect the rest of the system to be coded in Forth, Ficl acts as a
+component of your program. It is easy to export code written in C or
+ASM to Ficl (in the style of TCL), or to invoke Ficl code from a
+compiled module.
+
+
+
+<? feature("Ficl is", "fast.") ?>
+
+Thanks to its
+<a href=http://www.complang.tuwien.ac.at/forth/threaded-code.html#switch-threading>"switch-threaded"</a>
+virtual machine design, Ficl 4 is faster than ever&mdash;about 3x the speed of Ficl 3.
+Ficl also features blindingly fast "just in time" compiling, removing the "compile" step from
+the usual compile-debug-edit iterative debugging cycle.
+
+
+
+<? feature("Ficl is a", "complete and powerful programming language.") ?>
+
+Ficl is an implementation of the FORTH language, a language providing
+a wide range of standard programming language features:
+<ul>
+
+<li>
+Integer and floating-point numbers, with a rich set of operators.
+
+<li>
+Arrays.
+
+<li>
+File I/O.
+
+<li>
+Flow control (<code>if/then/else</code> and many looping structures).
+
+<li>
+Subroutines with named arguments.
+
+<li>
+Language extensibility.
+
+<li>
+Powerful code pre-processing features.
+
+</ul>
+
+
+
+<? feature("Ficl is ", "standards-compliant.") ?>
+
+Ficl conforms to the 1994 ANSI Standard for FORTH (DPANS94).
+See <a href=dpans.html>ANS Required Information</a> for
+more detail.
+
+
+<? feature("Ficl is", "extensible.") ?>
+
+Ficl is extensible both at compile-time and at run-time.
+You can add new script functions, new native functions,
+even new control structures.
+
+
+
+
+<? feature("Ficl adds ", "object oriented programming features.") ?>
+
+Ficl's flexible OOP library can be used to wrap
+data structures or classes of the host system without altering them.
+(And remember how we said Ficl was extensible? Ficl's object-oriented
+programming extensions are written in Ficl.)
+
+
+
+<? feature("Ficl is", "interactive.") ?>
+
+Ficl can be used interactively, like most other FORTHs, Python,
+and Smalltalk. You can inspect data, run commands, or even
+define new commands, all on a running Ficl VM.
+Ficl also has a built-in script debugger that allows you to
+step through Ficl code as it is executed.
+
+
+<? feature("Ficl is", "ROMable.") ?>
+
+Ficl is designed to work in RAM based and ROM code / RAM
+data environments.
+
+
+
+<? feature("Ficl is", "safe for multithreaded programs.") ?>
+
+Ficl is reentrant and thread-safe. After initialization,
+it does not write to any global data.
+
+
+<? feature("Ficl is ", "open-source and free.") ?>
+
+The <a href=license.html>Ficl licence</a> is a BSD-style
+license, requiring only that you document that you are
+using Ficl. There are no licensing costs for using Ficl.
+
+
+</dl>
+
+
+<a name=whatsnew>
+<? ficlHeader1("What's New In Ficl 4.0?") ?>
+</a>
+
+Ficl 4.0 is a major change for Ficl. Ficl 4.0 is <i>smaller</i>,
+<i>faster</i>, <i>more powerful</i>, and <i>easier to use</i>
+than ever before. (Or your money back!)
+<p>
+
+Ficl 4.0 features a major engine rewrite. Previous versions
+of Ficl stored compiled words as an array of pointers to data
+structure; Ficl 4.0 adds "instructions", and changes over to
+mostly using a "switch-threaded" model. The result? Ficl 4.0
+is approximately <i>three times</i> as fast as Ficl 3.03.
+<p>
+
+Ficl 4.0 also adds the ability to store the "softcore" words
+as LZ77 compressed text. Decompression is so quick as to be
+nearly unmeasurable (0.00384 seconds on a 750MHz AMD Duron-based
+machine). And even with the runtime decompressor, the resulting
+Ficl executable is over 13k smaller!
+<p>
+
+Another new feature: Ficl 4.0 can take advantage of native
+support for double-word math. If your platform supports it,
+set the preprocessor symbol <code>FICL_HAVE_NATIVE_2INTEGER</code>
+to 1, and create <code>typedefs</code> for <code>ficl2Integer</code>
+and <code>ficl2Unsigned</code>.
+<p>
+
+Ficl 4.0 also features a retooled API, and a redesigned directory
+tree. The API is now far more consistent. But for those of you
+who are upgrading from Ficl 3.03 or before, you can enable API
+backwards compatibility by turning on the compile-time flag
+<code>FICL_WANT_COMPATIBILITY</code>.
+<p>
+
+Ficl 4.0 also extends support every kind of local and
+global value imaginable. Every values can individually
+be local or global, single-cell or double-cell, and
+integer or floating-point.
+And <code>TO</code> <i>always</i> does the right thing.
+<p>
+
+If you're using Ficl under Windows, you'll be happy
+to know that there's a brand-new build process.
+The Ficl build process now builds Ficl as
+<ul>
+
+<li>
+a static library (.LIB),
+
+<li>
+a dynamic library (.DLL, with a .LIB import library), and
+
+<li>
+a standalone executable (.EXE).
+
+</ul>
+
+Furthermore, each of these targets can be built in
+Debug or Release, Singlethreaded or Multithreaded,
+and optionally using the DLL version of the C runtime
+library for Multithreaded builds. (And, plus, the
+<code>/objects/common</code> nonsense is gone!)
+<p>
+
+
+Finally, Ficl 4.0 adds a <code>contrib</code>
+directory, a repository for user-contributed code that isn't
+part of the standard Ficl release. The only package there
+right now is <b>XClasses</b>, a Python-based IDL that generates
+the definition files for C++-based classes, the equivalent Ficl
+classes, and code to allow the Ficl classes to call the C++ methods.
+Using <b>XClasses</b> you can write your class once, and use it
+immediately from both C++ and Ficl.
+
+
+<? ficlHeader1("Getting Ficl") ?>
+
+You can download Ficl from the
+<a href=http://sourceforge.net/project/showfiles.php?group_id=24441>
+Ficl download page at Sourceforge</a>.
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/license.ht b/doc/source/license.ht
new file mode 100644
index 000000000000..50b92b5f1432
--- /dev/null
+++ b/doc/source/license.ht
@@ -0,0 +1,47 @@
+<?
+ficlPageHeader("ficl licensing")
+
+ficlAddToNavBarAs("Licensing")
+
+ficlHeader1("Ficl License And Disclaimer")
+
+?>
+
+<font size=+1>
+Copyright (c) 1997-2001 John Sadler (john_sadler@alum.mit.edu)
+<br>
+All rights reserved.
+</font>
+<p>
+
+<b>
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+<ol>
+
+<li>
+Redistributions of source code must retain the above copyright
+notice, this list of conditions and the following disclaimer.
+
+<li>
+Redistributions in binary form must reproduce the above copyright
+notice, this list of conditions and the following disclaimer in the
+documentation and/or other materials provided with the distribution.
+
+</ol>
+
+THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+SUCH DAMAGE.
+</b>
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/links.ht b/doc/source/links.ht
new file mode 100644
index 000000000000..743b222c3fa3
--- /dev/null
+++ b/doc/source/links.ht
@@ -0,0 +1,156 @@
+<?
+ficlPageHeader("ficl links")
+
+ficlAddToNavBarAs("Links")
+
+def linkto(href):
+ print "<p><dt>\n<a href=\"" + href + "\">" + href + "</a>\n<dd>\n"
+
+?>
+
+<? ficlHeader1("Official Ficl Pages") ?>
+
+<dl>
+
+<? linkto("http://ficl.sourceforge.net") ?>
+The official web home of Ficl.
+
+<? linkto("http://sourceforge.net/project/showfiles.php?group_id=24441") ?>
+The Ficl download page.
+
+
+</dl>
+
+
+
+<? ficlHeader1("Forth Primers And Tutorials") ?>
+
+<dl>
+
+<? linkto("http://www.phys.virginia.edu/classes/551.jvn.fall01/primer.htm") ?>
+An excellent Forth primer, by Julian Nobel.
+
+<? linkto("http://ficl.sourceforge.net/pdf/Forth_Primer.pdf") ?>
+Another excellent Forth primer, by Hans Bezemer.
+
+<? linkto("http://www.taygeta.com/forth_intro/stackflo.html") ?>
+<i>An Introduction To Forth Using Stack Flow</i> by Gordon Charton.
+Mr. Charton's stack-flow diagrams make it easy to understand how
+to manipulate the FORTH stacks.
+
+<? linkto("http://www.softsynth.com/pforth/pf_tut.htm") ?>
+Phil Burk's Forth Tutorial.
+
+</dl>
+
+
+
+<? ficlHeader1("Technical Articles On Ficl And Forth") ?>
+
+<dl>
+
+<? linkto("articles/ficlddj.pdf") ?>
+Manuscript of John Sadler's article on Ficl for January 1999 <a href=http://www.ddj.com>Dr. Dobb's Journal</a>.
+
+<? linkto("articles/jwsforml.pdf") ?>
+1998 FORML Conference paper: <i>OO Programming in Ficl,</i> written and presented by John Sadler.
+
+
+<? linkto("http://www.complang.tuwien.ac.at/forth/threaded-code.html") ?>
+Anton Ertl's description of threaded code techniques. (The FORTH-related definition
+of "threaded code" is different from&mdash;and predates&mdash;the common modern
+usage dealing with light-weight processes.) Ficl 4 uses what Ertl calls
+"switch threading".
+
+<? linkto("http://ficl.sourceforge.net/dpans/dpans.htm") ?>
+1994 Draft Proposed American National Standard for Forth.
+And surprisingly readable, as language standards go.
+
+<? linkto("http://www.taygeta.com/forthlit.html") ?>
+Forth literature index on Taygeta, a web clearinghouse of Forth links.
+
+</dl>
+
+<? ficlHeader1("Other Forth Sites Of Interest") ?>
+
+<dl>
+
+<? linkto("http://www.forth.org") ?>
+The Forth Interest Group.
+
+<? linkto("http://www.forth.com") ?>
+FORTH, Incorporated. Thirty years old and going strong.
+You might be surprised to learn that they wrote software for
+the <a href=http://www.forth.com/Content/Stories/FedEx.htm>FedEx</a>
+"SuperTracker" bar code scanners / package trackers.
+
+</dl>
+
+<table width=100% bgcolor=#e0e0e0><tr><td width=160>
+<A href="http://t.webring.com/hub?sid=&ring=forth&list"><IMG src="graphics/4ring.gif" width="155" height="140" border="0" alt="Forth Webring Logo"></A>
+</td><td>
+<? ficlHeader1("The Forth Web Ring") ?>
+<A href="http://t.webring.com/hub?sid=&ring=forth&id=47&prev5">Previous 5 Sites</A><BR>
+<A href="http://t.webring.com/hub?sid=&ring=forth&id=47&prev">Previous</A><BR>
+<A href="http://t.webring.com/hub?sid=&ring=forth&id=47&next">Next</A><BR>
+<A href="http://t.webring.com/hub?sid=&ring=forth&id=47&next5">Next 5 Sites</A><BR>
+<A href="http://t.webring.com/hub?sid=&ring=forth&random">Random Site</A><BR>
+<A href="http://t.webring.com/hub?sid=&ring=forth&list">List Sites</A></FONT>
+</td></tr></table>
+
+
+
+<? ficlHeader1("Some Software That Uses Ficl") ?>
+
+<ul>
+<li>
+The <a href="http://www.freebsd.org/">FreeBSD</a> boot loader
+(Daniel Sobral, Jordan Hubbard)
+
+<li>
+<a href="http://www.chipcenter.com/networking/images/prod/prod158a.pdf">
+SwitchCore
+</a>
+Gigabit Ethernet switches (&Ouml;rjan Gustavsson )
+
+<li>
+<a href="http://debuffer.sourceforge.net/">
+Palm Pilot Debuffer
+</a>
+(Eric Sessoms)
+Also see <a href=http://sonic-weasel.org/eric/ficlx/>FiclX</a>, a C++ interface to Ficl.
+
+<li>
+<a href="http://www.swcp.com/%7Ejchavez/osmond.html">
+Osmond PC Board Layout tool
+</a>
+
+<li>
+<a href="http://www.netcomsystems.com">
+NetCom Systems
+</a>
+ML7710
+
+<li>
+<a href="http://www.parview.com/ds/homepage.html">
+ParView
+</a>
+GPS system
+
+<li>
+<a href="http://www.thekompany.com/products/powerplant/software/Languages/Embedded.php3">
+PowerPlant Software
+</a>
+Development Environment for Linux
+
+<li>
+<a href="http://www.vyyo.com/products/architecture_v3000.html">
+Vyyo V3000 Broadband Wireless Hub
+</a>
+
+</ul>
+
+(Contact us if you'd like your name and product listed here.)
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/locals.ht b/doc/source/locals.ht
new file mode 100644
index 000000000000..e75ac82c4908
--- /dev/null
+++ b/doc/source/locals.ht
@@ -0,0 +1,133 @@
+<?
+
+ficlPageHeader("local variables in Ficl")
+
+ficlAddToNavBarAs("Locals")
+
+def entry(definition, description):
+ print "<tr><td bgcolor=#e0e0e0>\n<b>" + definition + "</b>\n</td><td bgcolor=#f0f0f0>\n" + description + "\n</td></tr>\n"
+
+?>
+
+
+<? ficlHeader1("An Overview And A History") ?>
+
+
+
+Named, locally scoped variables came late to Forth. Purists feel that experienced
+Forth programmers can (and should) write supportable code using only anonymous
+stack variables and good factoring, and they complain that novices use
+global variables too frequently. But local variables cost little in terms of
+code size and execution speed, and are very convenient for OO programming
+(where stack effects are more complex).
+<p>
+
+Ficl provides excellent support
+for local variables, and the purists be damned&mdash;we use 'em all the time.
+<p>
+
+Local variables can only be declared inside a definition,
+and are only visible in that definition. Please refer to
+<a href="http://ficl.sourceforge.net/dpans/dpans13.htm">
+the ANS standard for FORTH
+</a> for more general information on local variables.
+
+
+<? ficlHeader1("John-Hopkins Forth Argument Syntax") ?>
+
+ANS Forth does not specify a complete local variable facility.
+Instead, it defines a foundation upon which to build one. Ficl comes with
+an adaptation of the Johns-Hopkins local variable syntax, as developed by John
+Hayes et al. However, Ficl extends this syntax with support for double-cell and
+floating-point numbers.
+
+<p>
+
+Here's the basic syntax of a JH-local variable declaration:
+<blockquote><code>
+<b>{</b> <i>arguments</i>
+<b>|</b> <i>locals</i>
+<b>--</b> <i>ignored</i>
+<b>}</b>
+</code></blockquote>
+(For experienced FORTH programmers: the declaration is designed to look like a stack comment,
+but it uses curly braces instead of parentheses.) Each section must list zero or more
+legal Ficl word names; comments and preprocessing are not allowed here.
+Here's what each section denotes:
+
+<ul>
+
+<li>
+The <i>arguments</i> section lists local variables which are initialized from the stack when the word executes.
+Each argument is set to the top value of the stack, starting at the rightmost argument name and moving left.
+You can have zero or more arguments.
+<p>
+
+<li>
+The <i>locals</i> section lists local variables which are set to zero when the word executes.
+You can have zero or more locals.
+<p>
+
+<li>
+Any characters between <code>--</code> and <code>}</code> are treated as a comment, and ignored.
+
+</ul>
+
+(The <code>|</code> and <code>--</code> sections are optional,
+but they must appear in the order shown if they appear at all.)
+<p>
+
+
+<? ficlHeader2("Argument Types") ?>
+
+Every time you specify a local variable (in either the <i>arguments</i> or the <i>locals</i> section),
+you can also specify the <i>type</i> of the local variable. By default, a local variable
+is a single-cell integer; you can specify that the local be a double-cell integer, and/or a
+floating-point number.
+<p>
+
+To specify the type of a local, specify one or more of the following single-character specifiers,
+followed by a colon (<code>:</code>).
+
+<table>
+
+<? entry("1", "single-cell") ?>
+
+<? entry("2", "double-cell") ?>
+
+<? entry("d", "double-cell") ?>
+
+<? entry("f", "floating-point (use floating stack)") ?>
+
+<? entry("i", "integer (use data stack)") ?>
+
+<? entry("s", "single-cell") ?>
+
+</table>
+
+For instance, the argument <code>f2:foo</code> would specify a double-width floating-point
+number.
+<p>
+
+The type specifiers are read right-to left, and when two specifiers conflict, the rightmost
+one takes priority. So <code>2is1f2:foo</code> would still specifiy a double-width floating-point
+number.
+<p>
+
+Note that this syntax <i>only works</i> for Ficl's JH-locals. Locals
+defined in some other way (say, with the FORTH standard word <code>LOCALS|</code>)
+will ignore this syntax, and the entire string will be used as the name of
+the local (type and all).
+
+<? ficlHeader2("A Simple Example") ?>
+
+<pre>
+: DEMONSTRATE-JH-LOCALS { c b a f:float -- a+b f:float*2 }
+ a b +
+ 2.0e float f*
+ ;
+</pre>
+
+<?
+ficlPageFooter()
+?> \ No newline at end of file
diff --git a/doc/source/oop.ht b/doc/source/oop.ht
new file mode 100644
index 000000000000..c928eb0795b3
--- /dev/null
+++ b/doc/source/oop.ht
@@ -0,0 +1,1224 @@
+<?
+
+ficlPageHeader("ficl oop")
+
+ficlAddToNavBarAs("OOP In Ficl")
+
+def glossaryEntry(name, description):
+ print "<dt><code>" + name + " <i>" + description + "</i></code><dd>\n"
+
+?>
+
+<? ficlHeader1("Ficl Object Oriented Programming") ?>
+
+
+Ficl's object extensions provide the traditional OO benefits of associating
+data with the code that manipulates it, and reuse through single inheritance.
+Ficl also has some unusual capabilities that support interoperation with
+systems written in C.
+<p>
+
+Some design points of Ficl's OOP system:
+
+<ul>
+
+<li>
+Ficl objects are normally late bound for safety (late binding guarantees
+that the appropriate method will always be invoked for a particular object).
+Early binding is also available, provided you know the object's class at
+compile-time.
+
+<li>
+Ficl OOP supports single inheritance, aggregation, and arrays of objects.
+
+<li>
+Classes have independent name spaces for their methods: methods are only
+visible in the context of a class or object. Methods can be overridden
+or added in subclasses; there is no fixed limit on the number of methods
+of a class or subclass.
+
+<li>
+Ficl OOP syntax is regular and unified over classes and objects. In ficl,
+all classes are objects. Class methods include the ability to subclass
+and instantiate.
+
+<li>
+Ficl can adapt legacy data structures with object wrappers. You can model
+a structure in a Ficl class, and create an instance that refers to an address
+in memory that holds an instance of the structure. The <i>ref object</i>
+can then manipulate the structure directly. This lets you wrap data structures
+written and instantiated in C.
+
+</ul>
+
+<? ficlHeader2("Object-Oriented Programming concepts") ?>
+
+If you're not familiar with object-oriented programming, you
+can click <a href="http://whatis.techtarget.com/definition/0,289893,sid9_gci212681,00.html">here</a>
+or <a href="http://www.softwaredesign.com/objects.html">here</a> for
+a general-purpose overview.
+Or click <a href="articles/oo_in_c.html#review">here</a> for a short review of object-oriented ideas,
+terms, and implementations in C.
+
+<? ficlHeader2("Acknowledgements") ?>
+
+Ficl is not the first Forth to include Object Oriented extensions. Ficl's
+OO syntax owes a debt to the work of John Hayes and Dick Pountain, among
+others. OO Ficl is different from other OO Forths in a few ways, though
+(some things never change). First, unlike several implementations, the
+syntax is documented (<a href="#ootutorial">below</a>) beyond the source
+code. In Ficl's spirit of working with C code, the OO syntax provides means
+to adapt existing data structures. I've tried to make Ficl's OO model simple
+and safe by unifying classes and objects, providing late binding by default,
+and separating namespaces so that methods and regular Forth words are not
+easily confused.
+
+
+<? ficlHeader2("Ficl Object Model") ?>
+
+All classes in Ficl are derived from the common base class
+<code><a href="#objectgloss">OBJECT</a></code>
+as shown in the <a href="#figure1">figure</a> below. All classes are instances
+of <code><a href="#glossclass">METACLASS</a></code>. This means that classes
+are objects, too. <code>METACLASS</code> implements the methods for messages
+sent to classes. Class methods create instances and subclasses, and give
+information about the class. Each class is represented by a data stucture
+of three elements:
+
+<ol>
+
+<li>
+The address (named <code>.CLASS</code> ) of a parent class, or zero if it's
+a base class (only <code>OBJECT</code> and <code>METACLASS</code> have this property).
+
+<li>
+The size (named <code>.SIZE</code> ) in address units of an instance of the
+class.
+
+<li>
+A wordlist ID (named <code>.WID</code> ) for the methods of the class.
+
+</ol>
+
+In the figure below, <code>METACLASS</code> and <code>OBJECT</code> are real system-supplied
+classes. The others are contrived to illustrate the relationships among
+derived classes, instances, and the two system base classes. The dashed
+line with an arrow at the end indicates that the object/class at the arrow
+end is an instance of the class at the other end. The vertical line with
+a triangle denotes inheritance.
+<p>
+
+Note for the curious: <code>METACLASS</code> behaves like a class&mdash;it responds
+to class messages and has the same properties as any other class. If you
+want to twist your brain in knots, you can think of <code>METACLASS</code>
+as an instance of itself.
+<p>
+
+
+<a NAME="figure1"></a><img SRC="graphics/ficl_oop.jpg" VSPACE=10 height=442 width=652>
+<br>
+
+<? ficlHeader2("Ficl Object-Oriented Syntax Tutorial") ?>
+<a NAME="ootutorial"></a>
+
+It's helpful to have some familiarity with Forth and the customary Forth
+stack notation to understand this tutorial. To get started, take a look
+at this <a href="http://www.taygeta.com/forth_intro/stackflo.html">web-based
+Forth tutorial</a>. If you're comfortable with both OO and Forth, you can
+<a href="#ootutorial-finally">jump ahead</a>.
+<p>
+
+A Ficl <a href="oo_in_c.html#object-def">object</a> associates a <a href="oo_in_c.html#class-def">class</a>
+with an <a href="oo_in_c.html#instance-def">instance</a> (the storage for
+one set of instance variables). This is done explicitly on Ficl's stack,
+in that any Ficl object is represented by a cell pair:
+<blockquote><code>( INSTANCE-address CLASS-address )</code></blockquote>
+
+The <code>INSTANCE-address</code> is the address of the object's storage, and the <code>CLASS-address</code>
+is the address of its class. Whenever a named Ficl object executes (e.g.
+when you type its name and press enter at the Ficl prompt), it leaves this
+"signature". All methods by convention expect a class and instance on the
+stack when they execute, too. In many other OO languages, including C++,
+instances contain information about their classes (a <a href="http://www.mvps.org/vbvision/vtable.htm">vtable</a>
+pointer, for example). By making this pairing explicit rather than implicit,
+Ficl can be OO about chunks of data that don't realize that they are objects,
+without sacrificing any robustness for native objects. That means that
+you can use Ficl to write object wrappers for data structures created in
+C or assembly language, as long as you can determine how they're laid out
+in memory.
+<p>
+
+Whenever you create an object in Ficl, you specify its class.
+After that, the object always pushes its class and the address of its
+<a href="http://www.aware.com/Glossary/main.htm#P">payload</a>
+(instance variable space) when invoked by name.
+<p>
+
+Classes are special kinds of objects that store the methods of their
+instances, the size of an instance's payload, and a parent class pointer.
+Classes themselves are instances of a special base class called <code>METACLASS</code>,
+and all classes inherit from class <code>OBJECT</code>. This is confusing at
+first, but it means that Ficl has a very simple syntax for constructing
+and using objects. Class methods include subclassing (<code>SUB</code>), creating
+initialized and uninitialized instances (<code>NEW</code> and <code>INSTANCE</code>),
+and creating reference instances (<code>REF</code>), described later. Classes
+also have methods for disassembling their methods (<code>SEE</code>), identifying
+themselves (<code>ID</code>), and listing their pedigree (<code>PEDIGREE</code>).
+All objects inherit (from <code>OBJECT</code>) methods for initializing instances
+and arrays of instances, for performing array operations, and for getting
+information about themselves.
+
+<? ficlHeader3("Methods And Messages") ?>
+
+Methods are the functions that objects execute in response to messages.
+A message is a request to an object for a behavior that the object supports.
+When it receives a message, the target object looks up a method that performs
+the behavior for its class, and executes it. Any specific message may be
+bound to different methods in different objects, according to class. This
+separation of messages and methods allows objects to behave <a href="http://www.whatis.com/polymorp.htm">polymorphically</a>.
+(In Ficl, methods are words defined in the context of a class, and messages
+are the names of those words.) Ficl classes associate messages with methods
+for their instances (a fancy way of saying that each class owns a wordlist).
+Ficl provides a late-binding operator <code>--></code> that sends messages
+to objects at run-time, and an early-binding operator <code>=></code>
+that compiles a specific class's method. These operators are the only supported
+way to invoke methods. Regular Forth words are not visible to the method-binding
+operators, so there's no chance of confusing a message with a regular
+word of the same name.
+
+<a NAME="ootutorial-finally"></a>
+
+<? ficlHeader2("Tutorial") ?>
+
+(Finally!)
+<p>
+
+This is a tutorial. It works best if you follow along by pasting the examples
+into <b>ficlWin</b>, the Win32 version of Ficl included with the release sources
+(or some other build that includes the OO part of <code>softcore.c</code>). If you're
+not familiar with Forth, please see one of these <a href="#links">references</a>.
+Ficl's OOP words are in vocabulary <code>OOP</code>. To put <code>OOP</code> in
+the search order and make it the compilation wordlist, type:
+<pre>
+ONLY
+ALSO OOP DEFINITIONS
+</pre>
+
+<b>Note for beginners:</b> To see the effect of the commands above, type
+<code>ORDER</code>
+after each line. You can repeat the sequence above if you like.
+<p>
+
+To start, we'll work with the two base classes <code>OBJECT</code> and <code>METACLASS</code>.
+Try this:
+<pre>
+METACLASS --> METHODS
+</pre>
+
+The line above contains three words. The first is the name of a class,
+so it pushes its signature on the stack. Since all classes are instances
+of <code>METACLASS</code>, <code>METACLASS</code> behaves as if it is an instance
+of itself (this is the only class with this property). It pushes the same
+address twice: once for the class and once for the payload, since they
+are the same. The next word finds a method in the context of a class and
+executes it. In this case, the name of the method is <code>METHODS</code>.
+Its job is to list all the methods that a class knows. What you get when
+you execute this line is a list of all the class methods Ficl provides.
+<pre>
+OBJECT --> SUB C-LED
+</pre>
+Causes the base-class <code>OBJECT</code> to derive from itself a new class
+called <code>C-LED</code>. Now we'll add some instance variables and methods to the new class.
+<p>
+
+<b>Note:</b> I like to prefix the names of classes with <code>c-</code> and the
+names of member variables with a period, but this is just a convention.
+If you don't like it, pick your own.
+<pre>
+C-BYTE OBJ: .STATE
+: INIT { 2:THIS -- }
+ THIS --> SUPER --> INIT
+ ." Initializing an instance of "
+ THIS --> CLASS --> ID TYPE CR ;
+: ON { LED# 2:THIS -- }
+ THIS --> .STATE --> GET
+ 1 LED# LSHIFT OR DUP !OREG
+ THIS --> .STATE --> SET ;
+: OFF { LED# 2:THIS -- }
+ THIS --> .STATE --> GET
+ 1 LED# LSHIFT INVERT AND DUP !OREG
+ THIS --> .STATE --> SET&NBSP; ;
+END-CLASS
+</pre>
+The first line adds an instance variable called <code>.STATE</code> to the
+class. This particular instance variable is an object&mdash;it will be an instance
+of <code>C-BYTE</code>, one of Ficl's stock classes (the source for which can be found
+in the distribution in <code>softcore/classes.fr</code>).
+<p>
+
+Next we've defined a method called <code>INIT</code>. This line also declares
+a <a href="locals.html">local variable</a> called <code>THIS</code>
+(the 2 in front tells Ficl that this is a double-cell local). All methods
+by convention expect the address of the class and instance on top of the
+stack when called. The next three lines define the behavior of <code>INIT</code> when it's called.
+It first calls its superclass's version of <code>INIT</code> (which in this
+case is "<code>OBJECT => INIT</code>"&mdash;this default implementation clears all
+instance variables). The rest displays some text and causes the instance
+to print its class name (<code>THIS --> CLASS --> ID</code>).
+<p>
+
+The <code>INIT</code>> method is special for Ficl objects: whenever
+you create an initialized instance using <code>NEW</code> or <code>NEW-ARRAY</code>,
+Ficl calls the class's <code>INIT</code> method for you on that instance. The
+default <code>INIT</code> method supplied by <code>OBJECT</code> clears the instance,
+so we didn't really need to override it in this case (see the source code
+in <code>softcore/oo.fr</code>).
+<p>
+
+The <code>ON</code> and <code>OFF</code> methods defined above hide the details
+of turning LEDs on and off. The interface to FiclWin's simulated hardware
+is handled by <code>!OREG</code>. The class keeps the LED state in a shadow
+variable (<code>.STATE</code>) so that <code>ON</code> and <code>OFF</code> can work
+in terms of LED number rather than a bitmask.
+<p>
+
+Now make an instance of the new class:
+<pre>
+C-LED --> NEW LED
+</pre>
+
+And try a few things...
+<pre>
+LED --> METHODS
+LED --> PEDIGREE
+1 LED --> ON
+1 LED --> OFF
+</pre>
+
+Or you could type this with the same effect:
+<pre>
+LED 2DUP --> METHODS --> PEDIGREE
+</pre>
+
+Notice (from the output of <code>METHODS</code>) that we've overridden the
+<code>INIT</code> method supplied by object, and added two more methods for the member
+variables. If you type <code>WORDS</code>, you'll see that these methods are
+not visible outside the context of the class that contains them. The method
+finder <code>--></code> uses the class to look up methods. You can use
+this word in a definition, as we did in <code>INIT</code>, and it performs
+late binding, meaning that the mapping from message (method name) to method
+(the code) is deferred until run-time. To see this, you can decompile the
+init method like this:
+<pre>
+C-LED --> SEE INIT
+</pre>
+
+or
+<pre>
+LED --> CLASS --> SEE INIT
+</pre>
+
+<? ficlHeader2("Early Binding") ?>
+
+Ficl also provides early binding if you ask for it. Early binding is not
+as safe as late binding, but it produces code that is more compact and
+efficient because it compiles method addresses rather then their names.
+In the preferred uses of early binding, the class is assumed to be the
+one you're defining. This kind of early binding can only be used inside
+a class definition. Early bound methods still expect to find a class and
+instance cell-pair on top of the stack when they run.
+<p>
+
+Here's an example that illustrates a potential problem:
+<pre>
+OBJECT --> SUB C1
+: M1 { 2:THIS -- } ." C1'S M1" CR ;
+: M2 { 2:THIS -- } ." Running " THIS MY=> M1 ; ( early )
+: M3 { 2:THIS -- } ." Running " THIS --> M1 ( late )
+END-CLASS
+C1 --> SUB C2
+: M1 { 2:THIS -- } ." C2'S M1" CR ;
+END-CLASS
+C2 --> NEW I2
+I2 --> M1 ( runs the M1 defined in C2 )
+I2 --> M2 ( Is this what you wanted? )
+I2 --> M3 { runs the overridden M1)
+</pre>
+
+Even though we overrode method <code>M1</code> in class <code>C2</code>, the definition of <code>M2</code> with
+early binding forced the use of <code>M1</code> as defined in <code>C1</code>. If that's what you
+want, great, but more often you'll want the flexibility of overriding parent
+class behaviors appropriately.
+
+<ol>
+
+<li>
+<code>MY=></code> binds early to a method in the class being defined,
+as in the example above.
+
+<li>
+<code>MY=[ ]</code> binds a sequence of methods in the current class.
+Useful when the class has object members. Lines like
+<code>THIS --> STATE --> SET</code> in the definition of <code>C-LED</code> above can be replaced with
+<code>THIS MY=[ STATE SET ]</code> to use early binding.
+
+<li>
+<code>=></code> (dangerous) pops a class off the stack and compiles
+the method in that class. Since you have to specify the class explicitly,
+there is a real danger that this will be out of sync with the class you
+really wanted. I recommend you use <code>MY=></code> or <code>MY=[ ]</code> instead.
+
+</ol>
+
+Early binding using <code>=></code> is dangerous because it partially
+defeats the data-to-code matching mechanism object oriented languages were
+created to provide, but it does increase run-time speed by binding the
+method at compile time. In many cases, such as the <code>INIT</code> method,
+you can be reasonably certain of the class of thing you're working on.
+This is also true when invoking class methods, since all classes are instances
+of <code>METACLASS</code>. Here's an example from the definition of <code>METACLASS</code>
+in oo.fr (don't paste this into ficlWin&mdash;it's already there):
+<pre>
+: NEW \ ( class metaclass "name" -- )
+ METACLASS => INSTANCE --> INIT ;
+</pre>
+
+Try this:
+<pre>
+METACLASS --> SEE NEW
+</pre>
+
+Decompiling the method with <code>SEE</code> shows the difference between the
+two strategies. The early bound method is compiled inline, while the late-binding
+operator compiles the method name and code to find and execute it in the
+context of whatever class is supplied on the stack at run-time.
+<p>
+
+Notice that the primitive early-binding operator <code>=></code> requires
+a class at compile time. For this reason, classes are <code>IMMEDIATE</code>,
+meaning that they push their signature at compile time or run time. I'd
+recommend that you avoid early binding until you're very comfortable with
+Forth, object-oriented programming, and Ficl's OOP syntax.
+
+<? ficlHeader2("More About Instance Variables") ?>
+
+<i>Untyped</i> instance variable methods (created by <code>CELL: CELLS: CHAR:</code>
+and <code>CHARS:</code>) just push the address of the corresponding instance
+variable when invoked on an instance of the class. It's up to you to remember
+the size of the instance variable and manipulate it with the usual Forth
+words for fetching and storing.
+<p>
+
+As advertised earlier, Ficl provides ways to objectify existing data
+structures without changing them. Instead, you can create a Ficl class
+that models the structure, and instantiate a <i>ref</i> from this class,
+supplying the address of the structure. After that, the <i>ref instance</i>
+behaves as a Ficl object, but its instance variables take on the values
+in the existing structure. Example (from <code>softcore/ficlclass.fr</code>):
+<pre>
+OBJECT SUBCLASS C-WORDLIST
+ C-WORDLIST REF: .PARENT
+ C-PTR OBJ: .NAME
+ C-CELL OBJ: .SIZE
+ C-WORD REF: .HASH ( first entry in hash table )
+
+ : ?
+ --> GET-NAME ." ficl wordlist " TYPE CR ;
+ : PUSH DROP >SEARCH ;
+ : POP 2DROP PREVIOUS ;
+ : SET-CURRENT DROP SET-CURRENT ;
+ : GET-NAME DROP WID-GET-NAME ;
+ : WORDS { 2:THIS -- }
+ THIS MY=[ .SIZE GET ] 0 DO
+ I THIS MY=[ .HASH INDEX ] ( 2list-head )
+ BEGIN
+ 2DUP --> GET-NAME TYPE SPACE
+ --> NEXT OVER
+ 0= UNTIL 2DROP CR
+ LOOP
+ ;
+END-CLASS
+</pre>
+
+In this case, <code>C-WORDLIST</code> describes Ficl's wordlist structure;
+<code>NAMED-WID</code> creates a wordlist and binds it to a ref instance of
+<code>C-WORDLIST</code>.
+The fancy footwork with <code>POSTPONE</code> and early binding is required
+because classes are immediate. An equivalent way to define <code>NAMED-WID</code> with
+late binding is:
+<pre>
+: NAMED-WID ( c-address u -- )
+ WORDLIST POSTPONE C-WORDLIST --> REF
+ ;
+</pre>
+
+To do the same thing at run-time (and call it <code>MY-WORDLIST</code>):
+
+<pre>wordlist c-wordlist --> ref my-wordlist</pre>
+
+Now you can deal with the wordlist through the ref instance:
+<pre>
+MY-WORDLIST --> PUSH
+MY-WORDLIST --> SET-CURRENT
+ORDER
+</pre>
+
+Ficl can also model linked lists and other structures that contain pointers
+to structures of the same or different types. The class constructor word
+<a href="#exampleref:"><code>REF:</code></a>
+makes an aggregate reference to a particular class. See the <a href="#glossinstance">instance
+variable glossary</a> for an <a href="#exampleref:">example</a>.
+<p>
+
+Ficl can make arrays of instances, and aggregate arrays into class descripions.
+The <a href="#glossclass">class methods</a> <code>ARRAY</code> and <code>NEW-ARRAY</code>
+create uninitialized and initialized arrays, respectively, of a class.
+In order to initialize an array, the class must define (or inherit) a reasonable
+<code>INIT</code> method. <code>NEW-ARRAY</code> invokes it on each member of the array
+in sequence from lowest to highest. Array instances and array members use
+the object methods <code>INDEX</CODE>, <CODE>NEXT</CODE>, and <CODE>PREV</code>
+to navigate. Aggregate a member array of objects using <a href="#arraycolon"><code>ARRAY:</code></a>.
+The objects are not automatically initialized in this case&mdash;your class
+initializer has to call <code>ARRAY-INIT</code> explicitly if you want
+this behavior.
+<p>
+
+For further examples of OOP in Ficl, please see the source file <code>softcore/ficlclass.fr</code>.
+This file wraps several Ficl internal data structures in objects and gives
+use examples.
+
+
+<? ficlHeader1("Ficl String Classes") ?>
+<a NAME="cstring"></a>
+
+<code>C-STRING</code> is a reasonably useful dynamic string class.
+Source code for the class is located in <code>softcore/string.fr</code>.
+Features:
+dynamic creation and resizing; deletion, char cout, concatenation, output,
+comparison; creation from quoted string constant (<code>S"</code>).
+<p>
+Examples of use:
+<pre>
+C-STRING --> NEW HOMER
+S" In this house, " HOMER --> SET
+S" we obey the laws of thermodynamics!" HOMER --> CAT
+HOMER --> TYPE
+</pre>
+
+
+<? ficlHeader2("OOP Glossary") ?>
+
+<a NAME="oopgloss"></a>
+
+<b>Note:</b> With the exception of the binding operators (the first two definitions
+here), all of the words in this section are internal factors that you don't
+need to worry about. These words provide method binding for all classes
+and instances. Also described are supporting words and execution factors.
+All are defined in <code>softcore/oo.fr</code>.
+
+<dl>
+
+<? glossaryEntry("-->", "( instance class \"method-name\" -- xn )") ?>
+
+Late binding: looks up and executes the given method in the context of
+the class on top of the stack.
+
+<? glossaryEntry("C->", "( instance class \"method-name\" -- xn exc )") ?>
+
+Late binding with <code>CATCH</code>: looks up and <code>CATCH</code>es the given
+method in the context of the class on top of the stack, pushes zero or
+exception code upon return.
+
+<? glossaryEntry("MY=>", "compilation: ( \"method-name\" -- ) execution: ( instance class -- xn )") ?>
+
+Early binding: compiles code to execute the method of the class being defined.
+Only visible and valid in the scope of a <code>--> SUB</CODE> .. <CODE>END-CLASS</code>
+class definition.
+
+<? glossaryEntry("MY=[", "compilation: ( \"obj1 obj2 .. method ]\" -- ) execution: ( instance class -- xn )") ?>
+
+Early binding: compiles code to execute a chain of methods of the class
+being defined. Only visible and valid in the scope of a <code>--> SUB</CODE>
+.. <CODE>END-CLASS</code> class definition.
+
+<? glossaryEntry("=>", "compilation: ( class metaclass \"method-name\" -- ) execution: ( instance class -- xn )") ?>
+
+Early binding: compiles code to execute the method of the class specified
+at compile time.
+
+<? glossaryEntry("do-do-instance", "") ?>
+
+When executed, causes the instance to push its <code>( INSTANCE CLASS )</code> stack
+signature. Implementation factor of <code>METACLASS --> SUB</code></b> .
+Compiles <code>.DO-INSTANCE</code> in the context of a class; <code>.DO-INSTANCE</code>
+implements the <code>DOES></code> part of a named instance.
+
+<? glossaryEntry("exec-method", "( instance class c-address u -- xn )") ?>
+
+Given the address and length of a method name on the stack, finds
+the method in the context of the specified class and invokes it. Upon entry
+to the method, the instance and class are on top of the stack, as usual.
+If unable to find the method, prints an error message and aborts.
+
+<? glossaryEntry("find-method-xt", "( class \"method-name\" -- class xt )") ?>
+
+Attempts to map the message to a method in the specified class. If successful,
+leaves the class and the execution token of the method on the stack. Otherwise
+prints an error message and aborts.
+
+<? glossaryEntry("lookup-method", "( class c-address u -- class xt )") ?>
+
+Given the address and length of a method name on the stack, finds
+the method in the context of the specified class. If unable to find the
+method, prints an error message and aborts.
+
+<? glossaryEntry("parse-method", "compilation: ( \"method-name\" -- ) execution: ( -- c-address u )") ?>
+
+Parse <code>"method-name"</code> from the input stream and compile code to push its length
+and address when the enclosing definition runs.
+</dl>
+
+<? ficlHeader3("Instance Variable Glossary") ?>
+<a NAME="glossinstance"></a>
+
+<b>Note:</b>: These words are only visible when creating a subclass! To
+create a subclass, use the <code>SUB</code> method on <code>OBJECT</code> or any
+class derived from it (<i>not</i> <code>METACLASS</code>). Source code for
+Ficl OOP is in <code>softcore/oo.fr</code>.
+<p>
+
+Instance variable words do two things: they create methods that do
+san action appropriate for the type of instance variable they represent,
+and they reserve space in the class template for the instance variable.
+We'll use the term <i>instance variable</i> to refer both to the method
+that gives access to a particular field of an object, and to the field
+itself. Rather than give esentially the same example over and over, here's
+one example that shows several of the instance variable construction words
+in use:
+
+<pre>
+OBJECT SUBCLASS C-EXAMPLE
+ CELL: .CELL0
+ C-4BYTE OBJ: .NCELLS
+ 4 C-4BYTE ARRAY: .QUAD
+ CHAR: .LENGTH
+ 79 CHARS: .NAME
+END-CLASS
+</pre>
+
+This class only defines instance variables, and it inherits some methods
+from <code>OBJECT</code>. Each untyped instance variable (<code>.CELL0</code>, <code>.LENGTH</code>,
+<code>.NAME</code>) pushes its address when executed. Each object instance variable
+pushes the address and class of the aggregate object. Similar to C, an
+array instance variable leaves its base address (and its class) when executed.
+The word <code>SUBCLASS</code> is shorthand for <code>--> sub</code> .
+
+<dl>
+
+<? glossaryEntry("CELL:", "compilation: ( offset \"name\" -- offset ) execution: ( -- cell-address )") ?>
+
+Create an untyped instance variable one cell wide. The instance variable
+leaves its payload's address when executed.
+
+<? glossaryEntry("CELLS:", "compilation: ( offset nCells \"name\" -- offset' ) execution: ( -- cell-address )") ?>
+
+Create an untyped instance variable <code>nCells</code> cells wide.
+
+<? glossaryEntry("CHAR:", "compilation: ( offset \"name\" -- offset' ) execution: ( -- cell-address )") ?>
+
+Create an untyped member variable one character wide.
+
+<? glossaryEntry("CHARS:", "compilation: ( offset nChars \"name\" -- offset' ) execution: ( -- cell-address )") ?>
+
+Create an untyped member variable <code>nChars</code> characters wide.
+
+<? glossaryEntry("OBJ:", "compilation: ( offset class metaclass \"name\" -- offset' ) execution: ( -- instance class )") ?>
+
+Aggregate an uninitialized instance of <code>CLASS</code> as a member variable
+of the class under construction.
+
+<? glossaryEntry("ARRAY:", "compilation: ( offset nObjects class metaclass \"name\" -- offset' ) execution: ( -- instance class )") ?>
+<a NAME="arraycolon"></a>
+
+Aggregate an uninitialized array of instances of the class specified as
+a member variable of the class under construction.
+
+<? glossaryEntry("EXAMPLEREF:", "compilation: ( offset class metaclass \"name\" -- offset' ) execution: ( -- ref-instance ref-class )") ?>
+
+Aggregate a reference to a class instance. There is no way to set the value
+of an aggregated ref&mdash;it's meant as a way to manipulate existing data
+structures with a Ficl OO model. For example, if your system contains a
+linked list of 4 byte quantities, you can make a class that represents
+a list element like this:
+
+<pre>
+OBJECT SUBCLASS C-4LIST
+ C-4LIST REF: .LINK
+ C-4BYTE OBJ: .PAYLOAD
+END-CLASS
+
+ADDRESS-OF-EXISTING-LIST C-4LIST --> REF MYLIST
+</pre>
+
+<dd>
+The last line binds the existing structure to an instance of the class
+we just created. The link method pushes the link value and the class <code>C_4LIST</code>,
+so that the link looks like an object to Ficl and like a struct to C (it
+doesn't carry any extra baggage for the object model&mdash;the Ficl methods
+alone take care of storing the class information).
+<p>
+
+<b>Note:</b> Since a <code>REF:</code> aggregate can only support one class, it's good for
+modeling static structures, but not appropriate for polymorphism. If you
+want polymorphism, aggregate a <code>C_REF</code> (see <code>softcore/classes.fr</code> for source)
+into your class&mdash;it has methods to set and get an object.
+<p>
+
+By the way, it is also possible to construct a pair of classes that contain
+aggregate pointers to each other. Here's an example:
+
+<pre>
+OBJECT SUBCLASS AKBAR
+ SUSPEND-CLASS \ put akbar on hold while we define jeff
+
+OBJECT SUBCLASS JEFF
+ AKBAR REF: .SIGNIFICANT-OTHER
+ ( <i>... your additional methods here ...</i> )
+END-CLASS \ done with jeff
+
+AKBAR --> RESUME-CLASS \ resume defining akbar
+ JEFF REF: .SIGNIFICANT-OTHER
+ ( <i>... your additional methods here ...</i> )
+END-CLASS \ done with akbar
+</pre>
+
+</dl>
+
+<a NAME="glossclass"></a>
+<? ficlHeader1("Class Methods Glossary") ?>
+
+These words are methods of <code>METACLASS</code>. They define the manipulations
+that can be performed on classes. Methods include various kinds of instantiation,
+programming tools, and access to member variables of classes. Source is
+in <code>softcore/oo.fr</code>.
+
+<dl>
+
+<? glossaryEntry("INSTANCE", "( class metaclass \"name\" -- instance class )") ?>
+
+Create an uninitialized instance of the class, giving it the name specified.
+The method leaves the instance's signature on the stack (handy if you
+want to initialize). Example:
+
+<pre>
+C_REF --> INSTANCE UNINIT-REF 2DROP
+</pre>
+
+<? glossaryEntry("NEW", "( class metaclass \"name\" -- )") ?>
+
+Create an initialized instance of class, giving it the name specified.
+This method calls <code>INIT</code> to perform initialization.
+
+<? glossaryEntry("ARRAY", "( nObjects class metaclass \"name\" -- nObjects instance class )") ?>
+
+Create an array of <code>nObjects</code> instances of the specified class.
+Instances are not initialized. Example:
+
+<pre>
+10 C_4BYTE --> ARRAY 40-RAW-BYTES 2DROP DROP
+</pre>
+
+
+<? glossaryEntry("NEW-ARRAY", "( nObjects class metaclass \"name\" -- )") ?>
+
+Creates an initialized array of <code>nObjects</code> instances of the class.
+Same syntax as <code>ARRAY</code>.
+
+<a NAME="alloc"></a>
+<? glossaryEntry("ALLOC", "( class metaclass -- instance class )") ?>
+
+Creates an anonymous instance of <code>CLASS</code> from the heap (using a call
+to <code>ficlMalloc()</code> to get the memory). Leaves the payload and class addresses
+on the stack. Usage example:
+
+<pre>
+C-REF --> ALLOC 2CONSTANT INSTANCE-OF-REF
+</pre>
+<p>
+
+Creates a double-cell constant that pushes the payload and class address
+of a heap instance of <code>C-REF</code>.
+
+<a NAME="allocarray"></a>
+<? glossaryEntry("ALLOC-ARRAY", "( nObjects class metaclass -- instance class )") ?>
+
+Same as <code>NEW-ARRAY</code>, but creates anonymous instances from the heap using
+a call to <code>ficlMalloc()</code>. Each instance is initialized using the class's
+<code>INIT</code> method.
+
+<a NAME="allot"></a>
+<? glossaryEntry("ALLOT", "( class metaclass -- instance class )") ?>
+
+Creates an anonymous instance of <code>CLASS</code> from the dictionary. Leaves
+the payload and class addresses on the stack. Usage example:
+
+<pre>
+C-REF --> ALLOT 2CONSTANT INSTANCE-OF-REF
+</pre>
+
+<p>
+
+Creates a double-cell constant that pushes the payload and class address
+of a heap instance of <code>C-REF</code>.
+
+<a NAME="allotarray"></a>
+<? glossaryEntry("ALLOT-ARRAY", "( nObjects class metaclass -- instance class )") ?>
+
+Same as <code>NEW-ARRAY</code>, but creates anonymous instances from the dictionary.
+Each instance is initialized using the class's <code>INIT</code> method.
+
+<? glossaryEntry("REF", "( instance-address class metaclass \"name\" -- )") ?>
+
+Make a ref instance of the class that points to the supplied instance address.
+No new instance space is allotted. Instead, the instance refers to the
+address supplied on the stack forever afterward. For wrapping existing
+structures.
+
+
+<? glossaryEntry("SUB", "( class metaclass -- old-wid address[size] size )") ?>
+
+Derive a subclass. You can add or override methods, and add instance variables.
+Alias: <code>SUBCLASS</code>. Examples:
+<p>
+
+<pre>
+C_4BYTE --> SUB C_SPECIAL4BYTE
+ ( <i>... your new methods and instance variables here ...</i> )
+END-CLASS
+</pre>
+
+or
+
+<pre>
+C_4BYTE SUBCLASS C_SPECIAL4BYTE
+ ( <i>... your new methods and instance variables here ...</i> )
+END-CLASS
+</pre>
+
+<? glossaryEntry(".SIZE", "( class metaclass -- instance-size )") ?>
+
+Returns address of the class's instance size field, in address units. This
+is a metaclass member variable.
+
+<? glossaryEntry(".SUPER", "( class metaclass -- superclass )") ?>
+
+Returns address of the class's superclass field. This is a metaclass member
+variable.
+
+<? glossaryEntry(".WID", "( class metaclass -- wid )") ?>
+
+Returns the address of the class's wordlist ID field. This is a metaclass
+member variable.
+
+<? glossaryEntry("GET-SIZE", "( -- instance-size )") ?>
+
+Returns the size of an instance of the class in address units. Imeplemented
+as follows:
+
+<pre>
+: GET-SIZE METACLASS => .SIZE @ ;
+</pre>
+
+<? glossaryEntry("GET-WID", "( -- wid )") ?>
+
+Returns the wordlist ID of the class. Implemented as:
+
+<pre>
+: GET-WID METACLASS => .WID @ ;
+</pre>
+
+<? glossaryEntry("GET-SUPER", "( -- superclass )") ?>
+
+Returns the class's superclass. Implemented as
+
+<pre>
+: GET-SUPER METACLASS => .super @ ;
+</pre>
+
+
+<? glossaryEntry("ID", "( class metaclass -- c-address u )") ?>
+
+Returns the address and length of a string that names the class.
+
+
+<? glossaryEntry("METHODS", "( class metaclass -- )") ?>
+
+Lists methods of the class and all its superclasses.
+
+
+<? glossaryEntry("OFFSET-OF", "( class metaclass \"name\" -- offset )") ?>
+
+Pushes the offset from the instance base address of the named member variable.
+If the name is not that of an instance variable method, you get garbage.
+There is presently no way to detect this error. Example:
+
+<pre>
+metaclass --> offset-of .wid
+</pre>
+
+
+<? glossaryEntry("PEDIGREE", "( class metaclass -- )") ?>
+
+
+Lists the pedigree of the class (inheritance trail).
+
+<? glossaryEntry("SEE", "( class metaclass \"name\" -- )") ?>
+
+Decompiles the specified method&mdash;obect version of <code>SEE</code>, from the
+<code>TOOLS</code> wordset.
+
+</dl>
+
+<? ficlHeader1("<code>OBJECT</code> Base-Class Methods Glossary") ?>
+<a NAME="objectgloss"></a>
+
+These are methods that are defined for all instances by the base class
+<code>OBJECT</code>.
+The methods include default initialization, array manipulations, aliases
+of class methods, upcasting, and programming tools.
+
+<dl>
+
+<? glossaryEntry("INIT", "( instance class -- )") ?>
+
+Default initializer, called automatically for all instances created with
+<code>NEW</code>
+or <code>NEW-ARRAY</code>. Zero-fills the instance. You do not normally need
+to invoke <code>INIT</code> explicitly.
+
+<? glossaryEntry("ARRAYINIT", "( nObjects instance class -- )") ?>
+
+Applies <code>INIT</code> to an array of objects created by <code>NEW-ARRAY</code>.
+Note that <code>ARRAY:</code> does not cause aggregate arrays to be initialized
+automatically. You do not normally need to invoke <code>ARRAY-INIT</code> explicitly.
+
+<? glossaryEntry("FREE", "( instance class -- )") ?>
+
+Releases memory used by an instance previously created with <code>ALLOC</code>
+or <code>ALLOC-ARRAY</code>. <b>Note:</b> This method is not presently protected
+against accidentally deleting something from the dictionary. If you do
+this, Bad Things are likely to happen. Be careful for the moment to apply
+free only to instances created with <code>ALLOC</code> or <code>ALLOC-ARRAY</code>.
+
+<? glossaryEntry("CLASS", "( instance class -- class metaclass )") ?>
+
+Convert an object signature into that of its class. Useful for calling
+class methods that have no object aliases.
+
+<? glossaryEntry("SUPER", "( instance class -- instance superclass )") ?>
+
+Upcast an object to its parent class. The parent class of <code>OBJECT</code>
+is zero. Useful for invoking an overridden parent class method.
+
+<? glossaryEntry("PEDIGREE", "( instance class -- )") ?>
+
+Display an object's pedigree&mdash;its chain of inheritance. This is an alias
+for the corresponding class method.
+
+<? glossaryEntry("SIZE", "( instance class -- instance-size )") ?>
+
+Returns the size, in address units, of one instance. Does not know about
+arrays! This is an alias for the class method <code>GET-SIZE</code>.
+
+<? glossaryEntry("METHODS", "( instance class -- )") ?>
+
+Class method alias. Displays the list of methods of the class and all superclasses
+of the instance.
+
+<? glossaryEntry("INDEX", "( n instance class -- instance[n] class )") ?>
+
+Convert array-of-objects base signature into signature for array element
+n. No check for bounds overflow. Index is zero-based, like C, so
+
+<pre>
+0 MY-OBJ --> INDEX
+</pre>
+
+is equivalent to
+
+<pre>
+MY-OBJ
+</pre>
+
+Check out the <a href="#minusrot">description of <code>-ROT</code></a> for
+help in dealing with indices on the stack.
+
+<? glossaryEntry("NEXT", "( instance[n] class -- instance[n+1] )") ?>
+
+Convert an array-object signature into the signature of the next
+object in the array. No check for bounds overflow.
+
+<? glossaryEntry("PREV", "( instance[n] class -- instance[n-1] class )") ?>
+
+Convert an object signature into the signature of the previous object
+in the array. No check for bounds underflow.
+
+</dl>
+
+
+<? ficlHeader2("Supplied Classes") ?>
+<a NAME="stockclasses"></a>
+
+For more information on theses classes, see <code>softcore/classes.fr</code>.
+
+<dl>
+
+<? glossaryEntry("METACLASS", "") ?>
+
+Describes all classes of Ficl. Contains class methods. Should never be
+directly instantiated or subclassed. Defined in <code>softcore/oo.fr</code>. Methods described
+above.
+
+<? glossaryEntry("OBJECT", "") ?>
+
+Mother of all Ficl objects. Defines default initialization and array indexing
+methods. Defined in <code>softcore/oo.fr</code>. Methods described above.
+
+<? glossaryEntry("C-REF", "") ?>
+
+Holds the signature of another object. Aggregate one of these into a data
+structure or container class to get polymorphic behavior. Methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- ref-instance ref-class )") ?>
+Push the referenced object value on the stack.
+
+<? glossaryEntry("SET", "( ref-instance ref-class instance class -- )") ?>
+Set the referenced object being held.
+
+<? glossaryEntry(".INSTANCE", "( instance class -- a-address )") ?>
+Cell member that holds the instance.
+
+<? glossaryEntry(".CLASS", "( instance class -- a-address )") ?>
+Cell member that holds the class.
+
+</dl>
+
+<? glossaryEntry("C-BYTE", "") ?>
+
+Primitive class derived from <code>OBJECT</code>, with a 1-byte payload. <code>SET</code>
+and <code>GET</code> methods perform correct width fetch and store. Methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- byte )") ?>
+Push the object's value on the stack.
+
+<? glossaryEntry("SET", "( byte instance class -- )") ?>
+Set the object's value from the stack.
+
+<? glossaryEntry(".PAYLOAD", "( instance class -- address )") ?>
+Member holds instance's value.
+
+</dl>
+
+<? glossaryEntry("C-2BYTE", "") ?>
+
+Primitive class derived from <code>OBJECT</code>, with a 2-byte payload. <code>SET</code>
+and <code>GET</code> methods perform correct width fetch and store. Methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- 2byte )") ?>
+Push the object's value on the stack.
+
+<? glossaryEntry("SET", "( 2byte instance class -- )") ?>
+Set the object's value from the stack.
+
+<? glossaryEntry(".PAYLOAD", "( instance class -- address )") ?>
+Member holds instance's value.
+
+</dl>
+
+<? glossaryEntry("C-4BYTE", "") ?>
+Primitive class derived from <code>object</code>, with a 4-byte payload. <code>SET</code>
+and <code>GET</code> methods perform correct width fetch and store. Methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- 4byte )") ?>
+Push the object's value on the stack.
+
+<? glossaryEntry("SET", "( 4byte instance class -- )") ?>
+Set the object's value from the stack.
+
+<? glossaryEntry(".PAYLOAD", "( instance class -- address )") ?>
+Member holds instance's value.
+
+</dl>
+
+<? glossaryEntry("C-CELL", "") ?>
+
+Primitive class derived from <code>OBJECT</code>, with a cell payload (equivalent
+to <code>C-4BYTE</code> on 32 bit platforms, 64 bits wide on Alpha and other
+64-bit platforms). <code>SET</code>
+and <code>GET</code> methods perform correct width fetch and store. Methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- 4byte )") ?>
+Push the object's value on the stack.
+
+<? glossaryEntry("SET", "( 4byte instance class -- )") ?>
+Set the object's value from the stack.
+
+<? glossaryEntry(".PAYLOAD", "( instance class -- address )") ?>
+Member holds instance's value.
+
+</dl>
+
+<? glossaryEntry("C-PTR", "") ?>
+
+Base class derived from <code>OBJECT</code> for pointers to non-object types.
+This class is not complete by itself: several methods depend on a derived
+class definition of <code>@SIZE</code>. Methods and members:
+
+<dl>
+
+<? glossaryEntry(".ADDR", "( instance class -- a-address )") ?>
+Member variable, holds the pointer address.
+
+<? glossaryEntry("GET-PTR", "( instance class -- pointer )") ?>
+Pushes the pointer address.
+
+<? glossaryEntry("SET-PTR", "( pointer instance class -- )") ?>
+Sets the pointer address.
+
+<? glossaryEntry("INC-PTR", "( instance class -- )") ?>
+Adds <code>@SIZE</code> to the pointer address.
+
+<? glossaryEntry("DEC-PTR", "( instance class -- )") ?>
+Subtracts <code>@SIZE</code> to the pointer address.
+
+<? glossaryEntry("INDEX-PTR", "( i instance class -- )") ?>
+Adds <code>i * @SIZE</code> to the pointer address.
+
+</dl>
+
+<? glossaryEntry("C-BYTEPTR", "") ?>
+
+Pointer to byte derived from <code>C-PTR</code>. Methods and members:
+
+<dl>
+
+<? glossaryEntry("@SIZE", "( instance class -- size )") ?>
+Push size of the pointed-to object.
+
+<? glossaryEntry("GET", "( instance class -- byte )") ?>
+Pushes the pointer's referent byte.
+
+<? glossaryEntry("SET", "( byte instance class -- )") ?>
+Stores <code>byte</code> at the pointer address.
+
+</dl>
+
+
+
+<? glossaryEntry("C-2BYTEPTR", "") ?>
+
+Pointer to 2byte derived from <code>C-PTR</code>. Methods and members:
+
+<dl>
+
+<? glossaryEntry("@SIZE", "( instance class -- size )") ?>
+Push size of the pointed-to object.
+
+<? glossaryEntry("GET", "( instance class -- 2byte )") ?>
+Pushes the pointer's referent 2byte.
+
+<? glossaryEntry("SET", "( 2byte instance class -- )") ?>
+Stores <code>2byte</code> at the pointer address.
+
+</dl>
+
+
+
+<? glossaryEntry("C-4BYTEPTR", "") ?>
+
+Pointer to 4byte derived from <code>C-PTR</code>. Methods and members:
+
+<dl>
+
+<? glossaryEntry("@SIZE", "( instance class -- size )") ?>
+Push size of the pointed-to object.
+
+<? glossaryEntry("GET", "( instance class -- 4byte )") ?>
+Pushes the pointer's referent 4byte.
+
+<? glossaryEntry("SET", "( 4byte instance class -- )") ?>
+Stores <code>4byte</code> at the pointer address.
+
+</dl>
+
+
+<? glossaryEntry("C-CELLPTR", "") ?>
+
+Pointer to cell derived from <code>C-PTR</code>. Methods and members:
+
+<dl>
+
+<? glossaryEntry("@SIZE", "( instance class -- size )") ?>
+Push size of the pointed-to object.
+
+<? glossaryEntry("GET", "( instance class -- cell )") ?>
+Pushes the pointer's referent cell.
+
+<? glossaryEntry("SET", "( cell instance class -- )") ?>
+Stores <code>cell</code> at the pointer address.
+
+</dl>
+
+
+
+<? glossaryEntry("C-STRING", "") ?>
+
+Dynamically allocated string, similar to MFC's <code>CString</code>.
+For more information, see <code>softcore/string.fr</code>.
+Partial list of methods and members:
+
+<dl>
+
+<? glossaryEntry("GET", "( instance class -- c-address u )") ?>
+Pushes the string buffer's contents as a <code>C-ADDR U</code> style string.
+
+<? glossaryEntry("SET", "( c-address u instance class -- )") ?>
+Sets the string buffer's contents to a new value.
+
+<? glossaryEntry("CAT", "( c-address u instance class -- )") ?>
+Concatenates a string to the string buffer's contents.
+
+<? glossaryEntry("COMPARE", "( c-address u instance class -- result )") ?>
+Lexical compiration of a string to the string buffer's contents.
+Return value is the same as the FORTH function <code>COMPARE</code>.
+
+<? glossaryEntry("TYPE", "( instance class -- )") ?>
+Prints the contents of the string buffer to the output stream.
+
+<? glossaryEntry("HASHCODE", "( instance class -- i )") ?>
+Returns a computed hash based on the contents of the string buffer.
+
+<? glossaryEntry("FREE", "( instance class -- )") ?>
+Releases the internal buffer.
+
+</dl>
+
+
+<? glossaryEntry("C-HASHSTRING", "") ?>
+
+Subclass of <code>C-STRING</code>, which adds a member variable to store a hashcode.
+For more information, see <code>softcore/string.fr</code>.
+
+</dl>
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/parsesteps.ht b/doc/source/parsesteps.ht
new file mode 100644
index 000000000000..ad083dce9d7a
--- /dev/null
+++ b/doc/source/parsesteps.ht
@@ -0,0 +1,234 @@
+<?
+ficlPageHeader("ficl parse steps")
+
+ficlAddToNavBarAs("Parse Steps")
+
+def entry(definition):
+ print "<dt>\n<code>" + definition + "</code>\n<dd>\n"
+
+?>
+
+
+<? ficlHeader1("Parse Steps") ?>
+
+Unlike every other FORTH we know of, Ficl features an <i>extensible
+parser chain</i>. The Ficl parser is not a monolithic function; instead,
+it is comprised of a simple tokenizer and a series of <i>parse steps</i>.
+A parse step is a step in the parser chain that handles a particular kind
+of token, acting on the token as appropriate. Example parse steps, in
+terms of traditional FORTH lore, would be the "number runner" and the
+"colon compiler".
+<p>
+
+The Ficl parser works like this:
+<ol>
+
+<li>
+Read in a new <i>token</i> (string of text with no internal whitespace).
+
+<li>
+For each parse step in the chain, call the parse step, passing in the token.
+If the parse step returns <code>FICL_TRUE</code>, that parse step must have
+handled the token appropriately; move on to the next token.
+
+<li>
+If the parser tries all the parse steps and none of them return
+<code>FICL_TRUE</code>, the token is illegal&mdash;print an error
+and reset the virtual machine.
+
+</ol>
+
+Parse steps can be written as native functions, or as Ficl script functions.
+New parse steps can be appended to the chain at any time.
+
+
+<? ficlHeader2("The Default Ficl Parse Chain") ?>
+
+These is the default Ficl parser chain, shown in order.
+
+<dl>
+
+<? entry("?word") ?>
+
+If compiling and local variable support is enabled, attempt to find the token in the local
+variable dictionary. If found, execute the token's compilation semantics and return <code>FICL_TRUE</code>.
+<p>
+
+Attempt to find the token in the system dictionary. If found, execute the token's semantics
+(may be different when compiling than when interpreting) and return <code>FICL_TRUE</code>.
+
+<? entry("?prefix") ?>
+This parse step is only active if prefix support is enabled, setting <code>FICL_WANT_PREFIX</code>
+in <code>ficl.h</code> to a non-zero value.
+Attempt to match the beginning of the token to the list of known prefixes. If there's a match,
+execute the associated prefix method and return <code>FICL_TRUE</code>.
+
+<? entry("?number") ?>
+Attempt to convert the token to a number in the present <code>BASE</code>. If successful, push the
+value onto the stack if interpreting, otherwise compile it, then return <code>FICL_TRUE</code>.
+
+<? entry("?float") ?>
+This parse step is only active if floating-point number support is enabled,
+setting <code>FICL_WANT_FLOAT</code> in <code>ficl.h</code> to a non-zero value.
+Attempt to convert the token to a floating-point number. If successful, push the
+value onto the floating-point stack if interpreting, otherwise compile it,
+then return <code>FICL_TRUE</code>.
+
+</dl>
+
+
+
+<? ficlHeader2("Adding A Parse Step From Within Ficl") ?>
+<a name=ficlparsestep></a>
+
+You can add a parse step in two ways. The first is to write a Ficl word that
+has the correct stack signature for a parse step:
+<pre>
+<i>MY-PARSE-STEP</i> ( c-addr u -- x*i flag )
+</pre>
+where <code>c-addr u</code> are the address and length of the incoming token,
+and <code>flag</code> is <code>FICL_TRUE</code> if the parse step processed
+the token and <code>FICL_FALSE</code> otherwise.
+<p>
+
+Install the parse step using <code>add-parse-step</code>.
+A trivial example:
+<pre>
+: ?silly ( c-addr u -- flag )
+ ." Oh no! Not another " type cr true ;
+' ?silly add-parse-step
+parse-order
+</pre>
+
+<? ficlHeader2("Adding A Native Parse Step") ?>
+
+The other way to add a parse step is to write it in C and add it into the
+parse chain with the following function:
+
+<pre>
+void ficlSystemAddPrimitiveParseStep(ficlSystem *system, char *name, ficlParseStep step);
+</pre>
+
+<code>name</code> is the display name of the parse step in the parse chain
+(as displayed by the Ficl word <code>PARSE-ORDER</code>). <code>step</code>
+is a pointer to the code for the parse step itself,
+and must match the following declaration:
+<pre>
+typedef int (*ficlParseStep)(ficlVm *vm, ficlString s);
+</pre>
+<p>
+
+When a native parse step is run, <code>si</code> points to the incoming token.
+The parse step must return <code>FICL_TRUE</code> if it succeeds in handling the
+token, and <code>FICL_FALSE</code> otherwise.
+See <code>ficlVmParseNumber()</code> in <code>system.c</code> for an example.
+
+
+<? ficlHeader1("Prefixes") ?>
+
+What's a prefix, anyway? A prefix (contributed by Larry Hastings) is a token that's
+recognized as the beginning of another token. Its presence modifies the semantics of
+the rest of the token. An example is <code>0x</code>, which causes digits following
+it to be converted to hex regardless of the current value of <code>BASE</code>.
+<p>
+
+Caveat: Prefixes are matched in sequence, so the more of them there are,
+the slower the interpreter gets. On the other hand, because the prefix
+parse step occurs immediately after the dictionary lookup step, if you
+have a prefix for a particular purpose, using it may save time since it
+stops the parse process. Also, the Ficl interpreter is wonderfully fast,
+and most interpretation only happens once, so it's likely you won't notice
+any change in interpreter speed even if you make heavy use of prefixes.
+<p>
+
+Each prefix is a Ficl word stored in a special wordlist called <code>&lt;PREFIXES&gt;</code>. When the
+prefix parse step (<code>?prefix</code>, implemented in C as <code>ficlVmParsePrefix()</code>) is
+executed, it searches each word in <code>&lt;PREFIXES&gt;</code> in turn, comparing it with the
+initial characters of the incoming token. If a prefix matches, the parse step returns the remainder
+of the token to the input stream and executes the code associated with the prefix. This code can be
+anything you like, but it would typically do something with the remainder of the token. If the prefix
+code does not consume the rest of the token, it will go through the parse process again (which may
+be what you want).
+<p>
+
+Prefixes are defined in <code>prefix.c</code> and in <code>softcore/prefix.fr</code>.
+The best way to add prefixes is by defining them in your own code, bracketed with the special
+words <code>START-PREFIXES</code> and <code>END-PREFIXES</code>. For example, the following
+code would make <code>.(</code> a prefix.
+
+<pre>
+start-prefixes
+: .( .( ;
+end-prefixes
+</pre>
+<p>
+
+The compile-time constant <code>FICL_EXTENDED_PREFIX</code> controls the inclusion of
+several additional prefixes. This is turned off in the default build, since several
+of these prefixes alter standard behavior, but you might like them.
+
+
+<? ficlHeader1("Notes") ?>
+
+<ul>
+
+<li>
+Prefixes and parser extensions are non-standard. However, with the exception of
+prefix support, Ficl's default parse order follows the standard.
+Inserting parse steps in some other order will almost certainly break standard behavior.
+<p>
+
+<li>
+The number of parse steps that can be added to the system is limited by the value of
+<code>FICL_MAX_PARSE_STEPS</code> (defined in <code>sysdep.h</code>). The default
+maximum number is 8.
+<p>
+
+<li>
+The compile-time constant <code>FICL_EXTENDED_PREFIX</code> controls the inclusion of
+several additional prefixes. This is turned off in the default build, since several
+of these prefixes alter standard behavior, but you might like them.
+<p>
+
+
+</ul>
+
+<? ficlHeader1("Parser Glossary") ?>
+
+<dl>
+
+<? entry("PARSE-ORDER ( -- )") ?>
+
+Prints the list of parse steps, in the order in which they are called.
+
+<? entry("ADD-PARSE-STEP ( xt -- )") ?>
+
+Appends a parse step to the parse chain. <code>xt</code> is the address
+(execution token) of a Ficl word to use as the parse step. The word must be a
+legal Ficl parse step (<a href=#ficlparsestep>see above</a>).
+
+<? entry("SHOW-PREFIXES ( -- )") ?>
+
+Prints the list of all prefixes. Each prefix is a Ficl word that is executed if its name
+is found at the beginning of a token.
+
+<? entry("START-PREFIXES ( -- )") ?>
+
+Declares the beginning of a series of prefix definitions.
+Should be followed, eventually, by <code>END-PREFIXES</code>.
+(All <code>START-PREFIXES</code> does is tell the Ficl virtual machine
+to compile into the <code>&lt;PREFIXES&gt;</code> wordlist.)
+
+<? entry("END-PREFIXES ( -- )") ?>
+
+Declares the end of a series of prefix definitions.
+Should only be used after calling <code>START-PREFIXES</code>.
+(All <code>END-PREFIXES</code> does is tell the Ficl virtual machine
+to switch back to the wordlist that was in use before <code>START-PREFIXES</code> was called.)
+
+</dl>
+
+
+<?
+ficlPageFooter()
+?> \ No newline at end of file
diff --git a/doc/source/releases.ht b/doc/source/releases.ht
new file mode 100644
index 000000000000..a594bb8e02f9
--- /dev/null
+++ b/doc/source/releases.ht
@@ -0,0 +1,1003 @@
+<?
+ficlPageHeader("ficl release history")
+
+ficlAddToNavBarAs("Release History")
+
+def ficlVersion(s):
+ ficlHeader1(s)
+
+?>
+
+<? ficlVersion("Version 4.0.31") ?>
+<ul>
+
+<li>
+First official release of new engine as Ficl 4! Hooray!
+
+<li>
+<code>ficlDictionarySee()</code> now takes a <code>ficlCallback</code>,
+so it knows where to print to. This is because <b>ficlWin</b> only
+sets a per-VM callback, which <i>should</i> work.
+
+<li>
+<code>ficlSystemCreate()</code> now passes in the system correctly
+into the dictionaries it creates, which lets dictionaries know what
+system they're a part of.
+
+<li>
+ficlCompatibility: Forgot to add the <code>errorTextOut</code> to the
+<code>ficl_system</code> structure (though I'd remembered to add it to
+the <code>ficl_vm</code> structure). This caused the <code>ficl_system</code>
+members after <code>textOut</code> to not line up with their equivalent
+<code>ficlSystem</code> members, which did bad things. (The bad thing
+in particular was calling <code>ficlDictionaryResetSearchOrder()</code>
+resulted in diddling the <code>vm->link</code> member, which strangely
+enough resulted in double-freeing the stacks.)
+
+<li>
+Added <code>ficlStackWalk()</code>, which walks a stack from top
+to bottom and calls your specified callback with each successive
+element. Cleaned up stack-printing functions as a result.
+
+<li>
+Changed <code>MULTICALL</code> so you can explicitly specify the vtable.
+
+<li>
+Changed XClasses so it explicitly specifies the vtable for
+non-virtual classes. This means you can now call a virtual
+method when you've <code>SUPER</code>ed an object and you'll
+get the method you wanted.
+
+<li>
+XClasses improvement: when removing a thunked method, remove
+the thunk variable too. Added <code>xClass.removeMember()</code>
+to support this.
+
+<li>
+XClasses now generates runtime stack-check code (<code>_DEBUG</code>
+only) for functions thunked from C to Ficl.
+
+<li>
+<code>FICL_WANT_PLATFORM</code> is now <code>0</code> by default.
+It is now set to <code>1</code> in the appropriate <code>ficlplatform/*.h</code>.
+
+<li>
+<code>softcore/win32.fr ENVIRONMENT? COMPARE<code> needed to be case-insensitive.
+
+<li>
+Whoops! Setting <code>FICL_PLATFORM_2INTEGER</code> to 0
+didn't compile. It now does, and works fine, as proved by
+the <code>ansi</code> platform.
+
+<li>
+Another whoops: contrib/xclasses/xclasses.py assumed that <code>"</code> (a prefix
+version of <code>S"</code>) defined. Switched to <code>S"</code>, which is safer.
+
+</ul>
+
+<? ficlVersion("Version 4.0.30") ?>
+
+<ul>
+
+<li>
+Cleaned up some <code>FICL_</code> definitions. Now all <code>FICL_HAVE_*</code> constants
+(and some other odds and ends) have been moved to <code>FICL_PLATFORM_</code>.
+
+<li>
+Whoops! Setting <code>FICL_PLATFORM_2INTEGER</code> to 0 didn't
+compile. It now does, and works fine, as proved by
+the <code>"ansi"</code> platform.
+
+<li>
+Another whoops: <code>contrib/xclasses/xclasses.py</code> assumed that <code>"</code> (a prefix
+version of <code>S"</code>) defined. Switched to <code>S"</code>, which is safer.
+
+<li>
+Added <code>ficlDictionarySetConstantString()</code>. 'Cause I needed it for:
+
+<li>
+Removed the <code>"WIN32"</code> <code>ENVIRONMENT?</code> setting, and added <code>"FICL_PLATFORM_OS"</code>
+and <code>"FICL_PLATFORM_ARCHITECTURE"</code> in its place. These are both <i>strings</i>.
+Updated <code>softcore/win32.fr</code> to match.
+
+<li>
+Compatibility: improved <code>ficlTextOut()</code> behavior. It makes life slightly
+less convenient for some users, but should be an improvement overall.
+The change: <code>ficlTextOut()</code> is now a compatibility-layer function that
+calls straight through to <code>vmTextOut()</code>. Lots of old code calls <code>ficlTextOut()</code>
+(naughty!). It's now explicit that you must set the <code>textOut</code> function
+by hand if you use a custom one... which is a good habit to get in to anyway.
+
+<li>
+Improved the documentation regarding upgrading, <code>ficllocals.h</code>, and compile-time
+constants.
+
+<li>
+Fixed <code>doc/source/generate.py</code> so it gracefully fails to copy over read-only
+files.
+
+<li>
+Got rid of every <code>#ifdef</code> in the sources. We now consistently use <code>#if defined()</code>
+everywhere. Similarly, got rid of all platform-switched <code>#if</code> code (except for the
+compatibility layer, sigh).
+
+</ul>
+
+<? ficlVersion("Version 4.0.29") ?>
+
+<ul>
+
+<li>
+Documentation totally reworked and updated.
+
+<li>
+<code>oldnames</code> renamed to <code>compatibility</code>.
+And improved, so that now Ficl 4 is basically a drop-in
+replacement for Ficl 3.
+
+</ul>
+
+<? ficlVersion("Version 4.0.28") ?>
+
+<ul>
+
+<li>
+Did backwards-compatibility testing. Ficl now drops in, more or less,
+with all the old Ficl-3.03-using projects I had handy.
+
+<li>
+Got Ficl compiling and running fine on Linux.
+
+<li>
+Weaned LZ77 code from needing htonl()/ntohl().
+
+<li>
+Moved all the primitives defined in "testmain.c" to their own file,
+"extras.c", and gave it its own global entry point.
+
+<li>
+Renamed "testmain.c" to just plain "main.c".
+
+<li>
+Renamed "softwords" directory to "softcore". More symmetrical.
+
+<li>
+Renamed "softcore\softcore.bat" to "make.bat". Added support for "CLEAN".
+
+</ul>
+
+<? ficlVersion("Version 4.0.27") ?>
+<ul>
+
+<li>
+Added runtime jump-to-jump peephole optimization in the new
+switch-threaded VM.
+
+<li>
+Fixed <code>INCLUDE-FILE</code> so it rethrows an exception in the
+subordinate evaluation.
+
+<li>
+Added a separate <code>errorOut</code> function to
+<code>ficlCallback()</code>,
+so under Windows you can have a jolly popup window to
+rub your nose in your failings.
+
+</ul>
+
+<? ficlVersion("Version 4.0.26") ?>
+<ul>
+
+<li>
+Namespace policing complete. There are now <i>no</i> external symbols
+which do not start with the word <code>ficl</code>.
+
+<li>
+Removed <code>ficlVmExec()</code>, renamed <code>ficlVmExecC()</code> to
+<code>ficlVmExecuteString()</code>, changed it to take a <code>ficlString()</code>.
+This is deliberate subterfuge on my part; I suspect most
+people who currently call <code>ficlVmExec() / ficlVmExecC()</code>
+should be calling <code>ficlVmEvaluate()</code>.
+</ul>
+
+<? ficlVersion("Version 4.0.25") ?>
+<ul>
+
+<li>
+First pass at support for "oldnames", and namespace policing.
+
+</ul>
+
+<? ficlVersion("Version 4.0.23") ?>
+First alpha release of Ficl 4.0 rewrite. Coded, for better
+or for worse, by Larry Hastings.
+Ficl is <i>smaller</i>, <i>faster</i>, <i>more powerful</i>,
+and <i>easier to use</i> than ever before. (Or your money back!)
+<ul>
+<li>
+Rewrote Ficl's virtual machine; Ficl now runs nearly 3x faster out-of-the-box.
+The new virtual machine is of the "big switch statement" variety.
+
+<li>
+Renamed most (probably all) external Ficl functions and data structures.
+They now make sense and are (gasp!) consistent.
+
+<li>
+Retooled double-cell number support to take advantage of platforms
+which natively support double-cell-sized integers. (Like most modern
+32-bit platforms.)
+
+<li>
+Locals and VALUEs are now totally orthogonal; they can be single- or
+double-cell, and use the float or data stack. TO automatically supports all variants.
+
+<li>
+The "softcore" words can now be stored compressed, with a (current)
+savings of 11k. Decompression is nigh-instantaneous. You can choose
+whether or not you want softcore stored compressed at compile-time.
+
+<li>
+Reworked Win32 build process. Ficl now builds out-of-the-box on Win32
+as a static library, as a DLL, and as a command-line program,
+in each of the six possible runtime variants (Debug,Release x Singlethreaded,
+Multithreaded,Multithreaded DLL).
+
+<li>
+There's very likely other wonderful things that I've long forgotten
+about. If you notice them, feel free to remind me :)
+
+</ul>
+
+<? ficlVersion("Version 3.03") ?>
+<ul>
+<li>
+Bugfix for floating-point numbers. Floats in compiled code were simply broken.
+
+<li>
+New words: <code>random</code> and <code>seed-random</code>
+
+<li>
+Bugfix: <code>included</code> never closed its file.
+
+<li>
+Bugfix: <code>include</code> was not <code>IMMEDIATE</code>.
+
+<li>
+Un-hid the OO words <code>parse-method</code>, <code>lookup-method</code>, and <code>find-method-xt</code>, as there are perfectly legitimate reasons why you might want to use them.
+
+<li>
+Changed the prefix version of <code>.(</code> to be <code>IMMEDIATE</code> too.
+
+<li>
+Fixed comment in Python softcore builder.
+
+<li>
+Put the <b>doc</b> directory back in to the distribution. (It was missing from 3.02... where'd it go?)
+
+</ul>
+
+
+
+<? ficlVersion("Version 3.02") ?>
+<ul>
+<li>
+Added support for <code>nEnvCells</code> (number of environment cells) to <code>FICL_SYSTEM_INFO</code>.
+
+<li>
+Consolidated <code>context</code> and <code>pExtend</code> pointers of <code>FICL_SYSTEM</code>&#151;VM's <code>pExtend</code> pointer is initialized from the copy in <code>FICL_SYSTEM</code> upon VM creation.
+
+<li>
+Added <code>ficl-robust</code> environment variable.
+
+<li>
+Added <code>FW_ISOBJECT</code> word type.
+
+<li>
+Bugfix: <code>environment?</code> was ignoring the length of the supplied string.
+
+<li>
+Portability cleanup in fileaccess.c.
+
+<li>
+Bugfix in <code>ficlParsePrefix</code>: if the prefix dictionary isn't in the wordlist, the word being examined cannot be a prefix, so return failure.
+
+<li>
+<code>SEE</code> improvements: <code>SEE</code> (and consequently <code>DEBUG</code>) have improved source listings with instruction offsets.
+
+<li>
+It's turned off with the preprocessor, but we have the beginnings of a switch-threaded implementation of the inner loop.
+
+<li>
+Added <code>objectify</code> and <code>?object</code> for use by OO infrastructure.
+
+<li>
+<code>my=[</code> detects object members (using <code>?object</code>) and assumes all other members leave class unchanged.
+
+<li>
+Removed <code>MEMORY-EXT</code> environment variable (there is no such wordset).
+
+<li>
+Ficlwin changes:
+<ul>
+<li>
+Ficlwin character handling is more robust
+
+<li>
+Ficlwin uses multi-system constructs (see ficlthread.c)
+
+</ul>
+
+<li>
+Documentation changes:
+<ul>
+<li>
+Corrected various bugs in docs.
+
+<li>
+Added ficl-ized version of JV Noble's Forth Primer
+
+<li>
+Ficl OO tutorial expanded and revised. Thanks to David McNab for his demo and suggestions.
+
+</ul>
+
+
+</ul>
+
+<? ficlVersion("Version 3.01") ?>
+<ul>
+<li>
+Major contributionss by Larry Hastings (larry@hastings.org):
+<ul>
+<li>
+FILE wordset (fileaccess.c)
+
+<li>
+ficlEvaluate wrapper for ficlExec
+
+<li>
+ficlInitSystemEx makes it possible to bind selectable properties to VMs at create time
+
+<li>
+Python version of softcore builder ficl/softwords/softcore.py
+
+</ul>
+
+<li>
+Environment contains ficl-version (double)
+
+<li>
+?number handles trailing decimal point per DOUBLE wordset spec
+
+<li>
+Fixed broken .env (thanks to Leonid Rosin for spotting this goof)
+
+<li>
+Fixed broken floating point words that depended on evaluation order of stack pops.
+
+<li>
+env-constant
+
+<li>
+env-2constant
+
+<li>
+dictHashSummary is now commented out unless FICL_WANT_FLOAT (thanks to Leonid Rosin again)
+
+<li>
+Thanks to David McNab for pointing out that .( should be IMMEDIATE. Now it is.
+
+</ul>
+
+<? ficlVersion("Version 3.00a") ?>
+
+<ul>
+<li>
+Fixed broken oo.fr by commenting out vcall stuff using FICL_WANT_VCALL. Vcall is still broken.
+
+</ul>
+
+<? ficlVersion("Version 3.00") ?>
+
+<ul>
+<li>
+Added pSys parameter to most ficlXXXX functions for multiple system support. Affected functions:
+<ul>
+<li>dictLookupLoc renamed to ficlLookupLoc after addition of pSys param
+<li>ficlInitSystem returns a FICL_SYSTEM*
+<li>ficlTermSystem
+<li>ficlNewVM
+<li>ficlLookup
+<li>ficlGetDict
+<li>ficlGetEnv
+<li>ficlSetEnv
+<li>ficlSetEnvD
+<li>ficlGetLoc
+<li>ficlBuild
+</ul>
+
+
+<li>Fixed off-by-one bug in ficlParsePrefix
+<li>Ficl parse-steps now work correctly - mods to interpret()
+<li>Made tools.c:isAFiclWord more selective
+<li>Tweaked makefiles and code to make gcc happy under linux
+<li>Vetted all instances of LVALUEtoCELL to make sure they're working on CELL sized operands
+(for 64 bit compatibility)
+</ul>
+
+<? ficlVersion("Version 2.06") ?>
+<ul>
+<li>Debugger changes:
+<ul>
+<li>New debugger command "x" to execute the rest of the command line as ficl
+<li>New debugger command "l" lists the source of the innermost word being debugged
+<li>If you attempt to debug a primitive, it gets executed rather than doing nothing
+<li><code>R.S</code> displays the stack contents symbolically
+<li>Debugger now operates correctly under ficlwin, although ficlwin's key handling leaves a lot to be desired.
+<li><code>SEE</code> listing enhanced for use with the debugger
+</ul>
+<li>Added Guy Carver's changes to oo.fr for VTABLE support
+<li><code>float.c</code> words f&gt; and &gt;f to move floats to and from the param stack, analogous to &gt;r and r&gt;
+<li><code>LOOKUP</code> - Surrogate precompiled parse step for ficlParseWord (this step is hard
+ coded in <code>INTERPRET</code>)
+<li>License text at top of source files changed from LGPL to BSD by request
+<li>Win32 console version now handles exceptions more gracefully rather than crashing - uses win32
+structured exception handling.
+<li>Fixed BASE bug from 2.05 (was returning the value rather than the address)
+<li>Fixed ALLOT bug - feeds address units to dictCheck, which expects Cells. Changed dictCheck
+to expect AU.
+<li>Float stack display word renamed to f.s from .f to be consistent with r.s and .s
+</ul>
+
+<? ficlVersion("Version 2.05") ?>
+<h3>General</h3>
+
+<ul>
+<li>HTML documentation extensively revised
+<li>Incorporated Alpha (64 bit) patches from the freeBSD team.
+<li>Split SEARCH and SEARCH EXT words from words.c to search.c
+<li><a href="ficl_loc.html">2LOCALS</a> defined in <a href="ficl_loc.html#jhlocal">Johns Hopkins local syntax</a> now lose the first '2:' in their names.
+<li>Simple step <a href="ficl_debug.html">debugger</a> (see tools.c)
+<li>The text interpreter is now extensible - this is accomplished through the use
+of <code>ficlAddParseStep()</code>. <code>FICL_MAX_PARSE_STEPS</code> limits the number of parse steps
+(default: 8). You can write a precompiled parse step (see <code>ficlParseNumber</code>) and
+append it to the chain, or you can write one in ficl and use <code>ADD-PARSE-STEP</code>
+to append it. Default parse steps are initialized in <code>ficlInitSystem</code>. You can list
+the parse steps with <code>parse-order ( -- )</code>.
+<li>There is now a FICL_SYSTEM structure. This is a transitional release - version 3.0
+will alter several API prototypes to take this as a parameter, allowing multiple
+systems per process (and therefore multiple dictionaries). For those who use ficl
+under a virtual memory O/S like Linux or Win NT, you can just create multiple ficl
+processes (not threads) instead and save youself the wait.
+<li>Fixes for improved command line operation in testmain.c (Larry Hastings)
+<li>Numerous extensions to OO facility, including a new allot methods, ability
+to catch method invocations (thanks to Daniel Sobral again)
+<li>Incorporated Alpha (64 bit) patches contributed by Daniel Sobral and the freeBSD team
+Ficl is now 64 bit friendly! UNS32 is now FICL_UNS.
+<li>Split SEARCH and SEARCH EXT words from words.c to search.c
+<li>ABORT" now complies with the ANS (-2 THROWs)
+<li>Floating point support contributed by Guy Carver (Enable FICL_WANT_FLOAT in sysdep.h).
+<li>Win32 vtable model for objects (Guy Carver)
+<li>Win32 dll load/call suport (Larry Hastings)
+<li>Prefix support (Larry Hastings) (prefix.c prefix.fr FICL_EXTENDED_PREFIX) makes it
+easy to extend the parser to recignize prefixes like 0x and act on them. Use show-prefixes
+to see what's defined.
+<li>Cleaned up initialization sequence so that it's all in ficlInitSystem, and so that
+a VM can be created successfully before the dictionary is created
+</ul>
+
+<h3>
+Bug fixes</h3>
+
+<ul>
+<li>
+<a href="http://www.taygeta.com/forth/dpans9.htm#9.6.2.0680">ABORT"</a>
+now works correctly (I promise!)
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans6.htm#6.2.2125">REFILL</a> works
+better
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans6.htm#6.1.0710">ALLOT</a>'s
+use of dictCheck corrected (finally)
+</ul>
+
+<h3>
+New words</h3>
+
+<ul>
+<li>
+<a href="http://www.taygeta.com/forth/dpans6.htm#6.2.0415">2r@</a> <a href="http://www.taygeta.com/forth/dpans6.htm#6.2.0410">2r></a> <a href="http://www.taygeta.com/forth/dpans6.htm#6.2.0340">2>r</a>
+(CORE EXT)
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.0440">2VARIABLE</a>
+(DOUBLE)
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans16.htm#16.6.2.1985">ORDER</a>
+now lists wordlists by name
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans15.htm#15.6.1.0220">.S</a> now
+displays all stack entries on one line, like a stack comment
+
+<li>
+<a href="ficl.html#wid-get-name"><tt>wid-get-name</tt>&nbsp;</a>&nbsp;
+given a wid, returns the address and count of its name. If no name, count
+is 0
+
+<li>
+<tt><a href="ficl.html#wid-set-name">wid-set-name</a></tt>&nbsp;
+set optional wid name pointer to the \0 terminated string address specified.
+
+<li>
+<tt><a href="ficl.html#ficlwordlist">ficl-named-wordlist</a></tt> creates
+a ficl-wordlist and names it. This is now used in <tt>vocabulary</tt> and
+<tt><a href="ficl.html#ficlvocabulary">ficl-vocabulary</a></tt>&nbsp;
+
+<li>
+<tt><a href="ficl.html#last-word">last-word</a></tt>&nbsp; returns the
+xt of the word being defined or most recently defined.
+
+<li>
+<tt><a href="ficl.html#qfetch">q@</a></tt> and <tt><a href="ficl.html#qbang">q!</a></tt>
+operate on quadbyte quantities for 64 bit friendliness
+</ul>
+
+<h3>
+New OO stuff</h3>
+
+<ul>
+<li>
+<tt>ALLOT (class method)</tt>
+
+<li>
+<tt>ALLOT-ARRAY (class method)</tt>
+
+<li>
+<tt>METHOD</tt> define method names globally
+
+<li>
+<tt>MY=></tt> early bind a method call to "this" class
+
+<li>
+<tt>MY=[ ]</tt> early bind a string of method calls to "this" class and
+obj members
+
+<li>
+<tt>C-></tt> late bind method invocation with CATCH
+
+<li>
+Metaclass method <tt>resume-class</tt> and instance word <tt>suspend-class</tt>
+create mutually referring classes. Example in string.fr
+
+<li>
+Early binding words are now in the instance-vars wordlist, not visible
+unless defining a class.
+
+<li>Support for refs to classes with VTABLE methods (contributed by Guy Carver). Guy writes:
+<p>
+My next favorite change is a set of VCALL words that allow me
+to call C++ class virtual methods from my forth classes. This
+is accomplished by interfacing with the VTABLE of the class. The
+class instance currently must be created on the C++ side.
+C++ places methods in the VTABLE in order of declaration in the
+header file. To use this in FICL one only needs to ensure
+that the VCALL: declerations occur in the same order. I use this
+quite a bit to interface with the C++ classes. When I need access
+to a method I make sure it is virtual (Even if it ultimately will
+not be). I use Visual C++ 6.0 and have not tested this under
+any other compiler but I believe VTABLE implementation is standard.
+</p><p>
+Here is an example of how to use VCALL:
+</p>
+<b>C++ class declaration</b>
+<pre>
+class myclass
+{
+public:
+ myclass();
+ virtual ~myclass();
+ virtual void Test( int iParam1 );
+ virtual int Test( int iParam1, char cParam2 );
+ virtual float Test();
+};
+</pre>
+<b>ficl class declaration</b>
+<pre>
+object subclass myfclass hasvtable \ hasvtable adds 4 to the offset to
+ \ accommodate for the VTABLE pointer.
+0 VCALL: Destructor() \ VCALL: ( ParamCount -<MethodName>- )
+1 VCALL: Test(int) \ Test takes 1 int parameter.
+2 VCALLR: iTest(int,char) \ iTest takes 2 parameters and returns an int.
+0 VCALLF: fTest() \ fTest takes no parameters and returns a float.
+end-class
+
+MyCAddress \ Primitive to return a pointer to a "myclass" instance.
+myfclass -> ref dude \ This makes the MyCAddress pointer a myfclass
+ \ instance with the name "dude".
+1234 dude -> Test(int) \ Calls the virtual method Test.
+1234 1 dude -> iTest(int,char) . \ Calls iTest and emits the returned int.
+dude -> fTest() f. \ Calls fTest and emits the returned float.
+</pre>
+
+</ul>
+
+<? ficlVersion("Version 2.04") ?>
+
+<h3>ficlwin</h3>
+
+<ul>
+<li>
+Catches exceptions thrown by VM in ficlThread (0 @ for example) rather
+than passing them off to the OS.&nbsp;
+</ul>
+
+<h3>
+ficl bugs vanquished</h3>
+
+<ul>
+<li>
+Fixed leading delimiter bugs in s" ." .( and ( (reported by Reuben Thomas)
+
+<li>
+Makefile tabs restored (thanks to Michael Somos)
+
+<li>
+ABORT" now throws -2 per the DPANS (thanks to Daniel Sobral for sharp eyes
+again)&nbsp;
+
+<li>
+ficlExec does not print the prompt string unless (source-id == 0)
+
+<li>
+Various fixes contributed by the FreeBSD team.
+</ul>
+
+<h3>
+ficl enhancements</h3>
+
+<ul>
+<li>
+Words.c: modified ficlCatch to use vmExecute and vmInnerLoop (request of
+Daniel Sobral) Added vmPop and vmPush functions (by request of Lars Krueger
+) in vm.c These are shortcuts to the param stack. (Use LVALUEtoCELL to
+get things into CELL form)&nbsp;
+
+<li>
+Added function vmGetStringEx with a flag to specify whether or not to skip
+lead delimiters
+
+<li>
+Added non-std word: number?
+
+<li>
+Added CORE EXT word AGAIN (by request of Reuben Thomas)&nbsp;
+
+<li>
+Added double cell local (2local) support
+
+<li>
+Augmented Johns Hopkins local syntax so that locals whose names begin with
+char 2 are treated as 2locals (OK - it's goofy, but handy for OOP)
+
+<li>
+C-string class revised and enhanced - now dynamically sized
+
+<li>
+C-hashstring class derived from c-string computes hashcode too.
+</ul>
+
+
+<? ficlVersion("Version 2.03") ?>
+
+This is the first version of Ficl that includes contributed code. Thanks
+especially to Daniel Sobral, Michael Gauland for contributions and bug
+finding.
+<p>
+New words:
+<ul>
+<li>
+<tt><a href="#clock">clock</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FICL)</tt>
+
+<li>
+<tt><a href="#clockspersec">clocks/sec</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FICL)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.1230">dnegate</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(DOUBLE)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905">ms</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FACILITY EXT - replaces MSEC <i>ficlWin only</i>)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.2275">throw</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(EXCEPTION)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.0875">catch</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(EXCEPTION)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.0707">allocate</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(MEMORY)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.1605">free</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(MEMORY)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.2145">resize</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(MEMORY)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans6.htm#6.2.2440">within</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(CORE EXT)</tt>
+
+<li>
+<tt><a href="#alloc">alloc</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(class method)</tt>
+
+<li>
+<tt><a href="#allocarray">alloc-array</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(class method)</tt>
+
+<li>
+<tt><a href="#oofree">free</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(class method)</tt>
+</ul>
+
+Bugs Fixed:
+<ul>
+<li>
+Bug fix in isNumber(): used to treat chars between 'Z' and 'a' as valid
+in base 10... (harmless, but weird)
+
+<li>
+ficlExec pushes the <i>ip</i> and <tt>interpret</tt>s at the right times
+so that nested calls to ficlExec behave the way you'd expect them to.
+
+<li>
+<tt>evaluate</tt> respects count parameter, and also passes exceptional
+return conditions back out to the calling instance of ficlExec.
+
+<li>
+VM_QUIT now clears the locals dictionary in ficlExec.
+</ul>
+Ficlwin Enhancements&nbsp;
+<ul>
+<li>
+File Menu: recent file list and Open now load files.
+
+<li>
+Text ouput function is now faster through use of string caching. Cache
+flushes at the end of each line and each time ficlExec returns.
+
+<li>
+Edit/paste now behaves more reasonably for text. File/open loads the specified
+file.
+
+<li>
+Registry entries specify dictionary and stack sizes, default window placement,
+and whether or not to create a splitter for multiple VMs. See HKEY_CURRENT_USER/Software/CodeLab/ficlwin/Settings
+</ul>
+Ficl Enhancements&nbsp;
+<ul>
+<li>
+This version includes changes to make it <b>64 bit friendly</b>. This unfortunately
+meant that I had to tweak some core data types and structures. I've tried
+to make this transparent to 32 bit code, but a couple of things got renamed.
+INT64 is now DPINT. UNS64 is now DPUNS. FICL_INT and FICL_UNS are synonyms
+for INT32 and UNS32 in 32 bit versions, but a are obsolescent. Please use
+the new data types instead. Typed stack operations on INT32 and UNS32 have
+been renamed because they operate on CELL scalar types, which are 64 bits
+wide on 64 bit systems. Added BITS_PER_CELL, which has legal values of
+32 or 64. Default is 32.
+
+<li>
+ficl.c: Added ficlExecXT() - executes an xt completely before returning,
+passing back any exception codes generated in the process. Normal exit
+code is VM_INNEREXIT.
+
+<li>
+ficl.c: Added ficlExecC() to operate on counted strings as opposed to zero
+terminated ones.
+
+<li>
+ficlExec pushes ip and executes interpret at the right times so that nested
+calls to ficlExec behave the way you'd expect them to.
+
+<li>
+ficlSetStackSize() allows specification of stack size at run-time (affects
+subsequent invocations of ficlNewVM()).
+
+<li>
+vm.c: vmThrow() checks for (pVM->pState != NULL) before longjmping it.
+vmCreate nulls this pointer initially.&nbsp;
+
+<li>
+EXCEPTION wordset contributed by Daniel Sobral of FreeBSD
+
+<li>
+MEMORY-ALLOC wordset contributed by Daniel Sobral, too. Added class methods
+<tt>alloc</tt>
+and <tt>alloc-array</tt> in softwords/oo.fr to allocate objects from the
+heap.
+
+<li>
+Control structure match check upgraded (thanks to Daniel Sobral for this
+suggestion). Control structure mismatches are now errors, not warnings,
+since the check accepts all syntactally legal constructs.
+
+<li>
+Added vmInnerLoop() to vm.h. This function/macro factors the inner&nbsp;
+interpreter out of ficlExec so it can be used in other places. Function/macro
+behavior is conditioned on INLINE_INNER_LOOP in sysdep.h. Default: 1 unless
+_DEBUG is set. In part, this is because VC++ 5 goes apoplectic when trying
+to compile it as a function. See&nbsp;
+
+<br>comments in vm.c
+<li>
+EVALUATE respects the count parameter, and also passes exceptional return
+conditions back out to the calling instance of ficlExec.
+
+<li>
+VM_QUIT clears locals dictionary in ficlExec()
+
+<li>
+Added Michael Gauland's ficlLongMul and ficlLongDiv and support routines
+to math64.c and .h. These routines are coded in C, and are compiled only
+if PORTABLE_LONGMULDIV == 1 (default is 0).
+
+<li>
+Added definition of ficlRealloc to sysdep.c (needed for memory allocation
+wordset). If your target OS supports realloc(), you'll probably want to
+redefine ficlRealloc in those terms. The default version does ficlFree
+followed by ficlMalloc.
+
+<li>
+testmain.c: Changed gets() in testmain to fgets() to appease the security
+gods.
+
+<li>
+testmain: <tt>msec</tt> renamed to <tt><a href="#ficlms">ms</a></tt> in
+line with the ANS
+
+<li>
+softcore.pl now removes comments &amp; spaces at the start and end of lines.
+As a result: sizeof (softWords) == 7663 bytes (used to be 20000)&nbsp;
+and consumes 11384 bytes of dictionary when compiled
+
+<li>
+Deleted license paste-o in readme.txt (oops).
+</ul>
+
+
+<? ficlVersion("Version 2.02") ?>
+
+New words:
+<ul>
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans6.htm#6.2.1850">marker</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(CORE EXT)</tt>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans15.htm#15.6.2.1580">forget</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(TOOLS EXT)</tt>
+
+<li>
+<tt><a href="#ficlforgetwid">forget-wid</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FICL)</tt>
+
+<li>
+<tt><a href="#ficlwordlist">ficl-wordlist</a>&nbsp;&nbsp;&nbsp;&nbsp; (FICL)</tt>
+
+<li>
+<tt><a href="#ficlvocabulary">ficl-vocabulary</a>&nbsp;&nbsp; (FICL)</tt>
+
+<li>
+<tt><a href="#ficlhide">hide</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FICL)</tt>
+
+<li>
+<tt><a href="#ficlhidden">hidden</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(FICL)</tt>
+
+<li>
+<a href="#jhlocal">Johns Hopkins local variable syntax</a> (as best I can
+determine)
+</ul>
+Bugs Fixed&nbsp;
+<ul>
+<li>
+<tt>forget</tt> now adjusts the dictionary pointer to remove the name of
+the word being forgotten (name chars come before the word header in ficl's
+dictionary)
+
+<li>
+<tt>:noname</tt> used to push the colon control marker and its execution
+token in the wrong order
+
+<li>
+<tt>source-id</tt> now behaves correctly when loading a file.
+
+<li>
+<tt>refill</tt> returns zero at EOF (Win32 load). Win32 <tt><a href="#ficlload">load</a></tt>
+command continues to be misnamed. Really ought to be called <tt>included</tt>,
+but does not exactly conform to that spec either (because <tt>included</tt>
+expects a string signature on the stack, while Ficl's <tt><a href="#ficlload">load</a></tt>
+expects a filename upon invocation). The "real" <tt>LOAD</tt> is a <tt>BLOCK</tt>
+word.
+</ul>
+Enhancements (IMHO)&nbsp;
+<ul>
+<li>
+dictUnsmudge no longer links anonymous definitions into the dictionary
+
+<li>
+<tt>oop</tt> is no longer the default compile wordlist at startup, nor
+is it in the search order. Execute <b><tt>also oop definitions</tt></b>
+to use Ficl OOP.
+
+<li>
+Revised oo.fr extensively to make more use of early binding
+
+<li>
+Added <tt>meta</tt> - a constant that pushes the address of metaclass.
+See oo.fr for examples of use.
+
+<li>
+Added classes: <tt>c-ptr&nbsp; c-bytePtr&nbsp; c-2bytePtr&nbsp; c-cellPtr
+</tt>These
+classes model pointers to non-object data, but each knows the size of its
+referent.
+</ul>
+
+
+<? ficlVersion("Version 2.01") ?>
+
+<ul>
+<li>
+Bug fix: <tt>(local)</tt> used to leave a value on the stack between the
+first and last locals declared. This value is now stored in a static.
+
+<li>
+Added new local syntax with parameter re-ordering. <a href="#newlocal">See
+description below</a>. (No longer compiled in version 2.02, in favor of
+the Johns Hopkins syntax)
+</ul>
+
+
+<? ficlVersion("Version 2.0") ?>
+
+<ul>
+<li>
+New ANS Forth words: <tt>TOOLS</tt> and part of <tt>TOOLS EXT, SEARCH</tt>
+and <tt>SEARCH EXT, LOCALS</tt> and <tt>LOCALS EXT</tt> word sets, additional
+words from <tt>CORE EXT, DOUBLE</tt>, and <tt>STRING</tt>. (See the function
+ficlCompileCore in words.c for an alphabetical list by word set).
+
+<li>
+Simple <tt>USER</tt> variable support - a user variable is a virtual machine
+instance variable. User variables behave as <tt>VARIABLE</tt>s in all other
+respects.
+
+<li>
+Object oriented syntax extensions (see below)
+
+<li>
+Optional stack underflow and overflow checking in many CORE words (enabled
+when FICL_ROBUST >= 2)
+
+<li>
+Various bug fixes
+</ul>
+
+
+
+<? ficlPageFooter() ?>
diff --git a/doc/source/upgrading.ht b/doc/source/upgrading.ht
new file mode 100644
index 000000000000..9d9b5f26a022
--- /dev/null
+++ b/doc/source/upgrading.ht
@@ -0,0 +1,349 @@
+<?
+
+ficlPageHeader("upgrading ficl")
+
+ficlAddToNavBarAs("Upgrading To 4.0")
+
+def startoldvsnew(extra = None):
+ print "<table width=100%><tr>\n"
+ print "<td bgcolor=#d0d0f0><b>old name</b></td>\n"
+ print "<td bgcolor=#e0e0ff><b>new name</td>\n"
+ if extra != None:
+ print "<td bgcolor=#d0d0f0><b>" + extra + "</td>\n"
+ print "</tr>\n"
+
+def oldvsnew(old, new, extra = None):
+ print "<tr>\n"
+ print "<td bgcolor=#e0e0e0><code>" + old + "</code></td>\n"
+ print "<td bgcolor=#f0f0f0><code>" + new + "</code></td>\n"
+ if extra != None:
+ print "<td bgcolor=#e0e0e0><code>" + extra + "</code></td>\n"
+ print"</tr>\n\n"
+
+
+def endoldvsnew():
+ print "</table><p>\n"
+
+?>
+
+Ficl 4.0 is smaller, faster, and more capable than any previous
+version. For more information on why Ficl 4.0 is so gosh-darned
+swell, see the <a href=index.html#WhatsNewInFicl4.0>What's New In Ficl 4.0?</a>
+section of the overview.
+<p>
+
+
+Since the Ficl API has changed so dramatically, you can't just drop
+the new Ficl source. You have two basic choices:
+<a href=#compatibility>use the <code>FICL_WANT_COMPATIBILITY</code> support</a>, and
+<a href=#newapi>switching to the new API</a>.
+<p>
+
+Note that using <i>either</i> of these choices <i>requires</i>
+that you recompile your application. You cannot build Ficl 4 into
+a shared library or DLL and use it with an application expecting
+Ficl 3.0. Stated another way: Ficl 4 is <i>source</i> compatible
+but not <i>binary</i> compatible with Ficl 3.
+
+
+<a name=oldnames>
+<? ficlHeader1("Using <code>FICL_WANT_COMPATIBILITY</code>") ?>
+</a>
+
+
+If you want to get Ficl 4.0 up and running in your project as quickly
+as possible, <code>FICL_WANT_COMPATIBILITY</code> is what you'll want to use.
+There are two easy steps, one of which you might be able to skip:
+<p>
+
+<ol>
+
+<li>
+Set the C preprocessor constant <code>FICL_WANT_COMPATIBILITY</code> to 1.
+The best way is by adding the following line to <code>ficllocal.h</code>:
+<pre>
+ #define FICL_WANT_COMPATIBILITY (1)
+</pre>
+
+
+<li>
+
+<i>If</i> you use a custom <code>ficlTextOut()</code> function, you'll
+have to rename it, and explicitly specify it to Ficl. Renaming it is
+necessary, because the Ficl compatibility layer also provides one for
+code that called <code>ficlTextOut()</code> directly (instead of calling
+<code>vmTextOut()</code> as it should have).
+We recommend renaming your function to <code>ficlTextOutLocal()</code>, as
+we have have provided a prototype for this function for you in <code>ficlcompatibility.h</code>.
+This will save you the trouble of defining your own prototype, ensuring you get
+correct name decoration / linkage, etc.
+
+<p>
+
+There are two methods you can use to specify your <code>ficlTextOut()</code>
+function:
+<ol>
+
+<li>
+Specify it in the <code>FICL_INIT_INFO</code> structure passed in to
+<code>ficlInitSystem()</code>. This is the preferred method, as it ensures
+you will see the results of Ficl's initialization code, and it will be
+automatically passed in to every newly created VM.
+
+<li>
+Set it explicitly in every VM by calling <code>vmSetTextOut()</code> and
+passing it in.
+
+</ol>
+<p>
+
+<b>Note:</b> Any other method, such as setting it by hand in the
+<code>FICL_SYSTEM</code> or <code>FICL_VM</code> structures,
+will <b>not</b> work. There is a special compatibility layer for old-style
+<code>OUTFUNC</code> functions, but it is only invoked properly when you
+use one of the two methods mentioned above.
+
+
+</ol>
+
+<p>
+
+This <i>should</i> be sufficient for you to recompile-and-go
+with Ficl 4. If it's not, please let us know, preferably including a
+suggested solution to the problem.
+
+
+<a name=newapi>
+<? ficlHeader1("Using The New API") ?>
+</a>
+
+Since most (all?) of the external symbols have changed names since the 3.0 series,
+here is a quick guide to get you started on renaming everything. This is by no
+means an exhaustive list; this is meant to guide you towards figuring out what
+the new name <i>should</i> be. (After all, part of the point of this massive
+renaming was to make all the external symbols consistent.)
+<p>
+
+
+
+
+<? ficlHeader2("Types") ?>
+
+Every external type has been renamed. They all begin with the
+word <code>ficl</code>, and they use mixed case (instead of all upper-case,
+which is now reserved for macros). Also, the confusingly-named
+string objects have been renamed:
+<code>FICL_STRING</code> is now <code>ficlCountedString</code>, as it
+represents a "counted string" in the language, and
+the more commonly-used <code>STRINGINFO</code> is now simply
+<code>ficlString</code>.
+
+<?
+
+startoldvsnew()
+
+oldvsnew("FICL_SYSTEM", "ficlSystem")
+oldvsnew("FICL_VM", "ficlVm")
+oldvsnew("FICL_SYSTEM_INFO", "ficlSystemInformation")
+oldvsnew("FICL_WORD", "ficlWord")
+oldvsnew("IPTYPE", "ficlIp")
+oldvsnew("FICL_CODE", "ficlPrimitive")
+oldvsnew("OUTFUNC", "ficlOutputFunction")
+oldvsnew("FICL_DICTIONARY", "ficlDictionary")
+oldvsnew("FICL_STACK", "ficlStack")
+oldvsnew("STRINGINFO", "ficlString")
+oldvsnew("FICL_STRING", "ficlCountedString")
+
+endoldvsnew()
+
+?>
+
+<? ficlHeader2("Structure Members") ?>
+
+In addition, many structure names have changed. To help ease the heartache,
+we've also added some accessor macros. So, in case they change in the future,
+your code might still compile (hooray!).
+<?
+
+startoldvsnew("accessor")
+
+oldvsnew("pExtend", "context", "ficlVmGetContext(), ficlSystemGetContext()")
+oldvsnew("pStack", "dataStack", "ficlVmGetDataStack()")
+oldvsnew("fStack", "floatStack", "ficlVmGetFloatStack()")
+oldvsnew("rStack", "returnStack", "ficlVmGetReturnStack()")
+
+endoldvsnew()
+
+?>
+
+<? ficlHeader2("Callback Functions") ?>
+
+Text output callbacks have changed in two major ways:
+
+<ul>
+
+<li>
+They no longer take a VM pointer; they now take a <code>ficlCallback</code> structure.
+This allows output to be printed before a VM is defined, or in circumstances where a
+VM may not be defined (such as an assertion failure in a <code>ficlSystem...()</code> function).
+
+<li>
+They no longer take a flag indicating whether or not to add a "newline".
+Instead, the function must output a newline whenever it encounters
+a <code>\n</code> character in the text.
+
+</ul>
+
+If you don't want to rewrite your output function yet, you can
+"thunk" the new-style call to the old-style. Just pass in <code>ficlOldnamesCallbackTextOut</code>
+as the name of the output function for the system and VM, and then set
+the <code>thunkedTextout</code> member of the <code>ficlSystem</code>
+or <code>ficlVm</code> to your old-style text output function.
+
+
+<? ficlHeader2("Renamed Macros") ?>
+
+<?
+
+startoldvsnew()
+
+oldvsnew("PUSHPTR(p)", "ficlStackPushPointer(vm->dataStack, p)")
+oldvsnew("POPUNS()", "ficlStackPopUnsigned(vm->dataStack)")
+oldvsnew("GETTOP()", "ficlStackGetTop(vm->dataStack)")
+
+oldvsnew("FW_IMMEDIATE", "FICL_WORD_IMMEDIATE")
+oldvsnew("FW_COMPILE", "FICL_WORD_COMPILE_ONLY")
+
+oldvsnew("VM_INNEREXIT", "FICL_VM_STATUS_INNER_EXIT")
+oldvsnew("VM_OUTOFTEXT", "FICL_VM_STATUS_OUT_OF_TEXT")
+oldvsnew("VM_RESTART", "FICL_VM_RESTART")
+
+
+endoldvsnew()
+
+?>
+
+<? ficlHeader2("<code>ficllocal.h</code>") ?>
+
+One more note about macros. Ficl now ships with a standard place for
+you to tweak the Ficl compile-time preprocessor switches such as
+<code>FICL_WANT_COMPATIBILITY</code> and <code>FICL_WANT_FLOAT</code>.
+It's a file called <code>ficllocal.h</code>, and we guarantee that it
+will always ship empty (or with only comments). We suggest that you
+put all your local changes there, rather than editing <code>ficl.h</code>
+or editing the makefile. That should make it much easier to integrate
+future Ficl releases into your product&mdash;all you need do is preserve
+your tweaked copy of <code>ficllocal.h</code> and replace the rest.
+
+
+<? ficlHeader2("Renamed Functions") ?>
+
+Every function that deals primarily with a particular structure
+is now named after that structure. For instance, any function
+that takes a <code>ficlSystem</code> as its first argument is
+named <code>ficlSystem<i>Something</i>()</code>. Any function
+that takes a <code>ficlVm</code> as its first argument is
+named <code>ficlVm<i>Something</i>()</code>. And so on.
+<p>
+
+Also, functions that create a new object are always
+called <code>Create</code> (not <code>Alloc</code>, <code>Allot</code>, <code>Init</code>, or <code>New</code>).
+Functions that create a new object are always
+called <code>Destroy</code> (not <code>Free</code>, <code>Term</code>, or <code>Delete</code>).
+<p>
+
+
+<?
+
+startoldvsnew()
+
+oldvsnew("ficlInitSystem()", "ficlSystemCreate()")
+oldvsnew("ficlTermSystem()", "ficlSystemDestroy()")
+oldvsnew("ficlNewVM()", "ficlSystemCreateVm()")
+oldvsnew("ficlFreeVM()", "ficlVmDestroy()")
+oldvsnew("dictCreate()", "ficlDictionaryCreate()")
+oldvsnew("dictDelete()", "ficlDictionaryDestroy()")
+
+endoldvsnew()
+
+?>
+<p>
+
+All functions exported by Ficl now start with the word <code>ficl</code>.
+This is a <i>feature</i>, as it means the Ficl project will no longer
+pollute your namespace.
+
+<?
+
+startoldvsnew()
+
+oldvsnew("PUSHPTR(p)", "ficlStackPushPointer(vm->dataStack, p)")
+oldvsnew("POPUNS()", "ficlStackPopUnsigned(vm->dataStack)")
+oldvsnew("GETTOP()", "ficlStackGetTop(vm->dataStack)")
+oldvsnew("ltoa()", "ficlLtoa()")
+oldvsnew("strincmp()", "ficlStrincomp()")
+
+endoldvsnew()
+
+?>
+
+
+
+<? ficlHeader2("Removed Functions") ?>
+
+A few entry points have simply been removed.
+For instance, functions specifically managing a system's <code>ENVIRONMENT</code>
+settings have been removed, in favor of managing the system's
+<code>environment</code> dictionary directly:
+<?
+
+startoldvsnew()
+
+oldvsnew("ficlSystemSetEnvironment(system)", "ficlDictionarySetConstant(ficlSystemGetEnvironment(system), ...)")
+oldvsnew("ficlSystemSet2Environment(system)", "ficlDictionarySet2Constant(ficlSystemGetEnvironment(system), ...)")
+
+endoldvsnew()
+
+?>
+
+
+In a similar vein, <code>ficlSystemBuild()</code> has been removed in favor
+of using <code>ficlDictionarySetPrimitive()</code> directly:
+
+<?
+startoldvsnew()
+oldvsnew("ficlSystemBuild(system, ...)", "ficlDictionarySetPrimitive(ficlSystemGetDictionary(system), ...)")
+endoldvsnew()
+?>
+
+Finally, there is no <i>exact</i> replacement for <code>ficlExec()</code>. 99% of the code
+that called <code>ficlExec()</code> never bothered to manage <code>SOURCE-ID</code> properly.
+If you were calling <code>ficlExec()</code>, and you weren't changing <code>SOURCE-ID</code>
+(or <code>vm->sourceId</code>) to match, you should replace those calls with <code>ficlVmEvaluate()</code>,
+which will manage <code>SOURCE-ID</code> for you.
+<p>
+
+There <i>is</i> a function that takes the place of <code>ficlExec()</code> which doesn't change
+<code>SOURCE-ID</code>: <code>ficlVmExecuteString()</code>. However, instead of taking a
+straight C string (a <code>char *</code>), it takes a <code>ficlString *</code> as its
+code argument. (This is to discourage its use.)
+
+
+<?
+ficlHeader1("Internal Changes")
+?>
+
+<b>Note:</b> none of these changes should affect you. If they do, there's probably
+a problem somewhere. Either Ficl's API doesn't abstract away something enough, or
+you are approaching a problem the wrong way. Food for thought.
+<p>
+
+There's only one internal change worth noting here.
+The top value on a Ficl stack used to be at (to use the modern structure names)
+<code>stack->top[-1]</code>. It is now at <code>stack->top[0]</code>.
+In other words, the "stack top" pointer used to point <i>past</i> the top
+element; it now points <i>at</i> the top element. (Pointing <i>at</i> the
+top element is not only less confusing, it is also faster.)
+
+</body>
+</html>