home: hub: 9ficl

Download patch

ref: 7995ea0d43c8e024add6708416bbd7b4c94c8804
parent: 61f45c3e019a92cfe0ba68af6fe9d782e9d5a894
author: jsadler <jsadler@ficl.sf.net>
date: Wed Jul 12 01:44:12 CDT 2000

intermediate for release to d c sobral

--- a/doc/ficl.html
+++ b/doc/ficl.html
@@ -12,11 +12,16 @@
 <h1>
 <b>Ficl Documentation</b></h1>
 
-<table BORDER=0 CELLSPACING=3 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 WIDTH="640" >
 <tr>
 <td><b>Forth Inspired Command Language&nbsp;</b></td>
 
 <td ROWSPAN="4"><img SRC="ficl_logo.jpg" height=64 width=64></td>
+<td ROWSPAN="4">
+    <a href=http://www.links2go.net/topic/Forth>
+        <img alt="Key Resource" src="skey.gif" width=81 height=81 border=0>
+    </a>
+</td>
 </tr>
 
 <tr>
@@ -37,61 +42,79 @@
 
 <ul>
 <li>
-<a href="ficl_rel.html">Release notes</a></li>
+<font size=+1><a href="ficl_rel.html">Release notes</a></font></li>
 
 <li>
-<a href="#whatis">What is ficl?</a></li>
+<font size=+1><a href="#whatis">What is ficl?</a></font></li>
 
 <li>
-<a href="#download"><b>Download</b> the latest version</a></li>
+<font size=+1><a href="#download">Download</a></font></li>
 
 <li>
-<a href="#links">More information on Ficl</a></li>
+<font size=+1><a href="#links">References</a></font></li>
 
 <li>
-<font color="#000000"><a href="#includesficl">Some software that incorporates
-Ficl</a></font></li>
+<font color="#000000"><font size=+1><a href="#includesficl">Some software
+that incorporates Ficl</a></font></font></li>
 
 <li>
-<a href="#lawyerbait">Disclaimer &amp; License</a></li>
+<font size=+1><a href="#lawyerbait">Disclaimer &amp; License</a></font></li>
 
 <li>
-<a href="#features">Ficl features</a></li>
+<font size=+1><a href="#features">Ficl features</a></font></li>
 
 <li>
-<a href="#porting">Porting</a></li>
+<font size=+1><a href="#porting">Porting</a></font></li>
 
 <li>
-<a href="#api">Application Programming Interface</a></li>
+<font size=+1><a href="#api">Application Programming Interface</a></font></li>
 
 <li>
-<a href="#manifest">Distribution source files</a></li>
+<font size=+1><a href="#manifest">Distribution source files</a></font></li>
 
 <li>
-<a href="ficl_loc.html">Local variables</a></li>
+<font size=+1><a href="ficl_loc.html">Local variables</a></font></li>
 
 <li>
-<a href="ficl_oop.html">Object Oriented Programming in ficl</a></li>
+<font size=+1><a href="ficl_oop.html">Object Oriented Programming in ficl</a></font></li>
 
 <li>
-<a href="#extras">Ficl extras</a></li>
+<font size=+1><a href="#extras">Ficl extras</a></font></li>
 
+<ul>
 <li>
-<a href="#ansinfo">ANS required information</a></li>
+<font size=+1><a href="#exnumber">Number syntax</a></font></li>
+
+<li>
+<font size=+1><a href="#exsearch">Search order words</a></font></li>
+
+<li>
+<font size=+1><a href="#exuser">User variables</a></font></li>
+
+<li>
+<font size=+1><a href="#exmisc">Miscellaneous useful words</a></font></li>
+
+<li>
+<font size=+1><a href="#exficlwin">FiclWin words</a></font></li>
 </ul>
 
+<li>
+<font size=+1><a href="#ansinfo">ANS required information</a></font></li>
+</ul>
+
 <br>&nbsp;
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h1>
 <a NAME="whatis"></a>What is ficl?</h1>
-<font size=+1>Ficl (Forth inspired command language) a complete programming
-language interpreter based on ANS Forth and written in Standard C. Ficl
-is designed to be embedded into other systems as a command/macro/development
-prototype language. Ficl provides object extensions that can be used to
-wrap methods and structures of the host system without altering them. See
-below for examples of <a href="#includesficl">software that includes ficl</a>.</font></td>
+<font size=+1>Ficl is a complete programming language interpreter designed
+to be embedded into other systems as a command/macro/development prototype
+language. Ficl provides object extensions that can be used to wrap methods
+and structures of the host system without altering them. The syntax is
+based on ANS Forth and the code is Standard C. See below for examples of
+<a href="#includesficl">software
+that includes ficl</a>. Ficl stands for "Forth inspired command language".&nbsp;</font></td>
 </tr>
 
 <tr>
@@ -104,7 +127,7 @@
 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 adapter for code written in C (or asm, Forth, C++...).&nbsp;</td>
+oriented <i>adapter</i> for code written in C (or asm, Forth, C++...).&nbsp;</td>
 </tr>
 
 <tr>
@@ -145,7 +168,7 @@
 <ul>
 <li>
 <b><a href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl205/ficl205.zip">Download
-ficl 2.05</a></b></li>
+ficl (latest release)</a></b></li>
 
 <li>
 <b><a href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl205/ficlwin.zip">Download
@@ -210,7 +233,7 @@
 </ul>
 
 <hr>
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -241,7 +264,7 @@
 </table>
 
 <br>&nbsp;
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -309,7 +332,7 @@
 </table>
 
 <hr>
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -355,10 +378,12 @@
 
 <ul>
 <li>
-Unimplemented system dependent <tt>CORE</tt> word: <tt>KEY</tt>&nbsp;</li>
+Unimplemented system dependent <tt>CORE</tt> word: <tt>KEY</tt> (implement
+this yourself if you need it)</li>
 
 <li>
-Kludged <tt>CORE</tt> word: <tt>ACCEPT</tt></li>
+Kludged <tt>CORE</tt> word: <tt>ACCEPT </tt>(implement this better if you
+need to)</li>
 </ul>
 </td>
 </tr>
@@ -366,7 +391,7 @@
 
 <br>&nbsp;
 <br>&nbsp;
-<table BORDER=0 COLS=1 WIDTH="600" >
+<table BORDER=0 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -491,7 +516,7 @@
 <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="#locals">local variables</a>.</dd>
+dictionary is the symbol table for <a href="ficl_loc.html">local variables</a>.</dd>
 
 <dt>
 <b>void ficlCompileCore(FICL_DICT *dp)</b></dt>
@@ -513,7 +538,7 @@
 </table>
 
 <hr>
-<table BORDER=0 CELLSPACING=5 WIDTH="600" >
+<table BORDER=0 CELLSPACING=5 WIDTH="675" >
 <tr>
 <td COLSPAN="2">
 <h2>
@@ -612,7 +637,7 @@
 </table>
 
 <hr WIDTH="100%">
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <dl>
@@ -620,7 +645,7 @@
 <a NAME="extras"></a>Ficl extras</h2>
 
 <h3>
-Number syntax</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 <tt>BASE</tt>. Example:&nbsp;
 <dl>
@@ -629,15 +654,16 @@
 
 <br><tt>123&nbsp;</tt>
 <br><tt>ok> 0x123 . cr</tt>
-<br><tt>291&nbsp;</tt></dl>
+<br><tt>291</tt>
+<br><tt>ok> 0x123 <a href="#xdot">x.</a> cr</tt>
+<br><tt>123</tt></dl>
 
 <h3>
-Search order words</h3>
+<a NAME="exsearch"></a>Search order words</h3>
 Ficl implements many of the search order words in terms of two primitives
 called <tt><a href="#tosearch">>SEARCH</a></tt> and <tt><a href="#searchfrom">SEARCH></a></tt>.
 As their names suggest (assuming you're familiar with Forth), they push
-and pop the search order stack. See the list of <a href="#extras">Ficl
-extras</a> for details.&nbsp;
+and pop the search order stack.&nbsp;
 <br>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
@@ -656,13 +682,17 @@
 <dd>
 Push <tt>wid</tt> onto the search order. Many of the other search order
 words are written in terms of the <tt>SEARCH></tt> and <tt>>SEARCH</tt>
-primitives.</dd>
+primitives. This word can be defined in ANS Forth as follows</dd>
 
+<dd>
+<tt>: >search&nbsp;&nbsp; >r get-order 1+ r> swap set-order ;</tt></dd>
+
 <dt>
 <a NAME="searchfrom"></a><tt>search>&nbsp;&nbsp; ( -- wid )</tt></dt>
 
 <dd>
-Pop <tt>wid</tt> off the search order</dd>
+Pop <tt>wid</tt> off the search order (can be coded in ANS Forth as&nbsp;<tt>
+: search>&nbsp; get-order nip 1- set-order ;</tt> )</dd>
 
 <dt>
 <a NAME="ficlsetcurrent"></a><tt>ficl-set-current&nbsp;&nbsp; ( wid --
@@ -691,7 +721,10 @@
 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 <tt>wordlist</tt> is single threaded by default.&nbsp;</dd>
+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>
@@ -720,24 +753,17 @@
 see what's in there, try:&nbsp; <b><tt>hide words previous set-current</tt></b></dd>
 
 <dt>
-<tt>last-word&nbsp;&nbsp; ( -- xt )</tt></dt>
+<a NAME="wid-get-name"></a><tt>wid-get-name&nbsp;&nbsp; ( wid -- c-addr
+u )</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 <tt>last-word
->name type</tt>&nbsp;</dd>
-
-<dt>
-<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>
-<tt>wid-set-name&nbsp;&nbsp; ( c-addr wid -- )</tt></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.
@@ -747,7 +773,7 @@
 definition of <tt>brand-wordlist</tt>&nbsp;</dd>
 
 <dt>
-<tt>wid-set-super&nbsp;&nbsp; ( wid -- )</tt></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
@@ -763,7 +789,7 @@
 </dl>
 
 <h3>
-User variables</h3>
+<a NAME="exuser"></a>User variables</h3>
 
 <dl>
 <dt>
@@ -773,11 +799,21 @@
 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.</dd>
+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>
+
+<dl>
+<dd>
+<tt>user current-class</tt></dd>
+
+<dd>
+<tt>0 current-class !</tt></dd>
 </dl>
+</dl>
 
 <h3>
-Miscellaneous</h3>
+<a NAME="exmisc"></a>Miscellaneous</h3>
 
 <dl>
 <dt>
@@ -851,6 +887,19 @@
 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>
+
+<dl>
+<dd>
+<b><tt>last-word >name type</tt>&nbsp;</b></dd>
+</dl>
+
+<dt>
 <tt>parse-word&nbsp;&nbsp; ( &lt;spaces>name -- c-addr u )</tt></dt>
 
 <dd>
@@ -860,6 +909,18 @@
 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>
@@ -873,7 +934,7 @@
 given value)</dd>
 
 <dt>
-<tt>x.&nbsp;&nbsp; ( x -- )</tt></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
@@ -881,7 +942,7 @@
 </dl>
 
 <h3>
-FiclWin Extras (defined in testmain.c)</h3>
+<a NAME="exficlwin"></a>FiclWin Extras (defined in testmain.c)</h3>
 
 <dl>
 <dt>
@@ -938,10 +999,12 @@
 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>
 FiclWin Exclusives (no source provided)</h3>
 
+<dl>
 <dt>
 <tt>!oreg&nbsp;&nbsp; ( c -- )</tt></dt>
 
@@ -987,10 +1050,10 @@
 </table>
 
 <hr>
-<p><a NAME="ansinfo"></a>
-<p>ANS Required Information
-<br>&nbsp;
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<h2>
+<a NAME="ansinfo"></a>ANS Required Information</h2>
+
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td><b>ANS Forth System</b>
 <br><b>Providing names from the Core Extensions word set&nbsp;</b>
--- a/doc/ficl_loc.html
+++ b/doc/ficl_loc.html
@@ -32,7 +32,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -43,13 +43,14 @@
 global variables too much. 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. I use them a lot.&nbsp;
-<br>&nbsp;
-<h3>
-Johns-Hopkins local variables</h3>
+<br><a href="http://www.taygeta.com/forth/dpans13.htm">Please refer to
+the Standard</a> for more information on local variables.
+<h2>
+<a NAME="jhlocal"></a>Johns-Hopkins local variables</h2>
 ANS Forth does not specify a complete and satisfying 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 developed by John
-Hayes et al. This is my preferred form, and i've extended it to make OOP
+Hayes et al. This is my preferred form, and I've extended it to make <a href="ficl_oop.html">OOP</a>
 a bit simpler. Local variables can only be declared inside a definition,
 and are only visible in that definition. Here's the syntax of a JH local
 variable declaration:
@@ -60,26 +61,30 @@
 values from the stack when the word executes. The &lt;cleared-locals> names
 are (you guessed it) set to zero when the word executes, and any characters
 between -- and } are treated as a comment. The | and -- sections are optional,
-but they must appear in the order shown if they appear at all. Another
-feature: ordinarily, locals represent one cell. Local variable names prefixed
-with the character '2' in the declaration are double-cell locals. They
-behave the same as single cell locals in all other respects. I use 2locals
-quite a bit in Ficl's OO classes, because objects in Ficl are require two
-cells on the stack. Following are some examples to illustrate usage (they
-are not intended to be good code otherwise). Try these out in FiclWin to
-get a feeling for how they work...
+but they must appear in the order shown if they appear at all.&nbsp;
+<br><b>Double cell locals </b>(AKA 2locals): ordinarily, each local represents
+one cell. Local variable names prefixed with the character '2' in the declaration
+are double-cell locals. They behave the same as single cell locals in all
+other respects. I use 2locals quite a bit in Ficl's OO classes, because
+objects in Ficl are require two cells on the stack. You can modify the
+value of a double cell local with <tt><a href="http://www.taygeta.com/forth/dpans13.htm#13.6.1.2295">TO</a></tt>
+the same as you would a single cell local.
+<br>Following are some examples to illustrate usage (they are not intended
+to be good code otherwise). Try these out in FiclWin to get a feeling for
+how they work...
 <blockquote><b><tt>: local-demo&nbsp; { a b | c -- }</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; ." a = " a . cr</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; ." b = " b . cr</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; ." c = " c . cr ;</tt></b>
-<br><b><tt>1 2 local-demo&nbsp;</tt></b><b><tt></tt></b>
-<p><b><tt>: my2dup&nbsp; { 2x }&nbsp;&nbsp; x x ;</tt></b>
-<br><b><tt>1 2 my2dup .s&nbsp;&nbsp;</tt></b>
-<br><b><tt>.( you should see 1 2 1 2 on the stack ) cr empty</tt></b><b><tt></tt></b>
+<br><b><tt>1 2 local-demo&nbsp; ( you should see 1 2 0 )</tt></b>
+<p><b><tt>: my2dup&nbsp; { 2x }&nbsp;&nbsp; x x ;&nbsp; ( uses a 2local
+)</tt></b>
+<br><b><tt>1 2 my2dup .s&nbsp;</tt></b>
+<br><b><tt>.( you should see 1 2 1 2 on the stack ) cr empty</tt></b>
 <p><b><tt>: my2swap&nbsp;&nbsp; { 2x 2y -- y x }&nbsp;&nbsp; y x ;&nbsp;
 ( note use of 2locals )</tt></b>
 <br><b><tt>1 2 3 4 my2swap .s</tt></b>
