ficlPageHeader("ficl release history") ficlAddToNavBarAs("Release History") def ficlVersion(s): ficlHeader1(s) ?> ficlVersion("Version 4.0.31") ?>
ficlDictionarySee() now takes a ficlCallback,
so it knows where to print to. This is because ficlWin only
sets a per-VM callback, which should work.
ficlSystemCreate() now passes in the system correctly
into the dictionaries it creates, which lets dictionaries know what
system they're a part of.
errorTextOut to the
ficl_system structure (though I'd remembered to add it to
the ficl_vm structure). This caused the ficl_system
members after textOut to not line up with their equivalent
ficlSystem members, which did bad things. (The bad thing
in particular was calling ficlDictionaryResetSearchOrder()
resulted in diddling the vm->link member, which strangely
enough resulted in double-freeing the stacks.)
ficlStackWalk(), which walks a stack from top
to bottom and calls your specified callback with each successive
element. Cleaned up stack-printing functions as a result.
MULTICALL so you can explicitly specify the vtable.
SUPERed an object and you'll
get the method you wanted.
xClass.removeMember()
to support this.
_DEBUG
only) for functions thunked from C to Ficl.
FICL_WANT_PLATFORM is now 0 by default.
It is now set to 1 in the appropriate ficlplatform/*.h.
softcore/win32.fr ENVIRONMENT? COMPARE needed to be case-insensitive.
-
Whoops! Setting
FICL_PLATFORM_2INTEGER to 0
didn't compile. It now does, and works fine, as proved by
the ansi platform.
-
Another whoops: contrib/xclasses/xclasses.py assumed that
" (a prefix
version of S") defined. Switched to S", which is safer.
FICL_ definitions. Now all FICL_HAVE_* constants
(and some other odds and ends) have been moved to FICL_PLATFORM_.
FICL_PLATFORM_2INTEGER to 0 didn't
compile. It now does, and works fine, as proved by
the "ansi" platform.
contrib/xclasses/xclasses.py assumed that " (a prefix
version of S") defined. Switched to S", which is safer.
ficlDictionarySetConstantString(). 'Cause I needed it for:
"WIN32" ENVIRONMENT? setting, and added "FICL_PLATFORM_OS"
and "FICL_PLATFORM_ARCHITECTURE" in its place. These are both strings.
Updated softcore/win32.fr to match.
ficlTextOut() behavior. It makes life slightly
less convenient for some users, but should be an improvement overall.
The change: ficlTextOut() is now a compatibility-layer function that
calls straight through to vmTextOut(). Lots of old code calls ficlTextOut()
(naughty!). It's now explicit that you must set the textOut function
by hand if you use a custom one... which is a good habit to get in to anyway.
ficllocals.h, and compile-time
constants.
doc/source/generate.py so it gracefully fails to copy over read-only
files.
#ifdef in the sources. We now consistently use #if defined()
everywhere. Similarly, got rid of all platform-switched #if code (except for the
compatibility layer, sigh).
oldnames renamed to compatibility.
And improved, so that now Ficl 4 is basically a drop-in
replacement for Ficl 3.
INCLUDE-FILE so it rethrows an exception in the
subordinate evaluation.
errorOut function to
ficlCallback(),
so under Windows you can have a jolly popup window to
rub your nose in your failings.
ficl.
ficlVmExec(), renamed ficlVmExecC() to
ficlVmExecuteString(), changed it to take a ficlString().
This is deliberate subterfuge on my part; I suspect most
people who currently call ficlVmExec() / ficlVmExecC()
should be calling ficlVmEvaluate().
random and seed-random
included never closed its file.
include was not IMMEDIATE.
parse-method, lookup-method, and find-method-xt, as there are perfectly legitimate reasons why you might want to use them.
.( to be IMMEDIATE too.
nEnvCells (number of environment cells) to FICL_SYSTEM_INFO.
context and pExtend pointers of FICL_SYSTEMVM's pExtend pointer is initialized from the copy in FICL_SYSTEM upon VM creation.
ficl-robust environment variable.
FW_ISOBJECT word type.
environment? was ignoring the length of the supplied string.
ficlParsePrefix: if the prefix dictionary isn't in the wordlist, the word being examined cannot be a prefix, so return failure.
SEE improvements: SEE (and consequently DEBUG) have improved source listings with instruction offsets.
objectify and ?object for use by OO infrastructure.
my=[ detects object members (using ?object) and assumes all other members leave class unchanged.
MEMORY-EXT environment variable (there is no such wordset).
R.S displays the stack contents symbolically
SEE listing enhanced for use with the debugger
float.c words f> and >f to move floats to and from the param stack, analogous to >r and r>
LOOKUP - Surrogate precompiled parse step for ficlParseWord (this step is hard
coded in INTERPRET)
ficlAddParseStep(). FICL_MAX_PARSE_STEPS limits the number of parse steps
(default: 8). You can write a precompiled parse step (see ficlParseNumber) and
append it to the chain, or you can write one in ficl and use ADD-PARSE-STEP
to append it. Default parse steps are initialized in ficlInitSystem. You can list
the parse steps with parse-order ( -- ).
My next favorite change is a set of VCALL words that allow me to call C++ class virtual methods from my forth classes. This is accomplished by interfacing with the VTABLE of the class. The class instance currently must be created on the C++ side. C++ places methods in the VTABLE in order of declaration in the header file. To use this in FICL one only needs to ensure that the VCALL: declerations occur in the same order. I use this quite a bit to interface with the C++ classes. When I need access to a method I make sure it is virtual (Even if it ultimately will not be). I use Visual C++ 6.0 and have not tested this under any other compiler but I believe VTABLE implementation is standard.
Here is an example of how to use VCALL:
C++ class declaration
class myclass
{
public:
myclass();
virtual ~myclass();
virtual void Test( int iParam1 );
virtual int Test( int iParam1, char cParam2 );
virtual float Test();
};
ficl class declaration
object subclass myfclass hasvtable \ hasvtable adds 4 to the offset to
\ accommodate for the VTABLE pointer.
0 VCALL: Destructor() \ VCALL: ( ParamCount -- )
1 VCALL: Test(int) \ Test takes 1 int parameter.
2 VCALLR: iTest(int,char) \ iTest takes 2 parameters and returns an int.
0 VCALLF: fTest() \ fTest takes no parameters and returns a float.
end-class
MyCAddress \ Primitive to return a pointer to a "myclass" instance.
myfclass -> ref dude \ This makes the MyCAddress pointer a myfclass
\ instance with the name "dude".
1234 dude -> Test(int) \ Calls the virtual method Test.
1234 1 dude -> iTest(int,char) . \ Calls iTest and emits the returned int.
dude -> fTest() f. \ Calls fTest and emits the returned float.
New words: