home: hub: 9ficl

Download patch

ref: ce2526daa8a2145efa1a242c39d04b512223d677
parent: f6e68cc9b5494b83db49fca97b7e25b9b39ef5e0
author: jsadler <jsadler@ficl.sf.net>
date: Tue Jun 6 23:43:23 CDT 2000

*** empty log message ***

--- /dev/null
+++ b/doc/ficl_oop.html
@@ -1,0 +1,1213 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Author" content="john sadler">
+   <meta name="Description" content="the coolest embedded scripting language ever">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+   <title>ficl release notes</title>
+</head>
+<body>
+
+<center>
+<h1>
+<b>Object Oriented Programming in ficl</b></h1></center>
+
+<table BORDER=0 CELLSPACING=3 WIDTH="600" >
+<tr>
+<td><b>Forth Inspired Command Language&nbsp;</b></td>
+
+<td ROWSPAN="4"><img SRC="ficl_logo.jpg" height=64 width=64></td>
+</tr>
+
+<tr>
+<td><b>Author: John Sadler (<a href="mailto:john_sadler@alum.mit.edu">john_sadler@alum.mit.edu</a>)</b></td>
+</tr>
+
+<tr>
+<td><b>This file created: 6 June 2000</b></td>
+</tr>
+
+<tr>
+<td><b>Revised:</b></td>
+</tr>
+</table>
+
+<h2>
+Contents</h2>
+
+<ul>
+<li>
+<a href="#objects">Object Oriented Programming in ficl</a></li>
+
+<li>
+<a href="#ootutorial">Ficl OO Tutorial</a></li>
+
+<li>
+<a href="#cstring">Ficl String Classes</a></li>
+
+<li>
+<a href="ficl.html#oopgloss">OOP glossary</a></li>
+
+<ul>&nbsp;
+<li>
+<a href="#glossinstance">Instance variable glossary</a></li>
+
+<li>
+<a href="#glossclass">Class methods glossary</a></li>
+
+<li>
+<a href="#objectgloss">Object base class methods glossary</a></li>
+
+<li>
+<a href="#stockclasses">Supplied Classes</a></li>
+</ul>
+</ul>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="objects"></a>Object Oriented Programming in ficl</h2>
+
+<h3>
+Review of OO ideas</h3>
+Click <a href="oo_in_c.html#review">here</a> for a short review of OO ideas
+and implementations in other languages
+<h3>
+Design goals of Ficl OO syntax</h3>
+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.&nbsp;
+<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>
+
+<li>
+Ficl OOP supports single inheritance, aggregation, and arrays of objects.</li>
+
+<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>
+
+<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>
+
+<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.</li>
+</ul>
+
+<h3>
+Acknowledgements</h3>
+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.&nbsp;</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+Ficl Object Model</h3>
+All classes in Ficl are derived from the common base class <tt><a href="#objectgloss">OBJECT</a></tt>.
+All classes are instances of <tt><a href="#glossclass">METACLASS</a></tt>.
+This means that classes are objects, too. <tt>METACLASS</tt> implements
+the methods for messages sent to classes. Class methods create instances
+and subclasses, and give information about the class. Classes have exactly
+three elements:&nbsp;
+<ul>
+<li>
+The address ( <tt>.CLASS</tt> ) of a parent class, or zero if it's a base
+class (only <tt>OBJECT</tt> and <tt>METACLASS</tt> have this property)</li>
+
+<li>
+The size ( <tt>.SIZE</tt> ) in address units of an instance of the class</li>
+
+<li>
+A wordlist ID ( <tt>.WID</tt> ) for the methods of the class</li>
+</ul>
+In the figure below, <tt>METACLASS</tt> and <tt>OBJECT</tt> are 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.&nbsp;
+<p>Note for the curious: <tt>METACLASS</tt> behaves like a class - 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 <tt>METACLASS</tt>
+as an instance of itself.&nbsp;
+<br>&nbsp;</td>
+</tr>
+</table>
+
+<p><img SRC="ficl_oop.jpg" VSPACE=10 height=442 width=652>
+<br>&nbsp;
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="ootutorial"></a>Ficl OO Syntax Tutorial</h2>
+
+<h3>
+Introduction</h3>
+Ficl objects associate a class with an instance (really the storage for
+one set of instance variables). This is done explicitly, in that any Ficl
+object is represented by the cell pair:&nbsp;
+<blockquote><b><tt>( instance-addr class-addr )</tt></b></blockquote>
+on the stack. Whenever a named Ficl object executes, it leaves this "signature".
+All methods 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 vtable 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. Whenever&nbsp; you create an object in Ficl, you specify
+its class. After that, the object always pushes its class and the address
+of its payload (instance variable space) when invoked by name.&nbsp;
+<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 <tt>METACLASS</tt>,
+and all classes inherit from class <tt>OBJECT</tt>. This is confusing at
+first, but it means that Ficl has a very simple syntax for constructing
+and using objects. Class methods include subclassing (<tt>SUB</tt>), creating
+initialized and uninitialized instances (<tt>NEW</tt> and <tt>INSTANCE</tt>),
+and creating reference instances (<tt>REF</tt>). Classes also have methods
+for disassembling their methods (<tt>SEE</tt>), identifying themselves
+(<tt>ID</tt>), and listing their pedigree (<tt>PEDIGREE</tt>). All objects
+inherit methods for initializing instances and arrays of instances, for
+performing array operations, and for getting information about themselves.&nbsp;
+<h3>
+Methods and messages</h3>
+Methods are the chunks of code 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 will
+be bound to different methods in different objects, according to class.
+This separation of messages and methods allows objects to behave polymorphically.
+(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 <b><tt>--></tt></b> that sends messages
+to objects at run-time, and an early-binding operator <b><tt>=></tt></b>
+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,&nbsp; so there's no chance of confusing a message with a regular
+word of the same name.&nbsp;</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+Tutorial (finally!)</h3>
+Since this is a tutorial, I'm assuming you're following along by pasting
+the examples into ficlWin, the Win32 version of Ficl (or some other build
+that includes the OO part of softcore.c). I also assume that you're familiar
+with Forth. If not, please see one of the <a href="#links">references</a>,
+below. Ficl's OOP words are in vocabulary OOP. To put OOP in the search
+order and make it the compilation wordlist from the default search order
+(as set by <tt>ONLY</tt>), type:&nbsp;
+<blockquote><b><tt>ONLY&nbsp;&nbsp; ( reset to default search order )</tt></b>
+<br><b><tt>ALSO OOP DEFINITIONS</tt></b></blockquote>
+To start, we'll work with the two base classes <tt>OBJECT</tt> and <tt>METACLASS</tt>.
+Try this:&nbsp;
+<blockquote><b><tt>metaclass --> methods</tt></b></blockquote>
+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 <tt>METACLASS</tt>, <tt>METACLASS</tt> 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 <tt>methods</tt>.
+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.&nbsp;
+<blockquote><b><tt>object --> sub c-foo</tt></b></blockquote>
+Causes base-class <tt>OBJECT</tt> to derive from itself a new class called
+c-foo. Now we'll add some instance variables and methods to the new class...&nbsp;
+<blockquote><b><tt>cell: m_cell1</tt></b>
+<br><b><tt>4 chars: m_chars</tt></b>
+<br><b><tt>: init&nbsp;&nbsp; ( inst class -- )</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; locals| class inst |</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; 0 inst class --> m_cell1 !</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; inst class --> m_chars 4 0 fill</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; ." initializing an instance of c_foo at "
+inst x. cr</tt></b>
+<br><b><tt>;</tt></b>
+<br><b><tt>end-class</tt></b></blockquote>
+The first two lines add named instance variables to the class, and create
+a method for each. <i>Untyped</i> instance variable methods (like those
+created by <tt>cell: cells: char:</tt> and <tt>chars:</tt>) 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 (we'll
+see below how to aggregate objects, which do know their size). We've also
+defined a method called <tt>init</tt> that clears the instance variables.
+Notice that the method expects the addresses of the class and instance
+when it's called. It stashes those in local variables to avoid stack tricks,
+and puts them onto the stack whenever it calls a method. In this case,
+we're storing zero to the two member variables.&nbsp;
+<p>The <tt>init</tt> method is special for Ficl objects: whenever you create
+an initialized instance using <b><tt>new</tt></b> or <b><tt>new-array</tt></b>,
+Ficl calls the class's <tt>init</tt> method for you on that instance. The
+default <tt>init</tt> method supplied by class <tt>object</tt> clears the
+instance, so we didn't really need to override it in this case (see the
+source code in ficl/softwords/oo.fr).&nbsp;
+<br>Now make an instance of the new class:&nbsp;
+<blockquote><b><tt>c-foo --> new foo-instance</tt></b></blockquote>
+And try a few things...&nbsp;
+<blockquote><b><tt>foo-instance --> methods</tt></b>
+<br><b><tt>foo-instance --> pedigree</tt></b></blockquote>
+Or you could type this with the same effect:&nbsp;
+<blockquote><b><tt>foo-instance 2dup --> methods --> pedigree</tt></b></blockquote>
+Notice that we've overridden the init method supplied by object, and added
+two more methods for the member variables. If you type WORDS, you'll see
+that these methods are not visible outside the context of the class that
+contains them. The method finder --> uses the class to look up methods.
+You can use this word in a definition, as we did in <tt>init</tt>, 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:&nbsp;
+<blockquote><b><tt>c-foo --> see init</tt></b>
+<br>or&nbsp;
+<br><b><tt>foo-instance --> class --> see init</tt></b></blockquote>
+Ficl also provides early binding, but you have to ask for it. Ficl's early
+binding operator pops a class off the stack and compiles the method you've
+named, so that that method executes regardless of the class of object it's
+used on. This can be dangerous, since it 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 init 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 <tt>metaclass</tt>. Here's an example
+from the definition of <tt>metaclass</tt> in oo.fr (don't paste this into
+ficlWin - it's already there):&nbsp;
+<blockquote><b><tt>: new&nbsp;&nbsp; \ ( class metaclass "name" -- )</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; metaclass => instance --> init ;</tt></b></blockquote>
+Try this...&nbsp;
+<blockquote><b><tt>metaclass --> see new</tt></b></blockquote>
+Decompiling the method with <tt>SEE</tt> 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&nbsp; run-time.&nbsp;
+<br>Notice that the early-binding operator requires a class at compile
+time. For this reason, classes are <tt>IMMEDIATE</tt>, 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,&nbsp; and Ficl's OOP syntax.&nbsp;
+<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 <b>ref </b>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 ficlclass.fr):&nbsp;
+<br>&nbsp;
+<blockquote><b><tt>object subclass c-wordlist \ OO model of FICL_HASH</tt></b>
+<br><b><tt>&nbsp;cell: .parent</tt></b>
+<br><b><tt>&nbsp;cell: .size</tt></b>
+<br><b><tt>&nbsp;cell: .hash</tt></b></blockquote>
+
+<blockquote><b><tt>&nbsp;: push&nbsp; drop&nbsp; >search ;</tt></b>
+<br><b><tt>&nbsp;: pop&nbsp;&nbsp; 2drop previous ;</tt></b>
+<br><b><tt>&nbsp;: set-current&nbsp;&nbsp; drop set-current ;</tt></b>
+<br><b><tt>&nbsp;: words&nbsp;&nbsp; --> push&nbsp; words previous ;</tt></b>
+<br><b><tt>end-class</tt></b></blockquote>
+
+<blockquote><b><tt>: named-wid&nbsp;&nbsp; ( "name" -- )&nbsp;</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; wordlist&nbsp; postpone c-wordlist&nbsp;
+metaclass => ref ;</tt></b></blockquote>
+In this case, <tt>c-wordlist</tt> describes Ficl's wordlist structure;
+named-wid creates a wordlist and binds it to a ref instance of <tt>c-wordlist</tt>.
+The fancy footwork with <tt>POSTPONE</tt> and early binding is required
+because classes are immediate. An equivalent way to define named-wid with
+late binding is:&nbsp;
+<blockquote><b><tt>: named-wid&nbsp;&nbsp; ( "name" -- )</tt></b>
+<br><b><tt>&nbsp;&nbsp;&nbsp; wordlist&nbsp; postpone c-wordlist&nbsp;
+--> ref ;</tt></b></blockquote>
+To do the same thing at run-time (and call it my-wordlist):&nbsp;
+<blockquote><b><tt>wordlist&nbsp; c-wordlist --> ref&nbsp; my-wordlist</tt></b></blockquote>
+Now you can deal with the wordlist through the ref instance:&nbsp;
+<blockquote><b><tt>my-wordlist --> push</tt></b>
+<br><b><tt>my-wordlist --> set-current</tt></b>
+<br><b><tt>order</tt></b></blockquote>
+Ficl can also model linked lists and other structures that contain pointers
+to structures of the same or different types. The class constructor word
+<b><tt><a href="#exampleref:">ref:</a></tt></b>
+makes an aggregate reference to a particular class. See the <a href="#glossinstance">instance
+variable glossary</a> for an <a href="#exampleref:">example</a>.&nbsp;
+<p>Ficl can make arrays of instances, and aggregate arrays into class descripions.
+The <a href="#glossclass">class methods</a> <b><tt>array</tt></b> and <b><tt>new-array</tt></b>
+create uninitialized and initialized arrays, respectively, of a class.
+In order to initialize an array, the class must define (or inherit) a reasonable
+<b><tt>init</tt></b>
+method. <b><tt>New-array</tt></b> invokes it on each member of the array
+in sequence from lowest to highest. Array instances and array members use
+the object methods <b><tt>index</tt></b>, <b><tt>next</tt></b>, and <b><tt>prev</tt></b>
+to navigate. Aggregate a member array of objects using <b><tt><a href="#arraycolon">array:</a></tt></b>.
+The objects are not automatically initialized in this case - your class
+initializer has to call <b><tt>array-init</tt></b> explicitly if you want
+this behavior.&nbsp;
+<p>For further examples of OOP in Ficl, please see the source file ficl/softwords/ficlclass.fr.
+This file wraps several Ficl internal data structures in objects and gives
+use examples.&nbsp;</td>
+</tr>
+
+<tr>
+<td>
+<h2>
+<a NAME="cstring"></a>Ficl String classes</h2>
+c-string (ficl 2.04 and later) is a reasonably useful dynamic string class.
+Source code for the class is located in ficl/softwords/string.fr. Features:
+dynamic creation and resizing; deletion, char cout, concatenation, output,
+comparison; creation from quoted string constant (s").
+<p>Examples of use:
+<blockquote>
+<pre><b>c-string --> new homer
+s" In this house, " homer --> set
+s" we obey the laws of thermodynamics!" homer --> cat
+homer --> type</b></pre>
+</blockquote>
+</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="oopgloss"></a>OOP Glossary</h2>
+Note: 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 softwords/oo.fr.&nbsp;
+<dl>
+<dt>
+<b><tt>-->&nbsp;&nbsp; ( instance class "method-name" -- xn )</tt></b></dt>
+
+<dd>
+Late binding: looks up and executes the given method in the context of
+the class on top of the stack.&nbsp;</dd>
+
+<dt>
+<b><tt>=>&nbsp;&nbsp; comp: ( class meta "method-name" -- )&nbsp; exec:
+( inst class -- xn )</tt></b></dt>
+
+<dd>
+Early binding: compiles code to execute the method of the class specified
+at compile time.</dd>
+
+<dt>
+<b><tt>do-do-instance</tt></b></dt>
+
+<dd>
+When executed, causes the instance to push its ( instance class ) stack
+signature. Implementation factor of <b><tt>metaclass --> sub</tt></b>.
+Compiles <b><tt>.do-instance</tt></b> in the context of a class; <tt>.do-instance</tt>
+implements the <tt>does></tt> part of a named instance.&nbsp;</dd>
+
+<dt>
+<b><tt>exec-method&nbsp;&nbsp; ( instance class c-addr u -- xn )</tt></b></dt>
+
+<dd>
+Given the address and length of a message (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.</dd>
+
+<dt>
+<b><tt>find-method-xt&nbsp;&nbsp; ( class "method-name" -- class xt )</tt></b></dt>
+
+<dd>
+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.</dd>
+
+<dt>
+<b><tt>lookup-method&nbsp;&nbsp; ( class c-addr u -- class xt )</tt></b></dt>
+
+<dd>
+Given the address and length of a message (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.</dd>
+
+<dt>
+<b><tt>parse-method&nbsp;&nbsp; comp: ( "method-name" -- )&nbsp; exec:
+( -- c-addr u )</tt></b></dt>
+
+<dd>
+Parse "name" from the input stream and compile code to push its length
+and address when the enclosing definition runs.</dd>
+</dl>
+</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+<a NAME="glossinstance"></a>Instance Variable Glossary</h3>
+<b>Note</b>: these words are only visible when creating a subclass! To
+create a subclass, use the <tt>sub</tt> method on <tt>object</tt> or any
+class derived from it (<i>not</i> <tt>metaclass</tt>). Source code for
+Ficl OOP is in ficl/softwords/oo.fr.&nbsp;
+<ul>
+<li>
+Instance variable words do two things: they create methods that do an 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:</li>
+
+<li>
+<tt>object subclass c-example</tt></li>
+
+<li>
+<tt>&nbsp;&nbsp;&nbsp; cell:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+.cell0</tt></li>
+
+<br><tt>&nbsp;&nbsp;&nbsp; c-4byte&nbsp;&nbsp; obj: .nCells</tt>
+<br><tt>&nbsp; 4 c-4byte array: .quad</tt>
+<br><tt>&nbsp;&nbsp;&nbsp; char:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+.length</tt>
+<br><tt>&nbsp;79 chars:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+.name</tt>
+<br><tt>end-class</tt> This class only defines instance variables, and
+it inherits some methods from <tt>object</tt>. Each untyped instance variable
+(.cell0, .length, .name) 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 <tt>subclass</tt> is shorthand for "<tt>-->
+sub</tt>"&nbsp;</ul>
+
+<dl>
+<dt>
+<b><font face="Courier New"><font size=-1>cell:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+( offset "name" -- offset' )</font></font></b></dt>
+
+<dt>
+<b><font face="Courier New"><font size=-1>Execution:&nbsp; ( -- cell-addr
+)</font></font></b></dt>
+
+<dd>
+Create an untyped instance variable one cell wide. The instance variable
+leaves its payload's address when executed.&nbsp;</dd>
+
+<dt>
+<b><tt>cells:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( offset nCells "name"
+-- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- cell-addr )</tt></b></dt>
+
+<dd>
+Create an untyped instance variable n cells wide.</dd>
+
+<dt>
+<b><tt>char:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( offset "name"
+-- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- char-addr )</tt></b></dt>
+
+<dd>
+Create an untyped member variable one char wide</dd>
+
+<dt>
+<b><tt>chars:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( offset nChars "name"
+-- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- char-addr )</tt></b></dt>
+
+<dd>
+Create an untyped member variable n chars wide.</dd>
+
+<dt>
+<b><tt>obj:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( offset class
+meta "name" -- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- instance class )</tt></b></dt>
+
+<dd>
+Aggregate an uninitialized instance of <b>class</b> as a member variable
+of the class under construction.</dd>
+
+<dt>
+<a NAME="arraycolon"></a><b><tt>array:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+( offset n class meta "name" -- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- instance class )</tt></b></dt>
+
+<dd>
+Aggregate an uninitialized array of instances of the class specified as
+a member variable of the class under construction.</dd>
+
+<dt>
+<a NAME="exampleref:"></a><b><tt>ref:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+( offset class meta "name" -- offset' )</tt></b></dt>
+
+<dt>
+<b><tt>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+Execution:&nbsp; ( -- ref-instance ref-class )</tt></b></dt>
+
+<dd>
+Aggregate a reference to a class instance. There is no way to set the value
+of an aggregated ref - 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:&nbsp;</dd>
+
+<dl>
+<dd>
+<tt>object subclass c-4list</tt></dd>
+
+<dd>
+<tt>c-4list ref: .link</tt></dd>
+
+<dd>
+<tt>c-4byte obj: .payload</tt></dd>
+
+<dd>
+<tt>end-class;</tt></dd>
+
+<dd>
+<tt>address-of-existing-list c-4list --> ref mylist</tt></dd>
+</dl>
+
+<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 c_4list,
+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 - the Ficl methods
+alone take care of storing the class information).&nbsp;</dd>
+
+<dd>
+Note: Since a ref: aggregate can only support one class, it's good for
+modeling static structures, but not appropriate for polymorphism. If you
+want polymorphism, aggregate a c_ref (see classes.fr for source) into your
+class - it has methods to set and get an object.</dd>
+
+<dd>
+By the way, it is also possible to construct a pair of classes that contain
+aggregate pointers to each other. Here's an example:</dd>
+
+<dl>
+<dd>
+<tt>object subclass akbar</tt></dd>
+
+<dd>
+<tt>suspend-class&nbsp;&nbsp;&nbsp;&nbsp; \ put akbar on hold while we
+define jeff</tt></dd>
+
+<dd>
+<tt>object subclass jeff</tt></dd>
+
+<dd>
+<tt>&nbsp;&nbsp;&nbsp; akbar ref: .significant-other</tt></dd>
+
+<dd>
+<tt>&nbsp;&nbsp;&nbsp; ( your additional methods here )</tt></dd>
+
+<dd>
+<tt>end-class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ done with
+jeff</tt></dd>
+
+<dd>
+<tt>akbar --> resume-class&nbsp; \ resume defining akbar</tt></dd>
+
+<dd>
+<tt>&nbsp;&nbsp;&nbsp; jeff ref: .significant-other</tt></dd>
+
+<dd>
+<tt>&nbsp;&nbsp;&nbsp; ( your additional methods here )</tt></dd>
+
+<dl><tt>end-class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; \ done
+with akbar</tt></dl>
+</dl>
+</dl>
+</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+<a NAME="glossclass"></a>Class Methods Glossary</h3>
+These words are methods of <tt>metaclass</tt>. 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 softwords/oo.fr.&nbsp;
+<dl>
+<dt>
+<b><tt>instance&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass "name" -- instance
+class )</tt></b>&nbsp;</dt>
+
+<dd>
+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:</dd>
+
+<dd>
+<tt>c_ref --> instance uninit-ref&nbsp; 2drop</tt></dd>
+
+<dt>
+<b><tt>new&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class
+metaclass
+"name" -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Create an initialized instance of class, giving it the name specified.
+This method calls init to perform initialization.&nbsp;</dd>
+
+<dt>
+<b><tt>array&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( nObj class metaclass
+"name" -- nObjs instance class )</tt></b>&nbsp;</dt>
+
+<dd>
+Create an array of nObj instances of the specified class. Instances are
+not initialized. Example:</dd>
+
+<dd>
+<tt>10 c_4byte --> array&nbsp; 40-raw-bytes&nbsp; 2drop drop</tt></dd>
+
+<dt>
+<b><tt>new-array&nbsp;&nbsp;&nbsp; ( nObj class metaclass "name" -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Creates an initialized array of nObj instances of the class. Same syntax
+as <tt>array</tt></dd>
+
+<dt>
+<a NAME="alloc"></a><b><tt>alloc&nbsp;&nbsp; ( class metaclass -- instance
+class )</tt></b></dt>
+
+<dd>
+Creates an anonymous instance of <b>class</b> from the heap (using a call
+to ficlMalloc() to get the memory). Leaves the payload and class addresses
+on the stack. Usage example:</dd>
+
+<dd>
+<tt>c-ref --> alloc 2constant instance-of-ref</tt></dd>
+
+<dd>
+Creates a double-cell constant that pushes the payload and class address
+of a heap instance of c-ref.</dd>
+
+<dt>
+<a NAME="allocarray"></a><b><tt>alloc-array&nbsp;&nbsp; ( nObj class metaclass
+-- instance class )</tt></b></dt>
+
+<dd>
+Same as new-array, but creates anonymous instances from the heap using
+a call to ficlMalloc(). Each instance is initialized using the class's
+<tt>init</tt>
+method</dd>
+
+<dt>
+<b><tt>ref&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance-addr
+class metaclass "name" -- )</tt></b>&nbsp;</dt>
+
+<dd>
+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.</dd>
+</dl>
+
+<dl>
+<dt>
+<b><tt>sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class
+metaclass -- old-wid addr[size] size )</tt></b></dt>
+
+<dd>
+Derive a subclass. You can add or override methods, and add instance variables.
+Alias: <tt>subclass</tt>. Examples:</dd>
+
+<dl>
+<dd>
+<tt>c_4byte --> sub c_special4byte</tt></dd>
+
+<dd>
+<tt>( your new methods and instance variables here )</tt></dd>
+
+<dd>
+<tt>end-class</tt></dd>
+
+<dd>
+or</dd>
+
+<dd>
+<tt>c_4byte subclass c_special4byte</tt></dd>
+
+<dd>
+<tt>( your new methods and instance variables here )</tt></dd>
+
+<dd>
+<tt>end-class</tt></dd>
+</dl>
+
+<dt>
+<b><tt>.size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass
+-- instance-size )</tt></b>&nbsp;</dt>
+
+<dd>
+Returns address of the class's instance size field, in address units. This
+is a metaclass member variable.</dd>
+
+<dt>
+<b><tt>.super&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass --
+superclass )</tt></b>&nbsp;</dt>
+
+<dd>
+Returns address of the class's superclass field. This is a metaclass member
+variable.</dd>
+
+<dt>
+<b><tt>.wid&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass
+-- wid )</tt></b>&nbsp;</dt>
+
+<dd>
+Returns the address of the class's wordlist ID field. This is a metaclass
+member variable.</dd>
+
+<dt>
+<b><tt>get-size</tt></b></dt>
+
+<dd>
+Returns the size of an instance of the class in address units. Imeplemented
+as</dd>
+
+<dd>
+<tt>: get-size&nbsp;&nbsp; metaclass => .size @ ;</tt></dd>
+
+<dt>
+<b><tt>get-wid</tt></b></dt>
+
+<dd>
+Returns the wordlist ID of the class. Implemented as&nbsp;</dd>
+
+<dd>
+<tt>: get-wid&nbsp;&nbsp; metaclass => .wid @ ;</tt></dd>
+
+<dt>
+<b><tt>get-super</tt></b></dt>
+
+<dd>
+Returns the class's superclass. Implemented as</dd>
+
+<dd>
+<tt>: get-super&nbsp;&nbsp; metaclass => .super @ ;</tt></dd>
+
+<dt>
+<b><tt>id&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (
+class metaclass -- c-addr u )</tt></b>&nbsp;</dt>
+
+<dd>
+Returns the address and length of a string that names the class.</dd>
+
+<dt>
+<b><tt>methods&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Lists methods of the class and all its superclasses</dd>
+
+<dt>
+<b><tt>offset-of&nbsp;&nbsp;&nbsp; ( class metaclass "name" -- offset )</tt></b></dt>
+
+<dd>
+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:</dd>
+
+<dl>
+<dd>
+<tt>metaclass --> offset-of .wid</tt></dd>
+</dl>
+
+<dt>
+<b><tt>pedigree&nbsp;&nbsp;&nbsp;&nbsp; ( class metaclass -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Lists the pedigree of the class (inheritance trail)</dd>
+
+<dt>
+<b><tt>see&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( class
+metaclass "name" -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Decompiles the specified method - obect version of <tt>SEE</tt>, from the
+<tt>TOOLS</tt>
+wordset.</dd>
+</dl>
+</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+<a NAME="objectgloss"></a><tt>object</tt> base-class Methods Glossary</h3>
+These are methods that are defined for all instances by the base class
+<tt>object</tt>.
+The methods include default initialization, array manipulations, aliases
+of class methods, upcasting, and programming tools.&nbsp;
+<dl>
+<dt>
+<b><tt>init&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance
+class -- )</tt>&nbsp;</b></dt>
+
+<dd>
+Default initializer called automatically for all instances created with
+<tt>new</tt>
+or <tt>new-array</tt>. Zero-fills the instance. You do not normally need
+to invoke <tt>init</tt> explicitly.</dd>
+
+<dt>
+<b><tt>array-init&nbsp;&nbsp; ( nObj instance class -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Applies <tt>init</tt> to an array of objects created by <tt>new-array</tt>.
+Note that <tt>array:</tt> does not cause aggregate arrays to be initialized
+automatically. You do not normally need to invoke <tt>array-init</tt> explicitly.</dd>
+
+<dt>
+<a NAME="oofree"></a><b><tt>free&nbsp;&nbsp; ( instance class -- )</tt></b></dt>
+
+<dd>
+Releases memory used by an instance previously created with <tt>alloc</tt>
+or <tt>alloc-array</tt>. Note - 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 <tt>alloc</tt> or <tt>alloc-array</tt>.</dd>
+
+<dt>
+<b><tt>class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance class
+-- class metaclass )</tt></b>&nbsp;</dt>
+
+<dd>
+Convert an object signature into that of its class. Useful for calling
+class methods that have no object aliases.</dd>
+
+<dt>
+<b><tt>super&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance class
+-- instance parent-class )</tt></b>&nbsp;</dt>
+
+<dd>
+Upcast an object to its parent class. The parent class of <tt>object</tt>
+is zero. Useful for invoking an overridden parent class method.</dd>
+
+<dt>
+<b><tt>pedigree&nbsp;&nbsp;&nbsp;&nbsp; ( instance class -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Display an object's pedigree - its chain of inheritance. This is an alias
+for the corresponding class method.</dd>
+
+<dt>
+<b><tt>size&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance
+class -- sizeof(instance) )</tt></b>&nbsp;</dt>
+
+<dd>
+Returns the size, in address units, of one instance. Does not know about
+arrays! This is an alias for the class method <tt>get-size</tt></dd>
+
+<dt>
+<b><tt>methods&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance class -- )</tt></b>&nbsp;</dt>
+
+<dd>
+Class method alias. Displays the list of methods of the class and all superclasses
+of the instance.</dd>
+
+<dt>
+<b><tt>index&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( n instance class
+-- instance[n] class )</tt></b>&nbsp;</dt>
+
+<dd>
+Convert array-of-objects base signature into signature for array element
+n. No check for bounds overflow. Index is zero-based, like C, so&nbsp;</dd>
+
+<dl>
+<dd>
+<tt>0 my-obj --> index</tt>&nbsp;</dd>
+</dl>
+
+<dd>
+is equivalent to&nbsp;</dd>
+
+<dl>
+<dd>
+<tt>my-obj</tt></dd>
+</dl>
+
+<dd>
+Check out the <a href="#minusrot">description of <tt>-ROT</tt></a> for
+help in dealing with indices on the stack.</dd>
+
+<dt>
+<b><tt>next&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance[n]
+class -- instance[n+1] class )</tt></b>&nbsp;</dt>
+
+<dd>
+Convert an array-object signature&nbsp; into the signature of the next
+object in the array. No check for bounds overflow.</dd>
+
+<dt>
+<b><tt>prev&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ( instance[n]
+class -- instance[n-1] class )</tt></b>&nbsp;</dt>
+
+<br>Convert an object signature into the signature of the previous object
+in the array. No check for bounds underflow.</dl>
+</td>
+</tr>
+</table>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h3>
+<a NAME="stockclasses"></a>Supplied Classes (See classes.fr)</h3>
+
+<dl>
+<dt>
+<b><tt>metaclass&nbsp;</tt></b></dt>
+
+<dd>
+Describes all classes of Ficl. Contains class methods. Should never be
+directly instantiated or subclassed. Defined in oo.fr. Methods described
+above.</dd>
+
+<dt>
+<b><tt>object</tt>&nbsp;</b></dt>
+
+<dd>
+Mother of all Ficl objects. Defines default initialization and array indexing
+methods. Defined in oo.fr. Methods described above.</dd>
+
+<dt>
+<b><tt>c-ref</tt>&nbsp;</b></dt>
+
+<dd>
+Holds the signature of another object. Aggregate one of these into a data
+structure or container class to get polymorphic behavior. Methods &amp;
+members:&nbsp;</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; ( inst class -- ref-inst ref-class )</tt></dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( ref-inst ref-class inst class -- )</tt></dd>
+
+<dd>
+<tt>.instance&nbsp;&nbsp; ( inst class -- a-addr ) </tt>cell member that
+holds the instance</dd>
+
+<dd>
+<tt>.class&nbsp;&nbsp; ( inst class -- a-addr ) </tt>cell member that holds
+the class</dd>
+
+<dt>
+<b><tt>c-byte&nbsp;</tt></b></dt>
+
+<dd>
+Primitive class derived from <tt>object</tt>, with a 1-byte payload. Set
+and get methods perform correct width fetch and store. Methods &amp; members:</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; ( inst class -- c )</tt></dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( c inst class -- )</tt></dd>
+
+<dd>
+<tt>.payload&nbsp;&nbsp; ( inst class -- addr ) </tt>member holds instance's
+value</dd>
+
+<dt>
+<b><tt>c-2byte</tt></b>&nbsp;</dt>
+
+<dd>
+Primitive class derived from <tt>object</tt>, with a 2-byte payload. Set
+and get methods perform correct width fetch and store. Methods &amp; members:</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; ( inst class -- 2byte )</tt></dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( 2byte inst class -- )</tt></dd>
+
+<dd>
+<tt>.payload&nbsp;&nbsp; ( inst class -- addr ) </tt>member holds instance's
+value</dd>
+
+<dt>
+<b><tt>c-4byte</tt></b>&nbsp;</dt>
+
+<dd>
+Primitive class derived from <tt>object</tt>, with a 4-byte (cell) payload.
+Set and get methods perform correct width fetch and store. Methods &amp;
+members:</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; ( inst class -- x )</tt></dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( x inst class -- )</tt></dd>
+
+<dd>
+<tt>.payload&nbsp;&nbsp; ( inst class -- addr ) </tt>member holds instance's
+value</dd>
+
+<dt>
+<b><tt>c-ptr</tt></b></dt>
+
+<dd>
+Base class derived from <tt>object</tt> for pointers to non-object types.
+This class is not complete by itself: several methods depend on a derived
+class definition of <tt>@size</tt>. Methods &amp; members:</dd>
+
+<dd>
+<tt>.addr&nbsp;&nbsp; ( inst class -- a-addr )</tt> member variable - holds
+the pointer address</dd>
+
+<dd>
+<tt>get-ptr&nbsp;&nbsp; ( inst class -- ptr )</tt></dd>
+
+<dd>
+<tt>set-ptr&nbsp;&nbsp; ( ptr inst class -- )</tt></dd>
+
+<dd>
+<tt>inc-ptr&nbsp;&nbsp; ( inst class -- )</tt> Adds @size to pointer address</dd>
+
+<dd>
+<tt>dec-ptr&nbsp;&nbsp; ( inst class -- )</tt> Subtracts @size from pointer
+address</dd>
+
+<dd>
+<tt>index-ptr&nbsp;&nbsp; ( i inst class -- )</tt> Adds i*@size to pointer
+address</dd>
+
+<dt>
+<b><tt>c-bytePtr</tt></b></dt>
+
+<dd>
+Pointer to byte derived from c-ptr. Methods &amp; members:</dd>
+
+<dd>
+<tt>@size&nbsp;&nbsp; ( inst class -- size )</tt> Push size of the pointed-to
+thing</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; (&nbsp; inst class -- c ) </tt>Fetch the pointer's
+referent byte</dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( c inst class -- ) </tt>Store c at the pointer address</dd>
+
+<dt>
+<b><tt>c-2bytePtr</tt></b></dt>
+
+<dd>
+Pointer to double byte derived from c-ptr. Methods &amp; members:</dd>
+
+<dd>
+<tt>@size&nbsp;&nbsp; ( inst class -- size )</tt> Push size of the pointed-to
+thing</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; (&nbsp; inst class -- x ) </tt>Fetch the pointer's
+referent 2byte</dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( x inst class -- )</tt> Store 2byte x at the pointer
+address</dd>
+
+<dt>
+<b><tt>c-cellPtr</tt></b></dt>
+
+<dd>
+Pointer to cell derived from c-ptr. Methods &amp; members:</dd>
+
+<dd>
+<tt>@size&nbsp;&nbsp; ( inst class -- size )</tt> Push size of the pointed-to
+thing</dd>
+
+<dd>
+<tt>get&nbsp;&nbsp; (&nbsp; inst class -- x ) </tt>Fetch the pointer's
+referent cell</dd>
+
+<dd>
+<tt>set&nbsp;&nbsp; ( x inst class -- )</tt> Storex at the pointer address</dd>
+
+<dt>
+<b><tt>c-string</tt></b>&nbsp;</dt>
+
+<dd>
+Dynamically allocated string similar to MFC CString (Partial list of methods
+follows)</dd>
+
+<dd>
+<font face="Courier New"><font size=-1>set ( c-addr u 2this -- ) </font></font><font size=+0>Initialize
+buffer to the specified string</font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>get ( 2this -- c-addr u ) Return
+buffer contents as counted string</font></font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>cat ( c-addr u 2this -- ) Append
+given string to end of buffer</font></font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>compare ( 2string 2this -- n ) Return
+result of lexical compare</font></font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>type ( 2this -- ) Print buffer to
+the output stream</font></font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>hashcode ( 2this -- x ) Return hashcode
+of string (as in dictionary)</font></font></dd>
+
+<dd>
+<font face="Courier New"><font size=-1>free ( 2this -- ) Release internal
+buffer</font></font></dd>
+</dl>
+</td>
+</tr>
+</table>
+
+</body>
+</html>
--- /dev/null
+++ b/doc/oo_in_c.html
@@ -1,0 +1,186 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en">
+<html>
+<head>
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+   <meta name="Generator" content="Microsoft Word 97">
+   <meta name="GENERATOR" content="Mozilla/4.73 [en] (Win98; U) [Netscape]">
+   <title>Object Oriented Idioms in C</title>
+</head>
+<body>
+<b><font face="Arial"><font size=+1>Object Oriented
+Idioms in C</font></font></b>
+<br><font face="Arial"><font size=-1>John Sadler</font></font>
+<br><font face="Arial"><font size=-1>10 Aug 98</font></font>
+<p><a NAME="review"></a><b><font face="Arial"><font size=+1>Review of Key
+OO Characteristics</font></font></b>
+<h3>
+<b><i><font face="Arial">Object</font></i></b></h3>
+<font face="Times New Roman,Times"><b>"A package of information and descriptions
+of its manipulation"</b> [<a href="#robson">Robson</a>]</font>
+<p><font face="Times New Roman,Times">Objects separate interface from implementation,
+"what" is wanted (on the outside) from "how" it is accomplished (on the
+inside). This idea of hiding the data inside a package with a fixed set
+of allowed manipulations is called encapsulation. Why? If the object always
+selects how to perform a requested manipulation, you guarantee that the
+procedure and the data it operates on always match.</font>
+<p><font face="Times New Roman,Times">A message describes an operation
+that can be performed on an object. The code that describes how to perform
+an operation on a specific object type is called a method. From the outside,
+objects receive messages. On the inside, these messages are mapped to methods
+that perform appropriate actions for the specific kind of object. An object�s
+interface is the set of messages to which it can respond. For example,
+several object types may have a "dump" method to cause the object to display
+its state. Each kind of object will need a unique method to accomplish
+this. So the message-method idea separates the interface from the implementation.
+The idea that different kinds of objects might invoke different methods
+to respond to the same message is called polymorphism. Methods can be bound
+to messages as soon as the type of the object receiving the message is
+known., or this mapping can wait until run-time.</font>
+<p><font face="Times New Roman,Times">Some languages (notably C++) make
+a syntactic distinction between early and late binding of methods to messages
+(virtual functions are bound late, while all others are bound early � at
+link time). Smalltalk makes no such distinction. The C++ approach has potentially
+dangerous consequences when you manipulate an object through a pointer
+to its parent class. If a method of the superclass is virtual, you get
+late binding to the appropriate function for the object�s class. On the
+other hand, if that method is not virtual, you get early binding to the
+parent class�s definition even if the child class has overridden it. Smalltalk
+adheres rigorously to the idea that the object itself has sole ownership
+of the mapping from methods to messages.</font>
+<h3>
+<b><i><font face="Arial">Class</font></i></b></h3>
+<b><font face="Times New Roman,Times">"A description of one or more similar
+objects"</font></b> [<a href="#robson">Robson</a>]
+<p>A specific object described by a particular class is called an instance
+of the class. A class can be thought of as an object whose members are
+the methods of instances of the class, and whose methods provide for creation,
+initialization, and destruction of an instance. All instances of a particular
+class use the same method to respond to a given message. Classes may define
+other members that are shared by all instances of the class. These are
+called class variables. (In C++, these would be static members.)
+<h3>
+<b><i><font face="Arial">Inheritance</font></i></b></h3>
+<font face="Times New Roman,Times">A means for creating a new object or
+class using an existing one as a starting place and defining only what
+changes. C++ only supports class-based inheritance, but some systems also
+allow objects to inherit directly from other objects. At minimum, inheritance
+requires that the child class override its parent�s name. In addition,
+a child class can:</font>
+<ul>
+<li>
+<font face="Times New Roman,Times">add instance variables</font></li>
+
+<li>
+<font face="Times New Roman,Times">add class variables</font></li>
+
+<li>
+<font face="Times New Roman,Times">define methods for new messages</font></li>
+
+<li>
+<font face="Times New Roman,Times">provide methods for (<b>override</b>)
+messages already handled by the parent class</font></li>
+</ul>
+
+<h3>
+<b><font face="Arial"><font size=+1>What C++ Does for you�</font></font></b></h3>
+<b><i><font face="Arial">Name mangling � separation of name spaces</font></i></b>
+<p><font face="Times New Roman,Times">This mechanism � decorating symbol
+names with extra characters that uniquely identify their class and prototype
+� is the traditional C++ method for operator overloading, method overloading,
+and namespace separation. C provides a much smaller set of namespaces than
+C++ requires, so this strategy allowed C++ to be implemented as a preprocessor
+for C compilers originally.</font>
+<p><b><i><font face="Arial">Rigorous type checking</font></i></b>
+<p>Because of the function prototype requirement and name mangling, a C++
+compiler can provide strict type checking for method invocations.
+<p><b><i><font face="Arial">Automatic lifetime control</font></i></b>
+<p>Guarantees constructor call upon creation and destructor call upon deletion
+<p><b><i><font face="Arial">Multiple Storage classes (same as C)</font></i></b>
+<p>Automatic, static, dynamically allocated
+<p><b><i><font face="Arial">Typed dynamic memory management</font></i></b>
+<p><b><i><font face="Arial">Default constructor, destructor, copy constructor,
+and assignment operator</font></i></b>
+<p><b><i><font face="Arial">Explicit early and late binding support</font></i></b>
+<p><b><i><font face="Arial">And more�</font></i></b>
+<br>&nbsp;
+<h3>
+<b><font face="Arial"><font size=+1>What other OO languages do (or don�t
+do)</font></font></b></h3>
+Just to make sure we don�t get caught in a C++ centered view of the world,
+here are some ways other OO systems differ.
+<p><b><i><font face="Arial">Run-time type identification</font></i></b>
+<p>This is a Big Deal in C++, but it�s relatively trivial in an interpreted
+language to know the type of a reference at run-time.
+<p><b><i><font face="Arial">Metaclasses</font></i></b>
+<p>Classes are objects, too (Smalltalk, Java?)
+<p><b><i><font face="Arial">Garbage collection</font></i></b>
+<p>Java and smalltalk both manage memory for you, freeing objects when
+they go out of scope or are no longer referenced anywhere.
+<p><b><i><font face="Arial">Single Inheritance only</font></i></b>
+<p>Java, Smalltalk 80
+<p><b><i><font face="Arial">Everything is an object</font></i></b>
+<p>Smalltalk
+<p><b><i><font face="Arial">Operator overloading</font></i></b>
+<p>Smalltalk makes no distinction between operators and other kinds of
+messages. The message syntax is flexible enough that you can define operators
+in the same way as any other kind of message.
+<p><b><i><font face="Arial">Visibility control</font></i></b>
+<p>Smalltalk 80 does not appear to provide options for visibility control
+(based on my quick survey). Instance variables are always private, methods
+are always public as far as I can tell.
+<p><b><i><font face="Arial">Pointers</font></i></b>
+<p>Not in Smalltalk, Java: Both languages deal with objects through implicit
+references. It is still possible to create data structures, but the language
+hides much of the memory management work.
+<p><b><i><font face="Arial">No Casting</font></i></b>
+<p>As far as I can tell, smalltalk has no equivalent of a C/C++ cast.
+<p><b><i><font face="Arial">Late binding</font></i></b>
+<p>Smalltalk makes no syntactic distinction between late and early bound
+methods (unlike C++ "virtual" methods)
+<h3>
+<b><font face="Arial"><font size=+1>OO-C framework options</font></font></b></h3>
+<font face="Times New Roman,Times">Covered: objects (encapsulation, explicit
+construct and destruct), classes, inheritance, polymorphism</font>
+<br><font face="Times New Roman,Times">Not covered: multiple inheritance,
+automatic initialization / destruction,</font>
+<h3>
+<b><font face="Arial"><font size=+1>Strategy 1: message maps and aggregation</font></font></b></h3>
+<font face="Times New Roman,Times">Class: a struct with a pointer to a
+method table (message map). Contructor and destuctor are really initializer
+and destructor, and are invoked manually at beginning and end of lifetime.</font><font face="Times New Roman,Times"></font>
+<p><font face="Times New Roman,Times">Messages and methods: mapping table
+(first cut: use macros like MFC to create a mapping between messages and
+methods). Alternative: message map can be built at run-time (hash, tree,
+linked list) � method resolution may be slower.</font><font face="Times New Roman,Times"></font>
+<p><font face="Times New Roman,Times">Inheritance: aggregate the parent
+struct (recursively) at the beginning of the derived one, link the child
+method table to the parent and search recursively to resolve messages to
+methods</font><font face="Times New Roman,Times"></font>
+<p><font face="Times New Roman,Times">Pros and cons:</font>
+<blockquote><font face="Times New Roman,Times">+ flexible and minimal manual
+steps required</font>
+<br><font face="Times New Roman,Times">+ relatively simple � no need to
+write a preprocessor!</font>
+<br><font face="Times New Roman,Times">- all methods are late bound, run-time
+penalty</font>
+<br><font face="Times New Roman,Times">&shy; defeats compile time type
+checking, may require a single prototype for all methods</font></blockquote>
+<font face="Times New Roman,Times"></font>
+<p><br><b><font face="Arial"><font size=+1>Strategy 2: manual name mangling</font></font></b>
+<br><font face="Times New Roman,Times">This is how the <a href="#samek">Samek</a>
+article handles encapsulation</font>
+<p><b><font face="Arial"><font size=+1>Strategy 3: preprocessor</font></font></b>
+<br><font face="Times New Roman,Times">This is how C++ started out.</font><font face="Times New Roman,Times"></font>
+<p><b><font face="Arial"><font size=+1>References</font></font></b>
+<ul>
+<li>
+<a NAME="robson"></a><font size=-1>David Robson, <i>Object Oriented Software
+Systems</i>. Byte, August 1981</font></li>
+
+<li>
+<a NAME="samek"></a><font size=-1>Miro Samek, <i>Portable Inheritance and
+Polymorphism in C</i>. Embedded Systems Programming, December 1997</font></li>
+</ul>
+
+</body>
+</html>
--- /dev/null
+++ b/ficlstring.c
@@ -1,0 +1,23 @@
+/*******************************************************************
+** f i c l s t r i n g . c
+** Forth Inspired Command Language
+** ANS STRING words plus ficl extras for c-string class
+** Author: John Sadler (john_sadler@alum.mit.edu)
+** Created: 2 June 2000
+** 
+*******************************************************************/
+
+#include <string.h>
+#include <ctype.h>
+#include "ficl.h"
+
+
+/**************************************************************************
+                        f o r m a t
+** ( params... fmt-addr fmt-u dest-addr dest-u -- dest-addr dest-u )
+**************************************************************************/
+
+void ficlStrFormat(FICL_VM *pVM)
+{
+	return;
+}
\ No newline at end of file
--- /dev/null
+++ b/search.c
@@ -1,0 +1,363 @@
+/*******************************************************************
+** s e a r c h . c
+** Forth Inspired Command Language
+** ANS Forth SEARCH and SEARCH-EXT word-set written in C
+** Author: John Sadler (john_sadler@alum.mit.edu)
+** Created: 6 June 2000
+** 
+*******************************************************************/
+
+#include <string.h>
+#include "ficl.h"
+#include "math64.h"
+
+/**************************************************************************
+                        d e f i n i t i o n s
+** SEARCH ( -- )
+** Make the compilation word list the same as the first word list in the
+** search order. Specifies that the names of subsequent definitions will
+** be placed in the compilation word list. Subsequent changes in the search
+** order will not affect the compilation word list. 
+**************************************************************************/
+static void definitions(FICL_VM *pVM)
+{
+    FICL_DICT *pDict = ficlGetDict();
+
+    assert(pDict);
+    if (pDict->nLists < 1)
+    {
+        vmThrowErr(pVM, "DEFINITIONS error - empty search order");
+    }
+
+    pDict->pCompile = pDict->pSearch[pDict->nLists-1];
+    return;
+}
+
+
+/**************************************************************************
+                        f o r t h - w o r d l i s t
+** SEARCH ( -- wid )
+** Return wid, the identifier of the word list that includes all standard
+** words provided by the implementation. This word list is initially the
+** compilation word list and is part of the initial search order. 
+**************************************************************************/
+static void forthWordlist(FICL_VM *pVM)
+{
+    FICL_HASH *pHash = ficlGetDict()->pForthWords;
+    stackPushPtr(pVM->pStack, pHash);
+    return;
+}
+
+
+/**************************************************************************
+                        g e t - c u r r e n t
+** SEARCH ( -- wid )
+** Return wid, the identifier of the compilation word list. 
+**************************************************************************/
+static void getCurrent(FICL_VM *pVM)
+{
+    ficlLockDictionary(TRUE);
+    stackPushPtr(pVM->pStack, ficlGetDict()->pCompile);
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        g e t - o r d e r
+** SEARCH ( -- widn ... wid1 n )
+** Returns the number of word lists n in the search order and the word list
+** identifiers widn ... wid1 identifying these word lists. wid1 identifies
+** the word list that is searched first, and widn the word list that is
+** searched last. The search order is unaffected.
+**************************************************************************/
+static void getOrder(FICL_VM *pVM)
+{
+    FICL_DICT *pDict = ficlGetDict();
+    int nLists = pDict->nLists;
+    int i;
+
+    ficlLockDictionary(TRUE);
+    for (i = 0; i < nLists; i++)
+    {
+        stackPushPtr(pVM->pStack, pDict->pSearch[i]);
+    }
+
+    stackPushUNS(pVM->pStack, nLists);
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        s e a r c h - w o r d l i s t
+** SEARCH ( c-addr u wid -- 0 | xt 1 | xt -1 )
+** Find the definition identified by the string c-addr u in the word list
+** identified by wid. If the definition is not found, return zero. If the
+** definition is found, return its execution token xt and one (1) if the
+** definition is immediate, minus-one (-1) otherwise. 
+**************************************************************************/
+static void searchWordlist(FICL_VM *pVM)
+{
+    STRINGINFO si;
+    UNS16 hashCode;
+    FICL_WORD *pFW;
+    FICL_HASH *pHash = stackPopPtr(pVM->pStack);
+
+    si.count         = (FICL_COUNT)stackPopUNS(pVM->pStack);
+    si.cp            = stackPopPtr(pVM->pStack);
+    hashCode         = hashHashCode(si);
+
+    ficlLockDictionary(TRUE);
+    pFW = hashLookup(pHash, si, hashCode);
+    ficlLockDictionary(FALSE);
+
+    if (pFW)
+    {
+        stackPushPtr(pVM->pStack, pFW);
+        stackPushINT(pVM->pStack, (wordIsImmediate(pFW) ? 1 : -1));
+    }
+    else
+    {
+        stackPushUNS(pVM->pStack, 0);
+    }
+
+    return;
+}
+
+
+/**************************************************************************
+                        s e t - c u r r e n t
+** SEARCH ( wid -- )
+** Set the compilation word list to the word list identified by wid. 
+**************************************************************************/
+static void setCurrent(FICL_VM *pVM)
+{
+    FICL_HASH *pHash = stackPopPtr(pVM->pStack);
+    FICL_DICT *pDict = ficlGetDict();
+    ficlLockDictionary(TRUE);
+    pDict->pCompile = pHash;
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        s e t - o r d e r
+** SEARCH ( widn ... wid1 n -- )
+** Set the search order to the word lists identified by widn ... wid1.
+** Subsequently, word list wid1 will be searched first, and word list
+** widn searched last. If n is zero, empty the search order. If n is minus
+** one, set the search order to the implementation-defined minimum
+** search order. The minimum search order shall include the words
+** FORTH-WORDLIST and SET-ORDER. A system shall allow n to
+** be at least eight.
+**************************************************************************/
+static void setOrder(FICL_VM *pVM)
+{
+    int i;
+    int nLists = stackPopINT(pVM->pStack);
+    FICL_DICT *dp = ficlGetDict();
+
+    if (nLists > FICL_DEFAULT_VOCS)
+    {
+        vmThrowErr(pVM, "set-order error: list would be too large");
+    }
+
+    ficlLockDictionary(TRUE);
+
+    if (nLists >= 0)
+    {
+        dp->nLists = nLists;
+        for (i = nLists-1; i >= 0; --i)
+        {
+            dp->pSearch[i] = stackPopPtr(pVM->pStack);
+        }
+    }
+    else
+    {
+        dictResetSearchOrder(dp);
+    }
+
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        w o r d l i s t
+** SEARCH ( -- wid )
+** Create a new empty word list, returning its word list identifier wid.
+** The new word list may be returned from a pool of preallocated word
+** lists or may be dynamically allocated in data space. A system shall
+** allow the creation of at least 8 new word lists in addition to any
+** provided as part of the system. 
+** Notes: 
+** 1. ficl creates a new single-list hash in the dictionary and returns
+**    its address.
+** 2. ficl-wordlist takes an arg off the stack indicating the number of
+**    hash entries in the wordlist. Ficl 2.02 and later define WORDLIST as
+**    : wordlist 1 ficl-wordlist ;
+**************************************************************************/
+static void wordlist(FICL_VM *pVM)
+{
+    FICL_DICT *dp = ficlGetDict();
+    FICL_HASH *pHash;
+    FICL_UNS nBuckets;
+    
+#if FICL_ROBUST > 1
+    vmCheckStack(pVM, 1, 1);
+#endif
+    nBuckets = stackPopUNS(pVM->pStack);
+
+    dictAlign(dp);
+    pHash    = (FICL_HASH *)dp->here;
+    dictAllot(dp, sizeof (FICL_HASH) 
+        + (nBuckets-1) * sizeof (FICL_WORD *));
+
+    pHash->size = nBuckets;
+    hashReset(pHash);
+
+    stackPushPtr(pVM->pStack, pHash);
+    return;
+}
+
+
+/**************************************************************************
+                        S E A R C H >
+** ficl  ( -- wid )
+** Pop wid off the search order. Error if the search order is empty
+**************************************************************************/
+static void searchPop(FICL_VM *pVM)
+{
+    FICL_DICT *dp = ficlGetDict();
+    int nLists;
+
+    ficlLockDictionary(TRUE);
+    nLists = dp->nLists;
+    if (nLists == 0)
+    {
+        vmThrowErr(pVM, "search> error: empty search order");
+    }
+    stackPushPtr(pVM->pStack, dp->pSearch[--dp->nLists]);
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        > S E A R C H
+** ficl  ( wid -- )
+** Push wid onto the search order. Error if the search order is full.
+**************************************************************************/
+static void searchPush(FICL_VM *pVM)
+{
+    FICL_DICT *dp = ficlGetDict();
+
+    ficlLockDictionary(TRUE);
+    if (dp->nLists > FICL_DEFAULT_VOCS)
+    {
+        vmThrowErr(pVM, ">search error: search order overflow");
+    }
+    dp->pSearch[dp->nLists++] = stackPopPtr(pVM->pStack);
+    ficlLockDictionary(FALSE);
+    return;
+}
+
+
+/**************************************************************************
+                        W I D - G E T - N A M E
+** ficl  ( wid -- c-addr u )
+** Get wid's (optional) name and push onto stack as a counted string
+**************************************************************************/
+static void widGetName(FICL_VM *pVM)
+{
+    FICL_HASH *pHash = vmPop(pVM).p;
+	char *cp = pHash->name;
+	int len = 0;
+	
+	if (cp)
+		len = strlen(cp);
+
+	vmPush(pVM, LVALUEtoCELL(cp));
+	vmPush(pVM, LVALUEtoCELL(len));
+	return;
+}
+
+/**************************************************************************
+                        W I D - S E T - N A M E
+** ficl  ( wid c-addr -- )
+** Set wid's name pointer to the \0 terminated string address supplied
+**************************************************************************/
+static void widSetName(FICL_VM *pVM)
+{
+	char *cp = (char *)vmPop(pVM).p;
+	FICL_HASH *pHash = vmPop(pVM).p;
+	pHash->name = cp;
+	return;
+}
+
+
+/**************************************************************************
+                        setParentWid
+** FICL
+** setparentwid   ( parent-wid wid -- )
+** Set WID's link field to the parent-wid. search-wordlist will 
+** iterate through all the links when finding words in the child wid.
+**************************************************************************/
+static void setParentWid(FICL_VM *pVM)
+{
+    FICL_HASH *parent, *child;
+#if FICL_ROBUST > 1
+    vmCheckStack(pVM, 2, 0);
+#endif
+    child  = (FICL_HASH *)stackPopPtr(pVM->pStack);
+    parent = (FICL_HASH *)stackPopPtr(pVM->pStack);
+
+    child->link = parent;
+    return;
+}
+
+
+/**************************************************************************
+                        f i c l C o m p i l e S e a r c h
+** Builds the primitive wordset and the environment-query namespace.
+**************************************************************************/
+
+void ficlCompileSearch(FICL_DICT *dp)
+{
+    assert (dp);
+
+    /*
+    ** optional SEARCH-ORDER word set 
+    */
+    dictAppendWord(dp, ">search",   searchPush,     FW_DEFAULT);
+    dictAppendWord(dp, "search>",   searchPop,      FW_DEFAULT);
+    dictAppendWord(dp, "definitions",
+                                    definitions,    FW_DEFAULT);
+    dictAppendWord(dp, "forth-wordlist",  
+                                    forthWordlist,  FW_DEFAULT);
+    dictAppendWord(dp, "get-current",  
+                                    getCurrent,     FW_DEFAULT);
+    dictAppendWord(dp, "get-order", getOrder,       FW_DEFAULT);
+    dictAppendWord(dp, "search-wordlist",  
+                                    searchWordlist, FW_DEFAULT);
+    dictAppendWord(dp, "set-current",  
+                                    setCurrent,     FW_DEFAULT);
+    dictAppendWord(dp, "set-order", setOrder,       FW_DEFAULT);
+    dictAppendWord(dp, "ficl-wordlist", wordlist,   FW_DEFAULT);
+    dictAppendWord(dp, "wid-get-name", widGetName,  FW_DEFAULT);
+    dictAppendWord(dp, "wid-set-name", widSetName,  FW_DEFAULT);
+
+    /*
+    ** Set SEARCH environment query values
+    */
+    ficlSetEnv("search-order",      FICL_TRUE);
+    ficlSetEnv("search-order-ext",  FICL_TRUE);
+    ficlSetEnv("wordlists",         FICL_DEFAULT_VOCS);
+
+    dictAppendWord(dp, "wid-set-super", 
+                                    setParentWid,   FW_DEFAULT);
+    return;
+}
+