-<br><b><tt>.( you should see 3 4 1 2 on the stack ) cr empty</tt></b><b><tt></tt></b>
+<br><b><tt>.( you should see 3 4 1 2 on the stack ) cr empty</tt></b>
 <p><b><tt>: totally-lame-swap&nbsp; { x y | temp -- y x }</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; y to temp</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; x to y</tt></b>
@@ -88,11 +93,14 @@
 The last definition introduces the use of <tt>TO</tt> applied to local
 variables. <tt>TO</tt> knows whether it's operating on a <tt>LOCAL</tt>,
 a <tt>2LOCAL</tt>, or a <tt>VALUE</tt>, and does the right thing accordingly.&nbsp;
-<p>There are other syntaxes in use for local variables. You get the same
-compiled code regardless of which style of local declaration you choose,
-but the Johns-Hopkins syntax is more readable, more flexible, and supports
-<tt>2LOCAL</tt>s - if you agree, then skip ahead.&nbsp;
-<br>Ficl includes support for <tt>LOCALS</tt> and <tt>LOCALS EXT</tt> words
+<br>&nbsp;
+<h2>
+Other local variable syntaxes (deprecated)</h2>
+There are other syntaxes in use for local variables. You get the same compiled
+code regardless of which style of local declaration you choose, but the
+Johns-Hopkins syntax is more readable, more flexible, and supports <tt>2LOCAL</tt>s
+- if you agree, then skip this section.&nbsp;
+<p>Ficl includes support for <tt>LOCALS</tt> and <tt>LOCALS EXT</tt> words
 (all three of them!). I've implemented both of the local variable syntaxes
 suggested in DPANS Appendix A.13. Examples: (By the way, Ficl implements
 <tt>-ROT</tt>
@@ -112,22 +120,24 @@
 <br><b><tt>&nbsp;&nbsp;&nbsp; c a b</tt></b>
 <br><b><tt>;</tt></b></ul>
 
-<h3>
-Build Controls</h3>
+<h2>
+Build Controls</h2>
 Local variable support is optional because it adds a small amount of overhead
 to the outer interpreter. You can disable it by setting FICL_WANT_LOCALS
-to 0 in sysdep.h. Beware: much of the OOP code described below uses local
-variables, so if you disable locals, you're going to lose other capabilities
-too. Local variables can make Forth code quite a bit easier to read, so
-I'd encourage you to experiment with them.&nbsp;
-<br>The default maximum number of local variables is 16. It's controlled
+to 0 in sysdep.h. Beware: <a href="ficl_oop.html">Ficl's OOP</a> code makes
+heavy use of local variables, so if you disable locals, you're going to
+lose other capabilities too. Local variables can make Forth code quite
+a bit easier to read, so I'd encourage you to experiment with them.&nbsp;
+<p>The default maximum number of local variables is 16. It's controlled
 by FICL_MAX_LOCALS in sysdep.h.&nbsp;
-<p><a NAME="jhlocal"></a>Ficl 2.02 includes by default an implementation
-of the Johns Hopkins local syntax (as best I can determine it from examples
-on the web). This syntax lets you declare local variables that look very
-much like a stack comment. Variables in the declaration appear in the "correct"
-order for a stack comment. Everything after the -- is treated as a comment.
-In addition, you can insert a | before the -- to declare one or more zero-initialized
+<h2>
+Release notes for local variables</h2>
+Ficl 2.02 includes by default an implementation of the Johns Hopkins local
+syntax (as best I can determine it from examples on the web). This syntax
+lets you declare local variables that look very much like a stack comment.
+Variables in the declaration appear in the "correct" order for a stack
+comment. Everything after the -- is treated as a comment. In addition,
+you can insert a | before the -- to declare one or more zero-initialized
 locals. Example:&nbsp;
 <blockquote><b><tt>:tuck0&nbsp;&nbsp; { a b c | d -- 0 a b c }</tt></b>
 <br><b><tt>&nbsp;&nbsp;&nbsp; d a b c ;</tt></b></blockquote>
@@ -135,9 +145,9 @@
 order shown in the example to work correctly. The local declaration ends
 at the first occurrence of }. The declaration must all be on one line as
 presently implemented.&nbsp;
-<p><a NAME="newlocal"></a>Ficl 2.01 added yet another local syntax that
-models a stack comment. This one is not compiled in the release, but you
-can add it by editing softwords/softcore.bat to include the file ficllocal.fr.
+<p><b>Deprecated</b>: Ficl 2.01 added yet another local syntax that models
+a stack comment. This one is not compiled in the release, but you can add
+it by editing softwords/softcore.bat to include the file ficllocal.fr.
 In this case, parameters are re-ordered so that the rightmost initialized
 param comes from the top of the stack. The syntax is:&nbsp;
 <blockquote><b><tt>{{ &lt;initialized params> -- &lt;cleared params> }}</tt></b></blockquote>
--- a/doc/ficl_oop.html
+++ b/doc/ficl_oop.html
@@ -61,7 +61,7 @@
 <a href="#stockclasses">Supplied Classes</a></li>
 </ul>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -123,7 +123,7 @@
 </table>
 
 <br>&nbsp;
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
@@ -163,7 +163,7 @@
 
 <p><a NAME="figure1"></a><img SRC="ficl_oop.jpg" VSPACE=10 height=442 width=652>
 <br>&nbsp;
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -175,7 +175,8 @@
 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="#ootutoial-finally">jump ahead</a>.
+<a href="#ootutoial-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,
@@ -230,7 +231,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
@@ -330,7 +331,11 @@
 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
 effiecient because it compiles method addresses rather then their names.
-Here's an example that illustrates a potential problem:
+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.
+<br>Here's an example that illustrates a potential problem:
 <blockquote><b><tt>object --> sub c1</tt></b>
 <br><b><tt>: m1&nbsp;&nbsp; { 2this -- }&nbsp; ." c1's m1" cr ;</tt></b>
 <br><b><tt>: m2&nbsp;&nbsp; { 2this -- }&nbsp; ." Running&nbsp; " this
@@ -367,14 +372,14 @@
 there is a real danger that this will be out of sync with the class you
 really wanted. I recommend the <b><tt>my=</tt></b> operations.</li>
 </ol>
-Early binding can be dangerous because&nbsp; 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 <tt>init</tt> 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;
+Early binding using <b><tt>=></tt></b> is dangerous because&nbsp; 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 <tt>init</tt> 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;
@@ -473,7 +478,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -570,7 +575,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
@@ -579,37 +584,29 @@
 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;
+<br>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:
+<blockquote><tt>object subclass c-example</tt>
+<br><tt>&nbsp;&nbsp; cell:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+.cell0</tt>
+<br><tt>&nbsp;&nbsp; c-4byte&nbsp;&nbsp; obj: .nCells</tt>
+<br><tt>&nbsp;4 c-4byte array: .quad</tt>
+<br><tt>&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>
-
+<br><tt>79 chars:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name</tt>
+<br><tt>end-class</tt>&nbsp;</blockquote>
+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;
 <dl>
 <dt>
 <b><font face="Courier New"><font size=-1>cell:&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
@@ -767,7 +764,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
@@ -825,7 +822,7 @@
 on the stack. Usage example:</dd>
 
 <dd>
-<tt>c-ref --> alloc 2constant instance-of-ref</tt></dd>
+<tt>c-ref --> alloc&nbsp; 2constant instance-of-ref</tt></dd>
 
 <dd>
 Creates a double-cell constant that pushes the payload and class address
@@ -842,6 +839,30 @@
 method</dd>
 
 <dt>
