ref: f6e68cc9b5494b83db49fca97b7e25b9b39ef5e0
parent: 778af2c25383b3571a79951e4ada36b15d4c0ff8
author: jsadler <jsadler@ficl.sf.net>
date: Tue Jun 6 23:43:12 CDT 2000
Incorporated freeBSD Alpha (64 bit) patches OO.fr: suspend-class, resume-class Wids now have name fields Moved search from words.c to search.c
--- a/ReadMe.txt
+++ b/ReadMe.txt
@@ -1,5 +1,4 @@
Coming up:
-Rewrite exception words using inner loop function
Web server scripting extension (GoAhead port)
ficlwin Debugger pane - step, stack trace, breakpoint
@@ -10,6 +9,23 @@
3. GO runs until breakpoint or leaves debug mode if no breaks
4. BREAK stops debug vm at next step
Requires a debug VM that checks for breaks, step mode, etc.
+
+rel 2.05
+Alpha patches from the freeBSD team incorporated
+Split SEARCH and SEARCH EXT words form words.c to search.c
+ficl words
+- wid-get-name given a wid, returns the address and count of its name. If no name, count is 0
+- wid-set-name set optional wid name pointer to the \0 terminated string address specified.
+- last-word returns the xt of the word being defined or most recently defined.
+- i@ and i! operate on quadbyte quantities for 64 bit friendliness
+softcore.fr words
+- ORDER now lists wordlists by name
+- ficl-named-wordlist
+- brand-wordlist
+New OO stuff
+- metaclass method resume-class and instance word suspend-class to create
+ mutually referring classes. Example in string.fr
+
rel 2.04 -- May 2000
ficlwin:
--- a/dict.c
+++ b/dict.c
@@ -224,10 +224,10 @@
/**************************************************************************
- d i c t A p p e n d U N S 3 2
-** Append the specified UNS32 to the dictionary
+ d i c t A p p e n d U N S
+** Append the specified FICL_UNS to the dictionary
**************************************************************************/
-void dictAppendUNS(FICL_DICT *pDict, UNS32 u)
+void dictAppendUNS(FICL_DICT *pDict, FICL_UNS u)
{
*pDict->here++ = LVALUEtoCELL(u);
return;
@@ -685,6 +685,8 @@
}
+
+
/**************************************************************************
h a s h I n s e r t W o r d
** Put a word into the hash table using the word's hashcode as
@@ -768,6 +770,7 @@
}
pHash->link = NULL;
+ pHash->name = NULL;
return;
}
--- a/doc/ficl.html
+++ b/doc/ficl.html
@@ -1,2667 +1,2116 @@
+<!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="Microsoft FrontPage Express 2.0">
-<title>ficl release notes</title>
+ <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>
-<h1 align="center"><b>ficl 2.04 release notes</b></h1>
+<center>
+<h1>
+<b>ficl 2.04 release notes</b></h1></center>
-<table border="0" cellspacing="3" width="600">
- <tr>
- <td><b>Forth Inspired Command Language </b></td>
- <td rowspan="4"><img src="ficl_logo.jpg" width="64"
- height="64"></td>
- </tr>
- <tr>
- <td><b>Author: John Sadler (</b><a
- href="mailto:john_sadler@alum.mit.edu"><b>john_sadler@alum.mit.edu</b></a><b>)</b></td>
- </tr>
- <tr>
- <td><b>Created: 19 July 1997 </b></td>
- </tr>
- <tr>
- <td><b>Revision 2.04: 20 May 2000</b></td>
- </tr>
+<table BORDER=0 CELLSPACING=3 WIDTH="600" >
+<tr>
+<td><b>Forth Inspired Command Language </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>Created: 19 July 1997 </b></td>
+</tr>
+
+<tr>
+<td><b>Revision 2.04: 20 May 2000</b></td>
+</tr>
</table>
-<h2>Contents</h2>
+<h2>
+Contents</h2>
<ul>
- <li><a href="#whatsnew">Release notes</a></li>
- <li><a href="#whatis">What is ficl?</a></li>
- <li><a href="#features">Ficl features</a></li>
- <li><a href="#porting">Porting</a></li>
- <li><a href="#api">Application Programming Interface</a></li>
- <li><a href="#manifest">Distribution source files</a></li>
- <li><a href="#locals">Local variables</a></li>
- <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><ul>
- <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>
- </li>
- <li><a href="#extras">Ficl extras</a></li>
- <li><a href="#ansinfo">ANS required information</a></li>
- <li><a href="#links">Forth and Ficl references, <font
- color="#000000"><b>download</b></font></a></li>
- <li><a href="#includesficl"><font color="#000000">Some
- software that includes ficl</font></a></li>
- <li><a href="#lawyerbait">Disclaimer & License</a></li>
+<li>
+<a href="#whatsnew">Release notes</a></li>
+
+<li>
+<a href="#whatis">What is ficl?</a></li>
+
+<li>
+<a href="#features">Ficl features</a></li>
+
+<li>
+<a href="#porting">Porting</a></li>
+
+<li>
+<a href="#api">Application Programming Interface</a></li>
+
+<li>
+<a href="#manifest">Distribution source files</a></li>
+
+<li>
+<a href="#locals">Local variables</a></li>
+
+<li>
+<a href="ficl_oop.html">Object Oriented Programming in ficl</a></li>
+
+<li>
+<a href="#extras">Ficl extras</a></li>
+
+<li>
+<a href="#ansinfo">ANS required information</a></li>
+
+<li>
+<a href="#links">Forth and Ficl references, <b><font color="#000000">download</font></b></a></li>
+
+<li>
+<font color="#000000"><a href="#includesficl">Some software that includes
+ficl</a></font></li>
+
+<li>
+<a href="#lawyerbait">Disclaimer & License</a></li>
</ul>
-<p> </p>
+<br>
+<table BORDER=0 CELLPADDING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="whatsnew"></a>What's new in version 2.04</h2>
-<table border="0" cellpadding="3" width="600" cols="1">
- <tr>
- <td><h2><a name="whatsnew"></a>What's new in version 2.04</h2>
- <h3>ficlwin</h3>
- <ul>
- <li>Catches exceptions thrown by VM in ficlThread (0
- @ for example) rather than passing them off to
- the OS. </li>
- </ul>
- <h3>ficl bugs vanquished</h3>
- <ul>
- <li>Fixed leading delimiter bugs in s" ."
- .( and ( (reported by Reuben Thomas)</li>
- <li>Makefile tabs restored (thanks to Michael Somos)</li>
- <li>ABORT" now throws -2 per the DPANS (thanks
- to Daniel Sobral for sharp eyes again) </li>
- <li>ficlExec does not print the prompt string unless
- (source-id == 0)</li>
- <li>Various fixes contributed by the FreeBSD team.</li>
- </ul>
- <h3>ficl enhancements</h3>
- <ul>
- <li>Words.c: modified ficlCatch to use vmExecute and
- vmInnerLoop (request of Daniel Sobral) Added
- vmPop and vmPush functions (by request of Lars
- Krueger ) in vm.c These are shortcuts to the
- param stack. (Use LVALUEtoCELL to get things into
- CELL form) </li>
- <li>Added function vmGetStringEx with a flag to
- specify whether or not to skip lead delimiters</li>
- <li>Added non-std word: number?</li>
- <li>Added CORE EXT word AGAIN (by request of Reuben
- Thomas) </li>
- <li>Added double cell local (2local) support</li>
- <li>Augmented Johns Hopkins local syntax so that
- locals whose names begin with char 2 are treated
- as 2locals (OK - it's goofy, but handy for OOP)</li>
- <li>C-string class revised and enhanced - now
- dynamically sized</li>
- <li>C-hashstring class derived from c-string computes
- hashcode too.</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td><h2>What's new in version 2.03</h2>
- <p>This is the first version of Ficl that includes
- contributed code. Thanks especially to Daniel Sobral,
- Michael Gauland for contributions and bug finding. </p>
- <p>New words </p>
- <ul>
- <li><a href="#clock"><tt>clock</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#clockspersec"><tt>clocks/sec</tt></a><tt>
- (FICL)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.1230"><tt>dnegate</tt></a><tt>
- (DOUBLE)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905"><tt>ms</tt></a><tt>
- (FACILITY EXT - replaces MSEC </tt><i><tt>ficlWin
- only</tt></i><tt>)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.2275"><tt>throw</tt></a><tt>
- (EXCEPTION)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.0875"><tt>catch</tt></a><tt>
- (EXCEPTION)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.0707"><tt>allocate</tt></a><tt>
- (MEMORY)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.1605"><tt>free</tt></a><tt>
- (MEMORY)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.2145"><tt>resize</tt></a><tt>
- (MEMORY)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans6.htm#6.2.2440"><tt>within</tt></a><tt>
- (CORE EXT)</tt></li>
- <li><a href="#alloc"><tt>alloc</tt></a><tt>
- (class method)</tt></li>
- <li><a href="#allocarray"><tt>alloc-array</tt></a><tt>
- (class method)</tt></li>
- <li><a href="#oofree"><tt>free</tt></a><tt>
- (class method)</tt></li>
- </ul>
- <p>Bugs Fixed </p>
- <ul>
- <li>Bug fix in isNumber(): used to treat chars
- between 'Z' and 'a' as valid in base 10...
- (harmless, but weird)</li>
- <li>ficlExec pushes the <i>ip</i> and <tt>interpret</tt>s
- at the right times so that nested calls to
- ficlExec behave the way you'd expect them to.</li>
- <li><tt>evaluate</tt> respects count parameter, and
- also passes exceptional return conditions back
- out to the calling instance of ficlExec.</li>
- <li>VM_QUIT now clears the locals dictionary in
- ficlExec.</li>
- </ul>
- <p>Ficlwin Enhancements </p>
- <ul>
- <li>File Menu: recent file list and Open now load
- files.</li>
- <li>Text ouput function is now faster through use of
- string caching. Cache flushes at the end of each
- line and each time ficlExec returns.</li>
- <li>Edit/paste now behaves more reasonably for text.
- File/open loads the specified file.</li>
- <li>Registry entries specify dictionary and stack
- sizes, default window placement, and whether or
- not to create a splitter for multiple VMs. See
- HKEY_CURRENT_USER/Software/CodeLab/ficlwin/Settings</li>
- </ul>
- <p>Ficl Enhancements </p>
- <ul>
- <li>This version includes changes to make it <b>64
- bit friendly</b>. This unfortunately meant that I
- had to tweak some core data types and structures.
- I've tried to make this transparent to 32 bit
- code, but a couple of things got renamed. INT64
- is now DPINT. UNS64 is now DPUNS. FICL_INT and
- FICL_UNS are synonyms for INT32 and UNS32 in 32
- bit versions, but a are obsolescent. Please use
- the new data types instead. Typed stack
- operations on INT32 and UNS32 have been renamed
- because they operate on CELL scalar types, which
- are 64 bits wide on 64 bit systems. Added
- BITS_PER_CELL, which has legal values of 32 or
- 64. Default is 32.</li>
- <li>ficl.c: Added ficlExecXT() - executes an xt
- completely before returning, passing back any
- exception codes generated in the process. Normal
- exit code is VM_INNEREXIT.</li>
- <li>ficl.c: Added ficlExecC() to operate on counted
- strings as opposed to zero terminated ones.</li>
- <li>ficlExec pushes ip and executes interpret at the
- right times so that nested calls to ficlExec
- behave the way you'd expect them to.</li>
- <li>ficlSetStackSize() allows specification of stack
- size at run-time (affects subsequent invocations
- of ficlNewVM()).</li>
- <li>vm.c: vmThrow() checks for (pVM->pState !=
- NULL) before longjmping it. vmCreate nulls this
- pointer initially. </li>
- <li>EXCEPTION wordset contributed by Daniel Sobral of
- FreeBSD</li>
- <li>MEMORY-ALLOC wordset contributed by Daniel
- Sobral, too. Added class methods <tt>alloc</tt>
- and <tt>alloc-array</tt> in softwords/oo.fr to
- allocate objects from the heap.</li>
- <li>Control structure match check upgraded (thanks to
- Daniel Sobral for this suggestion). Control
- structure mismatches are now errors, not
- warnings, since the check accepts all syntactally
- legal constructs.</li>
- <li>Added vmInnerLoop() to vm.h. This function/macro
- factors the inner interpreter out of
- ficlExec so it can be used in other places.
- Function/macro behavior is conditioned on
- INLINE_INNER_LOOP in sysdep.h. Default: 1 unless
- _DEBUG is set. In part, this is because VC++ 5
- goes apoplectic when trying to compile it as a
- function. See </li>
- <li><br>
- comments in vm.c </li>
- <li>EVALUATE respects the count parameter, and also
- passes exceptional return conditions back out to
- the calling instance of ficlExec.</li>
- <li>VM_QUIT clears locals dictionary in ficlExec()</li>
- <li>Added Michael Gauland's ficlLongMul and
- ficlLongDiv and support routines to math64.c and
- .h. These routines are coded in C, and are
- compiled only if PORTABLE_LONGMULDIV == 1
- (default is 0).</li>
- <li>Added definition of ficlRealloc to sysdep.c
- (needed for memory allocation wordset). If your
- target OS supports realloc(), you'll probably
- want to redefine ficlRealloc in those terms. The
- default version does ficlFree followed by
- ficlMalloc.</li>
- <li>testmain.c: Changed gets() in testmain to fgets()
- to appease the security gods.</li>
- <li>testmain: <tt>msec</tt> renamed to <a
- href="#ficlms"><tt>ms</tt></a> in line with the
- ANS</li>
- <li>softcore.pl now removes comments & spaces at
- the start and end of lines. As a result: sizeof
- (softWords) == 7663 bytes (used to be
- 20000) and consumes 11384 bytes of
- dictionary when compiled</li>
- <li>Deleted license paste-o in readme.txt (oops).</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td><h2>What's new in version 2.02</h2>
- <p>New words </p>
- <ul>
- <li><a
- href="http://www.taygeta.com/forth/dpans6.htm#6.2.1850"><tt>marker</tt></a><tt>
- (CORE EXT)</tt></li>
- <li><a
- href="http://www.taygeta.com/forth/dpans15.htm#15.6.2.1580"><tt>forget</tt></a><tt>
- (TOOLS EXT)</tt></li>
- <li><a href="#ficlforgetwid"><tt>forget-wid</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#ficlwordlist"><tt>ficl-wordlist</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#ficlvocabulary"><tt>ficl-vocabulary</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#ficlhide"><tt>hide</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#ficlhidden"><tt>hidden</tt></a><tt>
- (FICL)</tt></li>
- <li><a href="#jhlocal">Johns Hopkins local variable
- syntax</a> (as best I can determine)</li>
- </ul>
- <p>Bugs Fixed </p>
- <ul>
- <li><tt>forget</tt> now adjusts the dictionary
- pointer to remove the name of the word being
- forgotten (name chars come before the word header
- in ficl's dictionary)</li>
- <li><tt>:noname</tt> used to push the colon control
- marker and its execution token in the wrong order</li>
- <li><tt>source-id</tt> now behaves correctly when
- loading a file.</li>
- <li><tt>refill</tt> returns zero at EOF (Win32 load).
- Win32 <a href="#ficlload"><tt>load</tt></a>
- command continues to be misnamed. Really ought to
- be called <tt>included</tt>, but does not exactly
- conform to that spec either (because <tt>included</tt>
- expects a string signature on the stack, while
- Ficl's <a href="#ficlload"><tt>load</tt></a>
- expects a filename upon invocation). The
- "real" <tt>LOAD</tt> is a <tt>BLOCK</tt>
- word.</li>
- </ul>
- <p>Enhancements (IMHO) </p>
- <ul>
- <li>dictUnsmudge no longer links anonymous
- definitions into the dictionary</li>
- <li><tt>oop</tt> is no longer the default compile
- wordlist at startup, nor is it in the search
- order. Execute <b><tt>also oop definitions</tt></b>
- to use Ficl OOP.</li>
- <li>Revised oo.fr extensively to make more use of
- early binding</li>
- <li>Added <tt>meta</tt> - a constant that pushes the
- address of metaclass. See oo.fr for examples of
- use.</li>
- <li>Added classes: <tt>c-ptr c-bytePtr
- c-2bytePtr c-cellPtr </tt>These classes
- model pointers to non-object data, but each knows
- the size of its referent.</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td><h2>What's new in version 2.01</h2>
- <ul>
- <li>Bug fix: <tt>(local)</tt> used to leave a value
- on the stack between the first and last locals
- declared. This value is now stored in a static.</li>
- <li>Added new local syntax with parameter
- re-ordering. <a href="#newlocal">See description
- below</a>. (No longer compiled in version 2.02,
- in favor of the Johns Hopkins syntax)</li>
- </ul>
- </td>
- </tr>
- <tr>
- <td><h2>What's new in version 2.0</h2>
- <ul>
- <li>New ANS Forth words: <tt>TOOLS</tt> and part of <tt>TOOLS
- EXT, SEARCH</tt> and <tt>SEARCH EXT, LOCALS</tt>
- and <tt>LOCALS EXT</tt> word sets, additional
- words from <tt>CORE EXT, DOUBLE</tt>, and <tt>STRING</tt>.
- (See the function ficlCompileCore in words.c for
- an alphabetical list by word set).</li>
- <li>Simple <tt>USER</tt> variable support - a user
- variable is a virtual machine instance variable.
- User variables behave as <tt>VARIABLE</tt>s in
- all other respects.</li>
- <li>Object oriented syntax extensions (see below)</li>
- <li>Optional stack underflow and overflow checking in
- many CORE words (enabled when FICL_ROBUST >=
- 2)</li>
- <li>Various bug fixes</li>
- </ul>
- </td>
- </tr>
+<h3>
+ficlwin</h3>
+
+<ul>
+<li>
+Catches exceptions thrown by VM in ficlThread (0 @ for example) rather
+than passing them off to the OS. </li>
+</ul>
+
+<h3>
+ficl bugs vanquished</h3>
+
+<ul>
+<li>
+Fixed leading delimiter bugs in s" ." .( and ( (reported by Reuben Thomas)</li>
+
+<li>
+Makefile tabs restored (thanks to Michael Somos)</li>
+
+<li>
+ABORT" now throws -2 per the DPANS (thanks to Daniel Sobral for sharp eyes
+again) </li>
+
+<li>
+ficlExec does not print the prompt string unless (source-id == 0)</li>
+
+<li>
+Various fixes contributed by the FreeBSD team.</li>
+</ul>
+
+<h3>
+ficl enhancements</h3>
+
+<ul>
+<li>
+Words.c: modified ficlCatch to use vmExecute and vmInnerLoop (request of
+Daniel Sobral) Added vmPop and vmPush functions (by request of Lars Krueger
+) in vm.c These are shortcuts to the param stack. (Use LVALUEtoCELL to
+get things into CELL form) </li>
+
+<li>
+Added function vmGetStringEx with a flag to specify whether or not to skip
+lead delimiters</li>
+
+<li>
+Added non-std word: number?</li>
+
+<li>
+Added CORE EXT word AGAIN (by request of Reuben Thomas) </li>
+
+<li>
+Added double cell local (2local) support</li>
+
+<li>
+Augmented Johns Hopkins local syntax so that locals whose names begin with
+char 2 are treated as 2locals (OK - it's goofy, but handy for OOP)</li>
+
+<li>
+C-string class revised and enhanced - now dynamically sized</li>
+
+<li>
+C-hashstring class derived from c-string computes hashcode too.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td>
+<h2>
+What's new in version 2.03</h2>
+This is the first version of Ficl that includes contributed code. Thanks
+especially to Daniel Sobral, Michael Gauland for contributions and bug
+finding.
+<p>New words
+<ul>
+<li>
+<tt><a href="#clock">clock</a>
+(FICL)</tt></li>
+
+<li>
+<tt><a href="#clockspersec">clocks/sec</a>
+(FICL)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans8.htm#8.6.1.1230">dnegate</a>
+(DOUBLE)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905">ms</a>
+(FACILITY EXT - replaces MSEC <i>ficlWin only</i>)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.2275">throw</a>
+(EXCEPTION)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans9.htm#9.6.1.0875">catch</a>
+(EXCEPTION)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.0707">allocate</a>
+(MEMORY)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.1605">free</a>
+(MEMORY)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans14.htm#14.6.1.2145">resize</a>
+(MEMORY)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans6.htm#6.2.2440">within</a>
+(CORE EXT)</tt></li>
+
+<li>
+<tt><a href="#alloc">alloc</a>
+(class method)</tt></li>
+
+<li>
+<tt><a href="#allocarray">alloc-array</a>
+(class method)</tt></li>
+
+<li>
+<tt><a href="#oofree">free</a>
+(class method)</tt></li>
+</ul>
+Bugs Fixed
+<ul>
+<li>
+Bug fix in isNumber(): used to treat chars between 'Z' and 'a' as valid
+in base 10... (harmless, but weird)</li>
+
+<li>
+ficlExec pushes the <i>ip</i> and <tt>interpret</tt>s at the right times
+so that nested calls to ficlExec behave the way you'd expect them to.</li>
+
+<li>
+<tt>evaluate</tt> respects count parameter, and also passes exceptional
+return conditions back out to the calling instance of ficlExec.</li>
+
+<li>
+VM_QUIT now clears the locals dictionary in ficlExec.</li>
+</ul>
+Ficlwin Enhancements
+<ul>
+<li>
+File Menu: recent file list and Open now load files.</li>
+
+<li>
+Text ouput function is now faster through use of string caching. Cache
+flushes at the end of each line and each time ficlExec returns.</li>
+
+<li>
+Edit/paste now behaves more reasonably for text. File/open loads the specified
+file.</li>
+
+<li>
+Registry entries specify dictionary and stack sizes, default window placement,
+and whether or not to create a splitter for multiple VMs. See HKEY_CURRENT_USER/Software/CodeLab/ficlwin/Settings</li>
+</ul>
+Ficl Enhancements
+<ul>
+<li>
+This version includes changes to make it <b>64 bit friendly</b>. This unfortunately
+meant that I had to tweak some core data types and structures. I've tried
+to make this transparent to 32 bit code, but a couple of things got renamed.
+INT64 is now DPINT. UNS64 is now DPUNS. FICL_INT and FICL_UNS are synonyms
+for INT32 and UNS32 in 32 bit versions, but a are obsolescent. Please use
+the new data types instead. Typed stack operations on INT32 and UNS32 have
+been renamed because they operate on CELL scalar types, which are 64 bits
+wide on 64 bit systems. Added BITS_PER_CELL, which has legal values of
+32 or 64. Default is 32.</li>
+
+<li>
+ficl.c: Added ficlExecXT() - executes an xt completely before returning,
+passing back any exception codes generated in the process. Normal exit
+code is VM_INNEREXIT.</li>
+
+<li>
+ficl.c: Added ficlExecC() to operate on counted strings as opposed to zero
+terminated ones.</li>
+
+<li>
+ficlExec pushes ip and executes interpret at the right times so that nested
+calls to ficlExec behave the way you'd expect them to.</li>
+
+<li>
+ficlSetStackSize() allows specification of stack size at run-time (affects
+subsequent invocations of ficlNewVM()).</li>
+
+<li>
+vm.c: vmThrow() checks for (pVM->pState != NULL) before longjmping it.
+vmCreate nulls this pointer initially. </li>
+
+<li>
+EXCEPTION wordset contributed by Daniel Sobral of FreeBSD</li>
+
+<li>
+MEMORY-ALLOC wordset contributed by Daniel Sobral, too. Added class methods
+<tt>alloc</tt> and <tt>alloc-array</tt> in softwords/oo.fr to allocate
+objects from the heap.</li>
+
+<li>
+Control structure match check upgraded (thanks to Daniel Sobral for this
+suggestion). Control structure mismatches are now errors, not warnings,
+since the check accepts all syntactally legal constructs.</li>
+
+<li>
+Added vmInnerLoop() to vm.h. This function/macro factors the inner
+interpreter out of ficlExec so it can be used in other places. Function/macro
+behavior is conditioned on INLINE_INNER_LOOP in sysdep.h. Default: 1 unless
+_DEBUG is set. In part, this is because VC++ 5 goes apoplectic when trying
+to compile it as a function. See </li>
+
+<li>
+</li>
+
+<br>comments in vm.c
+<li>
+EVALUATE respects the count parameter, and also passes exceptional return
+conditions back out to the calling instance of ficlExec.</li>
+
+<li>
+VM_QUIT clears locals dictionary in ficlExec()</li>
+
+<li>
+Added Michael Gauland's ficlLongMul and ficlLongDiv and support routines
+to math64.c and .h. These routines are coded in C, and are compiled only
+if PORTABLE_LONGMULDIV == 1 (default is 0).</li>
+
+<li>
+Added definition of ficlRealloc to sysdep.c (needed for memory allocation
+wordset). If your target OS supports realloc(), you'll probably want to
+redefine ficlRealloc in those terms. The default version does ficlFree
+followed by ficlMalloc.</li>
+
+<li>
+testmain.c: Changed gets() in testmain to fgets() to appease the security
+gods.</li>
+
+<li>
+testmain: <tt>msec</tt> renamed to <tt><a href="#ficlms">ms</a></tt> in
+line with the ANS</li>
+
+<li>
+softcore.pl now removes comments & spaces at the start and end of lines.
+As a result: sizeof (softWords) == 7663 bytes (used to be 20000)
+and consumes 11384 bytes of dictionary when compiled</li>
+
+<li>
+Deleted license paste-o in readme.txt (oops).</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td>
+<h2>
+What's new in version 2.02</h2>
+New words
+<ul>
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans6.htm#6.2.1850">marker</a>
+(CORE EXT)</tt></li>
+
+<li>
+<tt><a href="http://www.taygeta.com/forth/dpans15.htm#15.6.2.1580">forget</a>
+(TOOLS EXT)</tt></li>
+
+<li>
+<tt><a href="#ficlforgetwid">forget-wid</a>
+(FICL)</tt></li>
+
+<li>
+<tt><a href="#ficlwordlist">ficl-wordlist</a> (FICL)</tt></li>
+
+<li>
+<tt><a href="#ficlvocabulary">ficl-vocabulary</a> (FICL)</tt></li>
+
+<li>
+<tt><a href="#ficlhide">hide</a>
+(FICL)</tt></li>
+
+<li>
+<tt><a href="#ficlhidden">hidden</a>
+(FICL)</tt></li>
+
+<li>
+<a href="#jhlocal">Johns Hopkins local variable syntax</a> (as best I can
+determine)</li>
+</ul>
+Bugs Fixed
+<ul>
+<li>
+<tt>forget</tt> now adjusts the dictionary pointer to remove the name of
+the word being forgotten (name chars come before the word header in ficl's
+dictionary)</li>
+
+<li>
+<tt>:noname</tt> used to push the colon control marker and its execution
+token in the wrong order</li>
+
+<li>
+<tt>source-id</tt> now behaves correctly when loading a file.</li>
+
+<li>
+<tt>refill</tt> returns zero at EOF (Win32 load). Win32 <tt><a href="#ficlload">load</a></tt>
+command continues to be misnamed. Really ought to be called <tt>included</tt>,
+but does not exactly conform to that spec either (because <tt>included</tt>
+expects a string signature on the stack, while Ficl's <tt><a href="#ficlload">load</a></tt>
+expects a filename upon invocation). The "real" <tt>LOAD</tt> is a <tt>BLOCK</tt>
+word.</li>
+</ul>
+Enhancements (IMHO)
+<ul>
+<li>
+dictUnsmudge no longer links anonymous definitions into the dictionary</li>
+
+<li>
+<tt>oop</tt> is no longer the default compile wordlist at startup, nor
+is it in the search order. Execute <b><tt>also oop definitions</tt></b>
+to use Ficl OOP.</li>
+
+<li>
+Revised oo.fr extensively to make more use of early binding</li>
+
+<li>
+Added <tt>meta</tt> - a constant that pushes the address of metaclass.
+See oo.fr for examples of use.</li>
+
+<li>
+Added classes: <tt>c-ptr c-bytePtr c-2bytePtr c-cellPtr
+</tt>These classes model pointers to non-object data, but each knows the
+size of its referent.</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td>
+<h2>
+What's new in version 2.01</h2>
+
+<ul>
+<li>
+Bug fix: <tt>(local)</tt> used to leave a value on the stack between the
+first and last locals declared. This value is now stored in a static.</li>
+
+<li>
+Added new local syntax with parameter re-ordering. <a href="#newlocal">See
+description below</a>. (No longer compiled in version 2.02, in favor of
+the Johns Hopkins syntax)</li>
+</ul>
+</td>
+</tr>
+
+<tr>
+<td>
+<h2>
+What's new in version 2.0</h2>
+
+<ul>
+<li>
+New ANS Forth words: <tt>TOOLS</tt> and part of <tt>TOOLS EXT, SEARCH</tt>
+and <tt>SEARCH EXT, LOCALS</tt> and <tt>LOCALS EXT</tt> word sets, additional
+words from <tt>CORE EXT, DOUBLE</tt>, and <tt>STRING</tt>. (See the function
+ficlCompileCore in words.c for an alphabetical list by word set).</li>
+
+<li>
+Simple <tt>USER</tt> variable support - a user variable is a virtual machine
+instance variable. User variables behave as <tt>VARIABLE</tt>s in all other
+respects.</li>
+
+<li>
+Object oriented syntax extensions (see below)</li>
+
+<li>
+Optional stack underflow and overflow checking in many CORE words (enabled
+when FICL_ROBUST >= 2)</li>
+
+<li>
+Various bug fixes</li>
+</ul>
+</td>
+</tr>
</table>
<hr>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h1>
+<a NAME="whatis"></a>What is ficl?</h1>
+<font size=+1>Ficl (Forth inspired command language) is an ANS Forth interpreter
+written in C. Unlike traditional Forths, this interpreter 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>
+</tr>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h1><a name="whatis"></a>What is ficl?</h1>
- <p><font size="4">Ficl (Forth inspired command language)
- is an ANS Forth interpreter written in C. Unlike
- traditional Forths, this interpreter 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 </font><a
- href="#includesficl"><font size="4">software that
- includes ficl</font></a><font size="4">.</font></p>
- </td>
- </tr>
- <tr>
- <td>Where Forths usually view themselves as the center of
- the system and expect the rest of the system to be coded
- in Forth, Ficl acts as a component of the system. It is
- easy to export code written in C or ASM to Ficl in the
- style of TCL, or to invoke Ficl code from a compiled
- module. This allows you to do incremental development in
- a way that combines the best features of threaded
- languages (rapid development, quick code/test/debug
- cycle, reasonably fast) with the best features of C
- (everyone knows it, easier to support large blocks of
- code, efficient, type checking). In addition, Ficl
- provides a simple object model that can act as an object
- oriented adapter for code written in C (or asm, Forth,
- C++...). </td>
- </tr>
- <tr>
- <td><b>Ficl Design goals</b> <ul>
- <li>Target 32 bit processors (<i>version 2.03 targets
- 64 bit processors too</i>)</li>
- <li>Scripting, prototyping, and extension language
- for systems written also in C</li>
- <li>Supportable - code is as transparent as I can
- make it</li>
- <li>Interface to functions written in C</li>
- <li>Conform to the Forth DPANS 94</li>
- <li>Minimize porting effort - require an ANSI C
- runtime environment and minimal glue code</li>
- <li>Provide object oriented extensions</li>
- </ul>
- </td>
- </tr>
+<tr>
+<td>Where Forths usually view themselves as the center of the system and
+expect the rest of the system to be coded in Forth, Ficl acts as a component
+of the system. It is easy to export code written in C or ASM to Ficl in
+the style of TCL, or to invoke Ficl code from a compiled module. This allows
+you to do incremental development in a way that combines the best features
+of threaded languages (rapid development, quick code/test/debug cycle,
+reasonably fast) with the best features of C (everyone knows it, easier
+to support large blocks of code, efficient, type checking). In addition,
+Ficl provides a simple object model that can act as an object oriented
+adapter for code written in C (or asm, Forth, C++...). </td>
+</tr>
+
+<tr>
+<td><b>Ficl Design goals</b>
+<ul>
+<li>
+Target 32 bit processors (<i>version 2.03 targets 64 bit processors too</i>)</li>
+
+<li>
+Scripting, prototyping, and extension language for systems written also
+in C</li>
+
+<li>
+Supportable - code is as transparent as I can make it</li>
+
+<li>
+Interface to functions written in C</li>
+
+<li>
+Conform to the Forth DPANS 94</li>
+
+<li>
+Minimize porting effort - require an ANSI C runtime environment and minimal
+glue code</li>
+
+<li>
+Provide object oriented extensions</li>
+</ul>
+</td>
+</tr>
</table>
-<p> </p>
+<br>
+<br>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="features"></a>Ficl features</h2>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="features"></a>Ficl features</h2>
- <ul>
- <li>Code is written in ANSI C for portability. </li>
- <li>Standard: Implements the ANS Forth CORE word set,
- part of the CORE EXT word set, SEARCH and SEARCH
- EXT, TOOLS and part of TOOLS EXT, LOCAL and LOCAL
- EXT, EXCEPTION, MEMORY, and various extras.</li>
- <li>Extensible: you can export code written in Forth,
- C, or asm in a straightforward way. Ficl provides
- open facilities for extending the language in an
- application specific way. You can even add new
- control structures (not surprising if you're
- familiar with Forth)</li>
- <li>Ficl and C can interact in two ways: Ficl can
- wrap C code, and C functions can invoke ficl
- code.</li>
- <li>Ficl code is thread safe and re-entrant:
- All Ficl VMs share one system dictionary; each
- Ficl virtual machine has an otherwise complete
- state, and each can be bound to a separate I/O
- channel (or none at all). An optional function
- called ficlLockDictionary() can control exclusive
- dictionary access. This function is stubbed out
- by default (See FICL_MULTITHREAD in sysdep.h). As
- long as there is only one "session"
- that can compile words into the dictionary, you
- do not need exclusive dictionary access for
- multithreading. <font color="#000099"><b>Note</b>:
- while the code is re-entrant, there are still
- restrictions on how you can use it safely in a
- multithreaded system. Specifically, the VM itself
- maintains state, so you generally need a VM per
- thread in a multithreaded system. If interrupt
- service routines make calls into Ficl code that
- alters VM state, then these generally need their
- own VM as well. Alternatively, you could provide
- a mutual exclusion mechanism to serialize access
- to a VM from multiple threads.</font></li>
- <li>Simple incorporation into existing systems: the
- sample implementation requires three Ficl
- function calls (see the example program in
- testmain.c).</li>
- <li>ROM able: Ficl is designed to work in RAM based
- and ROM code / RAM data environments. It does
- require somewhat more memory than a pure ROM
- implementation because it builds its system
- dictionary in RAM at startup time.</li>
- <li>Written an ANSI C to be as simple as I can make
- it to understand, support, debug, and port.
- Compiles without complaint at /Az /W4 (require
- ANSI C, max. warnings) under Microsoft VC++</li>
- <li>Does full 32 bit math (but you need to implement
- two mixed precision math primitives (see
- sysdep.c))</li>
- <li>Type 1 indirect threaded interpreter</li>
- </ul>
- </td>
- </tr>
+<ul>
+<li>
+Code is written in ANSI C for portability. </li>
+
+<li>
+Standard: Implements the ANS Forth CORE word set, part of the CORE EXT
+word set, SEARCH and SEARCH EXT, TOOLS and part of TOOLS EXT, LOCAL and
+LOCAL EXT, EXCEPTION, MEMORY, and various extras.</li>
+
+<li>
+Extensible: you can export code written in Forth, C, or asm in a straightforward
+way. Ficl provides open facilities for extending the language in an application
+specific way. You can even add new control structures (not surprising if
+you're familiar with Forth)</li>
+
+<li>
+Ficl and C can interact in two ways: Ficl can wrap C code, and C functions
+can invoke ficl code.</li>
+
+<li>
+Ficl code is thread safe and re-entrant: All Ficl VMs share one system
+dictionary; each Ficl virtual machine has an otherwise complete state,
+and each can be bound to a separate I/O channel (or none at all). An optional
+function called ficlLockDictionary() can control exclusive dictionary access.
+This function is stubbed out by default (See FICL_MULTITHREAD in sysdep.h).
+As long as there is only one "session" that can compile words into the
+dictionary, you do not need exclusive dictionary access for multithreading.
+<font color="#000099"><b>Note</b>: while the code is re-entrant, there
+are still restrictions on how you can use it safely in a multithreaded
+system. Specifically, the VM itself maintains state, so you generally need
+a VM per thread in a multithreaded system. If interrupt service routines
+make calls into Ficl code that alters VM state, then these generally need
+their own VM as well. Alternatively, you could provide a mutual exclusion
+mechanism to serialize access to a VM from multiple threads.</font></li>
+
+<li>
+Simple incorporation into existing systems: the sample implementation requires
+three Ficl function calls (see the example program in testmain.c).</li>
+
+<li>
+ROM able: Ficl is designed to work in RAM based and ROM code / RAM data
+environments. It does require somewhat more memory than a pure ROM implementation
+because it builds its system dictionary in RAM at startup time.</li>
+
+<li>
+Written an ANSI C to be as simple as I can make it to understand, support,
+debug, and port. Compiles without complaint at /Az /W4 (require ANSI C,
+max. warnings) under Microsoft VC++</li>
+
+<li>
+Does full 32 bit math (but you need to implement two mixed precision math
+primitives (see sysdep.c))</li>
+
+<li>
+Type 1 indirect threaded interpreter</li>
+</ul>
+</td>
+</tr>
</table>
<hr>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="porting"></a>Porting ficl</h2>
+To install ficl on your target system, you need an ANSI C compiler and
+its runtime library. Inspect the system dependent macros and functions
+in <tt>sysdep.h</tt> and <tt>sysdep.c</tt> and edit them to suit your system.
+For example, <tt>INT16</tt> is a <tt>short</tt> on some compilers and an
+<tt>int</tt> on others. Check the default <tt>CELL</tt> alignment controlled
+by <tt>FICL_ALIGN</tt>. If necessary, add new definitions of <tt>ficlMalloc,
+ficlFree, ficlLockDictionary</tt>, and <tt>ficlTextOut</tt> to work with
+your operating system. Finally, use <tt>testmain.c</tt> as a guide to installing
+the ficl system and one or more virtual machines into your code. You do
+not need to include <tt>testmain.c</tt> in your build.
+<p>Feel free to stub out the double precision math functions (which are
+presently implemented as inline assembly because it's so easy on many 32
+bit processors) with kludge code that only goes to 32 bit precision. In
+most applications, you won't notice the difference. If you're doing a lot
+of number crunching, consider implementing them correctly.
+<h3>
+Build controls</h3>
+The file sysdep.h contains default values for build controls. Most of these
+are written such that if you define them on the compiler command line,
+the defaults are overridden. I suggest you take the defaults on everything
+below the "build controls" section until you're confident of your port.
+Beware of declaring too small a dictionary, for example. You need about
+3200 cells for a full system, about 2000 if you strip out most of the "soft"
+words.
+<h3>
+To-Do List (target system dependent words)</h3>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="porting"></a>Porting ficl</h2>
- <p>To install ficl on your target system, you need an
- ANSI C compiler and its runtime library. Inspect the
- system dependent macros and functions in <tt>sysdep.h</tt>
- and <tt>sysdep.c</tt> and edit them to suit your system.
- For example, <tt>INT16</tt> is a <tt>short</tt> on some
- compilers and an <tt>int</tt> on others. Check the
- default <tt>CELL</tt> alignment controlled by <tt>FICL_ALIGN</tt>.
- If necessary, add new definitions of <tt>ficlMalloc,
- ficlFree, ficlLockDictionary</tt>, and <tt>ficlTextOut</tt>
- to work with your operating system. Finally, use <tt>testmain.c</tt>
- as a guide to installing the ficl system and one or more
- virtual machines into your code. You do not need to
- include <tt>testmain.c</tt> in your build. </p>
- <p>Feel free to stub out the double precision math
- functions (which are presently implemented as inline
- assembly because it's so easy on many 32 bit processors)
- with kludge code that only goes to 32 bit precision. In
- most applications, you won't notice the difference. If
- you're doing a lot of number crunching, consider
- implementing them correctly. </p>
- <h3>Build controls</h3>
- <p>The file sysdep.h contains default values for build
- controls. Most of these are written such that if you
- define them on the compiler command line, the defaults
- are overridden. I suggest you take the defaults on
- everything below the "build controls" section
- until you're confident of your port. Beware of declaring
- too small a dictionary, for example. You need about 3200
- cells for a full system, about 2000 if you strip out most
- of the "soft" words. </p>
- <h3>To-Do List (target system dependent words)</h3>
- <ul>
- <li>Unimplemented system dependent <tt>CORE</tt>
- word: <tt>KEY</tt> </li>
- <li>Kludged <tt>CORE</tt> word: <tt>ACCEPT</tt></li>
- </ul>
- </td>
- </tr>
+<ul>
+<li>
+Unimplemented system dependent <tt>CORE</tt> word: <tt>KEY</tt> </li>
+
+<li>
+Kludged <tt>CORE</tt> word: <tt>ACCEPT</tt></li>
+</ul>
+</td>
+</tr>
</table>
-<p> </p>
+<br>
+<br>
+<table BORDER=0 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="api"></a>Application Programming Interface</h2>
+<i>See the comments in ficl.c and ficl.h for additional information, and
+the example in file testmain.c.</i>
+<dl>
+<dt>
+<b>void ficlInitSystem(int nDictCells)</b></dt>
-<table border="0" width="600" cols="1">
- <tr>
- <td><h2><a name="api"></a>Application Programming
- Interface</h2>
- <p><i>See the comments in ficl.c and ficl.h for
- additional information, and the example in file
- testmain.c.</i> </p>
- <dl>
- <dt><b>void ficlInitSystem(int nDictCells)</b></dt>
- <dd>Initializes Ficl's shared system data structures,
- and creates the dictionary allocating the
- specified number of CELLs from the heap (by a
- call to ficlMalloc)</dd>
- <dt><b>void ficlTermSystem(void)</b></dt>
- <dd>Reclaims memory allocated for the ficl system
- including all dictionaries and all virtual
- machines created by vmCreate. Any uses of the
- memory allocation words (allocate and resize) are
- your problem.</dd>
- <dt><b>int ficlBuild(char *name, FICL_CODE code, char
- flags)</b></dt>
- <dd>Create a primitive word in ficl's main dictionary
- with the given name, code pointer, and properties
- (immediate, compile only, etc) as described by
- the flags (see ficl.h for flag descriptions of
- the form FW_XXXX)</dd>
- <dt><b>int ficlExec(FICL_VM *pVM, char *text)</b></dt>
- <dd>Feed the specified C string ('\0' terminated) to
- the given virtual machine for evaluation. Returns
- various exception codes (VM_XXXX in ficl.h) to
- indicate the reason for returning. Normal exit
- condition is VM_OUTOFTEXT, indicating that the VM
- consumed the string successfully and is back for
- more. ficlExec calls can be nested, and the
- function itself is re-entrant, but note that a VM
- is static, so you have to take reasonable
- precautions (for example, use one VM per thread
- in a multithreaded system if you want multiple
- threads to be able to execute commands).</dd>
- <dt><b>int ficlExecC(FICL_VM *pVM, char *text, int
- nChars)</b></dt>
- <dd>Same as ficlExec, but takes a count indicating
- the length of the supplied string. Setting nChars
- to -1 is equivalent to ficlExec (expects '\0'
- termination).</dd>
- <dt><b>int ficlExecXT(FICL_VM *pVM, FICL_WORD *pFW)</b></dt>
- <dd>Same as ficlExec, but takes a pointer to a
- FICL_WORD instead of a string. Executes the word
- and returns after it has finished. If executing
- the word results in an exception, this function
- will re-throw the same code if it is nested under
- another ficlExec family function, or return the
- exception code directly if not. This function is
- useful if you need to execute the same word
- repeatedly - you save the dictionary search and
- outer interpreter overhead.</dd>
- <dt><b>FICL_VM *ficlNewVM(void)</b></dt>
- <dd>Create, initialize, and return a VM from the heap
- using ficlMalloc. Links the VM into the system VM
- list for later reclamation by ficlTermSystem.</dd>
- <dt><b>FICL_WORD *ficlLookup(char *name)</b></dt>
- <dd>Returns the address (also known as an XT in this
- case) of the specified word in the main
- dictionary. If not found, returns NULL. The
- address can be used in a call to ficlExecXT.</dd>
- <dt><b>FICL_DICT *ficlGetDict(void)</b></dt>
- <dd>Returns a pointer to the main system dictionary,
- or NULL if the system is uninitialized.</dd>
- <dt><b>FICL_DICT *ficlGetEnv(void)</b></dt>
- <dd>Returns a pointer to the environment dictionary.
- This dictionary stores information that describes
- this implementation as required by the Standard.</dd>
- <dt><b>void ficlSetEnv(char *name, UNS32 value)</b></dt>
- <dd>Enters a new constant into the environment
- dictionary, with the specified name and value.</dd>
- <dt><b>void ficlSetEnvD(char *name, UNS32 hi, UNS32
- lo)</b></dt>
- <dd>Enters a new double-cell constant into the
- environment dictionary with the specified name
- and value.</dd>
- <dt><b>FICL_DICT *ficlGetLoc(void)</b></dt>
- <dd>Returns a pointer to the locals dictionary. This
- function is defined only if FICL_WANT_LOCALS is
- #defined as non-zero (see sysdep.h). The locals
- dictionary is the symbol table for <a
- href="#locals">local variables</a>.</dd>
- <dt><b>void ficlCompileCore(FICL_DICT *dp)</b></dt>
- <dd>Defined in words.c, this function builds ficl's
- primitives. </dd>
- <dt><b>void ficlCompileSoftCore(FICL_VM *pVM)</b></dt>
- <dd>Defined in softcore.c, this function builds ANS
- required words and ficl extras by evaluating a
- text string (think of it as a memory mapped file
- ;-) ). The string itself is built from files in
- the softwords directory by PERL script
- softcore.pl. </dd>
- </dl>
- </td>
- </tr>
-</table>
+<dd>
+Initializes Ficl's shared system data structures, and creates the dictionary
+allocating the specified number of CELLs from the heap (by a call to ficlMalloc)</dd>
-<hr>
+<dt>
+<b>void ficlTermSystem(void)</b></dt>
-<table border="0" cellspacing="5" width="600">
- <tr>
- <td colspan="2"><h2> <a name="manifest"></a>Ficl
- Source Files</h2>
- </td>
- </tr>
- <tr>
- <td><b>ficl.h</b></td>
- <td>Declares most public functions and all data
- structures. Includes sysdep.h and math.h</td>
- </tr>
- <tr>
- <td><b>sysdep.h</b></td>
- <td>Declares system dependent functions and contains
- build control macros. Edit this file to port to another
- system.</td>
- </tr>
- <tr>
- <td><b>math.h</b></td>
- <td>Declares functions for 64 bit math</td>
- </tr>
- <tr>
- <td><b>words.c</b></td>
- <td>Exports ficlCompileCore(), the run-time dictionary
- builder, and contains all primitive words as static
- functions.</td>
- </tr>
- <tr>
- <td><b>vm.c</b></td>
- <td>Virtual Machine methods</td>
- </tr>
- <tr>
- <td><b>stack.c</b></td>
- <td>Stack methods</td>
- </tr>
- <tr>
- <td><b>ficl.c</b></td>
- <td>System initialization, termination, and ficlExec</td>
- </tr>
- <tr>
- <td><b>dict.c</b></td>
- <td>Dictionary</td>
- </tr>
- <tr>
- <td><b>math64.c</b></td>
- <td>Implementation of 64 bit math words (except the two
- unsigned primitives declared in sysdep.h and implemented
- in sysdep.c)</td>
- </tr>
- <tr>
- <td><b>softcore.c</b></td>
- <td>Contains all of the "soft" words - those
- written in Forth and compiled by Ficl at startup time.
- Sources for these words are in the softwords directory.
- The files softwords/softcore.bat and
- softwords/softcore.pl generate softcore.c from the .fr
- sources.</td>
- </tr>
- <tr>
- <td><b>sysdep.c</b></td>
- <td>Implementation of system dependent functions declared
- in sysdep.h</td>
- </tr>
- <tr>
- <td><b>softwords/</b></td>
- <td>Directory contains sources and translation scripts
- for the words defined in softcore.c. Softcore.c depends
- on most of the files in this directory. See softcore.bat
- for the actual list of files that contribute to
- softcore.c. This is where you'll find source code for the
- object oriented extensions.</td>
- </tr>
+<dd>
+Reclaims memory allocated for the ficl system including all dictionaries
+and all virtual machines created by vmCreate. Any uses of the memory allocation
+words (allocate and resize) are your problem.</dd>
+
+<dt>
+<b>int ficlBuild(char *name, FICL_CODE code, char flags)</b></dt>
+
+<dd>
+Create a primitive word in ficl's main dictionary with the given name,
+code pointer, and properties (immediate, compile only, etc) as described
+by the flags (see ficl.h for flag descriptions of the form FW_XXXX)</dd>
+
+<dt>
+<b>int ficlExec(FICL_VM *pVM, char *text)</b></dt>
+
+<dd>
+Feed the specified C string ('\0' terminated) to the given virtual machine
+for evaluation. Returns various exception codes (VM_XXXX in ficl.h) to
+indicate the reason for returning. Normal exit condition is VM_OUTOFTEXT,
+indicating that the VM consumed the string successfully and is back for
+more. ficlExec calls can be nested, and the function itself is re-entrant,
+but note that a VM is static, so you have to take reasonable precautions
+(for example, use one VM per thread in a multithreaded system if you want
+multiple threads to be able to execute commands).</dd>
+
+<dt>
+<b>int ficlExecC(FICL_VM *pVM, char *text, int nChars)</b></dt>
+
+<dd>
+Same as ficlExec, but takes a count indicating the length of the supplied
+string. Setting nChars to -1 is equivalent to ficlExec (expects '\0' termination).</dd>
+
+<dt>
+<b>int ficlExecXT(FICL_VM *pVM, FICL_WORD *pFW)</b></dt>
+
+<dd>
+Same as ficlExec, but takes a pointer to a FICL_WORD instead of a string.
+Executes the word and returns after it has finished. If executing the word
+results in an exception, this function will re-throw the same code if it
+is nested under another ficlExec family function, or return the exception
+code directly if not. This function is useful if you need to execute the
+same word repeatedly - you save the dictionary search and outer interpreter
+overhead.</dd>
+
+<dt>
+<b>FICL_VM *ficlNewVM(void)</b></dt>
+
+<dd>
+Create, initialize, and return a VM from the heap using ficlMalloc. Links
+the VM into the system VM list for later reclamation by ficlTermSystem.</dd>
+
+<dt>
+<b>FICL_WORD *ficlLookup(char *name)</b></dt>
+
+<dd>
+Returns the address (also known as an XT in this case) of the specified
+word in the main dictionary. If not found, returns NULL. The address can
+be used in a call to ficlExecXT.</dd>
+
+<dt>
+<b>FICL_DICT *ficlGetDict(void)</b></dt>
+
+<dd>
+Returns a pointer to the main system dictionary, or NULL if the system
+is uninitialized.</dd>
+
+<dt>
+<b>FICL_DICT *ficlGetEnv(void)</b></dt>
+
+<dd>
+Returns a pointer to the environment dictionary. This dictionary stores
+information that describes this implementation as required by the Standard.</dd>
+
+<dt>
+<b>void ficlSetEnv(char *name, UNS32 value)</b></dt>
+
+<dd>
+Enters a new constant into the environment dictionary, with the specified
+name and value.</dd>
+
+<dt>
+<b>void ficlSetEnvD(char *name, UNS32 hi, UNS32 lo)</b></dt>
+
+<dd>
+Enters a new double-cell constant into the environment dictionary with
+the specified name and value.</dd>
+
+<dt>
+<b>FICL_DICT *ficlGetLoc(void)</b></dt>
+
+<dd>
+Returns a pointer to the locals dictionary. This function is defined only
+if FICL_WANT_LOCALS is #defined as non-zero (see sysdep.h). The locals
+dictionary is the symbol table for <a href="#locals">local variables</a>.</dd>
+
+<dt>
+<b>void ficlCompileCore(FICL_DICT *dp)</b></dt>
+
+<dd>
+Defined in words.c, this function builds ficl's primitives. </dd>
+
+<dt>
+<b>void ficlCompileSoftCore(FICL_VM *pVM)</b></dt>
+
+<dd>
+Defined in softcore.c, this function builds ANS required words and ficl
+extras by evaluating a text string (think of it as a memory mapped file
+;-) ). The string itself is built from files in the softwords directory
+by PERL script softcore.pl. </dd>
+</dl>
+</td>
+</tr>
</table>
<hr>
+<table BORDER=0 CELLSPACING=5 WIDTH="600" >
+<tr>
+<td COLSPAN="2">
+<h2>
+ <a NAME="manifest"></a>Ficl Source Files</h2>
+</td>
+</tr>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="locals"></a>Local Variables</h2>
- <p>Locally scoped variables came late to Forth. Purists
- seem to feel that experienced Forth programmers can write
- supportable code using only anonymous stack variables and
- good factoring, but they complain that novices use 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.</p>
- <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>
- as <tt>: -rot 2 -roll ;</tt> ) </p>
- <ul>
- <li><b><tt>\ Using LOCALS| from LOCALS EXT</tt></b> <br>
- <b><tt>: -rot ( a b c -- c a b )</tt></b>
- <br>
- <b><tt> locals| c b a |</tt></b>
- <br>
- <b><tt> c a b </tt></b> <br>
- <b><tt>;</tt></b> <br>
- <b><tt>\ Using LOCAL END-LOCAL</tt></b> <br>
- <b><tt>: -rot ( a b c -- c a b )</tt></b>
- <br>
- <b><tt> local c</tt></b> <br>
- <b><tt> local b</tt></b> <br>
- <b><tt> local a</tt></b> <br>
- <b><tt> end-locals</tt></b> <br>
- <b><tt> c a b</tt></b> <br>
- <b><tt>;</tt></b></li>
- </ul>
- <p>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. <br>
- The default maximum number of local variables is 16. It's
- controlled by FICL_MAX_LOCALS in sysdep.h. </p>
- <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 locals. Example: </p>
- <blockquote>
- <p><b><tt>:tuck0 { a b c | d -- 0 a b c }</tt></b>
- <br>
- <b><tt> d a b c ;</tt></b></p>
- </blockquote>
- <p>The | and -- delimiters can appear at most once, and
- must appear in the 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. </p>
- <p>In ficl 2.04 and later, this facilty can also declare
- double cell locals (this is handy for <a
- href="#ootutorial">OOP</a>, where objects take two cells
- to represent on the stack). Double cell locals (AKA
- 2locals) have names that start with 2. See
- ficl/softwords/string.fr for examples.</p>
- <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.
- In this case, parameters are re-ordered so that the
- rightmost initialized param comes from the top of the
- stack. The syntax is: </p>
- <blockquote>
- <p><b><tt>{{ <initialized params> --
- <cleared params> }}</tt></b></p>
- </blockquote>
- <p>You can omit either the initialized or the cleared
- parameters. Parameters after the double dash are set to
- zero initially. Those to the left are initialized from
- the stack at execution time. Examples (lame ones,
- admittedly): </p>
- <p><!--webbot bot="HTMLMarkup" startspan --><pre><!--webbot
- bot="HTMLMarkup" endspan --><b><tt>: -rot ( a
- b c -- c a b )</tt></b><br>
- <b><tt> {{ a b c }}</tt></b> <br>
- <b><tt> c a b </tt></b> <br>
- <b><tt>;</tt></b> <br>
- <b><tt>: tuck0 ( a b c -- 0 a b c )</tt></b> <br>
- <b><tt> {{ a b c -- d }}</tt></b> <br>
- <b><tt> d a b c </tt></b> <br>
- <b><tt>; <!--webbot bot="HTMLMarkup" startspan --></pre><!--webbot
- bot="HTMLMarkup" endspan --></tt></b></p>
- <h3>Search Order</h3>
- <p>Ficl implements many of the search order words in
- terms of two primitives called <a href="#tosearch"><tt>>SEARCH</tt></a>
- and <a href="#searchfrom"><tt>SEARCH></tt></a>. 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. <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
- underflows and overflows. <tt>QUIT</tt> does not affect
- the search order. The minimum search order (set by <tt>ONLY</tt>)
- is equivalent to <br>
- <b><tt>FORTH-WORDLIST 1 SET-ORDER</tt></b> <br>
- There is a default maximum of 16 wordlists in the search
- order. This can be changed by redefining
- FICL_DEFAULT_VOCS (declared in sysdep.h). </p>
- <h3>Soft Words</h3>
- <p>Many words from all the supported wordsets are written
- in Forth, and stored as a big string that Ficl compiles
- when it starts. The sources for all of these words are in
- directory ficl/softwords. There is a .bat file
- (softcore.bat) and a PERL 5 script (softcore.pl) that
- convert Forth files into the file softcore.c, so
- softcore.c is really dependent on the Forth sources. This
- is not reflected in the Visual C++ project database. For
- the time being, it's a manual step. You can edit
- softcore.bat to change the list of files that contribute
- to softcore.c. </p>
- </td>
- </tr>
+<tr>
+<td><b>ficl.h</b></td>
+
+<td>Declares most public functions and all data structures. Includes sysdep.h
+and math.h</td>
+</tr>
+
+<tr>
+<td><b>sysdep.h</b></td>
+
+<td>Declares system dependent functions and contains build control macros.
+Edit this file to port to another system.</td>
+</tr>
+
+<tr>
+<td><b>math.h</b></td>
+
+<td>Declares functions for 64 bit math</td>
+</tr>
+
+<tr>
+<td><b>words.c</b></td>
+
+<td>Exports ficlCompileCore(), the run-time dictionary builder, and contains
+all primitive words as static functions.</td>
+</tr>
+
+<tr>
+<td><b>vm.c</b></td>
+
+<td>Virtual Machine methods</td>
+</tr>
+
+<tr>
+<td><b>stack.c</b></td>
+
+<td>Stack methods</td>
+</tr>
+
+<tr>
+<td><b>ficl.c</b></td>
+
+<td>System initialization, termination, and ficlExec</td>
+</tr>
+
+<tr>
+<td><b>dict.c</b></td>
+
+<td>Dictionary</td>
+</tr>
+
+<tr>
+<td><b>math64.c</b></td>
+
+<td>Implementation of 64 bit math words (except the two unsigned primitives
+declared in sysdep.h and implemented in sysdep.c)</td>
+</tr>
+
+<tr>
+<td><b>softcore.c</b></td>
+
+<td>Contains all of the "soft" words - those written in Forth and compiled
+by Ficl at startup time. Sources for these words are in the softwords directory.
+The files softwords/softcore.bat and softwords/softcore.pl generate softcore.c
+from the .fr sources.</td>
+</tr>
+
+<tr>
+<td><b>sysdep.c</b></td>
+
+<td>Implementation of system dependent functions declared in sysdep.h</td>
+</tr>
+
+<tr>
+<td><b>softwords/</b></td>
+
+<td>Directory contains sources and translation scripts for the words defined
+in softcore.c. Softcore.c depends on most of the files in this directory.
+See softcore.bat for the actual list of files that contribute to softcore.c.
+This is where you'll find source code for the object oriented extensions.</td>
+</tr>
</table>
<hr>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="locals"></a>Local Variables</h2>
+Locally scoped variables came late to Forth. Purists seem to feel that
+experienced Forth programmers can write supportable code using only anonymous
+stack variables and good factoring, but they complain that novices use
+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.
+<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> as <tt>: -rot 2 -roll ;</tt> )
+<blockquote><b><tt>\ Using LOCALS| from LOCALS EXT</tt></b>
+<br><b><tt>: -rot ( a b c -- c a b )</tt></b>
+<br><b><tt> locals| c b a |</tt></b>
+<br><b><tt> c a b </tt></b>
+<br><b><tt>;</tt></b></blockquote>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="objects"></a>Object Oriented Programming
- in ficl</h2>
- <p>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. </p>
- <h3>Design goals of Ficl OO syntax</h3>
- <p>Ficl's object extensions provide the traditional OO
- benefits of associating data with the code that
- manipulates it, and reuse through single inheritance.
- Ficl also has some unusual capabilities that support
- interoperation with systems written in C. </p>
- <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>
- </td>
- </tr>
-</table>
+<ul><b><tt>\ Using LOCAL END-LOCAL</tt></b>
+<br><b><tt>: -rot ( a b c -- c a b )</tt></b>
+<br><b><tt> local c</tt></b>
+<br><b><tt> local b</tt></b>
+<br><b><tt> local a</tt></b>
+<br><b><tt> end-locals</tt></b>
+<br><b><tt> c a b</tt></b>
+<br><b><tt>;</tt></b></ul>
+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.
+<br>The default maximum number of local variables is 16. It's controlled
+by FICL_MAX_LOCALS in sysdep.h.
+<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
+locals. Example:
+<blockquote><b><tt>:tuck0 { a b c | d -- 0 a b c }</tt></b>
+<br><b><tt> d a b c ;</tt></b></blockquote>
+The | and -- delimiters can appear at most once, and must appear in the
+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.
+<p>In ficl 2.04 and later, this facilty can also declare double cell locals
+(this is handy for <a href="#ootutorial">OOP</a>, where objects take two
+cells to represent on the stack). Double cell locals (AKA 2locals) have
+names that start with 2. See ficl/softwords/string.fr for examples.
+<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.
+In this case, parameters are re-ordered so that the rightmost initialized
+param comes from the top of the stack. The syntax is:
+<blockquote><b><tt>{{ <initialized params> -- <cleared params> }}</tt></b></blockquote>
+You can omit either the initialized or the cleared parameters. Parameters
+after the double dash are set to zero initially. Those to the left are
+initialized from the stack at execution time. Examples (lame ones, admittedly):
+<br>
+<blockquote>
+<pre><b><tt>: -rot ( a b c -- c a b )
+ {{ a b c }}</tt></b>
+ <b><tt>c a b </tt></b>
+<b><tt>;</tt></b>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3>Ficl Object Model</h3>
- <p>All classes in Ficl are derived from the common base
- class <a href="#objectgloss"><tt>OBJECT</tt></a>. All
- classes are instances of <a href="#glossclass"><tt>METACLASS</tt></a>.
- 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: </p>
- <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>
- <p>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. </p>
- <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. <br>
- </p>
- </td>
- </tr>
+<b><tt>: tuck0 ( a b c -- 0 a b c )</tt></b>
+<b><tt> {{ a b c -- d }}</tt></b>
+<b><tt> d a b c </tt></b>
+<b><tt>; </tt></b></pre>
+</blockquote>
+
+<h3>
+Search Order</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.
+<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
+underflows and overflows. <tt>QUIT</tt> does not affect the search order.
+The minimum search order (set by <tt>ONLY</tt>) is equivalent to
+<br><b><tt>FORTH-WORDLIST 1 SET-ORDER</tt></b>
+<br>There is a default maximum of 16 wordlists in the search order. This
+can be changed by redefining FICL_DEFAULT_VOCS (declared in sysdep.h).
+<h3>
+Soft Words</h3>
+Many words from all the supported wordsets are written in Forth, and stored
+as a big string that Ficl compiles when it starts. The sources for all
+of these words are in directory ficl/softwords. There is a .bat file (softcore.bat)
+and a PERL 5 script (softcore.pl) that convert Forth files into the file
+softcore.c, so softcore.c is really dependent on the Forth sources. This
+is not reflected in the Visual C++ project database. For the time being,
+it's a manual step. You can edit softcore.bat to change the list of files
+that contribute to softcore.c. </td>
+</tr>
</table>
-<p><img src="ficl_oop.jpg" vspace="10" width="652" height="442"> </p>
+<hr>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<dl>
+<h2>
+<a NAME="extras"></a>Ficl extras</h2>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="ootutorial"></a>Ficl OO Syntax Tutorial</h2>
- <h3>Introduction</h3>
- <p>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: </p>
- <blockquote>
- <p><b><tt>( instance-addr class-addr )</tt></b></p>
- </blockquote>
- <p>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 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. </p>
- <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. </p>
- <h3>Methods and messages</h3>
- <p>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, so there's no chance of confusing a
- message with a regular word of the same name. </p>
- </td>
- </tr>
-</table>
+<h3>
+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:
+<dl>
+<dt>
+<tt>ok> decimal 123 . cr</tt> </dt>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3>Tutorial (finally!)</h3>
- <p>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: </p>
- <blockquote>
- <p><b><tt>ONLY ( reset to default search
- order )</tt></b> <br>
- <b><tt>ALSO OOP DEFINITIONS</tt></b></p>
- </blockquote>
- <p>To start, we'll work with the two base classes <tt>OBJECT</tt>
- and <tt>METACLASS</tt>. Try this: </p>
- <blockquote>
- <p><b><tt>metaclass --> methods</tt></b></p>
- </blockquote>
- <p>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. </p>
- <blockquote>
- <p><b><tt>object --> sub c-foo</tt></b></p>
- </blockquote>
- <p>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... </p>
- <blockquote>
- <p><b><tt>cell: m_cell1</tt></b> <br>
- <b><tt>4 chars: m_chars</tt></b> <br>
- <b><tt>: init ( inst class -- )</tt></b> <br>
- <b><tt> locals| class inst |</tt></b>
- <br>
- <b><tt> 0 inst class --> m_cell1
- !</tt></b> <br>
- <b><tt> inst class --> m_chars 4
- 0 fill</tt></b> <br>
- <b><tt> ." initializing an
- instance of c_foo at " inst x. cr</tt></b> <br>
- <b><tt>;</tt></b> <br>
- <b><tt>end-class</tt></b></p>
- </blockquote>
- <p>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. </p>
- <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).
- <br>
- Now make an instance of the new class: </p>
- <blockquote>
- <p><b><tt>c-foo --> new foo-instance</tt></b></p>
- </blockquote>
- <p>And try a few things... </p>
- <blockquote>
- <p><b><tt>foo-instance --> methods</tt></b> <br>
- <b><tt>foo-instance --> pedigree</tt></b></p>
- </blockquote>
- <p>Or you could type this with the same effect: </p>
- <blockquote>
- <p><b><tt>foo-instance 2dup --> methods -->
- pedigree</tt></b></p>
- </blockquote>
- <p>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: </p>
- <blockquote>
- <p><b><tt>c-foo --> see init</tt></b> <br>
- or <br>
- <b><tt>foo-instance --> class --> see init</tt></b></p>
- </blockquote>
- <p>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): </p>
- <blockquote>
- <p><b><tt>: new \ ( class metaclass
- "name" -- )</tt></b> <br>
- <b><tt> metaclass => instance
- --> init ;</tt></b></p>
- </blockquote>
- <p>Try this... </p>
- <blockquote>
- <p><b><tt>metaclass --> see new</tt></b></p>
- </blockquote>
- <p>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 run-time. <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, and Ficl's OOP syntax. </p>
- <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): <br>
- </p>
- <blockquote>
- <p><b><tt>object subclass c-wordlist \ OO model of
- FICL_HASH</tt></b> <br>
- <b><tt> cell: .parent</tt></b> <br>
- <b><tt> cell: .size</tt></b> <br>
- <b><tt> cell: .hash</tt></b> </p>
- </blockquote>
- <blockquote>
- <p><b><tt> : push drop >search ;</tt></b>
- <br>
- <b><tt> : pop 2drop previous ;</tt></b>
- <br>
- <b><tt> : set-current drop
- set-current ;</tt></b> <br>
- <b><tt> : words --> push
- words previous ;</tt></b> <br>
- <b><tt>end-class</tt></b> </p>
- </blockquote>
- <blockquote>
- <p><b><tt>: named-wid ( "name"
- -- ) </tt></b> <br>
- <b><tt> wordlist postpone
- c-wordlist metaclass => ref ;</tt></b></p>
- </blockquote>
- <p>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: </p>
- <blockquote>
- <p><b><tt>: named-wid ( "name"
- -- )</tt></b> <br>
- <b><tt> wordlist postpone
- c-wordlist --> ref ;</tt></b></p>
- </blockquote>
- <p>To do the same thing at run-time (and call it
- my-wordlist): </p>
- <blockquote>
- <p><b><tt>wordlist c-wordlist --> ref
- my-wordlist</tt></b></p>
- </blockquote>
- <p>Now you can deal with the wordlist through the ref
- instance: </p>
- <blockquote>
- <p><b><tt>my-wordlist --> push</tt></b> <br>
- <b><tt>my-wordlist --> set-current</tt></b> <br>
- <b><tt>order</tt></b></p>
- </blockquote>
- <p>Ficl can also model linked lists and other structures
- that contain pointers to structures of the same or
- different types. The class constructor word <a
- href="#exampleref:"><b><tt>ref:</tt></b></a> makes an
- aggregate reference to a particular class. See the <a
- href="#glossinstance">instance variable glossary</a> for
- an <a href="#exampleref:">example</a>. </p>
- <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 <a
- href="#arraycolon"><b><tt>array:</tt></b></a>. 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. </p>
- <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. </p>
- </td>
- </tr>
- <tr>
- <td><h2><a name="cstring"></a>Ficl String classes</h2>
- <p>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>
- <p>Examples of use:</p>
- <blockquote>
- <pre><strong>c-string --> new homer
-s" In this house, " homer --> set
-s" we obey the laws of thermodynamics!" homer --> cat
-homer --> type</strong></pre>
- </blockquote>
- </td>
- </tr>
-</table>
+<br><tt>123 </tt>
+<br><tt>ok> 0x123 . cr</tt>
+<br><tt>291 </tt></dl>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="oopgloss"></a>OOP Glossary</h2>
- <p>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. </p>
- <dl>
- <dt><b><tt>--> ( 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. </dd>
- <dt><b><tt>=> comp: ( class meta
- "method-name" -- ) 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. </dd>
- <dt><b><tt>exec-method ( 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 ( 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 ( 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 comp: (
- "method-name" -- ) 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>
+<h3>
+Search order words</h3>
+Note: Ficl resets the search order whenever it does <tt>ABORT</tt>. If
+you don't like this behavior, just comment out the dictResetSearchOrder()
+lines in ficlExec().
+<br>
+<dt>
+<a NAME="tosearch"></a><tt>>search ( wid -- )</tt></dt>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3><a name="glossinstance"></a>Instance Variable
- Glossary</h3>
- <p><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. </p>
- <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><ul>
- </ul>
- </li>
- <li><tt>object subclass c-example</tt></li>
- <li><tt>
- cell:
- .cell0</tt></li>
- <li><br>
- <tt> c-4byte obj:
- .nCells</tt> <br>
- <tt> 4 c-4byte array: .quad</tt> <br>
- <tt>
- char:
- .length</tt> <br>
- <tt> 79
- chars:
- .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>"
- <br>
- </li>
- </ul>
- <dl>
- <dt><font size="2" face="Courier New"><strong>cell:
- ( offset "name" -- offset' )</strong></font></dt>
- <dt><font size="2" face="Courier New"><strong>Execution:
- ( -- cell-addr )</strong></font></dt>
- <dd>Create an untyped instance variable one cell
- wide. The instance variable leaves its payload's
- address when executed. </dd>
- <dt><b><tt>cells:
- ( offset nCells "name" -- offset' )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- cell-addr )</tt></b></dt>
- <dd>Create an untyped instance variable n cells wide.</dd>
- <dt><b><tt>char:
- ( offset "name" -- offset' )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- char-addr )</tt></b></dt>
- <dd>Create an untyped member variable one char wide</dd>
- <dt><b><tt>chars:
- ( offset nChars "name" -- offset' )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- char-addr )</tt></b></dt>
- <dd>Create an untyped member variable n chars wide.</dd>
- <dt><b><tt>obj:
- ( offset class meta "name" -- offset' )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- 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:
- ( offset n class meta "name" -- offset'
- )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- 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:
- ( offset class meta "name" -- offset' )</tt></b></dt>
- <dt><b><tt>
- Execution: ( -- 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: </dd>
- <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>
- <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). </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 a rough example:</dd>
- <dd><dl>
- <dd><tt>object subclass c-fee</tt></dd>
- <dd><tt>object subclass c-fie</tt></dd>
- <dd><tt> c-fee ref: .fee</tt></dd>
- <dd><tt>end-class
- \ done with c-fie</tt></dd>
- <dd><tt> c-fie ref: .fie</tt></dd>
- <dd><br>
- <tt>end-class
- \ done with c-fee</tt></dd>
- </dl>
- </dd>
- </dl>
- </td>
- </tr>
-</table>
+<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>
+
+<dt>
+<a NAME="searchfrom"></a><tt>search> ( -- wid )</tt></dt>
+
+<dd>
+Pop <tt>wid</tt> off the search order</dd>
+
+<dt>
+<a NAME="ficlsetcurrent"></a><tt>ficl-set-current ( wid --
+old-wid )</tt></dt>
+
+<dd>
+Set wid as compile wordlist, leaving the previous compile wordlist on the
+stack</dd>
+
+<dt>
+<a NAME="ficlvocabulary"></a><tt>ficl-vocabulary ( nBins "name"
+-- )</tt></dt>
+
+<dd>
+Creates a <tt>ficl-wordlist</tt> with the specified number of hash table
+bins, binds it to the name, and associates the semantics of <tt>vocabulary</tt>
+with it (replaces the top wid in the search order list with its own wid
+when executed)</dd>
+
+<dt>
+<a NAME="ficlwordlist"></a><tt>ficl-wordlist ( nBins -- wid
+)</tt></dt>
+
+<dd>
+Creates a wordlist with the specified number of hash table bins, and leaves
+the address of the wordlist on the stack. A <tt>ficl-wordlist</tt> behaves
+exactly as a regular wordlist, but it may search faster depending on the
+number of bins chosen and the number of words it contains at search time.
+As implemented in ficl, a <tt>wordlist</tt> is single threaded by default. </dd>
+
+<dt>
+<a NAME="ficlforgetwid"></a><tt>forget-wid ( wid -- )</tt></dt>
+
+<dd>
+Iterates through the specified wordlist and unlinks all definitions whose
+xt addresses are greater than or equal to the value of <tt>HERE</tt>, the
+dictionary fill pointer. </dd>
+
+<dt>
+<a NAME="ficlhide"></a><tt>hide ( -- current-wid-was )</tt></dt>
+
+<dd>
+Push the <tt>hidden</tt> wordlist onto the search order, and set it as
+the current compile wordlist (unsing <tt>ficl-set-current</tt>). Leaves
+the previous compile wordlist ID. I use this word to hide implementation
+factor words that have low reuse potential so that they don't clutter the
+default wordlist. To undo the effect of hide, execute <b><tt>previous
+set-current</tt></b></dd>
+
+<dt>
+<a NAME="ficlhidden"></a><tt>hidden ( -- wid )</tt></dt>
+
+<dd>
+Wordlist for storing implementation factors of ficl provided words. To
+see what's in there, try: <b><tt>hide words previous set-current</tt></b></dd>
+
+<dt>
+<tt>wid-set-super ( wid -- )</tt></dt>
+
+<dd>
+Ficl wordlists have a parent wordlist pointer that is not specified in
+standard Forth. Ficl initializes this pointer to NULL whenever it creates
+a wordlist, so it ordinarily has no effect. This word sets the parent pointer
+to the wordlist specified on the top of the stack. Ficl's implementation
+of <tt>SEARCH-WORDLIST</tt> will chain backward through the parent link
+of the wordlist when searching. This simplifies Ficl's object model in
+that the search order does not need to reflect an object's class hierarchy
+when searching for a method. It is possible to implement Ficl object syntax
+in strict ANS Forth, but method finders need to manipulate the search order
+explicitly.</dd>
+</dl>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3><a name="glossclass"></a>Class Methods Glossary</h3>
- <p>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. </p>
- <dl>
- <dt><b><tt>instance ( class
- metaclass "name" -- instance class )</tt></b> </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 2drop</tt></dd>
- <dt><b><tt>new
- ( class metaclass "name" -- )</tt></b> </dt>
- <dd>Create an initialized instance of class, giving
- it the name specified. This method calls init to
- perform initialization. </dd>
- <dt><b><tt>array
- ( nObj class metaclass "name" -- nObjs
- instance class )</tt></b> </dt>
- <dd>Create an array of nObj instances of the
- specified class. Instances are not initialized.
- Example:</dd>
- <dd><tt>10 c_4byte --> array
- 40-raw-bytes 2drop drop</tt></dd>
- <dt><b><tt>new-array ( nObj class
- metaclass "name" -- )</tt></b> </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 (
- 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
- ( 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
- ( instance-addr class metaclass "name"
- -- )</tt></b> </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
- ( 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>
- <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>
- </dd>
- <dt><b><tt>.size
- ( class metaclass -- instance-size )</tt></b> </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
- ( class metaclass -- superclass )</tt></b> </dt>
- <dd>Returns address of the class's superclass field.
- This is a metaclass member variable.</dd>
- <dt><b><tt>.wid
- ( class metaclass -- wid )</tt></b> </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 metaclass => .size
- @ ;</tt></dd>
- <dt><b><tt>get-wid</tt></b></dt>
- <dd>Returns the wordlist ID of the class. Implemented
- as </dd>
- <dd><tt>: get-wid 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 metaclass =>
- .super @ ;</tt></dd>
- <dt><b><tt>id
- ( class metaclass -- c-addr u )</tt></b> </dt>
- <dd>Returns the address and length of a string that
- names the class.</dd>
- <dt><b><tt>methods (
- class metaclass -- )</tt></b> </dt>
- <dd>Lists methods of the class and all its
- superclasses</dd>
- <dt><b><tt>offset-of ( 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>
- <dd><dl>
- <dd><tt>metaclass --> offset-of .wid</tt></dd>
- </dl>
- </dd>
- <dt><b><tt>pedigree ( class
- metaclass -- )</tt></b> </dt>
- <dd>Lists the pedigree of the class (inheritance
- trail)</dd>
- <dt><b><tt>see
- ( class metaclass "name" -- )</tt></b> </dt>
- <dd>Decompiles the specified method - obect version
- of <tt>SEE</tt>, from the <tt>TOOLS</tt> wordset.</dd>
- </dl>
- </td>
- </tr>
-</table>
+<h3>
+User variables</h3>
+
+<dl>
+<dt>
+<tt>user ( -- ) name</tt></dt>
+
+<dd>
+Create a user variable with the given name. User variables are virtual
+machine local. Each VM allocates a fixed amount of storage for them. You
+can change the maximum number of user variables allowed by defining FICL_USER_CELLS
+on your compiiler's command line. Default is 16 user cells.</dd>
+</dl>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3><a name="objectgloss"></a><tt>object</tt>
- base-class Methods Glossary</h3>
- <p>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. </p>
- <dl>
- <dt><b><tt>init
- ( instance class -- )</tt></b><b> </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 ( nObj instance
- class -- )</tt></b> </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 (
- 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
- ( instance class -- class metaclass )</tt></b> </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
- ( instance class -- instance parent-class )</tt></b> </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 (
- instance class -- )</tt></b> </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
- ( instance class -- sizeof(instance) )</tt></b> </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 (
- instance class -- )</tt></b> </dt>
- <dd>Class method alias. Displays the list of methods
- of the class and all superclasses of the
- instance.</dd>
- <dt><b><tt>index
- ( n instance class -- instance[n] class )</tt></b> </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 </dd>
- <dd><dl>
- <dd><tt>0 my-obj --> index</tt> </dd>
- </dl>
- </dd>
- <dd>is equivalent to </dd>
- <dd><dl>
- <dd><tt>my-obj</tt></dd>
- </dl>
- </dd>
- <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
- ( instance[n] class -- instance[n+1] class )</tt></b> </dt>
- <dd>Convert an array-object signature into the
- signature of the next object in the array. No
- check for bounds overflow.</dd>
- <dt><b><tt>prev
- ( instance[n] class -- instance[n-1] class )</tt></b> </dt>
- <dd><br>
- Convert an object signature into the signature of
- the previous object in the array. No check for
- bounds underflow.</dd>
- </dl>
- </td>
- </tr>
-</table>
+<h3>
+Miscellaneous</h3>
+
+<dl>
+<dt>
+<tt>-roll ( xu xu-1 ... x0 u -- x0 xu-1 ... x1 ) </tt></dt>
+
+<dd>
+Rotate u+1 items on top of the stack after removing u. Rotation is in the
+opposite sense to <tt>ROLL</tt></dd>
+</dl>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h3><a name="stockclasses"></a>Supplied Classes (See
- classes.fr)</h3>
- <dl>
- <dt><b><tt>metaclass </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></b><b> </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></b><b> </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 &
- members: </dd>
- <dd><tt>get ( inst class -- ref-inst
- ref-class )</tt></dd>
- <dd><tt>set ( ref-inst ref-class inst
- class -- )</tt></dd>
- <dd><tt>.instance ( inst class -- a-addr
- ) </tt>cell member that holds the instance</dd>
- <dd><tt>.class ( inst class -- a-addr ) </tt>cell
- member that holds the class</dd>
- <dt><b><tt>c-byte </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
- & members:</dd>
- <dd><tt>get ( inst class -- c )</tt></dd>
- <dd><tt>set ( c inst class -- )</tt></dd>
- <dd><tt>.payload ( inst class -- addr ) </tt>member
- holds instance's value</dd>
- <dt><b><tt>c-2byte</tt></b> </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
- & members:</dd>
- <dd><tt>get ( inst class -- 2byte )</tt></dd>
- <dd><tt>set ( 2byte inst class -- )</tt></dd>
- <dd><tt>.payload ( inst class -- addr ) </tt>member
- holds instance's value</dd>
- <dt><b><tt>c-4byte</tt></b> </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
- & members:</dd>
- <dd><tt>get ( inst class -- x )</tt></dd>
- <dd><tt>set ( x inst class -- )</tt></dd>
- <dd><tt>.payload ( 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 & members:</dd>
- <dd><tt>.addr ( inst class -- a-addr )</tt>
- member variable - holds the pointer address</dd>
- <dd><tt>get-ptr ( inst class -- ptr )</tt></dd>
- <dd><tt>set-ptr ( ptr inst class -- )</tt></dd>
- <dd><tt>inc-ptr ( inst class -- )</tt>
- Adds @size to pointer address</dd>
- <dd><tt>dec-ptr ( inst class -- )</tt>
- Subtracts @size from pointer address</dd>
- <dd><tt>index-ptr ( 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 &
- members:</dd>
- <dd><tt>@size ( inst class -- size )</tt>
- Push size of the pointed-to thing</dd>
- <dd><tt>get ( inst class -- c ) </tt>Fetch
- the pointer's referent byte</dd>
- <dd><tt>set ( 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 & members:</dd>
- <dd><tt>@size ( inst class -- size )</tt>
- Push size of the pointed-to thing</dd>
- <dd><tt>get ( inst class -- x ) </tt>Fetch
- the pointer's referent 2byte</dd>
- <dd><tt>set ( 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 &
- members:</dd>
- <dd><tt>@size ( inst class -- size )</tt>
- Push size of the pointed-to thing</dd>
- <dd><tt>get ( inst class -- x ) </tt>Fetch
- the pointer's referent cell</dd>
- <dd><tt>set ( x inst class -- )</tt>
- Storex at the pointer address</dd>
- <dt><b><tt>c-string</tt></b> </dt>
- <dd>Dynamically allocated string similar to MFC
- CString (Partial list of methods follows)</dd>
- <dd><font size="2" face="Courier New">set ( c-addr u
- 2this -- ) </font><font size="3">Initialize
- buffer to the specified string</font></dd>
- <dd><font size="2" face="Courier New">get ( 2this --
- c-addr u ) Return buffer contents as counted
- string</font></dd>
- <dd><font size="2" face="Courier New">cat ( c-addr u
- 2this -- ) Append given string to end of buffer</font></dd>
- <dd><font size="2" face="Courier New">compare (
- 2string 2this -- n ) Return result of lexical
- compare</font></dd>
- <dd><font size="2" face="Courier New">type ( 2this --
- ) Print buffer to the output stream</font></dd>
- <dd><font size="2" face="Courier New">hashcode (
- 2this -- x ) Return hashcode of string (as in
- dictionary)</font></dd>
- <dd><font size="2" face="Courier New">free ( 2this --
- ) Release internal buffer</font></dd>
- </dl>
- </td>
- </tr>
-</table>
+<dl>
+<dt>
+<a NAME="minusrot"></a><tt>-rot ( a b c -- c a b )</tt></dt>
-<hr>
+<dd>
+Rotate the top three stack entries, moving the top of stack to third place.
+I like to think of this as <tt>1<sup>1</sup>/<sub>2</sub>swap</tt> because
+it's good for tucking a single cell value behind a cell-pair (like an object). </dd>
+</dl>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><dl>
- <dd><h2><a name="extras"></a>Ficl extras</h2>
- <h3>Number syntax</h3>
- <p>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: </p>
- <dl>
- <dt><tt>ok> decimal 123 . cr</tt> <br>
- <tt>123 </tt> <br>
- <tt>ok> 0x123 . cr</tt> <br>
- <tt>291 </tt></dt>
- </dl>
- <h3>Search order words</h3>
- <p>Note: Ficl resets the search order whenever it
- does <tt>ABORT</tt>. If you don't like this
- behavior, just comment out the
- dictResetSearchOrder() lines in ficlExec().
- <br>
- </p>
- </dd>
- <dt><a name="tosearch"></a><tt>>search
- ( wid -- )</tt></dt>
- <dd>Push <tt>wid</tt> onto the search order. Many of
- the other search order words are written in terms
- of the <tt>SEARCH></tt> and <tt>>SEARCH</tt>
- primitives.</dd>
- <dt><a name="searchfrom"></a><tt>search>
- ( -- wid )</tt></dt>
- <dd>Pop <tt>wid</tt> off the search order</dd>
- <dt><a name="ficlsetcurrent"></a><tt>ficl-set-current
- ( wid -- old-wid )</tt></dt>
- <dd>Set wid as compile wordlist, leaving the previous
- compile wordlist on the stack</dd>
- <dt><a name="ficlvocabulary"></a><tt>ficl-vocabulary
- ( nBins "name" -- )</tt></dt>
- <dd>Creates a <tt>ficl-wordlist</tt> with the
- specified number of hash table bins, binds it to
- the name, and associates the semantics of <tt>vocabulary</tt>
- with it (replaces the top wid in the search order
- list with its own wid when executed)</dd>
- <dt><a name="ficlwordlist"></a><tt>ficl-wordlist
- ( nBins -- wid )</tt></dt>
- <dd>Creates a wordlist with the specified number of
- hash table bins, and leaves the address of the
- wordlist on the stack. A <tt>ficl-wordlist</tt>
- behaves exactly as a regular wordlist, but it may
- search faster depending on the number of bins
- chosen and the number of words it contains at
- search time. As implemented in ficl, a <tt>wordlist</tt>
- is single threaded by default. </dd>
- <dt><a name="ficlforgetwid"></a><tt>forget-wid
- ( wid -- )</tt></dt>
- <dd>Iterates through the specified wordlist and
- unlinks all definitions whose xt addresses are
- greater than or equal to the value of <tt>HERE</tt>,
- the dictionary fill pointer. </dd>
- <dt><a name="ficlhide"></a><tt>hide ( --
- current-wid-was )</tt></dt>
- <dd>Push the <tt>hidden</tt> wordlist onto the search
- order, and set it as the current compile wordlist
- (unsing <tt>ficl-set-current</tt>). Leaves the
- previous compile wordlist ID. I use this word to
- hide implementation factor words that have low
- reuse potential so that they don't clutter the
- default wordlist. To undo the effect of hide,
- execute <b><tt>previous set-current</tt></b></dd>
- <dt><a name="ficlhidden"></a><tt>hidden (
- -- wid )</tt></dt>
- <dd>Wordlist for storing implementation factors of
- ficl provided words. To see what's in there,
- try: <b><tt>hide words previous set-current</tt></b></dd>
- <dt><tt>wid-set-super ( wid -- )</tt></dt>
- <dd>Ficl wordlists have a parent wordlist pointer
- that is not specified in standard Forth. Ficl
- initializes this pointer to NULL whenever it
- creates a wordlist, so it ordinarily has no
- effect. This word sets the parent pointer to the
- wordlist specified on the top of the stack.
- Ficl's implementation of <tt>SEARCH-WORDLIST</tt>
- will chain backward through the parent link of
- the wordlist when searching. This simplifies
- Ficl's object model in that the search order does
- not need to reflect an object's class hierarchy
- when searching for a method. It is possible to
- implement Ficl object syntax in strict ANS Forth,
- but method finders need to manipulate the search
- order explicitly.</dd>
- </dl>
- <h3>User variables</h3>
- <dl>
- <dt><tt>user ( -- ) name</tt></dt>
- <dd>Create a user variable with the given name. User
- variables are virtual machine local. Each VM
- allocates a fixed amount of storage for them. You
- can change the maximum number of user variables
- allowed by defining FICL_USER_CELLS on your
- compiiler's command line. Default is 16 user
- cells.</dd>
- </dl>
- <h3>Miscellaneous</h3>
- <dl>
- <dt><tt>-roll ( xu xu-1 ... x0 u -- x0
- xu-1 ... x1 ) </tt></dt>
- <dd>Rotate u+1 items on top of the stack after
- removing u. Rotation is in the opposite sense to <tt>ROLL</tt></dd>
- </dl>
- <dl>
- <dt><a name="minusrot"></a><tt>-rot ( a b
- c -- c a b )</tt></dt>
- <dd>Rotate the top three stack entries, moving the
- top of stack to third place. I like to think of
- this as <tt>1</tt><sup><tt>1</tt></sup><tt>/</tt><sub><tt>2</tt></sub><tt>swap</tt>
- because it's good for tucking a single cell value
- behind a cell-pair (like an object). </dd>
- </dl>
- <dl>
- <dt><tt>.env ( -- )</tt></dt>
- <dd>List all environment variables of the system</dd>
- <dt><tt>.hash ( -- )</tt></dt>
- <dd>List hash table performance statistics of the
- wordlist that's first in the search order</dd>
- <dt><tt>.ver ( -- )</tt></dt>
- <dd>Display ficl version ID</dd>
- <dt><tt>>name ( xt -- c-addr u )</tt></dt>
- <dd>Convert a word's execution token into the address
- and length of its name</dd>
- <dt><tt>body> ( a-addr -- xt )</tt></dt>
- <dd>Reverses the effect of <tt>CORE</tt> word <tt>>body
- </tt>(converts a parameter field address to an
- execution token)</dd>
- <dt><tt>compile-only</tt></dt>
- <dd>Mark the most recently defined word as being
- executable only while in compile state. Many <tt>immediate</tt>
- words have this property.</dd>
- <dt><tt>empty ( -- )</tt> </dt>
- <dd>Empty the parameter stack</dd>
- <dt><tt>endif</tt></dt>
- <dd>Synonym for <tt>THEN</tt></dd>
- <dt><tt>parse-word ( <spaces>name
- -- c-addr u )</tt></dt>
- <dd>Skip leading spaces and parse name delimited by a
- space. c-addr is the address within the input
- buffer and u is the length of the selected
- string. If the parse area is empty, the resulting
- string has a zero length. (From the Standard)</dd>
- <dt><tt>w@ ( addr -- x )</tt></dt>
- <dd>Fetch a 16 bit quantity from the specified
- address</dd>
- <dt><tt>w! ( x addr -- )</tt></dt>
- <dd>Store a 16 bit quantity to the specified address
- (the low 16 bits of the given value)</dd>
- <dt><tt>x. ( x -- )</tt></dt>
- <dd>Pop and display the value in hex format,
- regardless of the current value of <tt>BASE</tt></dd>
- </dl>
- <h3>FiclWin Extras (defined in testmain.c)</h3>
- <dl>
- <dt><tt>break ( -- )</tt></dt>
- <dd>Does nothing - just a handy place to set a
- debugger breakpoint</dd>
- <dt><tt>cd (
- "directory-name<newline>" -- )</tt></dt>
- <dd>Executes the Win32 chdir() function, changing the
- program's logged directory.</dd>
- <dt><a name="clock"></a><tt>clock ( --
- now )</tt></dt>
- <dd>Wrapper for the ANSI C clock() function. Returns
- the number of clock ticks elapsed since process
- start.</dd>
- <dt><a name="clockspersec"></a><tt>clocks/sec
- ( -- clocks_per_sec )</tt></dt>
- <dd>Pushes the number of ticks in a second as
- returned by <tt>clock</tt></dd>
- <dt><a name="ficlload"></a><tt>load
- ( "filename<newline>" -- )</tt></dt>
- <dd>Opens the Forth source file specified and loads
- it one line at a time, like <tt>INCLUDED (FILE)</tt></dd>
- <dt><tt>pwd ( -- )</tt></dt>
- <dd>Prints the current working directory as set by <tt>cd</tt></dd>
- <dt><tt>system (
- "command<newline>" -- )</tt></dt>
- <dd>Issues a command to a shell; implemented with the
- Win32 system() call.</dd>
- <dt><tt>spewhash (
- "filename<newline>" -- )</tt></dt>
- <dd>Dumps all threads of the current compilation
- wordlist to the specified text file. This was
- useful when I thought there might be some point
- in attempting to optimize the hash function. I no
- longer harbor those illusions.</dd>
- <dd><h3>FiclWin Exclusives (no source provided)</h3>
- </dd>
- <dt><tt>!oreg ( c -- )</tt></dt>
- <dd>Set the value of the simulated LED register as
- specified (0..255)</dd>
- <dt><tt>@ireg ( -- c )</tt></dt>
- <dd>Gets the value of the simulated switch block
- (0..255)</dd>
- <dt><tt>!dac ( c -- )</tt></dt>
- <dd>Sets the value of the bargraph control as
- specified. Valid values range from 0..255</dd>
- <dt><tt>@adc ( -- c )</tt></dt>
- <dd>Fetches the current position of the slider
- control. Range is 0..255</dd>
- <dt><tt>status" (
- "ccc<quote>" -- )</tt></dt>
- <dd>Set the mainframe window's status line to the
- text specified, up to the first trailing quote
- character.</dd>
- <dt><a name="ficlms"></a><a
- href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905"><tt>ms</tt></a><tt>
- ( u -- )</tt></dt>
- <dd>Causes the running virtual machine to sleep() for
- the number of milliseconds specified by the
- top-of-stack value.</dd>
- </dl>
- </td>
- </tr>
+<dl>
+<dt>
+<tt>.env ( -- )</tt></dt>
+
+<dd>
+List all environment variables of the system</dd>
+
+<dt>
+<tt>.hash ( -- )</tt></dt>
+
+<dd>
+List hash table performance statistics of the wordlist that's first in
+the search order</dd>
+
+<dt>
+<tt>.ver ( -- )</tt></dt>
+
+<dd>
+Display ficl version ID</dd>
+
+<dt>
+<tt>>name ( xt -- c-addr u )</tt></dt>
+
+<dd>
+Convert a word's execution token into the address and length of its name</dd>
+
+<dt>
+<tt>body> ( a-addr -- xt )</tt></dt>
+
+<dd>
+Reverses the effect of <tt>CORE</tt> word <tt>>body </tt>(converts a parameter
+field address to an execution token)</dd>
+
+<dt>
+<tt>compile-only</tt></dt>
+
+<dd>
+Mark the most recently defined word as being executable only while in compile
+state. Many <tt>immediate</tt> words have this property.</dd>
+
+<dt>
+<tt>empty ( -- )</tt> </dt>
+
+<dd>
+Empty the parameter stack</dd>
+
+<dt>
+<tt>endif</tt></dt>
+
+<dd>
+Synonym for <tt>THEN</tt></dd>
+
+<dt>
+<tt>parse-word ( <spaces>name -- c-addr u )</tt></dt>
+
+<dd>
+Skip leading spaces and parse name delimited by a space. c-addr is the
+address within the input buffer and u is the length of the selected string.
+If the parse area is empty, the resulting string has a zero length. (From
+the Standard)</dd>
+
+<dt>
+<tt>w@ ( addr -- x )</tt></dt>
+
+<dd>
+Fetch a 16 bit quantity from the specified address</dd>
+
+<dt>
+<tt>w! ( x addr -- )</tt></dt>
+
+<dd>
+Store a 16 bit quantity to the specified address (the low 16 bits of the
+given value)</dd>
+
+<dt>
+<tt>x. ( x -- )</tt></dt>
+
+<dd>
+Pop and display the value in hex format, regardless of the current value
+of <tt>BASE</tt></dd>
+</dl>
+
+<h3>
+FiclWin Extras (defined in testmain.c)</h3>
+
+<dl>
+<dt>
+<tt>break ( -- )</tt></dt>
+
+<dd>
+Does nothing - just a handy place to set a debugger breakpoint</dd>
+
+<dt>
+<tt>cd ( "directory-name<newline>" --
+)</tt></dt>
+
+<dd>
+Executes the Win32 chdir() function, changing the program's logged directory.</dd>
+
+<dt>
+<a NAME="clock"></a><tt>clock ( -- now )</tt></dt>
+
+<dd>
+Wrapper for the ANSI C clock() function. Returns the number of clock ticks
+elapsed since process start.</dd>
+
+<dt>
+<a NAME="clockspersec"></a><tt>clocks/sec ( -- clocks_per_sec
+)</tt></dt>
+
+<dd>
+Pushes the number of ticks in a second as returned by <tt>clock</tt></dd>
+
+<dt>
+<a NAME="ficlload"></a><tt>load ( "filename<newline>"
+-- )</tt></dt>
+
+<dd>
+Opens the Forth source file specified and loads it one line at a time,
+like <tt>INCLUDED (FILE)</tt></dd>
+
+<dt>
+<tt>pwd ( -- )</tt></dt>
+
+<dd>
+Prints the current working directory as set by <tt>cd</tt></dd>
+
+<dt>
+<tt>system ( "command<newline>" -- )</tt></dt>
+
+<dd>
+Issues a command to a shell; implemented with the Win32 system() call.</dd>
+
+<dt>
+<tt>spewhash ( "filename<newline>" -- )</tt></dt>
+
+<dd>
+Dumps all threads of the current compilation wordlist to the specified
+text file. This was useful when I thought there might be some point in
+attempting to optimize the hash function. I no longer harbor those illusions.</dd>
+
+<h3>
+FiclWin Exclusives (no source provided)</h3>
+
+<dt>
+<tt>!oreg ( c -- )</tt></dt>
+
+<dd>
+Set the value of the simulated LED register as specified (0..255)</dd>
+
+<dt>
+<tt>@ireg ( -- c )</tt></dt>
+
+<dd>
+Gets the value of the simulated switch block (0..255)</dd>
+
+<dt>
+<tt>!dac ( c -- )</tt></dt>
+
+<dd>
+Sets the value of the bargraph control as specified. Valid values range
+from 0..255</dd>
+
+<dt>
+<tt>@adc ( -- c )</tt></dt>
+
+<dd>
+Fetches the current position of the slider control. Range is 0..255</dd>
+
+<dt>
+<tt>status" ( "ccc<quote>" -- )</tt></dt>
+
+<dd>
+Set the mainframe window's status line to the text specified, up to the
+first trailing quote character.</dd>
+
+<dt>
+<a NAME="ficlms"></a><tt><a href="http://www.taygeta.com/forth/dpans10.htm#10.6.2.1905">ms</a>
+( u -- )</tt></dt>
+
+<dd>
+Causes the running virtual machine to sleep() for the number of milliseconds
+specified by the top-of-stack value.</dd>
+</dl>
+</td>
+</tr>
</table>
<hr>
+<p><a NAME="ansinfo"></a>
+<p>ANS Required Information
+<br>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td><b>ANS Forth System</b>
+<br><b>Providing names from the Core Extensions word set </b>
+<br><b>Providing the Exception word set</b>
+<br><b>Providing names from the Exception Extensions word set</b>
+<br><b>Providing the Locals word set </b>
+<br><b>Providing the Locals Extensions word set </b>
+<br><b>Providing the Memory Allocation word set</b>
+<br><b>Providing the Programming-Tools word set</b>
+<br><b>Providing names from the Programming-Tools Extensions word set</b>
+<br><b>Providing the Search-Order word set</b>
+<br><b>Providing the Search-Order Extensions word set</b>
+<h3>
+Implementation-defined Options</h3>
+The implementation-defined items in the following list represent characteristics
+and choices left to the discretion of the implementor, provided that the
+requirements of the Standard are met. A system shall document the values
+for, or behaviors of, each item.
+<ul>
+<li>
+<b>aligned address requirements (3.1.3.3 Addresses);</b> </li>
-<p><a name="ansinfo"></a></p>
+<li>
+</li>
-<p>ANS Required Information </p>
+<br><font color="#000000">System dependent. You can change the default
+address alignment by defining FICL_ALIGN on your compiler's command line.
+The default value is set to 2 in sysdep.h. This causes dictionary entries
+and <tt>ALIGN</tt> and <tt>ALIGNED</tt> to align on 4 byte boundaries.
+To align on <b>2<sup>n</sup></b> byte boundaries, set FICL_ALIGN to <b>n</b>. </font>
+<li>
+<b>behavior of 6.1.1320 EMIT for non-graphic characters</b>; </li>
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><b>ANS Forth System</b> <br>
- <b>Providing names from the Core Extensions word
- set </b> <br>
- <b>Providing the Exception word set</b> <br>
- <b>Providing names from the Exception Extensions word set</b>
- <br>
- <b>Providing the Locals word set </b> <br>
- <b>Providing the Locals Extensions word set </b> <br>
- <b>Providing the Memory Allocation word set</b> <br>
- <b>Providing the Programming-Tools word set</b> <br>
- <b>Providing names from the Programming-Tools Extensions
- word set</b> <br>
- <b>Providing the Search-Order word set</b> <br>
- <b>Providing the Search-Order Extensions word set</b> <h3>Implementation-defined
- Options</h3>
- <p>The implementation-defined items in the following list
- represent characteristics and choices left to the
- discretion of the implementor, provided that the
- requirements of the Standard are met. A system shall
- document the values for, or behaviors of, each
- item. </p>
- <ul>
- <li><b>aligned address requirements (3.1.3.3
- Addresses);</b> </li>
- <li><br>
- <font color="#000000">System dependent. You can
- change the default address alignment by defining
- FICL_ALIGN on your compiler's command line. The
- default value is set to 2 in sysdep.h. This
- causes dictionary entries and <tt>ALIGN</tt> and <tt>ALIGNED</tt>
- to align on 4 byte boundaries. To align on <b>2</b><sup><b>n</b></sup>
- byte boundaries, set FICL_ALIGN to <b>n</b>. </font>
- </li>
- <li><b>behavior of 6.1.1320 EMIT for non-graphic
- characters</b>; </li>
- <li><br>
- <font color="#000000">Depends on target system, C
- runtime library, and your implementation of
- ficlTextOut().</font> </li>
- <li><b>character editing of 6.1.0695 ACCEPT and
- 6.2.1390 EXPECT</b>; </li>
- <li><br>
- <font color="#000000">None implemented in the
- versions supplied in words.c. Because ficlExec()
- is supplied a text buffer externally, it's up to
- your system to define how that buffer will be
- obtained.</font> </li>
- <li><b>character set (3.1.2 Character types, 6.1.1320
- EMIT, 6.1.1750 KEY)</b>; </li>
- <li><br>
- <font color="#000000">Depends on target system
- and implementation of ficlTextOut()</font> </li>
- <li><b>character-aligned address requirements
- (3.1.3.3 Addresses)</b>; </li>
- <li><br>
- <font color="#000000">Ficl characters are one
- byte each. There are no alignment requirements.</font>
- </li>
- <li><b>character-set-extensions matching
- characteristics (3.4.2 Finding definition n</b><font
- color="#000000"><b>ames)</b>; </font></li>
- <li><br>
- <font color="#000000">No special processing is
- performed on characters beyond case-folding.
- Therefore, extended characters will not match
- their unaccented counterparts.</font> </li>
- <li><b>conditions under which control characters
- match a space delimiter (3.4.1.1 Delimiters)</b>;<font
- color="#FF6666"> </font></li>
- <li><br>
- <font color="#000000">Ficl uses the Standard C
- function isspace() to distinguish space
- characters. The rest is up to your library
- vendor.</font> </li>
- <li><b>format of the control-flow stack (3.2.3.2
- Control-flow stack)</b>; </li>
- <li><br>
- <font color="#000000">Uses the data stack</font> </li>
- <li><b>conversion of digits larger than thirty-five
- (3.2.1.2 Digit conversion)</b>; </li>
- <li><br>
- <font color="#000000">The maximum supported value
- of <tt>BASE</tt> is 36. Ficl will assertion fail
- in function ltoa of vm.c if the base is found to
- be larger than 36 or smaller than 2. There will
- be no effect if NDEBUG is defined</font>,
- however, other than possibly unexpected
- behavior. </li>
- <li><b>display after input terminates in 6.1.0695
- ACCEPT and 6.2.1390 EXPECT</b>; </li>
- <li><br>
- <font color="#000000">Target system dependent</font>
- </li>
- <li><b>exception abort sequence (as in 6.1.0680
- ABORT")</b>; </li>
- <li><br>
- <font color="#000000">Does <tt>ABORT</tt></font> </li>
- <li><b>input line terminator (3.2.4.1 User input
- device)</b>;<font color="#FF0000"> </font></li>
- <li><br>
- <font color="#000000">Target system dependent
- (implementation of outer loop that calls
- ficlExec)</font> </li>
- <li><b>maximum size of a counted string, in
- characters (3.1.3.4 Counted strings, 6.1.2450
- WORD)</b>; </li>
- <li><br>
- <font color="#000000">255</font> </li>
- <li><b>maximum size of a parsed string (3.4.1
- Parsing)</b>; </li>
- <li><br>
- Limited by available memory and the maximum
- unsigned value that can fit in a CELL (2<sup>32</sup>-1).
- </li>
- <li><b>maximum size of a definition name, in
- characters (3.3.1.2 Definition names)</b>; </li>
- <li><br>
- <font color="#000000">Ficl stores the first 31
- characters of a definition name.</font> </li>
- <li><b>maximum string length for 6.1.1345
- ENVIRONMENT?, in characters</b>; </li>
- <li><br>
- <font color="#000000">Same as maximum definition
- name length</font> </li>
- <li><b>method of selecting 3.2.4.1 User input device</b>; </li>
- <li><br>
- None supported. This is up to the target
- system </li>
- <li><b>method of selecting 3.2.4.2 User output device</b>; </li>
- <li><br>
- None supported. This is up to the target
- system </li>
- <li><b>methods of dictionary compilation (3.3 The
- Forth dictionary)</b>; </li>
- <li><b>number of bits in one address unit (3.1.3.3
- Addresses)</b>; </li>
- <li><br>
- <font color="#000000">Target system dependent.
- Ficl generally supports processors that can
- address 8 bit quantities, but there is no
- dependency that I'm aware of.</font> </li>
- <li><b>number representation and arithmetic (3.2.1.1
- Internal number representation)</b>; </li>
- <li><br>
- System dependent. Ficl represents a CELL
- internally as a union that can hold INT32 (a
- signed 32 bit scalar value), UNS32 (32 bits
- unsigned), and an untyped pointer. No specific
- byte ordering is assumed. </li>
- <li><b>ranges for n, +n, u, d, +d, and ud (3.1.3
- Single-cell types, 3.1.4 Cell-pair types)</b>; </li>
- <li><br>
- Assuming a 32 bit implementation, range for
- signed single-cell values is -2<sup>31</sup>..2<sup>31</sup>-1.
- Range for unsigned single cell values is 0..2<sup>32</sup>-1.
- Range for signed double-cell values is -2<sup>63</sup>..2<sup>63</sup>-1.
- Range for unsigned single cell values is 0..2<sup>64</sup>-1.
- </li>
- <li><b>read-only data-space regions (3.3.3 Data
- space)</b>;</li>
- <li><br>
- None </li>
- <li><b>size of buffer at 6.1.2450 WORD (3.3.3.6 Other
- transient regions)</b>; </li>
- <li><br>
- Default is 255. Depends on the setting of nPAD in
- ficl.h. </li>
- <li><b>size of one cell in address units (3.1.3
- Single-cell types)</b>; </li>
- <li><br>
- <font color="#000000">System dependent, generally
- four.</font> </li>
- <li><b>size of one character in address units (3.1.2
- Character types)</b>; </li>
- <li><br>
- <font color="#000000">System dependent, generally
- one.</font> </li>
- <li><b>size of the keyboard terminal input buffer
- (3.3.3.5 Input buffers)</b>; </li>
- <li><br>
- <font color="#000000">This buffer is supplied by
- the host program. Ficl imposes no practical
- limit.</font> </li>
- <li><b>size of the pictured numeric output string
- buffer (3.3.3.6 Other transient regions)</b>; </li>
- <li><br>
- Default is 255 characters. Depends on the setting
- of nPAD in ficl.h. </li>
- <li><b>size of the scratch area whose address is
- returned by 6.2.2000 PAD (3.3.3.6 Other transient
- regions)</b>; </li>
- <li><br>
- Not presently supported </li>
- <li><b>system case-sensitivity characteristics (3.4.2
- Finding definition names)</b>; </li>
- <li><br>
- <font color="#000000">Ficl is not case sensitive</font>
- </li>
- <li><b>system prompt (3.4 The Forth text interpreter,
- 6.1.2050 QUIT)</b>; </li>
- <li><br>
- <font color="#000000">"ok>"</font> </li>
- <li><b>type of division rounding (3.2.2.1 Integer
- division, 6.1.0100 */, 6.1.0110 */MOD, 6.1.0230
- /, 6.1.0240 /MOD, 6.1.1890 MOD)</b>; </li>
- <li><br>
- <font color="#000000">Symmetric</font> </li>
- <li><b>values of 6.1.2250 STATE when true</b>; </li>
- <li><br>
- <font color="#000000">One (no others)</font> </li>
- <li><b>values returned after arithmetic overflow
- (3.2.2.2 Other integer operations)</b>; </li>
- <li><br>
- System dependent. Ficl makes no special checks
- for overflow. </li>
- <li><b>whether the current definition can be found
- after 6.1.1250 DOES> (6.1.0450 :)</b>. </li>
- <li><br>
- <font color="#000000">No. Definitions are
- unsmudged after ; only, and only then if no
- control structure matching problems have been
- detected.</font></li>
- </ul>
- <h3>Ambiguous Conditions</h3>
- <p>A system shall document the system action taken upon
- each of the general or specific ambiguous conditions
- identified in this Standard. See 3.4.4 Possible actions
- on an ambiguous condition. </p>
- <p>The following general ambiguous conditions could occur
- because of a combination of factors: </p>
- <ul>
- <li><dl>
- </dl>
- </li>
- <li><b>a name is neither a valid definition name nor
- a valid number during text interpretation (3.4
- The Forth text interpreter)</b>; </li>
- <li><br>
- <font color="#000000">Ficl does <tt>ABORT</tt>
- and prints the name followed by " not
- found".</font> </li>
- <li><b>a definition name exceeded the maximum length
- allowed (3.3.1.2 Definition names)</b>; </li>
- <li><br>
- <font color="#000000">Ficl stores the first 31
- characters of the definition name, and uses all
- characters of the name in computing its hash
- code. The actual length of the name, up to 255
- characters, is stored in the definition's length
- field.</font> </li>
- <li><b>addressing a region not listed in 3.3.3 Data
- Space</b>; </li>
- <li><br>
- <font color="#000000">No problem: all addresses
- in ficl are absolute. You can reach any 32 bit
- address in Ficl's address space.</font> </li>
- <li><b>argument type incompatible with specified
- input parameter, e.g., passing a flag to a word
- expecting an n (3.1 Data types)</b>; </li>
- <li><br>
- <font color="#000000">Ficl makes no check for
- argument type compatibility. Effects of a
- mismatch vary widely depending on the specific
- problem and operands.</font> </li>
- <li><b>attempting to obtain the execution token,
- (e.g., with 6.1.0070 ', 6.1.1550 FIND, etc.) of a
- definition with undefined interpretation
- semantics</b>; </li>
- <li><br>
- <font color="#000000">Ficl returns a valid token,
- but the result of executing that token while
- interpreting may be undesirable.</font> </li>
- <li><b>dividing by zero (6.1.0100 */, 6.1.0110 */MOD,
- 6.1.0230 /, 6.1.0240 /MOD, 6.1.1561 FM/MOD,
- 6.1.1890 MOD, 6.1.2214 SM/REM, 6.1.2370 UM/MOD,
- 8.6.1.1820 M*/)</b>;</li>
- <li><br>
- <font color="#000000">Results are target procesor
- dependent. Generally, Ficl makes no check for
- divide-by-zero. The target processor will
- probably throw an exception.</font> </li>
- <li><b>insufficient data-stack space or return-stack
- space (stack overflow)</b>; </li>
- <li><br>
- <font color="#000000">With FICL_ROBUST (sysdep.h)
- set >= 2, most parameter stack operations are
- checked for underflow and overflow. Ficl does not
- check the return stack.</font> </li>
- <li><b>insufficient space for loop-control parameters</b>; </li>
- <li><br>
- <font color="#000000">No check - Evil results.</font>
- </li>
- <li><b>insufficient space in the dictionary</b>; </li>
- <li><br>
- <font color="#000000">Ficl generates an error
- message if the dictionary is too full to create a
- definition header. It checks <tt>ALLOT</tt> as
- well, but it is possible to make an unchecked
- allocation request that overflows the dictionary.</font>
- </li>
- <li><b>interpreting a word with undefined
- interpretation semantics</b>; </li>
- <li><br>
- <font color="#000000">Ficl protects all ANS Forth
- words with undefined interpretation semantics
- from being executed while in interpret state. It
- is possible to defeat this protection using '
- (tick) and <tt>EXECUTE</tt>, though.</font> </li>
- <li><b>modifying the contents of the input buffer or
- a string literal (3.3.3.4 Text-literal regions,
- 3.3.3.5 Input buffers)</b>; </li>
- <li><br>
- <font color="#000000">Varies depending on the
- nature of the buffer. The input buffer is
- supplied by ficl's host function, and may reside
- in read-only memory. If so, writing the input
- buffer can ganerate an exception. String literals
- are stored in the dictionary, and are writable.</font>
- </li>
- <li><b>overflow of a pictured numeric output string</b>;</li>
- <li><br>
- In the unlikely event you are able to construct a
- pictured numeric string of more than 255
- characters, the system will be corrupted
- unpredictably. The buffer area that holds
- pictured numeric output is at the end of the
- virtual machine. Whatever is mapped after the
- offending VM in memory will be trashed, along
- with the heap structures that contain it. </li>
- <li><b>parsed string overflow</b>;</li>
- <li><br>
- Ficl does not copy parsed strings unless asked
- to. Ordinarily, a string parsed from the input
- buffer during normal interpretation is left
- in-place, so there is no possibility of overflow.
- If you ask to parse a string into the dictionary,
- as in <tt>SLITERAL</tt>, you need to have enough
- room for the string, otherwise bad things may
- happen. This is not usually a problem. </li>
- <li><b>producing a result out of range, e.g.,
- multiplication (using *) results in a value too
- big to be represented by a single-cell integer
- (6.1.0090 *, 6.1.0100 */, 6.1.0110 */MOD,
- 6.1.0570 >NUMBER, 6.1.1561 FM/MOD, 6.1.2214
- SM/REM, 6.1.2370 UM/MOD, 6.2.0970 CONVERT,
- 8.6.1.1820 M*/)</b>; </li>
- <li><br>
- <font color="#000000">Value will be truncated</font>
- </li>
- <li><b>reading from an empty data stack or return
- stack (stack underflow)</b>; </li>
- <li><br>
- <font color="#000000">Most stack underflows are
- detected and prevented if FICL_ROBUST (sysdep.h)
- is set to 2 or greater. Otherwise, the stack
- pointer and size are likely to be trashed.</font>
- </li>
- <li><b>unexpected end of input buffer, resulting in
- an attempt to use a zero-length string as a name</b>; </li>
- <li><br>
- <font color="#000000">Ficl returns for a new
- input buffer until a non-empty one is supplied.</font></li>
- </ul>
- <p>The following specific ambiguous conditions are noted
- in the glossary entries of the relevant words: </p>
- <ul>
- <li><b>>IN greater than size of input buffer
- (3.4.1 Parsing)</b></li>
- <li><br>
- Bad Things occur - unpredictable bacause the
- input buffer is supplied by the host program's
- outer loop. </li>
- <li><b>6.1.2120 RECURSE appears after 6.1.1250
- DOES></b></li>
- <li><br>
- It finds the address of the definition before <tt>DOES></tt>
- </li>
- <li><b>argument input source different than current
- input source for 6.2.2148 RESTORE-INPUT</b></li>
- <li><br>
- Not implemented </li>
- <li><b>data space containing definitions is
- de-allocated (3.3.3.2 Contiguous regions)</b></li>
- <li><br>
- This is OK until the cells are overwritten with
- something else. The dictionary maintains a hash
- table, and the table must be updated in order to
- de-allocate words without corruption. </li>
- <li><b>data space read/write with incorrect alignment
- (3.3.3.1 Address alignment)</b></li>
- <li><br>
- Target processor dependent. Consequences include:
- none (Intel), address error exception
- (68K). </li>
- <li><b>data-space pointer not properly aligned
- (6.1.0150 ,, 6.1.0860 C,)</b></li>
- <li><br>
- See above on data space read/write
- alignment </li>
- <li><b>less than u+2 stack items (6.2.2030 PICK,
- 6.2.2150 ROLL)</b></li>
- <li><br>
- Ficl detects a stack underflow and reports it,
- executing <tt>ABORT,</tt> as long as FICL_ROBUST
- is two or larger. </li>
- <li><b>loop-control parameters not available (
- 6.1.0140 +LOOP, 6.1.1680 I, 6.1.1730 J, 6.1.1760
- LEAVE, 6.1.1800 LOOP, 6.1.2380 UNLOOP)</b></li>
- <li><br>
- Loop initiation words are responsible for
- checking the stack and guaranteeing that the
- control parameters are pushed. Any underflows
- will be detected early if FICL_ROBUST is set to
- two or greater. Note however that Ficl only
- checks for return stack underflows at the end of
- each line of text. </li>
- <li><b>most recent definition does not have a name
- (6.1.1710 IMMEDIATE)</b></li>
- <li><br>
- No problem. </li>
- <li><b>name not defined by 6.2.2405 VALUE used by
- 6.2.2295 TO</b></li>
- <li><br>
- Ficl's version of <tt>TO</tt> works correctly
- with <tt>VALUE</tt>s, <tt>CONSTANT</tt>s and <tt>VARIABLE</tt>s.
- </li>
- <li><b>name not found (6.1.0070 ', 6.1.2033 POSTPONE,
- 6.1.2510 ['], 6.2.2530 [COMPILE])</b></li>
- <li><br>
- Ficl prints an error message and does <tt>ABORT</tt>
- </li>
- <li><b>parameters are not of the same type (6.1.1240
- DO, 6.2.0620 ?DO, 6.2.2440 WITHIN)</b></li>
- <li><br>
- No check. Results vary depending on the specific
- problem. </li>
- <li><b>6.1.2033 POSTPONE or 6.2.2530 [COMPILE]
- applied to 6.2.2295 TO</b></li>
- <li><br>
- The word is postponed correctly. </li>
- <li><b>string longer than a counted string returned
- by 6.1.2450 WORD</b></li>
- <li><br>
- Ficl stores the first FICL_STRING_MAX-1 chars in
- the destination buffer. (The extra character is
- the trailing space required by the standard.
- Yuck.) </li>
- <li><b>u greater than or equal to the number of bits
- in a cell (6.1.1805 LSHIFT, 6.1.2162 RSHIFT)</b></li>
- <li><br>
- Depends on target process or and C runtime
- library implementations of the << and
- >> operators on unsigned values. For I386,
- the processor appears to shift modulo the number
- of bits in a cell. </li>
- <li><b>word not defined via 6.1.1000 CREATE (6.1.0550
- >BODY, 6.1.1250 DOES>)</b></li>
- <li><br>
- <b>words improperly used outside 6.1.0490 <#
- and 6.1.0040 #> (6.1.0030 #, 6.1.0050 #S,
- 6.1.1670 HOLD, 6.1.2210 SIGN)</b> <br>
- Don't. <tt>CREATE</tt> reserves a field in words
- it builds for <tt>DOES></tt>to fill in. If you
- use <tt>DOES></tt> on a word not made by <tt>CREATE</tt>,
- it will overwrite the first cell of its parameter
- area. That's probably not what you want.
- Likewise, pictured numeric words assume that
- there is a string under construction in the VM's
- scratch buffer. If that's not the case, results
- may be unpleasant.</li>
- </ul>
- <h3>Locals Implementation-defined options</h3>
- <ul>
- <li><b>maximum number of locals in a definition
- (13.3.3 Processing locals, 13.6.2.1795 LOCALS|)</b></li>
- <li><br>
- Default is 16. Change by redefining
- FICL_MAX_LOCALS, defined in sysdep.h</li>
- </ul>
- <h3>Locals Ambiguous conditions</h3>
- <ul>
- <li><b>executing a named local while in
- interpretation state (13.6.1.0086 (LOCAL))</b></li>
- <li><br>
- Locals can be found in interpretation state while
- in the context of a definition under
- construction. Under these circumstances, locals
- behave correctly. Locals are not visible at all
- outside the scope of a definition. </li>
- <li><b>name not defined by VALUE or LOCAL
- (13.6.1.2295 TO)</b></li>
- <li><br>
- See the CORE ambiguous conditions, above (no
- change)</li>
- </ul>
- <h3>Programming Tools Implementation-defined options</h3>
- <ul>
- <li><b>source and format of display by 15.6.1.2194
- SEE</b></li>
- <li><br>
- SEE de-compiles definitions from the dictionary.
- Because Ficl words are threaded by their header
- addresses, it is very straightforward to print
- the name and other characteristics of words in a
- definition. Primitives are so noted. Colon
- definitions are decompiled, but branch target
- labels are not reconstructed. Literals and string
- literals are so noted, and their contents
- displayed.</li>
- </ul>
- <h3>Search Order Implementation-defined options</h3>
- <ul>
- <li><b>maximum number of word lists in the search
- order (16.3.3 Finding definition names,
- 16.6.1.2197 SET-ORDER)</b> </li>
- <li><br>
- Defaults to 16. Can be changed by redefining
- FICL_DEFAULT_VOCS, declared in sysdep.h </li>
- <li><b>minimum search order (16.6.1.2197 SET-ORDER,
- 16.6.2.1965 ONLY)</b> </li>
- <li><br>
- Equivalent to <tt>FORTH-WORDLIST 1 SET-ORDER</tt></li>
- </ul>
- <h3>Search Order Ambiguous conditions</h3>
- <ul>
- <li><b>changing the compilation word list (16.3.3
- Finding definition names)</b></li>
- <li><br>
- Ficl stores a link to the current definition
- independently of the compile wordlist while it is
- being defined, and links it into the compile
- wordlist only after the definition completes
- successfully. Changing the compile wordlist
- mid-definition will cause the definition to link
- into the <i>new</i> compile wordlist. </li>
- <li><b>search order empty (16.6.2.2037 PREVIOUS)</b></li>
- <li><br>
- Ficl prints an error message if the search order
- underflows, and resets the order to its default
- state. </li>
- <li><b>too many word lists in search order
- (16.6.2.0715 ALSO)</b></li>
- <li><br>
- Ficl prints an error message if the search order
- overflows, and resets the order to its default
- state.</li>
- </ul>
- </td>
- </tr>
+<li>
+</li>
+
+<br><font color="#000000">Depends on target system, C runtime library,
+and your implementation of ficlTextOut().</font>
+<li>
+<b>character editing of 6.1.0695 ACCEPT and 6.2.1390 EXPECT</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">None implemented in the versions supplied in
+words.c. Because ficlExec() is supplied a text buffer externally, it's
+up to your system to define how that buffer will be obtained.</font>
+<li>
+<b>character set (3.1.2 Character types, 6.1.1320 EMIT, 6.1.1750 KEY)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Depends on target system and implementation of
+ficlTextOut()</font>
+<li>
+<b>character-aligned address requirements (3.1.3.3 Addresses)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl characters are one byte each. There are
+no alignment requirements.</font>
+<li>
+<b>character-set-extensions matching characteristics (3.4.2 Finding definition
+n<font color="#000000">ames)</font></b><font color="#000000">; </font></li>
+
+<li>
+</li>
+
+<br><font color="#000000">No special processing is performed on characters
+beyond case-folding. Therefore, extended characters will not match their
+unaccented counterparts.</font>
+<li>
+<b>conditions under which control characters match a space delimiter (3.4.1.1
+Delimiters)</b>;<font color="#FF6666"> </font></li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl uses the Standard C function isspace() to
+distinguish space characters. The rest is up to your library vendor.</font>
+<li>
+<b>format of the control-flow stack (3.2.3.2 Control-flow stack)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Uses the data stack</font>
+<li>
+<b>conversion of digits larger than thirty-five (3.2.1.2 Digit conversion)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">The maximum supported value of <tt>BASE</tt>
+is 36. Ficl will assertion fail in function ltoa of vm.c if the base is
+found to be larger than 36 or smaller than 2. There will be no effect if
+NDEBUG is defined</font>, however, other than possibly unexpected behavior.
+<li>
+<b>display after input terminates in 6.1.0695 ACCEPT and 6.2.1390 EXPECT</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Target system dependent</font>
+<li>
+<b>exception abort sequence (as in 6.1.0680 ABORT")</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Does <tt>ABORT</tt></font>
+<li>
+<b>input line terminator (3.2.4.1 User input device)</b>;<font color="#FF0000"> </font></li>
+
+<li>
+</li>
+
+<br><font color="#000000">Target system dependent (implementation of outer
+loop that calls ficlExec)</font>
+<li>
+<b>maximum size of a counted string, in characters (3.1.3.4 Counted strings,
+6.1.2450 WORD)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">255</font>
+<li>
+<b>maximum size of a parsed string (3.4.1 Parsing)</b>; </li>
+
+<li>
+</li>
+
+<br>Limited by available memory and the maximum unsigned value that can
+fit in a CELL (2<sup>32</sup>-1).
+<li>
+<b>maximum size of a definition name, in characters (3.3.1.2 Definition
+names)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl stores the first 31 characters of a definition
+name.</font>
+<li>
+<b>maximum string length for 6.1.1345 ENVIRONMENT?, in characters</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Same as maximum definition name length</font>
+<li>
+<b>method of selecting 3.2.4.1 User input device</b>; </li>
+
+<li>
+</li>
+
+<br>None supported. This is up to the target system
+<li>
+<b>method of selecting 3.2.4.2 User output device</b>; </li>
+
+<li>
+</li>
+
+<br>None supported. This is up to the target system
+<li>
+<b>methods of dictionary compilation (3.3 The Forth dictionary)</b>; </li>
+
+<li>
+<b>number of bits in one address unit (3.1.3.3 Addresses)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Target system dependent. Ficl generally supports
+processors that can address 8 bit quantities, but there is no dependency
+that I'm aware of.</font>
+<li>
+<b>number representation and arithmetic (3.2.1.1 Internal number representation)</b>; </li>
+
+<li>
+</li>
+
+<br>System dependent. Ficl represents a CELL internally as a union that
+can hold INT32 (a signed 32 bit scalar value), UNS32 (32 bits unsigned),
+and an untyped pointer. No specific byte ordering is assumed.
+<li>
+<b>ranges for n, +n, u, d, +d, and ud (3.1.3 Single-cell types, 3.1.4 Cell-pair
+types)</b>; </li>
+
+<li>
+</li>
+
+<br>Assuming a 32 bit implementation, range for signed single-cell values
+is -2<sup>31</sup>..2<sup>31</sup>-1. Range for unsigned single cell values
+is 0..2<sup>32</sup>-1. Range for signed double-cell values is -2<sup>63</sup>..2<sup>63</sup>-1.
+Range for unsigned single cell values is 0..2<sup>64</sup>-1.
+<li>
+<b>read-only data-space regions (3.3.3 Data space)</b>;</li>
+
+<li>
+</li>
+
+<br>None
+<li>
+<b>size of buffer at 6.1.2450 WORD (3.3.3.6 Other transient regions)</b>; </li>
+
+<li>
+</li>
+
+<br>Default is 255. Depends on the setting of nPAD in ficl.h.
+<li>
+<b>size of one cell in address units (3.1.3 Single-cell types)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">System dependent, generally four.</font>
+<li>
+<b>size of one character in address units (3.1.2 Character types)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">System dependent, generally one.</font>
+<li>
+<b>size of the keyboard terminal input buffer (3.3.3.5 Input buffers)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">This buffer is supplied by the host program.
+Ficl imposes no practical limit.</font>
+<li>
+<b>size of the pictured numeric output string buffer (3.3.3.6 Other transient
+regions)</b>; </li>
+
+<li>
+</li>
+
+<br>Default is 255 characters. Depends on the setting of nPAD in ficl.h.
+<li>
+<b>size of the scratch area whose address is returned by 6.2.2000 PAD (3.3.3.6
+Other transient regions)</b>; </li>
+
+<li>
+</li>
+
+<br>Not presently supported
+<li>
+<b>system case-sensitivity characteristics (3.4.2 Finding definition names)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl is not case sensitive</font>
+<li>
+<b>system prompt (3.4 The Forth text interpreter, 6.1.2050 QUIT)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">"ok>"</font>
+<li>
+<b>type of division rounding (3.2.2.1 Integer division, 6.1.0100 */, 6.1.0110
+*/MOD, 6.1.0230 /, 6.1.0240 /MOD, 6.1.1890 MOD)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Symmetric</font>
+<li>
+<b>values of 6.1.2250 STATE when true</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">One (no others)</font>
+<li>
+<b>values returned after arithmetic overflow (3.2.2.2 Other integer operations)</b>; </li>
+
+<li>
+</li>
+
+<br>System dependent. Ficl makes no special checks for overflow.
+<li>
+<b>whether the current definition can be found after 6.1.1250 DOES> (6.1.0450
+:)</b>. </li>
+
+<li>
+</li>
+
+<br><font color="#000000">No. Definitions are unsmudged after ; only, and
+only then if no control structure matching problems have been detected.</font></ul>
+
+<h3>
+Ambiguous Conditions</h3>
+A system shall document the system action taken upon each of the general
+or specific ambiguous conditions identified in this Standard. See 3.4.4
+Possible actions on an ambiguous condition.
+<p>The following general ambiguous conditions could occur because of a
+combination of factors:
+<ul>
+<li>
+<b>a name is neither a valid definition name nor a valid number during
+text interpretation (3.4 The Forth text interpreter)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl does <tt>ABORT</tt> and prints the name
+followed by " not found".</font>
+<li>
+<b>a definition name exceeded the maximum length allowed (3.3.1.2 Definition
+names)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl stores the first 31 characters of the definition
+name, and uses all characters of the name in computing its hash code. The
+actual length of the name, up to 255 characters, is stored in the definition's
+length field.</font>
+<li>
+<b>addressing a region not listed in 3.3.3 Data Space</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">No problem: all addresses in ficl are absolute.
+You can reach any 32 bit address in Ficl's address space.</font>
+<li>
+<b>argument type incompatible with specified input parameter, e.g., passing
+a flag to a word expecting an n (3.1 Data types)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl makes no check for argument type compatibility.
+Effects of a mismatch vary widely depending on the specific problem and
+operands.</font>
+<li>
+<b>attempting to obtain the execution token, (e.g., with 6.1.0070 ', 6.1.1550
+FIND, etc.) of a definition with undefined interpretation semantics</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl returns a valid token, but the result of
+executing that token while interpreting may be undesirable.</font>
+<li>
+<b>dividing by zero (6.1.0100 */, 6.1.0110 */MOD, 6.1.0230 /, 6.1.0240
+/MOD, 6.1.1561 FM/MOD, 6.1.1890 MOD, 6.1.2214 SM/REM, 6.1.2370 UM/MOD,
+8.6.1.1820 M*/)</b>;</li>
+
+<li>
+</li>
+
+<br><font color="#000000">Results are target procesor dependent. Generally,
+Ficl makes no check for divide-by-zero. The target processor will probably
+throw an exception.</font>
+<li>
+<b>insufficient data-stack space or return-stack space (stack overflow)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">With FICL_ROBUST (sysdep.h) set >= 2, most parameter
+stack operations are checked for underflow and overflow. Ficl does not
+check the return stack.</font>
+<li>
+<b>insufficient space for loop-control parameters</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">No check - Evil results.</font>
+<li>
+<b>insufficient space in the dictionary</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl generates an error message if the dictionary
+is too full to create a definition header. It checks <tt>ALLOT</tt> as
+well, but it is possible to make an unchecked allocation request that overflows
+the dictionary.</font>
+<li>
+<b>interpreting a word with undefined interpretation semantics</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl protects all ANS Forth words with undefined
+interpretation semantics from being executed while in interpret state.
+It is possible to defeat this protection using ' (tick) and <tt>EXECUTE</tt>,
+though.</font>
+<li>
+<b>modifying the contents of the input buffer or a string literal (3.3.3.4
+Text-literal regions, 3.3.3.5 Input buffers)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Varies depending on the nature of the buffer.
+The input buffer is supplied by ficl's host function, and may reside in
+read-only memory. If so, writing the input buffer can ganerate an exception.
+String literals are stored in the dictionary, and are writable.</font>
+<li>
+<b>overflow of a pictured numeric output string</b>;</li>
+
+<li>
+</li>
+
+<br>In the unlikely event you are able to construct a pictured numeric
+string of more than 255 characters, the system will be corrupted unpredictably.
+The buffer area that holds pictured numeric output is at the end of the
+virtual machine. Whatever is mapped after the offending VM in memory will
+be trashed, along with the heap structures that contain it.
+<li>
+<b>parsed string overflow</b>;</li>
+
+<li>
+</li>
+
+<br>Ficl does not copy parsed strings unless asked to. Ordinarily, a string
+parsed from the input buffer during normal interpretation is left in-place,
+so there is no possibility of overflow. If you ask to parse a string into
+the dictionary, as in <tt>SLITERAL</tt>, you need to have enough room for
+the string, otherwise bad things may happen. This is not usually a problem.
+<li>
+<b>producing a result out of range, e.g., multiplication (using *) results
+in a value too big to be represented by a single-cell integer (6.1.0090
+*, 6.1.0100 */, 6.1.0110 */MOD, 6.1.0570 >NUMBER, 6.1.1561 FM/MOD, 6.1.2214
+SM/REM, 6.1.2370 UM/MOD, 6.2.0970 CONVERT, 8.6.1.1820 M*/)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Value will be truncated</font>
+<li>
+<b>reading from an empty data stack or return stack (stack underflow)</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Most stack underflows are detected and prevented
+if FICL_ROBUST (sysdep.h) is set to 2 or greater. Otherwise, the stack
+pointer and size are likely to be trashed.</font>
+<li>
+<b>unexpected end of input buffer, resulting in an attempt to use a zero-length
+string as a name</b>; </li>
+
+<li>
+</li>
+
+<br><font color="#000000">Ficl returns for a new input buffer until a non-empty
+one is supplied.</font></ul>
+The following specific ambiguous conditions are noted in the glossary entries
+of the relevant words:
+<ul>
+<li>
+<b>>IN greater than size of input buffer (3.4.1 Parsing)</b></li>
+
+<li>
+</li>
+
+<br>Bad Things occur - unpredictable bacause the input buffer is supplied
+by the host program's outer loop.
+<li>
+<b>6.1.2120 RECURSE appears after 6.1.1250 DOES></b></li>
+
+<li>
+</li>
+
+<br>It finds the address of the definition before <tt>DOES></tt>
+<li>
+<b>argument input source different than current input source for 6.2.2148
+RESTORE-INPUT</b></li>
+
+<li>
+</li>
+
+<br>Not implemented
+<li>
+<b>data space containing definitions is de-allocated (3.3.3.2 Contiguous
+regions)</b></li>
+
+<li>
+</li>
+
+<br>This is OK until the cells are overwritten with something else. The
+dictionary maintains a hash table, and the table must be updated in order
+to de-allocate words without corruption.
+<li>
+<b>data space read/write with incorrect alignment (3.3.3.1 Address alignment)</b></li>
+
+<li>
+</li>
+
+<br>Target processor dependent. Consequences include: none (Intel), address
+error exception (68K).
+<li>
+<b>data-space pointer not properly aligned (6.1.0150 ,, 6.1.0860 C,)</b></li>
+
+<li>
+</li>
+
+<br>See above on data space read/write alignment
+<li>
+<b>less than u+2 stack items (6.2.2030 PICK, 6.2.2150 ROLL)</b></li>
+
+<li>
+</li>
+
+<br>Ficl detects a stack underflow and reports it, executing <tt>ABORT,</tt>
+as long as FICL_ROBUST is two or larger.
+<li>
+<b>loop-control parameters not available ( 6.1.0140 +LOOP, 6.1.1680 I,
+6.1.1730 J, 6.1.1760 LEAVE, 6.1.1800 LOOP, 6.1.2380 UNLOOP)</b></li>
+
+<li>
+</li>
+
+<br>Loop initiation words are responsible for checking the stack and guaranteeing
+that the control parameters are pushed. Any underflows will be detected
+early if FICL_ROBUST is set to two or greater. Note however that Ficl only
+checks for return stack underflows at the end of each line of text.
+<li>
+<b>most recent definition does not have a name (6.1.1710 IMMEDIATE)</b></li>
+
+<li>
+</li>
+
+<br>No problem.
+<li>
+<b>name not defined by 6.2.2405 VALUE used by 6.2.2295 TO</b></li>
+
+<li>
+</li>
+
+<br>Ficl's version of <tt>TO</tt> works correctly with <tt>VALUE</tt>s,
+<tt>CONSTANT</tt>s and <tt>VARIABLE</tt>s.
+<li>
+<b>name not found (6.1.0070 ', 6.1.2033 POSTPONE, 6.1.2510 ['], 6.2.2530
+[COMPILE])</b></li>
+
+<li>
+</li>
+
+<br>Ficl prints an error message and does <tt>ABORT</tt>
+<li>
+<b>parameters are not of the same type (6.1.1240 DO, 6.2.0620 ?DO, 6.2.2440
+WITHIN)</b></li>
+
+<li>
+</li>
+
+<br>No check. Results vary depending on the specific problem.
+<li>
+<b>6.1.2033 POSTPONE or 6.2.2530 [COMPILE] applied to 6.2.2295 TO</b></li>
+
+<li>
+</li>
+
+<br>The word is postponed correctly.
+<li>
+<b>string longer than a counted string returned by 6.1.2450 WORD</b></li>
+
+<li>
+</li>
+
+<br>Ficl stores the first FICL_STRING_MAX-1 chars in the destination buffer.
+(The extra character is the trailing space required by the standard. Yuck.)
+<li>
+<b>u greater than or equal to the number of bits in a cell (6.1.1805 LSHIFT,
+6.1.2162 RSHIFT)</b></li>
+
+<li>
+</li>
+
+<br>Depends on target process or and C runtime library implementations
+of the << and >> operators on unsigned values. For I386, the processor
+appears to shift modulo the number of bits in a cell.
+<li>
+<b>word not defined via 6.1.1000 CREATE (6.1.0550 >BODY, 6.1.1250 DOES>)</b></li>
+
+<li>
+</li>
+
+<br><b>words improperly used outside 6.1.0490 <# and 6.1.0040 #> (6.1.0030
+#, 6.1.0050 #S, 6.1.1670 HOLD, 6.1.2210 SIGN)</b>
+<br>Don't. <tt>CREATE</tt> reserves a field in words it builds for <tt>DOES></tt>to
+fill in. If you use <tt>DOES></tt> on a word not made by <tt>CREATE</tt>,
+it will overwrite the first cell of its parameter area. That's probably
+not what you want. Likewise, pictured numeric words assume that there is
+a string under construction in the VM's scratch buffer. If that's not the
+case, results may be unpleasant.</ul>
+
+<h3>
+Locals Implementation-defined options</h3>
+
+<ul>
+<li>
+<b>maximum number of locals in a definition (13.3.3 Processing locals,
+13.6.2.1795 LOCALS|)</b></li>
+
+<li>
+</li>
+
+<br>Default is 16. Change by redefining FICL_MAX_LOCALS, defined in sysdep.h</ul>
+
+<h3>
+Locals Ambiguous conditions</h3>
+
+<ul>
+<li>
+<b>executing a named local while in interpretation state (13.6.1.0086 (LOCAL))</b></li>
+
+<li>
+</li>
+
+<br>Locals can be found in interpretation state while in the context of
+a definition under construction. Under these circumstances, locals behave
+correctly. Locals are not visible at all outside the scope of a definition.
+<li>
+<b>name not defined by VALUE or LOCAL (13.6.1.2295 TO)</b></li>
+
+<li>
+</li>
+
+<br>See the CORE ambiguous conditions, above (no change)</ul>
+
+<h3>
+Programming Tools Implementation-defined options</h3>
+
+<ul>
+<li>
+<b>source and format of display by 15.6.1.2194 SEE</b></li>
+
+<li>
+</li>
+
+<br>SEE de-compiles definitions from the dictionary. Because Ficl words
+are threaded by their header addresses, it is very straightforward to print
+the name and other characteristics of words in a definition. Primitives
+are so noted. Colon definitions are decompiled, but branch target labels
+are not reconstructed. Literals and string literals are so noted, and their
+contents displayed.</ul>
+
+<h3>
+Search Order Implementation-defined options</h3>
+
+<ul>
+<li>
+<b>maximum number of word lists in the search order (16.3.3 Finding definition
+names, 16.6.1.2197 SET-ORDER)</b> </li>
+
+<li>
+</li>
+
+<br>Defaults to 16. Can be changed by redefining FICL_DEFAULT_VOCS, declared
+in sysdep.h
+<li>
+<b>minimum search order (16.6.1.2197 SET-ORDER, 16.6.2.1965 ONLY)</b> </li>
+
+<li>
+</li>
+
+<br>Equivalent to <tt>FORTH-WORDLIST 1 SET-ORDER</tt></ul>
+
+<h3>
+Search Order Ambiguous conditions</h3>
+
+<ul>
+<li>
+<b>changing the compilation word list (16.3.3 Finding definition names)</b></li>
+
+<li>
+</li>
+
+<br>Ficl stores a link to the current definition independently of the compile
+wordlist while it is being defined, and links it into the compile wordlist
+only after the definition completes successfully. Changing the compile
+wordlist mid-definition will cause the definition to link into the <i>new</i>
+compile wordlist.
+<li>
+<b>search order empty (16.6.2.2037 PREVIOUS)</b></li>
+
+<li>
+</li>
+
+<br>Ficl prints an error message if the search order underflows, and resets
+the order to its default state.
+<li>
+<b>too many word lists in search order (16.6.2.0715 ALSO)</b></li>
+
+<li>
+</li>
+
+<br>Ficl prints an error message if the search order overflows, and resets
+the order to its default state.</ul>
+</td>
+</tr>
</table>
<hr>
+<p><a NAME="links"></a>
+<p>For more information
+<ul>
+<li>
+<a href="http://www.taygeta.com/ficl.html">Web home of ficl</a></li>
-<p><a name="links"></a></p>
+<li>
+<b><a href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl204/ficl204.zip">Download
+ficl 2.04</a></b></li>
-<p>For more information </p>
+<li>
+<b><a href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl204/ficlwin.zip">Download
+ficlWin</a> (not for resale. please contact me for resale license arrangements)</b></li>
+<li>
+<a href="ficlddj.pdf">Manuscript of Ficl article for January 1999 Dr. Dobb's
+Journal</a></li>
+
+<li>
+<a href="jwsforml.pdf">1998 FORML Conference paper</a></li>
+
+<li>
+<a href="http://www.taygeta.com/forthlit.html">Forth literature</a></li>
+
<ul>
- <li><a href="http://www.taygeta.com/ficl.html">Web home of
- ficl</a></li>
- <li><a
- href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl204/ficl204.zip"><b>Download
- ficl 2.04</b></a></li>
- <li><a
- href="ftp://ftp.taygeta.com/pub/Forth/Compilers/native/misc/ficl204/ficlwin.zip"><b>Download
- ficlWin</b></a><b> (not for resale. please contact me for
- resale license arrangements)</b></li>
- <li><a href="ficlddj.pdf">Manuscript of Ficl article for
- January 1999 Dr. Dobb's Journal</a></li>
- <li><a href="jwsforml.pdf">1998 FORML Conference paper</a></li>
- <li><a href="http://www.taygeta.com/forthlit.html">Forth
- literature</a></li>
- <li><ul>
- <li><a
- href="http://www.softsynth.com/pforth/pf_tut.htm">Phil
- Burk's Forth Tutorial</a></li>
- <li><a href="http://www.taygeta.com/forth/dpans.html">Draft
- Proposed American National Standard for Forth</a></li>
- </ul>
- </li>
- <li><a href="http://www.forth.org">Forth Interest Group</a></li>
+<li>
+<a href="http://www.softsynth.com/pforth/pf_tut.htm">Phil Burk's Forth
+Tutorial</a></li>
+
+<li>
+<a href="http://www.taygeta.com/forth/dpans.html">Draft Proposed American
+National Standard for Forth</a></li>
</ul>
-<h2><a name="includesficl"></a>Some software that uses ficl</h2>
+<li>
+<a href="http://www.forth.org">Forth Interest Group</a></li>
+</ul>
+<h2>
+<a NAME="includesficl"></a>Some software that uses ficl</h2>
+
<ul>
- <li><a href="http://www.freebsd.org/">FreeBSD</a> boot loader</li>
- <li><a href="http://www.pagesz.net/~sessoms/debuffer/">Palm
- Pilot Debuffer</a> (Eric Sessoms)</li>
- <li><a href="http://www.swcp.com/~jchavez/osmond.html">Mac PC
- Board Layout tool</a> (J Chavez)</li>
- <li><a href="http://www.netcomsystems.com">NetCom Systems</a>
- ML7710 (Martin Usher)</li>
+<li>
+<a href="http://www.freebsd.org/">FreeBSD</a> boot loader</li>
+
+<li>
+<a href="http://www.pagesz.net/~sessoms/debuffer/">Palm Pilot Debuffer</a>
+(Eric Sessoms)</li>
+
+<li>
+<a href="http://www.swcp.com/~jchavez/osmond.html">Mac PC Board Layout
+tool</a> (J Chavez)</li>
+
+<li>
+<a href="http://www.netcomsystems.com">NetCom Systems</a> ML7710 (Martin
+Usher)</li>
</ul>
<hr>
-
-<table border="0" cellspacing="3" width="600" cols="1">
- <tr>
- <td><h2><a name="lawyerbait"></a>DISCLAIMER OF WARRANTY
- and LICENSE</h2>
- <p><i>Ficl is freeware. Use it in any way that you like,
- with the understanding that the code is not supported.</i>
- </p>
- <p>Any third party may reproduce, distribute, or modify
- the ficl software code or any derivative works thereof
- without any compensation or license, provided that the
- original author information and this disclaimer text are
- retained in the source code files. The ficl software code
- is provided on an "as is" basis without
- warranty of any kind, including, without limitation, the
- implied warranties of merchantability and fitness for a
- particular purpose and their equivalents under the laws
- of any jurisdiction. </p>
- <p>The FiclWin distribution, a derivative work of the
- ficl source code, is hereby licensed for unrestricted
- non-commercial use under the ficl license provided the
- user notifies the author (John Sadler) in writing or by
- electronic mail or their intended use of the FiclWin
- sources. You may freely redistribute the FiclWin
- distribution provided it contains this notice and adheres
- to all other provisions of this license. </p>
- <p>Reselling the FiclWin source code, executable, or
- works derived from the FiclWin source code is prohibited
- under this license. Please contact me directly in order
- to discuss license terms for commercial use and
- distribution.</p>
- <p>I am interested in hearing from anyone who uses ficl.
- If you have a problem, a success story, a defect, an
- enhancement request, or if you would like to contribute
- to the ficl release, please <a
- href="mailto:john_sadler@alum.mit.edu">send me email</a>. </p>
- </td>
- </tr>
+<table BORDER=0 CELLSPACING=3 COLS=1 WIDTH="600" >
+<tr>
+<td>
+<h2>
+<a NAME="lawyerbait"></a>DISCLAIMER OF WARRANTY and LICENSE</h2>
+<i>Ficl is freeware. Use it in any way that you like, with the understanding
+that the code is not supported.</i>
+<p>Any third party may reproduce, distribute, or modify the ficl software
+code or any derivative works thereof without any compensation or license,
+provided that the original author information and this disclaimer text
+are retained in the source code files. The ficl software code is provided
+on an "as is" basis without warranty of any kind, including, without limitation,
+the implied warranties of merchantability and fitness for a particular
+purpose and their equivalents under the laws of any jurisdiction.
+<p>The FiclWin distribution, a derivative work of the ficl source code,
+is hereby licensed for unrestricted non-commercial use under the ficl license
+provided the user notifies the author (John Sadler) in writing or by electronic
+mail or their intended use of the FiclWin sources. You may freely redistribute
+the FiclWin distribution provided it contains this notice and adheres to
+all other provisions of this license.
+<p>Reselling the FiclWin source code, executable, or works derived from
+the FiclWin source code is prohibited under this license. Please contact
+me directly in order to discuss license terms for commercial use and distribution.
+<p>I am interested in hearing from anyone who uses ficl. If you have a
+problem, a success story, a defect, an enhancement request, or if you would
+like to contribute to the ficl release, please <a href="mailto:john_sadler@alum.mit.edu">send
+me email</a>. </td>
+</tr>
</table>
+
</body>
</html>
--- a/ficl.c
+++ b/ficl.c
@@ -81,7 +81,10 @@
nDictCells = defaultDict;
dp = dictCreateHashed((unsigned)nDictCells, HASHSIZE);
+ dp->pForthWords->name = "forth-wordlist";
envp = dictCreate( (unsigned)FICL_DEFAULT_ENV);
+ envp->pForthWords->name = "environment";
+
#if FICL_WANT_LOCALS
/*
** The locals dictionary is only searched while compiling,
--- a/ficl.dsp
+++ b/ficl.dsp
@@ -100,6 +100,10 @@
# End Source File
# Begin Source File
+SOURCE=.\search.c
+# End Source File
+# Begin Source File
+
SOURCE=.\softcore.c
# End Source File
# Begin Source File
@@ -152,10 +156,26 @@
# End Source File
# Begin Source File
+SOURCE=.\softwords\ficllocal.fr
+# End Source File
+# Begin Source File
+
+SOURCE=.\softwords\forml.fr
+# End Source File
+# Begin Source File
+
SOURCE=.\softwords\ifbrack.fr
# End Source File
# Begin Source File
+SOURCE=.\softwords\jhlocal.fr
+# End Source File
+# Begin Source File
+
+SOURCE=.\softwords\marker.fr
+# End Source File
+# Begin Source File
+
SOURCE=.\softwords\oo.fr
# End Source File
# Begin Source File
@@ -170,6 +190,14 @@
SOURCE=.\softwords\softcore.pl
# End Source File
+# Begin Source File
+
+SOURCE=.\softwords\string.fr
+# End Source File
# End Group
+# Begin Source File
+
+SOURCE=..\ReadMe.txt
+# End Source File
# End Target
# End Project
--- a/ficl.h
+++ b/ficl.h
@@ -217,7 +217,7 @@
/*
** the Good Stuff starts here...
*/
-#define FICL_VER "2.04"
+#define FICL_VER "2.05"
#if !defined (FICL_PROMPT)
#define FICL_PROMPT "ok> "
#endif
@@ -279,13 +279,13 @@
typedef struct
{
- UNS32 count;
+ FICL_UNS count;
char *cp;
} STRINGINFO;
#define SI_COUNT(si) (si.count)
#define SI_PTR(si) (si.cp)
-#define SI_SETLEN(si, len) (si.count = (UNS32)(len))
+#define SI_SETLEN(si, len) (si.count = (FICL_UNS)(len))
#define SI_SETPTR(si, ptr) (si.cp = (char *)(ptr))
/*
** Init a STRINGINFO from a pointer to NULL-terminated string
@@ -314,7 +314,7 @@
*/
typedef struct
{
- INT32 index;
+ FICL_INT index;
char *end;
char *cp;
} TIB;
@@ -423,8 +423,8 @@
IPTYPE ip; /* instruction pointer */
struct ficl_word
*runningWord;/* address of currently running word (often just *(ip-1) ) */
- UNS32 state; /* compiling or interpreting */
- UNS32 base; /* number conversion base */
+ FICL_UNS state; /* compiling or interpreting */
+ FICL_UNS base; /* number conversion base */
FICL_STACK *pStack; /* param stack */
FICL_STACK *rStack; /* return stack */
CELL sourceID; /* -1 if string, 0 if normal input */
@@ -570,7 +570,7 @@
** PopTib restores the TIB state given a saved TIB from PushTib
** GetInBuf returns a pointer to the next unused char of the TIB
*/
-void vmPushTib(FICL_VM *pVM, char *text, INT32 nChars, TIB *pSaveTib);
+void vmPushTib(FICL_VM *pVM, char *text, FICL_INT nChars, TIB *pSaveTib);
void vmPopTib(FICL_VM *pVM, TIB *pTib);
#define vmGetInBuf(pVM) ((pVM)->tib.cp + (pVM)->tib.index)
#define vmGetInBufLen(pVM) ((pVM)->tib.end - (pVM)->tib.cp)
@@ -617,7 +617,8 @@
typedef struct ficl_hash
{
- struct ficl_hash *link; /* eventual inheritance support */
+ struct ficl_hash *link; /* link to parent class wordlist for OO */
+ char *name; /* optional pointer to \0 terminated wordlist name */
unsigned size;
FICL_WORD *table[1];
} FICL_HASH;
@@ -757,7 +758,7 @@
** Successful creation and init of the VM by ficlNewVM (or equiv)
*/
int ficlExec (FICL_VM *pVM, char *pText);
-int ficlExecC(FICL_VM *pVM, char *pText, INT32 nChars);
+int ficlExecC(FICL_VM *pVM, char *pText, FICL_INT nChars);
int ficlExecXT(FICL_VM *pVM, FICL_WORD *pWord);
/*
@@ -798,8 +799,8 @@
*/
FICL_DICT *ficlGetDict(void);
FICL_DICT *ficlGetEnv(void);
-void ficlSetEnv(char *name, UNS32 value);
-void ficlSetEnvD(char *name, UNS32 hi, UNS32 lo);
+void ficlSetEnv(char *name, FICL_UNS value);
+void ficlSetEnvD(char *name, FICL_UNS hi, UNS32 lo);
#if FICL_WANT_LOCALS
FICL_DICT *ficlGetLoc(void);
#endif
@@ -827,6 +828,7 @@
** ficlInitSystem - no need to waste dict space by doing it again.
*/
void ficlCompileCore(FICL_DICT *dp);
+void ficlCompileSearch(FICL_DICT *dp);
void ficlCompileSoftCore(FICL_VM *pVM);
/*
--- a/softwords/classes.fr
+++ b/softwords/classes.fr
@@ -34,6 +34,14 @@
end-class
object subclass c-4byte
+ 4 chars: .payload
+
+ : get drop i@ ;
+ : set drop i! ;
+end-class
+
+
+object subclass c-cell
cell: .payload
: get drop @ ;
@@ -54,23 +62,23 @@
\ Returns the size in address units of the thing the pointer
\ refers to.
object subclass c-ptr
- c-4byte obj: .addr
+ c-cell obj: .addr
\ get the value of the pointer
: get-ptr ( inst class -- addr )
- c-ptr => .addr
- c-4byte => get
+ c-ptr => .addr
+ c-cell => get
;
\ set the pointer to address supplied
: set-ptr ( addr inst class -- )
- c-ptr => .addr
- c-4byte => set
+ c-ptr => .addr
+ c-cell => set
;
\ force the pointer to be null
: clr-ptr
- 0 -rot c-ptr => .addr c-4byte => set
+ 0 -rot c-ptr => .addr c-cell => set
;
\ return flag indicating null-ness
@@ -106,9 +114,9 @@
\ ** C - C E L L P T R
-\ Models a pointer to cell (a 32 bit scalar).
+\ Models a pointer to cell (a 32 or 64 bit scalar).
c-ptr subclass c-cellPtr
- : @size 2drop 4 ;
+ : @size 2drop 1 cells ;
\ fetch and store through the pointer
: get ( inst class -- cell )
c-ptr => get-ptr @
@@ -119,6 +127,19 @@
end-class
+\ ** C - 4 B Y T E P T R
+\ Models a pointer to a quadbyte scalar
+c-ptr subclass c-4bytePtr
+ : @size 2drop 4 ;
+ \ fetch and store through the pointer
+ : get ( inst class -- value )
+ c-ptr => get-ptr i@
+ ;
+ : set ( value inst class -- )
+ c-ptr => get-ptr i!
+ ;
+ end-class
+
\ ** C - 2 B Y T E P T R
\ Models a pointer to a 16 bit scalar
c-ptr subclass c-2bytePtr
--- a/softwords/ficlclass.fr
+++ b/softwords/ficlclass.fr
@@ -47,6 +47,7 @@
c-wordlist ref: .parent
c-4byte obj: .size
c-word ref: .hash
+ c-ptr obj: .name
: ?
2drop ." ficl wordlist " cr ;
@@ -56,7 +57,7 @@
: words --> push words previous ;
end-class
-: named-wid wordlist postpone c-wordlist metaclass => ref ;
+\ : named-wid wordlist postpone c-wordlist metaclass => ref ;
\ ** C - F I C L S T A C K
--- a/softwords/jhlocal.fr
+++ b/softwords/jhlocal.fr
@@ -11,6 +11,9 @@
\ 2 = found --
\ 3 = found }
\ 4 = end of line
+\
+\ revised 2 June 2000 - { | a -- } now works correctly
+.( loading Johns-Hopkins locals ) cr
hide
0 constant zero
@@ -49,7 +52,7 @@
repeat
\ now unstack the locals
- 0 do
+ 0 ?do
?2loc if (2local) else (local) endif
loop \ ( )
--- a/softwords/marker.fr
+++ b/softwords/marker.fr
@@ -2,7 +2,7 @@
\ ** Ficl implementation of CORE EXT MARKER
\ John Sadler, 4 Oct 98
\ Requires ficl 2.02 FORGET-WID !!
-
+.( loading MARKER ) cr
: marker ( "name" -- )
create
get-current ,
--- a/softwords/oo.fr
+++ b/softwords/oo.fr
@@ -3,7 +3,7 @@
\ ** john sadler aug 1998
.( loading ficl O-O extensions ) cr
-7 ficl-vocabulary oop
+17 ficl-vocabulary oop
also oop definitions
\ Design goals:
@@ -125,9 +125,9 @@
\ prior state. Note that these words are hidden in their own
\ wordlist to prevent accidental use outside a SUB END-CLASS pair.
\
-wordlist
-dup constant instance-vars
-dup >search ficl-set-current
+1 ficl-named-wordlist instance-vars
+instance-vars @ constant instance-vars
+instance-vars dup >search ficl-set-current
: do-instance-var
does> ( instance class addr[offset] -- addr[field] )
nip @ +
@@ -206,6 +206,11 @@
search> drop \ pop struct builder wordlist
;
+\ See resume-class (a metaclass method) below for usage
+\ This is equivalent to end-class for now, but that will change
+\ when we support vtable bindings.
+: suspend-class ( old-wid addr[size] size -- ) end-class ;
+
set-current previous
\ E N D I N S T A N C E V A R I A B L E S
@@ -243,7 +248,9 @@
3 cells , \ instance size
ficl-set-current
does> dup
-; execute metaclass
+; execute metaclass
+\ now brand OBJECT's wordlist (so that ORDER can display it by name)
+metaclass drop cell+ @ brand-wordlist
metaclass drop current-class !
do-do-instance
@@ -324,13 +331,38 @@
does> 2@
;
+\ suspend-class and resume-class help to build mutually referent classes.
+\ Example:
+\ object subclass c-akbar
+\ suspend-class ( put akbar on hold while we define jeff )
+\ object subclass c-jeff
+\ c-akbar ref: .akbar
+\ ( and whatever else comprises this class )
+\ end-class ( done with c-jeff )
+\ c-akbar --> resume-class
+\ c-jeff ref: .jeff
+\ ( and whatever else goes in c-akbar )
+\ end-class ( done with c-akbar )
+\
+: resume-class { 2this -- old-wid addr[size] size }
+ 2this --> .wid @ ficl-set-current ( old-wid )
+ 2this --> .size dup @ ( old-wid addr[size] size )
+ instance-vars >search
+;
+
\ create a subclass
+\ This method leaves the stack and search order ready for instance variable
+\ building. Pushes the instance-vars wordlist onto the search order,
+\ and sets the compilation wordlist to be the private wordlist of the
+\ new class. The class's wordlist is deliberately NOT in the search order -
+\ to prevent methods from getting used with wrong data.
: sub ( class metaclass "name" -- old-wid addr[size] size )
wordlist
locals| wid meta parent |
parent meta metaclass => get-wid
- wid wid-set-super
- create immediate
+ wid wid-set-super \ set superclass
+ create immediate \ get the subclass name
+ wid brand-wordlist \ label the subclass wordlist
here current-class ! \ prep for do-do-instance
parent , \ save parent class
wid , \ save wid
@@ -338,7 +370,7 @@
metaclass => .do-instance
wid ficl-set-current -rot
do-do-instance
- instance-vars >search \ push struct builder wordlist
+ instance-vars >search \ push struct builder wordlist
;
\ OFFSET-OF returns the offset of an instance variable
@@ -402,6 +434,8 @@
ficl-set-current
does> meta
; execute object
+\ now brand OBJECT's wordlist (so that ORDER can display it by name)
+object drop cell+ @ brand-wordlist
object drop current-class !
do-do-instance
--- a/softwords/softcore.fr
+++ b/softwords/softcore.fr
@@ -5,8 +5,8 @@
\ ** Ficl USER variables
\ ** See words.c for primitive def'n of USER
+.( loading ficl soft extensions ) cr
\ #if FICL_WANT_USER
-
variable nUser 0 nUser !
: user \ name ( -- )
nUser dup @ user 1 swap +! ;
@@ -40,6 +40,7 @@
\ ** CORE EXT
+.( loading CORE EXT words ) cr
0 constant false
-1 constant true
: <> = 0= ;
@@ -82,21 +83,47 @@
;
\ ** SEARCH+EXT words and ficl helpers
-\
+.( loading SEARCH & SEARCH-EXT words ) cr
+\ BRAND-WORDLIST is a helper for ficl-named-wordlist. Usage idiom:
+\ wordlist dup create , brand-wordlist
+\ gets the name of the word made by create and applies it to the wordlist...
+: brand-wordlist ( wid -- ) last-word >name drop wid-set-name ;
+
+: ficl-named-wordlist ( name -- )
+ ficl-wordlist dup create , brand-wordlist ;
+
: wordlist ( -- )
1 ficl-wordlist ;
+\ FICL-SET-CURRENT sets the compile wordlist and pushes the previous value
+: ficl-set-current ( wid -- old-wid )
+ get-current swap set-current ;
+
\ DO_VOCABULARY handles the DOES> part of a VOCABULARY
\ When executed, new voc replaces top of search stack
: do-vocabulary ( -- )
does> @ search> drop >search ;
+: ficl-vocabulary ( nBuckets name -- )
+ ficl-named-wordlist do-vocabulary ;
+
: vocabulary ( name -- )
- wordlist create , do-vocabulary ;
+ 1 ficl-vocabulary ;
-: ficl-vocabulary ( nBuckets name -- )
- ficl-wordlist create , do-vocabulary ;
+\ PREVIOUS drops the search order stack
+: previous ( -- ) search> drop ;
+\ HIDDEN vocabulary is a place to keep helper words from cluttering the namespace
+\ USAGE:
+\ hide
+\ <definitions to hide>
+\ set-current
+\ <words that use hidden defs>
+\ previous ( pop HIDDEN off the search order )
+
+1 ficl-named-wordlist hidden
+: hide hidden @ dup >search ficl-set-current ;
+
\ ALSO dups the search stack...
: also ( -- )
search> dup >search >search ;
@@ -111,20 +138,24 @@
-1 set-order ;
\ ORDER displays the compile wid and the search order list
+hide
+: list-wid ( wid -- )
+ dup wid-get-name ( wid c-addr u )
+ ?dup if
+ type drop
+ else
+ drop ." (unnamed wid) " x.
+ endif cr
+;
+set-current \ stop hiding words
+
: order ( -- )
- ." Search: "
- get-order 0 ?do x. loop cr
- ." Compile: " get-current x. cr ;
+ ." Search:" cr
+ get-order 0 ?do 3 spaces list-wid loop cr
+ ." Compile: " get-current list-wid cr
+;
-\ PREVIOUS drops the search order stack
-: previous ( -- ) search> drop ;
-
-\ FICL-SET-CURRENT sets the compile wordlist and pushes the previous value
-: ficl-set-current ( wid -- old-wid )
- get-current swap set-current ;
-
-wordlist constant hidden
-: hide hidden dup >search ficl-set-current ;
+previous \ lose hidden words from search order
\ ** E N D S O F T C O R E . F R
--- a/softwords/string.fr
+++ b/softwords/string.fr
@@ -15,10 +15,10 @@
also oop definitions
object subclass c-string
- c-4byte obj: .count
- c-4byte obj: .buflen
- c-ptr obj: .buf
- 64 constant min-buf
+ c-cell obj: .count
+ c-cell obj: .buflen
+ c-ptr obj: .buf
+ 32 constant min-buf
: get-count ( 2this -- count ) c-string => .count c-4byte => get ;
: set-count ( count 2this -- ) c-string => .count c-4byte => set ;
@@ -104,18 +104,18 @@
;
: compare ( 2string 2this -- n )
- c-string => get
+ --> get
2swap
- c-string => get
+ --> get
2swap compare
;
: hashcode ( 2this -- hashcode )
- c-string => get hash
+ --> get hash
;
\ destructor method (overrides object --> free)
- : free ( 2this -- ) 2dup c-string => free-buf object => free ;
+ : free ( 2this -- ) 2dup --> free-buf object => free ;
end-class
--- a/test/ficltest.fr
+++ b/test/ficltest.fr
@@ -1,12 +1,32 @@
\ test file for ficl
\ test ANSI CORE stuff first...
-1 set-order
+
+\ set up local variable regressions before { gets redefined!
+: local1 { a b c | clr -- c b a 0 }
+ c b a clr
+;
+
+: local2 { | clr -- 0 } clr ;
+: local3 { a b | c }
+ a to c
+ b to a
+ c to b
+ a b
+;
+
load tester.fr
load core.fr
+{ -> }
\ Now test ficl extras and optional word-sets
+testing locals
+{ 1 2 3 local1 -> 3 2 1 0 }
+{ local2 -> 0 }
+{ 1 local2 -> 1 0 }
+{ 1 2 local3 -> 2 1 }
+
testing :noname
-{ -> }
{ :noname 1 ; execute -> 1 }
{ 1 2 3 -rot -> 3 1 2 }
--- a/testmain.c
+++ b/testmain.c
@@ -249,7 +249,7 @@
static void ficlClock(FICL_VM *pVM)
{
clock_t now = clock();
- stackPushUNS(pVM->pStack, (UNS32)now);
+ stackPushUNS(pVM->pStack, (FICL_UNS)now);
return;
}
--- a/vm.c
+++ b/vm.c
@@ -170,7 +170,7 @@
char *pSrc = vmGetInBuf(pVM);
char *pEnd = vmGetInBufEnd(pVM);
STRINGINFO si;
- UNS32 count = 0;
+ FICL_UNS count = 0;
char ch;
pSrc = skipSpace(pSrc, pEnd);
@@ -589,7 +589,7 @@
while (ud.lo)
{
- result = ficlLongDiv(ud, (UNS32)radix);
+ result = ficlLongDiv(ud, (FICL_UNS)radix);
ud.lo = result.quot;
*cp++ = digits[result.rem];
}
--- a/words.c
+++ b/words.c
@@ -997,6 +997,27 @@
}
+static void quadFetch(FICL_VM *pVM)
+{
+ UNS32 *pw;
+#if FICL_ROBUST > 1
+ vmCheckStack(pVM, 1, 1);
+#endif
+ pw = (UNS32 *)stackPopPtr(pVM->pStack);
+ stackPushUNS(pVM->pStack, (FICL_UNS)*pw);
+ return;
+}
+
+static void quadStore(FICL_VM *pVM)
+{
+ UNS32 *pw;
+#if FICL_ROBUST > 1
+ vmCheckStack(pVM, 2, 0);
+#endif
+ pw = (UNS32 *)stackPopPtr(pVM->pStack);
+ *pw = (UNS32)(stackPop(pVM->pStack).u);
+}
+
static void wFetch(FICL_VM *pVM)
{
UNS16 *pw;
@@ -1408,8 +1429,8 @@
vmTextOut(pVM, pPad, 1);
}
- sprintf(pVM->pad, "Dictionary: %d words, %ld cells used of %lu total",
- nWords, dp->here - dp->dict, dp->size);
+ 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;
}
@@ -1431,8 +1452,8 @@
}
}
- sprintf(pVM->pad, "Environment: %d words, %ld cells used of %lu total",
- nWords, dp->here - dp->dict, dp->size);
+ 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;
}
@@ -2261,6 +2282,16 @@
}
+static void getLastWord(FICL_VM *pVM)
+{
+ FICL_DICT *pDict = ficlGetDict();
+ FICL_WORD *wp = pDict->smudge;
+ assert(wp);
+ vmPush(pVM, LVALUEtoCELL(wp));
+ return;
+}
+
+
/**************************************************************************
l b r a c k e t e t c
**
@@ -3220,260 +3251,6 @@
/**************************************************************************
- 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;
-}
-
-
-/**************************************************************************
c o l o n N o N a m e
** CORE EXT ( C: -- colon-sys ) ( S: -- xt )
** Create an unnamed colon definition and push its address.
@@ -3857,27 +3634,6 @@
#endif
/**************************************************************************
- 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;
-}
-
-
-/**************************************************************************
s e e
** TOOLS ( "<spaces>name" -- )
** Display a human-readable representation of the named word's definition.
@@ -4623,33 +4379,12 @@
ficlSetEnv("memory-alloc", FICL_TRUE);
ficlSetEnv("memory-alloc-ext", FICL_FALSE);
- /*
+ /*
** 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);
+ ficlCompileSearch(dp);
/*
- ** Set SEARCH environment query values
- */
- ficlSetEnv("search-order", FICL_TRUE);
- ficlSetEnv("search-order-ext", FICL_TRUE);
- ficlSetEnv("wordlists", FICL_DEFAULT_VOCS);
-
- /*
** TOOLS and TOOLS EXT
*/
dictAppendWord(dp, ".s", displayStack, FW_DEFAULT);
@@ -4678,12 +4413,13 @@
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);
dictAppendWord(dp, "parse-word",parseNoCopy, FW_DEFAULT);
dictAppendWord(dp, "sliteral", sLiteralCoIm, FW_COMPIMMED); /* STRING */
- dictAppendWord(dp, "wid-set-super",
- setParentWid, FW_DEFAULT);
+ dictAppendWord(dp, "i@", quadFetch, FW_DEFAULT);
+ dictAppendWord(dp, "i!", quadStore, FW_DEFAULT);
dictAppendWord(dp, "w@", wFetch, FW_DEFAULT);
dictAppendWord(dp, "w!", wStore, FW_DEFAULT);
dictAppendWord(dp, "x.", hexDot, FW_DEFAULT);
@@ -4725,6 +4461,7 @@
dictAppendWord(dp, "exit-inner",ficlExitInner, FW_DEFAULT);
assert(dictCellsAvail(dp) > 0);
+
return;
}