+<a NAME="allot"></a><b><tt>allot&nbsp;&nbsp; ( class metaclass -- instance
+class )</tt></b></dt>
+
+<dd>
+Creates an anonymous instance of <b>class</b> from the dictionary. Leaves
+the payload and class addresses on the stack. Usage example:</dd>
+
+<dd>
+<tt>c-ref --> allot&nbsp; 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="allotarray"></a><b><tt>allot-array&nbsp;&nbsp; ( nObj class metaclass
+-- instance class )</tt></b></dt>
+
+<dd>
+Same as new-array, but creates anonymous instances from the dictionary.
+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>
 
@@ -981,7 +1002,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
@@ -1100,7 +1121,7 @@
 </tr>
 </table>
 
-<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h3>
--- a/doc/ficl_rel.html
+++ b/doc/ficl_rel.html
@@ -32,7 +32,7 @@
 </table>
 
 <br>&nbsp;
-<table BORDER=0 CELLPADDING=3 COLS=1 WIDTH="600" >
+<table BORDER=0 CELLPADDING=3 COLS=1 WIDTH="675" >
 <tr>
 <td>
 <h2>
@@ -58,45 +58,62 @@
 
 <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!)
-<br><a href="http://www.taygeta.com/forth/dpans6.htm#6.2.2125">REFILL</a>
-works better
+now works correctly (I promise!)</li>
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans6.htm#6.2.2125">REFILL</a> works
+better</li>
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans6.htm#6.1.0710">ALLOT</a>'s
+use of dictCheck corrected (finally)</li>
+</ul>
+
 <h3>
 New words</h3>
 
 <ul>
 <li>
-ANS CORE EXT words: <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>&nbsp;</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>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(CORE EXT)</li>
 
 <li>
-ANS DOUBLE words: <a href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.0440">2VARIABLE</a></li>
+<a href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.0440">2VARIABLE</a>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(DOUBLE)</li>
 
 <li>
-ANS ORDER now lists wordlists by name</li>
+<a href="http://www.taygeta.com/forth/dpans16.htm#16.6.2.1985">ORDER</a>
+now lists wordlists by name</li>
 
 <li>
-ANS .S now displays all stack entries on one line, like a stack comment</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>
 
 <li>
-<tt>wid-get-name</tt>&nbsp;&nbsp; given a wid, returns the address and
-count of its name. If no name, count is 0</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>
 
 <li>
-<tt>wid-set-name</tt>&nbsp;&nbsp; set optional wid name pointer to the
-\0 terminated string address specified.</li>
+<tt><a href="ficl.html#wid-set-name">wid-set-name</a></tt>&nbsp;&nbsp;
+set optional wid name pointer to the \0 terminated string address specified.</li>
 
 <li>
-<tt>ficl-named-wordlist</tt> creates a ficl-wordlist and names it. This
-is now used in <tt>vocabulary</tt> and <tt>ficl-vocabulary</tt>&nbsp;</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>
 
 <li>
-<tt>last-word</tt>&nbsp; returns the xt of the word being defined or most
-recently defined.</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>
 
 <li>
-<tt>q@</tt> and <tt>q!</tt> operate on quadbyte quantities for 64 bit friendliness</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</li>
 </ul>
 
 <h3>
@@ -104,7 +121,11 @@
 
 <ul>
 <li>
-Class methods <tt>ALLOT</tt> and <tt>ALLOT-ARRAY</tt></li>
+<tt>ALLOT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
+(class method)</tt></li>
+
+<li>
+<tt>ALLOT-ARRAY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (class method)</tt></li>
 
 <li>
 <tt>METHOD</tt> define method names globally</li>
--- a/doc/oo_in_c.html
+++ b/doc/oo_in_c.html
@@ -7,12 +7,17 @@
    <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>
+
+<h1>
+<b><font face="Arial"><font size=+1>Object Oriented Idioms in C</font></font></b></h1>
+<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>
+<br>&nbsp;
+<br>&nbsp;
+<table COLS=1 WIDTH="675" >
+<tr>
+<td><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>
 <a NAME="object-def"></a><font face="Times New Roman,Times"><b>"A package
@@ -23,19 +28,20 @@
 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">A <b>message</b> denotes an operation
+that can be performed on an <b>object</b>. The code that describes how
+to perform an operation on a specific object type is called a <b>method</b>.
+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 <b>interface</b> 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 <b>polymorphism</b>. Methods can be bound to messages as soon as
+the type of the object receiving the message is known (called <b>early
+binding</b>), or this mapping can wait until run-time (<b>late binding</b>).</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
@@ -47,6 +53,11 @@
 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>
+<br>&nbsp;</td>
+</tr>
+
+<tr>
+<td>
 <h3>
 <b><i><font face="Arial">Class</font></i></b></h3>
 <a NAME="class-def"></a><b><font face="Times New Roman,Times">"A description
@@ -61,6 +72,11 @@
 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.)
+<br>&nbsp;</td>
+</tr>
+
+<tr>
+<td>
 <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
@@ -83,7 +99,11 @@
 <font face="Times New Roman,Times">provide methods for (<b>override</b>)
 messages already handled by the parent class</font></li>
 </ul>
+</td>
+</tr>
 
+<tr>
+<td>
 <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>
@@ -105,7 +125,11 @@
 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;
+<br>&nbsp;</td>
+</tr>
+
+<tr>
+<td>
 <h3>
 <b><font face="Arial"><font size=+1>What other OO languages do (or don�t
 do)</font></font></b></h3>
@@ -140,6 +164,11 @@
 <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)
+<br>&nbsp;</td>
+</tr>
+
+<tr>
+<td>
 <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
@@ -174,7 +203,11 @@
 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>
-<p><b><font face="Arial"><font size=+1>References</font></font></b>
+<br>&nbsp;</td>
+</tr>
+
+<tr>
+<td><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
@@ -184,6 +217,9 @@
 <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>
+</td>
+</tr>
+</table>
 
 </body>
 </html>
--- a/ficl.c
+++ b/ficl.c
@@ -3,7 +3,7 @@
 ** Forth Inspired Command Language - external interface
 ** Author: John Sadler (john_sadler@alum.mit.edu)
 ** Created: 19 July 1997
-** $Id: ficl.c,v 1.6 2000/06/17 14:43:45 jsadler Exp $
+** $Id: ficl.c,v 1.7 2000/07/12 06:44:07 jsadler Exp $
 *******************************************************************/
 /*
 ** This is an ANS Forth interpreter written in C.
@@ -263,6 +263,7 @@
 
     case VM_USEREXIT:
     case VM_INNEREXIT:
+	case VM_BREAK:
         break;
 
     case VM_QUIT:
@@ -348,6 +349,7 @@
         break;
 
     case VM_INNEREXIT:
+	case VM_BREAK:
         break;
 
     case VM_RESTART:
--- a/ficl.h
+++ b/ficl.h
@@ -3,7 +3,7 @@
 ** Forth Inspired Command Language
 ** Author: John Sadler (john_sadler@alum.mit.edu)
 ** Created: 19 July 1997
-** $Id: ficl.h,v 1.7 2000/06/17 14:43:46 jsadler Exp $
+** $Id: ficl.h,v 1.8 2000/07/12 06:44:08 jsadler Exp $
 *******************************************************************/
 /*
 ** N O T I C E -- DISCLAIMER OF WARRANTY
@@ -500,6 +500,7 @@
 #define VM_RESTART   -258   /* word needs more text to succeed - re-run it */
 #define VM_USEREXIT  -259   /* user wants to quit */
 #define VM_ERREXIT   -260   /* interp found an error */
+#define VM_BREAK     -261   /* debugger breakpoint */
 #define VM_ABORT       -1   /* like errexit -- abort */
 #define VM_ABORTQ      -2   /* like errexit -- abort" */
 #define VM_QUIT       -56   /* like errexit, but leave pStack & base alone */
@@ -799,7 +800,7 @@
 FICL_DICT *ficlGetDict(void);
 FICL_DICT *ficlGetEnv(void);
 void       ficlSetEnv(char *name, FICL_UNS value);
-void       ficlSetEnvD(char *name, FICL_UNS hi, UNS32 lo);
+void       ficlSetEnvD(char *name, FICL_UNS hi, FICL_UNS lo);
 #if FICL_WANT_LOCALS
 FICL_DICT *ficlGetLoc(void);
 #endif
@@ -829,6 +830,7 @@
 void       ficlCompileCore(FICL_DICT *dp);
 void       ficlCompileSearch(FICL_DICT *dp);
 void       ficlCompileSoftCore(FICL_VM *pVM);
+void       ficlCompileTools(FICL_DICT *dp);
 
 /*
 ** from words.c...
@@ -835,6 +837,33 @@
 */
 void       constantParen(FICL_VM *pVM);
 void       twoConstParen(FICL_VM *pVM);
+void       ficlTick(FICL_VM *pVM);
+
+/* 
+** The following supports SEE and the debugger.
+*/
+enum  
+{
+	BRANCH,
+	COLON, 
+	CONSTANT, 
+	CREATE,
+	DO,
+	DOES, 
+	IF,
+	LITERAL,
+	LOOP,
+	PLOOP,
+	PRIMITIVE,
+	QDO,
+	STRINGLIT,
+	USER, 
+    VARIABLE, 
+} wordkinds;
+
+typedef enum wordkinds WORDKIND;
+
+WORDKIND   ficlWordClassify(FICL_WORD *pFW);
 
 #ifdef __cplusplus
 }
--- a/softwords/ficlclass.fr
+++ b/softwords/ficlclass.fr
@@ -18,20 +18,16 @@
     \ Push word's name...
     : get-name   ( inst class -- c-addr u )
         2dup
-        --> .pName --> get-ptr  -rot
-        --> .nName --> get
+        my=[ .pName get-ptr ] -rot
+        my=[ .nName get ]
     ;
 
     : next   ( inst class -- link-inst class )
-        --> .link ;
+        my=> .link ;
         
     : ?
-        ." ficl word: " 
+        ." c-word: " 
         2dup --> get-name type cr
-        ." hash = "
-        2dup --> .hashcode --> get x. cr
-        ." flags = "
-        --> .flags --> get x. cr
     ;
 
 end-class
--- a/softwords/oo.fr
+++ b/softwords/oo.fr
@@ -74,6 +74,12 @@
     class swap
 ;
 
+: find-method-xt   \ name ( class -- class xt )
+	parse-word lookup-method
+;
+
+set-current  ( stop hiding definitions )
+
 : catch-method  ( instance class c-addr u -- <method-signature> exc-flag )
     lookup-method catch
 ;
@@ -82,12 +88,6 @@
     lookup-method execute
 ;
 
-: find-method-xt   \ name ( class -- class xt )
-	parse-word lookup-method
-;
-
-set-current  ( stop hiding definitions )
-
 \ Method lookup operator takes a class-addr and instance-addr
 \ and executes the method from the class's wordlist if
 \ interpreting. If compiling, bind late.
@@ -458,11 +458,11 @@
 previous set-current	
 \ E N D   M E T A C L A S S
 
-\ META is a nickname for the address of METACLASS...
+\ ** META is a nickname for the address of METACLASS...
 metaclass drop  
 constant meta
 
-\ SUBCLASS is a nickname for a class's SUB method...
+\ ** SUBCLASS is a nickname for a class's SUB method...
 \ Subclass compilation ends when you invoke end-class
 \ This method is late bound for safety...
 : subclass   --> sub ;
--- a/softwords/softcore.fr
+++ b/softwords/softcore.fr
@@ -33,7 +33,7 @@
     state @ if
         postpone if
         postpone ."
-        postpone type
+\        postpone type
         postpone cr
         -2
         postpone literal
--- a/tools.c
+++ b/tools.c
@@ -3,7 +3,7 @@
 ** Forth Inspired Command Language - programming tools
 ** Author: John Sadler (john_sadler@alum.mit.edu)
 ** Created: 20 June 2000
-** $Id: tools.c,v 1.0 2000/06/23 18:06:38 jsadler Exp $
+** $Id: tools.c,v 1.1 2000/07/12 06:44:12 jsadler Exp $
 *******************************************************************/
 /*
 ** NOTES:
@@ -29,11 +29,13 @@
 #include "ficl.h"
 
 
+#if 0
 /*
 ** nBREAKPOINTS sizes the breakpoint array. One breakpoint (bp 0) is reserved
 ** for the STEP command. The rest are user programmable. 
 */
 #define nBREAKPOINTS 10
+#endif
 
 /*
 ** BREAKPOINT record.
@@ -40,16 +42,21 @@
 ** origXT - if NULL, this breakpoint is unused. Otherwise it stores the xt 
 ** that the breakpoint overwrote. This is restored to the dictionary when the
 ** BP executes or gets cleared
+** address - the location of the breakpoint (address of the instruction that
+**           has been replaced with the breakpoint trap
+** origXT  - The original contents of the location with the breakpoint
+** Note: address is NULL when this breakpoint is empty
 */
 typedef struct breakpoint
 {
-	FICL_WORD *origXT;
-	FICL_WORD *onBreak;
+	void      *address;
+    FICL_WORD *origXT;
 } BREAKPOINT;
 
-static BREAKPOINT bpTable[nBREAKPOINTS];
-static FICL_WORD *pBreak = NULL;
+static BREAKPOINT bpStep = {NULL, NULL};
+static FICL_WORD *pStep = NULL;
 
+#if 0
 /**************************************************************************
                         i n i t T o o l s
 ** Initializes static variables of this file, including:
@@ -67,9 +74,9 @@
 
     return;	
 }
+#endif
 
 
-
 /**************************************************************************
                         s e e 
 ** TOOLS ( "<spaces>name" -- )
@@ -271,41 +278,143 @@
 ** Given an xt of a colon definition or a word defined by DOES>, set the
 ** VM up to debug the word: push IP, set the xt as the next thing to execute,
 ** set a breakpoint at its first instruction, and run to the breakpoint.
+** Note: the semantics of this word are equivalent to "step in"
 **************************************************************************/
 void ficlDebug(FICL_VM *pVM)
 {
-	int ret;
-	FICL_WORD *xt = stackPopPtr(pVM->pStack);
-    assert(pBreak);
+    FICL_WORD *xt = stackPopPtr(pVM->pStack);
+    WORDKIND wk = ficlWordClassify(xt);
 
-	if (ficlWordIsDebuggable(xt))
+    assert(pStep);
+
+    stackPushPtr(pVM->pStack, xt);
+    seeXT(pVM);
+
+	switch (wk)
 	{
-		stackPushPtr(pVM, xt);
-		seeXT(pVM);
+	case COLON:
+    case DOES:
 		/*
-		** Set a breakpoint at the first instruction and run the word
+		** Run the colon code and set a breakpoint at the next instruction
 		*/
-        
-	    ret = ficlExecXT(pVM, xt);
+        vmExecute(pVM, xt);
+        bpStep.address = pVM->ip;
+        bpStep.origXT = *pVM->ip;
+        *pVM->ip = pStep;
+        break;
+
+    default:
+        break;
 	}
-	else
-	{
-		ficlTextOut(pVM, "primitive - cannot debug", 1);
-	}
 
     return;
 }
 
 
+void stepIn(FICL_VM *pVM)
+{
+    assert(pStep);
+    /*
+    ** Do one step of the inner loop
+    */
+    { 
+        M_VM_STEP(pVM) 
+    }
 
+    /*
+    ** Now set a breakpoint at the next instruction
+    */
+    bpStep.address = pVM->ip;
+    bpStep.origXT = *pVM->ip;
+    *pVM->ip = pStep;
+    
+    return;
+}
+
+
 /**************************************************************************
-                        d e b u g - b r e a k
+                        s t e p O v e r
+** FICL 
+** Execute the next instruction atomically.
+**************************************************************************/
+void stepOver(FICL_VM *pVM)
+{
+    assert(pStep);
+    /*
+    ** Do one step of the inner loop
+    */
+    { 
+        M_VM_STEP(pVM) 
+    }
+
+    /*
+    ** Now set a breakpoint at the next instruction
+    */
+    bpStep.address = pVM->ip;
+    bpStep.origXT = *pVM->ip;
+    *pVM->ip = pStep;
+    
+    return;
+}
+
+
+
+/**************************************************************************
+                        s t e p - b r e a k
 ** FICL
-** Throws a breakpoint exception - used by DEBUG to step and break.
+** Handles breakpoints for stepped execution.
+** Upon entry, bpStep contains the address and replaced instruction
+** of the current breakpoint.
+** Clear the breakpoint
+** Get a command from the console. 
+** in (step in) - execute the current instruction and set a new breakpoint 
+**    at the IP
+** ov (step over) - execute the current instruction to completion and set
+**    a new breakpoint at the IP
+** go - execute the current instruction and exit
 **************************************************************************/
-void debugBreak(FICL_VM *pVM)
+void stepBreak(FICL_VM *pVM)
 {
-	vmThrow(pVM, VM_BREAK);
+    STRINGINFO si;
+    FICL_WORD *pFW;
+
+    if (!pVM->fRestart)
+    {
+
+        assert(bpStep.address != NULL);
+        /*
+        ** restore the original instruction at the breakpoint, and restore the IP
+        */
+        pVM->ip = (IPTYPE)bpStep.address;
+        *pVM->ip = pFW = bpStep.origXT;
+
+        /*
+        ** Print the name of the next instruction and get a debug command
+        */
+        sprintf(pVM->pad, "%.*s", pFW->nName, pFW->name);
+        vmTextOut(pVM, pVM->pad, 1);
+    }
+
+    si = vmGetWord(pVM);
+
+    if      (!strincmp(si.cp, "in", (unsigned char)si.count))
+    {
+        stepIn(pVM);
+    }
+    else if (!strincmp(si.cp, "go", (unsigned char)si.count))
+    {
+        return;
+    }
+    else if (!strincmp(si.cp, "ov", (unsigned char)si.count))
+    {
+        stepOver(pVM);
+    }
+    else
+    {
+        vmTextOut(pVM, "unrecognized debug command", 1);
+        vmThrow(pVM, VM_ABORT);
+    }
+
 	return;
 }
 
@@ -510,8 +619,8 @@
     */
     dictAppendWord(dp, ".env",      listEnv,        FW_DEFAULT);
     dictAppendWord(dp, "debug",     ficlDebug,      FW_DEFAULT);
-	pBreak = 
-    dictAppendWord(dp, "debug-break",debugBreak,    FW_DEFAULT);
+	pStep = 
+    dictAppendWord(dp, "step-break",stepBreak,      FW_DEFAULT);
     dictAppendWord(dp, "forget-wid",forgetWid,      FW_DEFAULT);
     dictAppendWord(dp, "see-xt",    seeXT,          FW_DEFAULT);
     return;
--- a/words.c
+++ b/words.c
@@ -4,7 +4,7 @@
 ** ANS Forth CORE word-set written in C
 ** Author: John Sadler (john_sadler@alum.mit.edu)
 ** Created: 19 July 1997
-** $Id: words.c,v 1.7 2000/06/17 14:43:51 jsadler Exp $
+** $Id: words.c,v 1.8 2000/07/12 06:44:09 jsadler Exp $
 *******************************************************************/
 
 #include <stdlib.h>
@@ -418,20 +418,6 @@
 
 
 /**************************************************************************
-                        b y e
-** TOOLS
-** Signal the system to shut down - this causes ficlExec to return
-** VM_USEREXIT. The rest is up to you.
-**************************************************************************/
-
-static void bye(FICL_VM *pVM)
-{
-    vmThrow(pVM, VM_USEREXIT);
-    return;
-}
-
-
-/**************************************************************************
                         c o l o n   d e f i n i t i o n s
 ** Code to begin compiling a colon definition
 ** This function sets the state to COMPILE, then creates a
@@ -662,33 +648,6 @@
 
 
 /**************************************************************************
-                        d i s p l a y S t a c k
-** Display the parameter stack (code for ".s")
-**************************************************************************/
-
-static void displayStack(FICL_VM *pVM)
-{
-    int d = stackDepth(pVM->pStack);
-    int i;
-    CELL *pCell;
-
-    vmCheckStack(pVM, 0, 0);
-
-    if (d == 0)
-        vmTextOut(pVM, "(Stack Empty) ", 0);
-    else
-    {
-        pCell = pVM->pStack->base;
-        for (i = 0; i < d; i++)
-        {
-            vmTextOut(pVM, ltoa((*pCell++).i, pVM->pad, pVM->base), 0);
-            vmTextOut(pVM, " ", 0);
-        }
-    }
-}
-
-
-/**************************************************************************
                         d u p   &   f r i e n d s
 ** 
 **************************************************************************/
@@ -1209,8 +1168,9 @@
 
 static void interpret(FICL_VM *pVM)
 {
-    STRINGINFO si = vmGetWord0(pVM);
+    STRINGINFO si;
     assert(pVM);
+    si = vmGetWord0(pVM);
 
     vmBranchRelative(pVM, -1);
 
@@ -1375,92 +1335,6 @@
 }
 
 /**************************************************************************
-                        l i s t W o r d s
-** 
-**************************************************************************/
-#define nCOLWIDTH 8
-static void listWords(FICL_VM *pVM)
-{
-    FICL_DICT *dp = ficlGetDict();
-    FICL_HASH *pHash = dp->pSearch[dp->nLists - 1];
-    FICL_WORD *wp;
-    int nChars = 0;
-    int len;
-    unsigned i;
-    int nWords = 0;
-    char *cp;
-    char *pPad = pVM->pad;
-
-    for (i = 0; i < pHash->size; i++)
-    {
-        for (wp = pHash->table[i]; wp != NULL; wp = wp->link, nWords++)
-        {
-            if (wp->nName == 0) /* ignore :noname defs */
-                continue;
-
-            cp = wp->name;
-            nChars += sprintf(pPad + nChars, "%s", cp);
-
-            if (nChars > 70)
-            {
-                pPad[nChars] = '\0';
-                nChars = 0;
-                vmTextOut(pVM, pPad, 1);
-            }
-            else
-            {
-                len = nCOLWIDTH - nChars % nCOLWIDTH;
-                while (len-- > 0)
-                    pPad[nChars++] = ' ';
-            }
-
-            if (nChars > 70)
-            {
-                pPad[nChars] = '\0';
-                nChars = 0;
-                vmTextOut(pVM, pPad, 1);
-            }
-        }
-    }
-
-    if (nChars > 0)
-    {
-        pPad[nChars] = '\0';
-        nChars = 0;
-        vmTextOut(pVM, pPad, 1);
-    }
-
-    sprintf(pVM->pad, "Dictionary: %d words, %ld cells used of %u total", 
-        nWords, (long) (dp->here - dp->dict), dp->size);
-    vmTextOut(pVM, pVM->pad, 1);
-    return;
-}
-
-
-static void listEnv(FICL_VM *pVM)
-{
-    FICL_DICT *dp = ficlGetEnv();
-    FICL_HASH *pHash = dp->pForthWords;
-    FICL_WORD *wp;
-    unsigned i;
-    int nWords = 0;
-
-    for (i = 0; i < pHash->size; i++)
-    {
-        for (wp = pHash->table[i]; wp != NULL; wp = wp->link, nWords++)
-        {
-            vmTextOut(pVM, wp->name, 1);
-        }
-    }
-
-    sprintf(pVM->pad, "Environment: %d words, %ld cells used of %u total", 
-        nWords, (long) (dp->here - dp->dict), dp->size);
-    vmTextOut(pVM, pVM->pad, 1);
-    return;
-}
-
-
-/**************************************************************************
                         l o g i c   a n d   c o m p a r i s o n s
 ** 
 **************************************************************************/
@@ -2016,7 +1890,7 @@
 ** name and return xt, the execution token for name. An ambiguous condition
 ** exists if name is not found. 
 **************************************************************************/
-static void tick(FICL_VM *pVM)
+void ficlTick(FICL_VM *pVM)
 {
     FICL_WORD *pFW = NULL;
     STRINGINFO si = vmGetWord(pVM);
@@ -2034,7 +1908,7 @@
 
 static void bracketTickCoIm(FICL_VM *pVM)
 {
-    tick(pVM);
+    ficlTick(pVM);
     literalIm(pVM);
     
     return;
@@ -2054,7 +1928,7 @@
     FICL_WORD *pFW;
     assert(pComma);
 
-    tick(pVM);
+    ficlTick(pVM);
     pFW = stackGetTop(pVM->pStack).p;
     if (wordIsImmediate(pFW))
     {
@@ -3675,183 +3549,6 @@
 
 #endif
 /**************************************************************************
-                        s e e 
-** TOOLS ( "<spaces>name" -- )
-** Display a human-readable representation of the named word's definition.
-** The source of the representation (object-code decompilation, source
-** block, etc.) and the particular form of the display is implementation
-** defined. 
-** NOTE: these funcs come late in the file because they reference all
-** of the word-builder funcs without declaring them again. Call me lazy.
-**************************************************************************/
-/*
-** isAFiclWord
-** Vet a candidate pointer carefully to make sure
-** it's not some chunk o' inline data...
-** It has to have a name, and it has to look
-** like it's in the dictionary address range.
-** NOTE: this excludes :noname words!
-*/
-static int isAFiclWord(FICL_WORD *pFW)
-{
-    FICL_DICT *pd  = ficlGetDict();
-
-    if (!dictIncludes(pd, pFW))
-       return 0;
-
-    if (!dictIncludes(pd, pFW->name))
-        return 0;
-
-    return ((pFW->nName > 0) && (pFW->name[pFW->nName] == '\0'));
-}
-
-/*
-** seeColon (for proctologists only)
-** Walks a colon definition, decompiling
-** on the fly. Knows about primitive control structures.
-*/
-static void seeColon(FICL_VM *pVM, CELL *pc)
-{
-    for (; pc->p != pSemiParen; pc++)
-    {
-        FICL_WORD *pFW = (FICL_WORD *)(pc->p);
-
-        if (isAFiclWord(pFW))
-        {
-            if      (pFW->code == literalParen)
-            {
-                CELL v = *++pc;
-                if (isAFiclWord(v.p))
-                {
-                    FICL_WORD *pLit = (FICL_WORD *)v.p;
-                    sprintf(pVM->pad, "    literal %.*s (%#lx)", 
-                        pLit->nName, pLit->name, v.u);
-                }
-                else
-                    sprintf(pVM->pad, "    literal %ld (%#lx)", v.i, v.u);
-            }
-            else if (pFW->code == stringLit) 
-            {
-                FICL_STRING *sp = (FICL_STRING *)(void *)++pc;
-                pc = (CELL *)alignPtr(sp->text + sp->count + 1) - 1;
-                sprintf(pVM->pad, "    s\" %.*s\"", sp->count, sp->text);
-            }
-            else if (pFW->code == ifParen) 
-            {
-                CELL c = *++pc;
-                if (c.i > 0)
-                    sprintf(pVM->pad, "    if / while (branch rel %ld)", c.i);
-                else
-                    sprintf(pVM->pad, "    until (branch rel %ld)", c.i);
-            }
-            else if (pFW->code == branchParen) 
-            {
-                CELL c = *++pc;
-                if (c.i > 0)
-                    sprintf(pVM->pad, "    else (branch rel %ld)", c.i);
-                else
-                    sprintf(pVM->pad, "    repeat (branch rel %ld)", c.i);
-            }
-            else if (pFW->code == qDoParen) 
-            {
-                CELL c = *++pc;
-                sprintf(pVM->pad, "    ?do (leave abs %#lx)", c.u);
-            }
-            else if (pFW->code == doParen) 
-            {
-                CELL c = *++pc;
-                sprintf(pVM->pad, "    do (leave abs %#lx)", c.u);
-            }
-            else if (pFW->code == loopParen) 
-            {
-                CELL c = *++pc;
-                sprintf(pVM->pad, "    loop (branch rel %#ld)", c.i);
-            }
-            else if (pFW->code == plusLoopParen) 
-            {
-                CELL c = *++pc;
-                sprintf(pVM->pad, "    +loop (branch rel %#ld)", c.i);
-            }
-            else /* default: print word's name */
-            {
-                sprintf(pVM->pad, "    %.*s", pFW->nName, pFW->name);
-            }
- 
-            vmTextOut(pVM, pVM->pad, 1);
-        }
-        else /* probably not a word - punt and print value */
-        {
-            sprintf(pVM->pad, "    %ld (%#lx)", pc->i, pc->u);
-            vmTextOut(pVM, pVM->pad, 1);
-        }
-    }
-
-    vmTextOut(pVM, ";", 1);
-}
-
-/*
-** Here's the outer part of the decompiler. It's 
-** just a big nested conditional that checks the
-** CFA of the word to decompile for each kind of
-** known word-builder code, and tries to do 
-** something appropriate. If the CFA is not recognized,
-** just indicate that it is a primitive.
-*/
-static void see(FICL_VM *pVM)
-{
-    FICL_WORD *pFW;
-
-    tick(pVM);
-    pFW = (FICL_WORD *)stackPopPtr(pVM->pStack);
-
-    if (pFW->code == colonParen) 
-    {
-        sprintf(pVM->pad, ": %.*s", pFW->nName, pFW->name);
-        vmTextOut(pVM, pVM->pad, 1);
-        seeColon(pVM, pFW->param);
-    }
-    else if (pFW->code == doDoes)
-    {
-        vmTextOut(pVM, "does>", 1);
-        seeColon(pVM, (CELL *)pFW->param->p);
-    }
-    else if (pFW->code ==  createParen)
-    {
-        vmTextOut(pVM, "create", 1);
-    }
-    else if (pFW->code == variableParen)
-    {
-        sprintf(pVM->pad, "variable = %ld (%#lx)", 
-            pFW->param->i, pFW->param->u);
-        vmTextOut(pVM, pVM->pad, 1);
-    }
-    else if (pFW->code == userParen)
-    {
-        sprintf(pVM->pad, "user variable %ld (%#lx)", 
-            pFW->param->i, pFW->param->u);
-        vmTextOut(pVM, pVM->pad, 1);
-    }
-    else if (pFW->code == constantParen)
-    {
-        sprintf(pVM->pad, "constant = %ld (%#lx)", 
-            pFW->param->i, pFW->param->u);
-        vmTextOut(pVM, pVM->pad, 1);
-    }
-    else 
-    {
-        vmTextOut(pVM, "primitive", 1);
-    }
-
-    if (pFW->flags & FW_IMMEDIATE)
-    {
-        vmTextOut(pVM, "immediate", 1);
-    }
-
-    return;
-}
-
-
-/**************************************************************************
                         c o m p a r e 
 ** STRING ( c-addr1 u1 c-addr2 u2 -- n )
 ** Compare the string specified by c-addr1 u1 to the string specified by
@@ -3939,45 +3636,6 @@
 
 
 /**************************************************************************
-                        f o r g e t
-** TOOLS EXT  ( "<spaces>name" -- )
-** Skip leading space delimiters. Parse name delimited by a space.
-** Find name, then delete name from the dictionary along with all
-** words added to the dictionary after name. An ambiguous
-** condition exists if name cannot be found. 
-** 
-** If the Search-Order word set is present, FORGET searches the
-** compilation word list. An ambiguous condition exists if the
-** compilation word list is deleted. 
-**************************************************************************/
-static void forgetWid(FICL_VM *pVM)
-{
-    FICL_DICT *pDict = ficlGetDict();
-    FICL_HASH *pHash;
-
-    pHash = (FICL_HASH *)stackPopPtr(pVM->pStack);
-    hashForget(pHash, pDict->here);
-
-    return;
-}
-
-
-static void forget(FICL_VM *pVM)
-{
-    void *where;
-    FICL_DICT *pDict = ficlGetDict();
-    FICL_HASH *pHash = pDict->pCompile;
-
-    tick(pVM);
-    where = ((FICL_WORD *)stackPopPtr(pVM->pStack))->name;
-    hashForget(pHash, where);
-    pDict->here = PTRtoCELL where;
-
-    return;
-}
-
-
-/**************************************************************************
                         freebsd exception handling words
 ** Catch, from ANS Forth standard. Installs a safety net, then EXECUTE
 ** the word in ToS. If an exception happens, restore the state to what
@@ -4090,16 +3748,17 @@
 	}
 }
 
-/*
- * Throw --  From ANS Forth standard.
- *
- * Throw takes the ToS and, if that's different from zero,
- * returns to the last executed catch context. Further throws will
- * unstack previously executed "catches", in LIFO mode.
- *
- * Daniel C. Sobral Jan 09/1999
- */
-
+/**************************************************************************
+**                     t h r o w
+** EXCEPTION
+** Throw --  From ANS Forth standard.
+**
+** Throw takes the ToS and, if that's different from zero,
+** returns to the last executed catch context. Further throws will
+** unstack previously executed "catches", in LIFO mode.
+**
+** Daniel C. Sobral Jan 09/1999
+**************************************************************************/
 static void ficlThrow(FICL_VM *pVM)
 {
     int except;
@@ -4111,6 +3770,10 @@
 }
 
 
+/**************************************************************************
+**                     a l l o c a t e
+** MEMORY
+**************************************************************************/
 static void ansAllocate(FICL_VM *pVM)
 {
     size_t size;
@@ -4126,6 +3789,10 @@
 }
 
 
+/**************************************************************************
+**                     f r e e 
+** MEMORY
+**************************************************************************/
 static void ansFree(FICL_VM *pVM)
 {
     void *p;
@@ -4136,6 +3803,10 @@
 }
 
 
+/**************************************************************************
+**                     r e s i z e
+** MEMORY
+**************************************************************************/
 static void ansResize(FICL_VM *pVM)
 {
     size_t size;
@@ -4157,10 +3828,10 @@
 }
 
 
-/*
-** exit-inner 
+/**************************************************************************
+**                     e x i t - i n n e r 
 ** Signals execXT that an inner loop has completed
-*/
+**************************************************************************/
 static void ficlExitInner(FICL_VM *pVM)
 {
     vmThrow(pVM, VM_INNEREXIT);
@@ -4196,6 +3867,53 @@
 
 #endif
 /**************************************************************************
+                        f i c l W o r d C l a s s i f y
+** This public function helps to classify word types for SEE
+** and the deugger in tools.c. Given an pointer to a word, it returns
+** a member of WOR
+**************************************************************************/
+WORDKIND ficlWordClassify(FICL_WORD *pFW)
+{
+    typedef struct 
+	{
+		WORDKIND kind;
+		FICL_CODE code;
+	} CODEtoKIND;
+
+	static CODEtoKIND codeMap[] =
+	{
+		{BRANCH, branchParen},
+		{COLON, colonParen},
+		{CONSTANT, constantParen},
+		{CREATE, createParen},
+		{DO, doParen},
+		{DOES, doDoes},
+		{IF, ifParen},
+		{LITERAL, literalParen},
+		{LOOP, loopParen},
+		{PLOOP, plusLoopParen},
+		{QDO, qDoParen},
+		{STRINGLIT, stringLit},
+		{USER, userParen},
+		{VARIABLE, variableParen},
+	};
+
+#define nMAP (sizeof(codeMap) / sizeof(CODEtoKIND))
+
+    FICL_CODE code = pFW->code;
+	int i;
+
+	for (i=0; i < nMAP; i++)
+	{
+		if (codeMap[i].code == code)
+			return codeMap[i].kind;
+	}
+
+	return PRIMITIVE;
+}
+
+
+/**************************************************************************
                         f i c l C o m p i l e C o r e
 ** Builds the primitive wordset and the environment-query namespace.
 **************************************************************************/
@@ -4213,7 +3931,7 @@
     dictAppendWord(dp, "#",         numberSign,     FW_DEFAULT);
     dictAppendWord(dp, "#>",        numberSignGreater,FW_DEFAULT);
     dictAppendWord(dp, "#s",        numberSignS,    FW_DEFAULT);
-    dictAppendWord(dp, "\'",        tick,           FW_DEFAULT);
+    dictAppendWord(dp, "\'",        ficlTick,       FW_DEFAULT);
     dictAppendWord(dp, "(",         commentHang,    FW_IMMEDIATE);
     dictAppendWord(dp, "*",         mul,            FW_DEFAULT);
     dictAppendWord(dp, "*/",        mulDiv,         FW_DEFAULT);
@@ -4452,22 +4170,11 @@
     /*
     ** TOOLS and TOOLS EXT
     */
-    dictAppendWord(dp, ".s",        displayStack,   FW_DEFAULT);
-    dictAppendWord(dp, "bye",       bye,            FW_DEFAULT);
-    dictAppendWord(dp, "forget",    forget,         FW_DEFAULT);
-    dictAppendWord(dp, "see",       see,            FW_DEFAULT);
-    dictAppendWord(dp, "words",     listWords,      FW_DEFAULT);
+	ficlCompileTools(dp);
 
     /*
-    ** Set TOOLS environment query values
-    */
-    ficlSetEnv("tools",            FICL_TRUE);
-    ficlSetEnv("tools-ext",        FICL_FALSE);
-
-    /*
     ** Ficl extras
     */
-    dictAppendWord(dp, ".env",      listEnv,        FW_DEFAULT);
     dictAppendWord(dp, ".hash",     dictHashSummary,FW_DEFAULT);
     dictAppendWord(dp, ".ver",      ficlVersion,    FW_DEFAULT);
     dictAppendWord(dp, "-roll",     minusRoll,      FW_DEFAULT);
@@ -4477,7 +4184,6 @@
     dictAppendWord(dp, "compile-only",
                                     compileOnly,    FW_DEFAULT);
     dictAppendWord(dp, "endif",     endifCoIm,      FW_COMPIMMED);
-    dictAppendWord(dp, "forget-wid",forgetWid,      FW_DEFAULT);
     dictAppendWord(dp, "last-word", getLastWord,    FW_DEFAULT);
 	dictAppendWord(dp, "hash",      hash,           FW_DEFAULT);
 	dictAppendWord(dp, "number?",   ficlIsNum,      FW_DEFAULT);