(sorted early to last)
The maximum supported display size is 1200 x 800 (NT). This should become 1600x1200. (produces checkerboard lines in full-screen mode).
Installed svgalib-1.4 which (more-or-less) supports S3 Virge 1e1 chips. This uncovered a bug in linuxgrf.c, gl_copybox(). This function can consume upto 1600x1200x4 bytes of stackspace. Therefore the datastack location of Linux iForth was changed to be the same as the C-stack. The Linux and WinNT iForths are now exactly equal in this respect.
Found a second bug related to updating the jump table in GRAPHICS.FRT by hand. This is *only* done in the newest (never released) Linux drivers. The comments describing the offsets were a few units off. The visible effect was that !RECT didn't work, in practice *many* complex functions would have done nothing or produced stack errors. This bug does not affect Linux iForth users because they are supposed to use the GRAPHICS.FRT in the (old) snapshot.
Made it possible to compile iforth.img with iForth 1.11 for Linux 2.0.0. Superficial testing shows that everything works fine.
Found an optimizer bug when testing /graphics/chaos.frt. All CASE ENDCASE statements are compiled wrong with iForth 1.11. This again does not affect Linux users.
The graphics libraries in dfwforth/include depend on the display hardware, e.g. BytesPerPixel. This is no problem for NT where the display resolution can't be changed and BytesPerPixel is always 4. It does, however, show up under DOS and Linux where BytesPerPixel varies between 1 and 4. Whenever BPP is used AT RUNTIME there is the chance of a bug (BPP is 4 by default and gets its correct value only AFTER the word GRAPHICS has executed). This is a long standing problem which becomes unacceptable now that I'm again using Linux. The first step is an enhanced /dfwforth/include/lmouse.frt which test BytesPerPixel at execute-time. In principle these bugs can be caught by systematically checking if Xmax Ymax BytesPerPixel and PosblColors are used inappropriately.
Added interpolation shaded triangles to iForth for Linux (linking to 3DKit). I want to rewrite plane.c in iForth ...
Linux:
Linux:
The X Windows driver works. It has about the same functionality as the NT version. The pensize function
was slimmed down, no more variable NIBs. The floodfill routines are incredibly slow under X (temporarily?). This is no
big problem as the tile-fill X code can be used instead, for most purposes. There are still some bugs waiting to be
fixed in the color management and resize code [fixed, March 12 -mhx], but the demos run.
NT:
CLAPACK's eigenvalue + eigenvector routine DGEEVX crashes (NOT in the example,
in an application). *** FIXED ***
The faster READ-LINE lib must be used, the present one is too slow. *** FIXED ***
Noticed that many words use BL WORD to get filenames. This doesn't work for 'Program Files' etc. *** FIXED (use quotes) ***
Recompiled NRCLIB (NT/Linux) with omitted framepointer. This is *much* faster.
The FSL_UTIL and GAUSSJ were rewritten for speed. It helped, I think around 1.2 - 1.7 times faster. For an additional 10-20% it is possible to use }}R4 or }}R8 .
POWERL.FRT updated so the material losses can be properly dependent on temperature.
Added rules to the optimizer to do fadd/fsub/fplusadd/fmul/fdiv from mem operand to stacktop.
General Sallen-Key filter program
Tapped-boost program
RLCG sampled-data program that finds steady-state.
The FP optimizer now handles FLOCALs in connection with F@ F* F+ F- and F/ . Because all FP constants are really variables internally, F@ works on them too and <r> F* etc. is optimized.
Working with Robert Epprecht's BREW let me find and fix a small bug in SAVE-INPUT and RESTORE-INPUT .
The x86 seems to be _extremely_ sensitive to aligned data. This was not a problem in the past because the rest of ( FP ) iForth was not fast enough to show it. With all the new optimizations it proves that extended FP is about twice slower than double-precision (64-bit). Also because the 80-bit format does not support optimization fully (you can't combine 80-bit fetch and store with other instructions), I decided to make DP the standard iForth FP format. Fixed a few small bugs in miscutil.frt that didn't take this possibility into account. Also tried a single precision iForth. It is only marginally faster and there are problems with NRC CLAPACK and GAUSSJ.
Another problem was stack-alignment. Here I found that unaligned stacks slowed down the assembler BLAS by a factor of 2! (verified with the Linux executable). This is fixed.
Another problem is accessing data that is in the same cache line as code (found thanks to Anton Ertl). The 'fix' for this is rather unelegant: any iForth internal datastructure now leaves generous gaps, and faligns where ever possible. This still leaves user defined data (e.g. DOES> ) open for improvement. Not leaving the gap gives a large slowdown on some code. A factor of 4 was observed! For the Pentium a gap of 32 bytes (cacheline size) between data and code is enough. For the Athlon this must be 64 bytes.
Optimized TRUNC and NEGINF modes. The default OS rounding mode is kept intact, so NOT set to truncate anymore. The accuracy is much better now; check the FLOPS benchmark.
Numerous FP improvements. Everything that can usefully be inlined and optimized is now indeed done that way. Tried to make string-to-float conversion more accurate. Improved F> F>= F< F<= F= F<> F0> F0>= F0< F0<= F0= F0<> ( NAN INF & speed)
Added optimizers for D0= D0< D> D< D= D<> WITHIN 2SWAP DNEGATE M- . Added UT* UT/ UD+c MT* , optimized M*/ .
Brought back the word LEX . It was written and debugged (for BASIS17), so why not expose it?
LEX
(lex)es the source string using all the delimiters specified in a second
string. It returns the results found for the first matching delimiter.
As soon as a delimiter is located at position `a', we only have to scan for
the next delimiter upto this `a' ! So string2 should be sorted: `frequent'
delimiters belong up front.
Fixed the disassembler / SEE for some alignment cases.
QUADS.FRT
: rewrote UD/MOD and friends in floating-point. They became several times faster
than the original code by Nathaniel Grossman, FD Vol VI, no 6, page 25.
Also added words BCD@ and BCD! to fetch and store BCD (80-bit) numbers. They are
not as useful as I expected.
SPLINE.FRT
: rewritten and reformatted. (The same code is also in the NRC and BLAS4 DLLs).
ASSEMBLE.FRT
: The assembler framework has changed. It is now possible to use ASM{ and
friends without surprises (i.e. puzzling OS exception warnings).
BLAS.FRT
: I am trying to minimize the need for NRCLIB.DLL (which has the ugly off-by-one
array indexes iForth has to cover up for). The routines I use most often are being
moved to BLAS4.DLL. In the process they also get as much optimization as I can think
of (e.g. rewritten in terms of the BLAS, loop unrolls, static array copies etc.).
Available now:
amebsa amoeba balanc broydn dgemm dgemv dgemv1 dger dgetri drot dswap dsymm dsymv dsyr dsyr2 dsyr2k dsyrk dtrmm dtrmv dtrsm dtrsv dtrti2 dtrtri elmhes fdjac four1 gaussj hqr idamax idamin isamax isamin laguer lnsrch lubksb ludcmp odeint4 polint qgaus qromb ran1 ratint realft rk4 rkck rkqs4 splie2 splin2 spline splint srot sswap svdcmp trapzd zbiters zbrak zbrent zrootsEspecially matrix multiplication, EXPM and GAUSSJ have improved a lot.
GAUSSJ.FRT
: *many* improvements, examples and tests. Most algorithms are now combinations of
special-case optimizers. E.g. matrix multiplication for small matrices is done with
an unrolled loop entirely on the FP stack, optimized for minimum latency.
iForth can now control and automate MATLAB 5.x.
Many more benchmarks have been added. Most of these are ported from 'C' to have reference numbers available: clinpack, fft, fib, flops, nsieve, queens, shuffle and tfftdp.
Ported and debugged the tForth BIGNUM package. It works quite well now. Check the bignum directory for examples using prime numbers (LPERFECT etc).
Some very extended new [example] code has been added: CHESS (113 Kbytes) and BREW (2.15 Mbytes).
Overall floating-point speed may have improved between 4 and 10 times compared to release 1.10.
Public Declare Function Train Lib "NN50.DLL" Alias "TRAIN" _ (ByRef dwArrayPointer() As Double, lpEpochs As Long, nResetWeights As Integer, _ nLearningRate As Double, nMomentum As Double, nMaxNeurons As Integer, _ ByVal lpCallBackOfEpoch As Long, ByVal lpCallBackOfRMSError As Long) As IntegerThe second parameter "lpEpochs As Long" is the address of the variable #epochs . The parameters nResetWeights, nLearningRate, nMomentum and nMaxNeurons are also passed by reference (address). A Long and an Integer are simply 32-bit cells. A double is a Forth DFLOAT and its address is passed. "ByVal lpCallBackOfEpoch As Long" is the address of the (pascal-)callback. What the "ByVal" and "As Long" are doing is anybody's guess.
0 VALUE epoch 0 VALUE nMaxNeurons 0 VALUE nResetWeights 0 VALUE #epochs 0e FVALUE LRate -- Learning rate (0.1 to 10) 0e FVALUE nMomentum -- Neural network momentum (0.1 to 10) #120 4 DOUBLE MATRIX MUL{{ CREATE OLE_SAFEARRAY1 2 C, 0 C, -- cDims ( 16-bit word), a matrix has 2 dimensions $10 C, 0 C, -- Flags (16-bit word), do not resize or reallocate. 1 DFLOATS , -- cbElements (size in bytes of DFLOAT) 0 , -- lock count MUL{{ DADDR , -- pointer to data -- rgsabound[2] Describe the dimensions claimed above #120 , 1 , -- dimension 0: #120 cElements lLbound = 0? 4 , 1 , -- dimension 1: 4 cElements lLbound = 0? : INIT-EVERYTHING ( -- ) OLE_SAFEARRAY1 LOCAL 'array 'OF 'array 'OF #epochs 'OF nResetWeights 'OF LRate 'OF nMomentum 'OF nMaxNeurons CallBackEpoch CallBackRMSError 8 NN50-LIB: TRAIN FOREIGN 1 = IF ." successful" ELSE ." unsuccessful" ENDIF ;As you can see in INIT-EVERYTHING , the first parameter is something special. "ByRef dwArrayPointer() As Double" is VB speak for a pointer to a pointer that points to a SAFEARRAY structure that describes (in this case) a 2 dimensional matrix of DFLOATS ! The useless first indirection is handled by putting OLE_SAFEARRY1 in a local variable and passing the address of that local. How to build an OLE SAFEARRAY is best taken from the VBASIC pages at the MS site, or from the documentation of your (Windows) C compiler. Note that the layout of the rgsabound[2] field, lLbound, is quite strange. It didn't work when I put the expected 0 there.
comp.lang.forth #54014 (1 more) From: mhx@iaehv.iae.nl (Marcel Hendrix) Subject: File interpretation Date: Sun May 20 11:56:59 CEST 2001 Lines: 47 This is a problem I face every time I want to solve a file-related problem in Forth. To analyse the solar conditions of a certain location in the Netherlands the testers send me ASCII text files with measurements taken every 10 seconds. The instruments run about 20 hours per day, and a single measurement takes about 32 bytes in the file. The file spanning October last year to May 14 2001 takes 48 MBytes. This file is so large that simple text editors and spreadsheets have 'problems' with it. Efficiency is important here. An example line: 10 12 15 178 184 13.8<cr^gt;<lf> (month, day, hour, sequence number, Watts/m^2, deg Celcius) The above is formatted by Forth to: date time G_sun (W/m^2) temperature (deg C) 12 Oct 15:29:30 184 14 There are errors in the measurements like missing days or invalid number strings ( "139-29.0" instead of "139 -29.0", things like that). Because of this problem, I'd like to use the Forth interpreter *itself* to parse the data line-by-line. There seems to be no way to send data to the interpreter directly, so I can do BL WORD etc.. EVALUATE doesn't work in this case. I solve this by writing the text directly to TIB , but I think that is non-ANS. Any ideas? : @LINE ( -- ) \ fhandle is the data file handle TIB #32 fhandle READ-LINE ?FILE 0= ABORT" EOF" #TIB ! >IN OFF BL <WORD> >FLOAT IF F>S TO month ELSE exit ENDIF BL <WORD> >FLOAT IF F>S TO day ELSE exit ENDIF BL <WORD> >FLOAT IF F>S TO hour ELSE exit ENDIF ( .. ) BL <WORD> >FLOAT IF F>S TO G_sun ELSE exit ENDIF BL <WORD> >FLOAT IF FROUND F>S TO temp ELSE exit ENDIF #TIB @ >IN ! ; -marcel comp.lang.forth #54016 From: anton@mips.complang.tuwien.ac.at (Anton Ertl) Subject: Re: File interpretation Date: Sun May 20 12:20:02 CEST 2001 Lines: 29 In article <9e84db$n0k$1@news.IAEhv.nl>, mhx@iaehv.iae.nl (Marcel Hendrix) writes: >that). Because of this problem, I'd like to use the Forth >interpreter *itself* to parse the data line-by-line. > >There seems to be no way to send data to the interpreter directly, >so I can do BL WORD etc.. > >EVALUATE doesn't work in this case. You can probably use EVALUATE by prepending the word to be executed to the string, setting up the context in the right way, and then EVALUATEing. This could be an application of the word we discussed half a year ago under various names: STRING-INPUT-EXECUTE ( ... addr u xt -- ... ) make addr u the input stream, EXECUTE xt, then restore the original input stream. I also proposed the name EXECUTE-PARSING, and others proposed other names. - anton -- M. Anton Ertl Some things have to be seen to be believed anton@mips.complang.tuwien.ac.at Most things have to be believed to be seen http://www.complang.tuwien.ac.at/anton/home.html comp.lang.forth #54019 From: mhx@iaehv.iae.nl (Marcel Hendrix) Subject: Re: File interpretation Date: Sun May 20 14:45:33 CEST 2001 Lines: 36 (#54016) anton@mips.complang.tuwien.ac.at (Anton Ertl) writes Re: File interpretation > In article <9e84db$n0k$1@news.IAEhv.nl>, > mhx@iaehv.iae.nl (Marcel Hendrix) writes: >> There seems to be no way to send data to the interpreter directly, >> so I can do BL WORD etc.. >> EVALUATE doesn't work in this case. [..] > This could be an application of the word we discussed half a year ago > under various names: > STRING-INPUT-EXECUTE ( ... addr u xt -- ... ) > make addr u the input stream, EXECUTE xt, then restore the original > input stream. Thanks! I had forgotten the discussion in December 2000. Re-reading it, it looked like iForth's EVALUATE could easily be factored in the needed components. I've called the new word $PROCESS ( .. c-addr u xt -- .. ). EVALUATE is simply : EVALUATE ( c-addr u -- ) ['] $EVAL $PROCESS ; When there's convergence to an accepted name for this functionality I'll add an ALIAS to the startup files. An added benefit is that $PROCESS nests input streams (instead of simply over-writing them). With my old solution you can't type @LINE @LINE at the command line. There could be a slight problem when a program wants to know the actual input source and consults SOURCE-ID . It will find -1 in my case. -marcel
Added support for some 32-bit float matrix operations in BLAS4.DLL. Try ./examples/benchmar/mmul/smm.frt . Note that 32-bit floats are exactly as fast as 64-bit floats (around 1.1 GFlops on the 900 MHz Athlon). They take less space though ...
SF@ and friends are best ignored: not many iForth utilities will support single-precision FP.
Improved the speed of ALLOCATE FREE and RESIZE . From now on, the iForth memory manager will only be used in case there is no OS.
Slightly faster COMPARE when strings have same length.
iForth now allows spaces in file names, using a repeated parsing trick
first shown by Bernd Paysan.
The new word is called /PARSE ( "string" -- c-addr u )
INCLUDE test INCLUDE "c:/Program Files/iForth/test.frt" INCLUDE 'c:/Program Files/iForth/test.frt' : test EVAL" INCLUDE 'c:/Program Files/iForth/test.frt'" ;
The trick is also used in a few other places where BL WORD COUNT might be expected.
Fixed a memory allocation bug in MIDIRW.frt. This bug (writing in a deallocated buffer) was apparently masked by the old ALLOCATE stuff.
Installed the new fast READ-LINE library in the kernel. Extra word: MAP-FILE ( handle -- addr u ) returns the internal buffer for the file (everything read in one big leap).
Found a memory allocation bug in DGETRI (mat^-1). This reminded me that it isn't even clear that DGETRI gives the right answer! Didn't test it, just made sure mat^-1 always uses GAUSSJ.
Changed doLIST and doNEXT . These routines now _very_ much favor the AMD Athlon call stack, i.e. thread.frt, thread2.frt ... and most (small) recursive benchmarks got a lot faster for the Athlon.
Found why the random number generator in MPE's benchm.f is so slow on the Athlon: it's the code + data in a single cache line item again. The generator got 4 times faster with a single ALIGN64 added after the variable.
Found a similar problem in GOLYGONC.frt. There may be a few more in bdriver.frt.
Fixed the "immediate byte problem" with SEE ( 83s had/s imm problem ).
Numerous changes to the kernel to get consistent alignment for Athlon. Unfortunately, the AMD alignment hurts older Pentia. Therefore _calign_ and _align_ must be set up. Not yet documented, done setup in iForth.prf. (not automatically).
Added a small peephole routine to remove "ebx push, ebx pop,". This brought speed of Sieve up to old standard (1700 ms on P54C, 360 ms on Athlon).
Increased the iForth stack sizes so that the Ackermann benchmark can be run without special tricks ( needed about 2051 cells ).
Worked on the documentation, most kernel words are now both in HELP.FRT and the HTLM files.
Increased BDRIVER so that the Monster Benchmark now runs 85 tests, including many shootout files.
It looks like the new optimizer works and gives good/very good performance for the Athlon, so-so performance on a P54C. Announced 1.12 release on CLF. The new optimizer is installed by default, but the old workhorse is present as a backup.
Modified EXIT to do tail-call optimization (forgot!)
Experiments with I/O FI/FO :FAST FAST; and [XCOMPILE] an immediate COMPILE, that needs a header address [XCOMPILE] ( dea -- ). The results are immeasurable on the P54C, not checked on Athlon (my hardware broke down because of the high summer temperatures, can't burn any CDROMs) This needs a modified EXIT to work transparantly. After it works I expect to move it into the kernel without needing new words (apart from I/O to specify the stack effect). To run or compile words with non-default stack effects it will be necessary to change $INTERPRET and $COMPILE . The idea is to have a standard stub that calls the real thing, the optimizing compiler dissects the stub to find the faster inner code.
Some assembler bugs uncovered by ./asm/test-asm.frt, one looks serious (byte/word mov). The assembler/disasembler is missing cmovxx and fcmovxx and maybe a few other handy new instructions ** FIXED **
The SAVE-SYSTEM word was completely broken on older iForths (many versions back) ** FIXED **
Fixed a bug with recursive uses of NEEDS. This produced an error in REMEMBER.HANDLE. Changed REMEMBER.HANDLE? so it can report errors. Also renamed FORGET.HANDLE to FORGET.HANDLE?.
There is now a WORDS: ( "text" -- ) in addition to WORDS and WORDS? . The new WORDS: will (case insensitively) match dictionary words against "text" and print the word if successfull.
Factored the word doWORDS ( xt -- ). The xt will be called with a counted string and must return a boolean ( 'string -- bool ). The counted 'string points to a dea (count < 32). Returning TRUE assures dea being printed.
The word TEXTMODE? ( -- u ) from terminal.frt now returns the text colors in the high 16 bit word. (high nibble == bgcolor, low nibble is fgcolor). The WIN32 iForth respects the color setting of the console window, and will not try to use white-on-black regardless.
KEY does EKEY $FF AND instead of EKEY $7F AND . This may improve the response of non-US keyboard layouts (note that one should do EKEY EKEY>CHAR officially).
Added ?EXIT and ?LEAVE to miscutil.frt
Checked that there are no specific iForth THROW values. The value -21 is generated when there is an internal compiler error, but the accompanying messages will differ widely.
Stored full (i.e., not fully qualified, but exactly as entered) pathnames of included files in an attempt to make WHAT work better.
Added features to HELP "word". The "word" is first searched as is, then upper cased, and finally lower cased. If it is still not found, a list of possibilities is presented (words in the dictionary that "word" partly matches to).
FORTH> help pu `pu' is not listed, suggesting: FPUSH2 FPUSH3 FPUSH4 FPUSH5 FPUSH6 RESTORE-INPUT SAVE-INPUT +LOOPu FPU-ovf! FPU-ovf@ XFPUSHD FPUSHD FPUSHS CPUFLAGS #CPU ok
Added >LWC . The words >UPC and >LWC are now optimized somewhat.
The interface to IN/OUT and FIN/FOUT changed slightly. It is not possible to have FIN/FOUT by it's own, it needs to go together with an IN/OUT statement, even if this is only 0 0 IN/OUT . Example:
FORTH> ALSO ASSEMBLER ok ASSEMBLER> : myfadd 0 0 IN/OUT 2 1 FIN/FOUT POSTPONE ASM{ ST(1) -> ST fadd, }ASM ADJUST-STACK ; IMMEDIATE COMPILE-ONLY PREVIOUS ok FORTH> : 2add 33e 22e myfadd F. ; ok FORTH> see 2add $004D2650 : 2add $004D2656 fld $004D2688 qword-ptr DD0588264D00 $004D265C fld $004D2680 qword-ptr DD0580264D00 $004D2662 fadd ST, ST(1) D8C1 $004D2664 fpush, 8B4710D9C9DD58F88D40F8 894710 $004D2672 call F. ( $00462AF0 ) offset NEAR E87904F9FF $004D2677 ; FORTH>Without the "0 0 IN/OUT" the code generator doesn't know myfadd is a macro:
FORTH> also assembler ok ASSEMBLER> : myfadd 2 1 FIN/FOUT POSTPONE ASM{ ST(1) -> ST fadd, }ASM ADJUST-STACK ; IMMEDIATE COMPILE-ONLY PREVIOUS ok FORTH> : 2add 33e 22e myfadd F. ; ok FORTH> see 2add $004D2640 : 2add $004D2646 fld $004D2688 qword-ptr DD0588264D00 $004D264C fld $004D2680 qword-ptr DD0580264D00 $004D2652 fpop, 8B4710DD00D9C98D400889 4710 $004D265F fadd ST, ST(1) D8C1 $004D2661 mov eax, [edi #16 +] dword 8B4710 $004D2664 lea eax, [eax #-16 +] dword 8D40F0 $004D2667 mov [edi #16 +] dword, eax 894710 $004D266A fxch ST(2) D9CA $004D266C fstp [eax 8 +] qword DD5808 $004D266F fstp [eax 0 +] qword DD18 $004D2671 call F. ( $00462AF0 ) offset NEAR E87A04F9FF $004D2676 ;... which is completely wrong.
Please note that it is valid to have an IN/OUT statement without an FIN/FOUT, but only when the FPU stack isn't touched.
With respect to IN/OUT: iForth does not support more than 2 2 IN/OUT for user macro-like words.
Old compile time: ~ 32 seconds New compile time: ~ 24 seconds
The difference strengthens my belief that the new iForth is about 25 to 30 percent faster than the old one.
Increased the (arbitrary) limit on string sizes handled by $+ S" MULTI-LINE and $>UPC to 4K. Added words CELLPACK and CELLPLACE+ (analogous to PACK and PLACE+) in miscutil.frt.
Several directories with upper case filenames were fixed. I may not have catched them all (send a script to help, please... )
The console color handling when starting up has changed and should be a little friendlier now:
The keyboard handling under Linux was a mess. I've removed termcap indirection and assume the Linux console everywhere. This is possible because newer Linuxes allow you to set the keyboard and the screen color scheme in every X session (so please set them to 'Linux console').
It is now possible to remote login to an iForth over the network (with telnet or ssh) and run it without problems. PROCED works, this is because tty.c now strictly uses ESC sequences for getting and setting the cursor position.
Linux: the cursor position and keypad mode are adjusted over a shell invocation. So no more 'random cursor' after "ls" etc.
For Linux there proved to be an enormous overhead on writing files with the O_SYNC flag set. Turning O_SYNC off resulted in a 577 (!) times speedup on SuSE 8.0, Linux 2.4 with reiserfs filesystem. On an older Linux 2.0 with ext2 filesystem the speed gain was about a factor of 2 to 3 (sometimes unnoticeable, especially when there was sufficient filebuffer space?)
CREATE-FILE and OPEN-FILE always set permissions to -rwxr-xr-x. Changed it to do -rw-r--r-- with R/W, -r--r--r-- with W/O and --w------- with R/O. Note that CREATE-FILE with R/O is possible, but (of course) such a file can't be written to, so it will stay 0 bytes long.
It is now possible to input 'high ASCII' with KEY. Note that you should use EKEY>CHAR according to the standard.
/dfwforth/iflinux...
files should be copied to e.g. /usr/local/iForth_2.0
(Personally I want only a single directory for all platforms and therefore copy everything to /dfwforth
).
There is a bug on the iForth 2.0 CD, Linux part, in ../dfwforth/iflinux/iserver/maksuse
.
maksuse:49: *** missing separator (did you mean TAB instead of 8 spaces?). Stop.This is simple to fix, add a <TAB> before iForth:
all: \ iforthIt seems iForth 2.0 can be installed on a Debian potato.
: evalLP ( sq -- sq ) DUP DUP CELLS pawnPcSq + @ >R ( R: value ) DUP file 1+ CELLS ( sq f+1 ) DUP lightPawnRank + ( sq f+1 ^lpr ) ROT rank ( f+1 ^lpr r ) OVER @ OVER U> IF R> DOUBLED_PAWN_PENALTY + >R THEN ... ^-- causes SIGSEGV *** FIXED ***
The bug can be cause for other spurious SIGSEGV's. The condition should be: a comparison between something and an indexed fetch.
Two new flags: _fastcall?_
( e.g. _fastcall?_ ON
) and ALT-used@ ALT-used!
.
The ALT-used..
is to set an alternative NEXT,
routine. FALSE ALT-used!
is best
for the Athlon, TRUE ALT-used! is good for old Pentia. Likewise _fastcall?_ ON
sometimes produces a speedup on old Pentia.
Linux: CR on last line didn't work. *** FIXED ***
Linux: Sometimes iForth starts up with a seemingly random chosen text foreground color. *** FIXED ***
Windows: After resizing the text window the cursor position is random *** FIXED ***
The call r/m32 instruction is missing from the assembler ( $FF $15 <addr> etc. ) (it is not missing, but there is no valid syntax to trigger it) This code can be assembled with C, for now. *** FIXED ***
iForth version number is still 1.12.8xxxx ... *** FIXED ***
Under win32 it proved to be that the stdin and stdout handles in redirected mode were not simply 0 and 1, as they should be. *** FIXED ***
Also, iForth did not reliably detect when its input was redirected. The latter problem proved insolvable under win32, therefore a new commandline argument is now supported by the iwserver. Use "iwserver #io .." to start iForth with redirected input and/or output. Here redirected input is "#10", redirected output "#01", both redirected is requested with "#11" (none is "#00"). (The commandline argument is not strictly necessary, but without it the first three characters in redirected input mode will vanish.)
Some more or less puzzling problems when using win32 iForth with input and output redirected were solved by using an eof(0) test in qkey(). *** FIXED ***
The tcl/tk interface is not compiled into iwserver.exe anymore. The pipe version works much better anyway. There was a problem with a cw3215.dll that caused a segmentation fault for TCL 8.02b, only on Win98. I now use tcl 8.05, but users will have to fetch the binaries for themselves from now on.
This is now fixed, also in D> D>= D<= DU< DU> DU<= DU>= ... etc. A remaining flaw is that D> etc. do not support comparing two double precision constants anymore.
This bug should not be too serious because most of the time D< etc. are used with smallish arguments. The best fix is to use the assembler to generate a new D< , as follows:
CODE D< ( a b -- bool ) -1 ALLOT [ebp -4 +] pop, ebx pop, eax pop, ecx pop, eax -> [esp] cmp, eax pop, ebx -> ecx sbb, 0 b# -> eax mov, <, IF, eax dec, ENDIF, eax push, [ebp -4 +] jmp, END-CODE
This solution automatically prevents the optimizer to continue using the wrong code.
A bug in mille2.frt. Completely new code; merstwist.frt.
Fixed an optimizer bug in
: test LOCAL tt tt COUNT 2DUP BOUNDS ; C" ttt" test .DATAThe output was wrong because of a wrong (PLUS) for certain indexed parameters.
Some error in the gray pattern for gbox# (terminal.frt).
OPEN-FILE / FILE-STATUS was buggy. A check on a directory returned 3 stack-entries on Linux.
Added (E.R) (F.R) (FE.R) ( F: r -- ) ( -- c-addr u ) see E.R F.R FE.R
The x.R print '*..' if the fieldwidth is insufficient.
The x.R print '0.0..' if |number| < 10^-PRECISION .
: test LOCAL tt tt COUNT 2DUP BOUNDS ; C" ttt" test .DATA
again, it had side effects in dsieve.frt.
This crashed diehard.frt:
: ran-MWC256 ( -- u ) index 1+ #255 AND TO index qq index CELL[] @ #809430660 UM* carry UM+ TO carry DUP qq index CELL[] ! ;
The problem is in UM* (also in M*). In case a constant is multiplied with a memory based operand EDX was garbling one of the source registers. This is an old bug, that was insufficiently squashed. It is almost certain that it leads to an access violation, so the chance that it stays hidden in user code is quite unlikely.
Some code for the 8 queens problem by Ian Osgood demonstrated the problem:
ANEW -queens \ 8 queens \ Triangular array of bitmasks, one bit per square \ recursion depth 0, ranks 0..N-1 are at offsets 0..N-1 \ recursion depth 1, ranks 1..N-1 are at offsets N..N+(N-1)-1 \ etc. 14 constant maxN 8 value N create ranks maxN dup 1+ * 2/ cells allot : init_ranks 1 N lshift 1- N 0 do dup ranks I cells + ! loop drop ; :INLINE lowBit ( mask -- bit ) dup negate and ; :INLINE lowBit- ( mask -- bits ) dup 1- and ; \ Copy the square availability from the current ranks \ to the next ranks, excluding attacks by the new queen \ at nextBit of ^rank. \ Aborts if there is no possible solution from here. variable excludes \ N=8 should be 4380 : exclude ( ranksLeft ^rank -- tf ) over 1- cells over + swap rot ( dest src ranksLeft ) 1 do 1 excludes +! 2dup dup @ lowBit ( dest src mask ) \ file dup I lshift or \ left diagonal \ The noop removed the problem. Without NOOP the number of queens is wrong. \ noop dup I rshift or invert \ right diagonal swap I cells + @ and ( dest masked ) dup 0= if 2drop 2drop unloop false exit then swap I cells + ! loop 2drop true ; variable nodes \ N=8 should be 1073 variable solutions \ N=8 should be 92 : tryRank ( ranksLeft ^rank -- ) 1 nodes +! begin over 1- if 2dup exclude if over 1- 2dup 1+ cells + recurse then else ( .solution) 1 solutions +! then dup @ lowBit- dup while over ! repeat drop 2drop ; : queens CR TIMER-RESET init_ranks 0 solutions ! 0 nodes ! 0 excludes ! N ranks tryRank .ELAPSED SPACE N . ." queens: " solutions @ . ." solutions, " nodes @ . ." nodes, " excludes @ . ." exclude loops " ; : t_queens CR TIMER-RESET #1000 0 DO init_ranks 0 solutions ! 0 nodes ! 0 excludes ! N ranks tryRank LOOP MS? DEC. ." microseconds elapsed, " N . ." queens: " solutions @ . ." solutions, " nodes @ . ." nodes, " excludes @ . ." exclude loops " ; queens : test_queens begin queens N maxN < while N 1+ to N repeat ;
Here queens should give
FORTH> in yqueens 0.002 seconds elapsed. 8 queens: 92 solutions, 1073 nodes, 4380 exclude loops ok
BUG in RREF found.
Error -21 no:nos@EA :: infinite loop ? \ : L.I { Y2 Y1 X2 X1 x -- y } \ Y2 Y2 Y1 - X2 x - X2 X1 - */ - ; \ ^ ^ ^ ^ \ -1.- -2.- -3.- -4.- : L.I ( Y2 Y1 X2 X1 x -- y ) >R >R >R ( [y2] [y1] ) over swap - ( [y2] [y2-y1] ) R> R> over ( ... [x2] [x1] [x2]) R> - ( ... [x2] [x1] [x2-x] ) rot rot - ( [y2] [y2-y1] [x2-x] [x2-x1] ) */ - ; : L.I ( Y2 Y1 X2 X1 x -- y ) 4 PICK >S >R >R >R - ( [y2-y1] ) R> R> over ( [y2-y1] [x2] [x1] [x2]) R> - >R ( [y2-y1] [x2] [x1] ) ( R: x2-x ) ( S: y2 ) - ( [y2-y1] [x2-x1] ) R> SWAP */ S> SWAP - ;
This works now (Aug 20, 2005).
Fixed a documentation bug for IN/OUT .
FORTH> in 3dimming.frt Creating --- Graphics Package Version 3.02 --- Creating --- Win32 driver Version 1.02 --- Creating --- Postscript driver Version 2.00 --- Creating --- Array arithmetic Version 4.01 --- Creating --- Mouse Driver Version 1.17 --- Creating --- Mathematical Spikes Version 1.00 --- Redefining offset Redefining 1/f Wrong combination of operands: $42 -> @ea_reg, line 163, at PC: $004DAD6A, near surface1 Thrown out of `3dimming.frt' Error -21 in line #163 at nesting level 1 / :: unknown operand combination ?
: mymax ( a b -- max[a,b]) 2DUP < >R R@ AND SWAP R> 0= AND + ; \ 10 words
THIS IS HORRIBLY WRONG!
FORTH> : mymax ( a b -- max[a,b] ) <2>[FORTH>] 2DUP < >R R@ AND SWAP R> 0= AND + ; ok FORTH> see mymax $005008C0 : mymax 8F45FC83ED04 $005008C6 pop ebx 5B $005008C7 pop ecx 59 $005008C8 cmp ebx, ecx 3BD9 $005008CA setg [edi 0 +] byte 0F9F0F ^^__ start next instruction! $005008CD sahf 9E $005008CE ror [edi 0 +] byte, #182 b# C00FB6 $005008D1 xxx bh, #216 b# C0F7D8 $005008D4 and ecx, eax 23C8 $005008D6 add ebp, 4 b# 83C504 $005008D9 lea ebx, [ebx ecx*1 0 +] dword 8D1C0B $005008DC push ebx 53 $005008DD jmp [ebp -4 +] dword FF65FC
Problem: (cond) deliberately generated an invalid instruction. This instruction was not restored to the correct state when no conditional jump instruction followed the flag forming code.
: (number?) ( c-addr u -- d|ud double? number? ) base @ >r over c@ [char] - = dup >r if 1 /string then \ negative? over c@ [char] $ = if 1 /string hex then \ hex? 0. 2swap >number \ convert r> if 2>r dnegate 2r> then \ negative <<<<<<<<<<<<<< swap \ ( d|ud u c-addr ) c@ [char] . = 1 and \ double number? tuck = \ number? r> base ! ;With 2>r 2r>
Wrong combination of operands: $42 -> @ea_reg, line 8, at PC: $004EDB32, near -cjb1 Thrown out of `input.frt' Error -21 in line #8 at nesting level 1
This bug was fixed by turning off double number optimization: (2cond), (+cy) and (-borrow). These didn't provide much of a speedup anyway.
\ Zeller's Congruence \ From day month year, calculate the day of the week : fmod ( n1 n2 -- floored-mod ) >R S>D R> FM/MOD DROP ; : dow ( d m ccyy -- 0=Sunday...6=Saturday ) \ Make year begin in March >R 2 - DUP 1 < IF 12 + R> 1- >R THEN R> \ Separate ccyy into yy and cc 100 /MOD 2>R ( d m ) ( R: yy cc ) \ Zeller's Congruence: \ dow = (d + (26*m - 2)/10 + cc/4 - 2*cc + yy/4 + yy) mod 7 26 * ( <<<<<<<<<<<<< produced insCHECK error ) 2 - 10 / + \ d + (26*m - 2)/10 R@ 4 / + R> 2* - \ + cc/4 - 2*cc R@ 4 / + R> + \ + yy/4 + yy 7 fmod ; \ mod 7 = dow
When there were not enough free registers, the optimization for "*" failed, producing a compiler stack error (26 * needs more than 2 registers). This error could happen whenever no:nos,tos=EA or no:nos,tos@EA was called, because these (might) flush all but TOS and NOS.
Testing ' ['] FIND EXECUTE IMMEDIATE COUNT LITERAL POSTPONE STATE Incorrect result: { GT1STRING FIND -> ' GT1 -1 }
VARIABLE rsave : GP7 BASE @ >R MAX-BASE BASE ! <TRUE> A 0 DO I 0 <# #S #> <<<< rsave ! C@ 30 I + = AND <<<< rsave @ 1 = AND <<<< LOOP \ wait: MAX-BASE converts to 10 ! So we can only test upto MAX-BASE 1- \ MAX-BASE 1+ A DO MAX-BASE A DO I 0 <# #S #> rsave ! C@ 41 I A - + = AND rsave @ 1 = AND LOOP R> BASE ! ; { GP7 -> <TRUE> } \ bug: fails on jhforth: lowercase a $00530134 mov ecx, [ebp 0 +] dword $00530137 lea edi, [ecx #48 +] dword <<< 30 I + $0053013A cmp bh, [ebx 0 +] byte <<< C@ = ^^------- cmp edi_low, [ebx] byte $0053013C sete bl $0053013F movzx ebx, bl $00530142 neg ebx $00530144 pop ecx $00530145 and ecx, ebx
twords1
and twords2
tools.
The new compiler had version 2.1.934 when I considered it 'good enough.' Many, many, internal changes:
COMPILE,
now tokenizes source and automatically inlines token strings where appropriate
COMPILE,
can tokenize and inline DOES>
parts
IMMEDIATE
kernel and elective words
coretest
and Anton Ertl's test whether
POSTPONE
conforms to ANS Forth when working on words with special
compilation semantics (even S"
, C"
and Z"
work)
CONST-DATA
. Very effective for DOES>
parts with constants, e.g. ARRAY
, MATRIX
etc.
PARAMS|
. Stack order reversed from LOCALS|
LIBRARY
.LIBRARIES
( u -- ) IMPORT name
IMPORTF name
.FUNCTIONS
to ./include/dynlink.frt
DENOTATION
. A word of this type is known to scan the input stream, but promises to direct all its actions through COMPILE,
. Examples are [CHAR]
, S"
and of course :
One of the most important results is that the need for :INLINE
and smart DOES>
parts
using STATE
has almost completely gone away. In principle, the only STATE-smart word is COMPILE,
.
Below is an example result for a PIV 3 GHz HT, Windows XP Home, 512 MB machine, running an unmodified BENCHMRK.FTH as used by MPE (only harness code changes).
Note the enormous speedup of iForth 2.1 with respect to 1.12.
Also note that iForth beats VFX on all but one (Fibonacci) of the application code tests. The ghastly results of vsn 1.12 for random numbers and LZ77 were caused by a code / data issue.
Benchmark code size 92923 bytes+idata (VFX) // 164752 bytes (iForth) This system's primitives using no extensions and using no hackery VFX 3.80 iForth 2.1.934 iForth 1.12.8722 Test time including overhead ms ms ms DO LOOP 2 0 0 + 1 0 0 M+ 2 0 16 * 2 0 0 / 17 15 16 M* 5 0 0 M/ 10 16 15 /MOD 12 16 16 */ 16 15 15 ARRAY fill 5 0 32 Total: 72 62 110 This system's O/S interface using no extensions and using no hackery Test time including overhead ms ms ms Win32 API: SendMessage 34 0 0 Win32 API: COUNTER 66 16 47 System I/O: KEY? 6 0 0 Total: 106 16 47 This system's application performance using no extensions and using no hackery Test time including overhead ms ms ms Eratosthenes sieve 1899 Primes 89 78 203 Fibonacci recursion ( 35 -> 9227465 ) 158 172 343 Hoare's quick sort (reverse order) 81 78 485 Generate random numbers (1024 kb array) 123 109 1031 LZ77 Comp. (400 kb Random Data Mem>Mem) 150 141 1500 Dhrystone (integer) 136 109 219 Total: 737 687 3781
PARAMETERS|
should not be mixed with any form of LOCALS|
. Note that, contrary to
LOCALS|
words, words with parameters can be auto-inlined. It is possible that after
inlining some references to the local stack still exist and cause interference with
variants of LOCALS|
( LOCALS|
can not be optimized because the construct supports
taking the address of items with 'OF
). One can be reasonably sure that PARAMS|
does
not cause referencing the local stack in short words without control constructs,
which is the kind of situation PARAMS|
were designed for.
This bug affects (at least) some of the less often-used features of ./include/gaussj.frt.
In case of doubt, simply use LOCALS|
.
Note that the size of iforth.img has grown lately, and that the iForth Linux server must therefore be recompiled. The distribution contains an old iforth server that doesn't work with the new images.
'PANIC
is not pointing to ABORT
as documented and crashes the system. The documentation
of PANIC
contains an irrelevant reference to MS-DOS: PANIC
is used in all iForth systems.
Windows Users have reported startup problems with the supplied Tcl/Tk examples in ./examples/tcl_tk. These could be caused by resident Virus and Spyware checkers, which seems to delay opening of files and indexing the Tcl/Tk directory structure. Killing the WISH window and retrying to load an example eventually fixes the problem. A more robust way to start Tcl/Tk and check for response on its pipe is due.
A quick fix is to add
#1000 ( or more) MSafter
CR .( loading Tk ... ) S~ source "$tk_library/tk.tcl"~ TYPEin the various exampxxx.frt files.
The user may decide to have CREATE .. DOES>
children that are IMMEDIATE
.
This can interfere with optimizations that try to inline short DOES>
parts.
Example:
VARIABLE bar : foo: CREATE , IMMEDIATE DOES> @ bar ! ; 3 foo: ape bar ? : test ape ; bar ? ( should print 3 ) see test ( should contain no real work )
The distribution used a fast replacement of EXECUTE
( IEXECUTE
) all over the
place. The word IEXECUTE
does not commit all stacks and was observed to produce
wrong code for some floating point words. There's now a new EXECUTE
that is as
smart as IEXECUTE
but does not have the problem.
A quick fix is to redefine IEXECUTE
somewhere in ./include/miscutils.frt
: IEXECUTE EXECUTE ;
The file ./include/strings.frt has several problems because 0
is used to
initialize the $methods
vtable. This should be changed to ' NOOP
. The old
method worked because the old EXECUTE
checked for xt's that were 0 and skipped
execution (like SwiftForth). The strings package also suffers from the IEXECUTE
problem above.
There are several bugs in the assembler and SEE
with regards to SSE2 and 3DNow!
instructions. Many have been fixed, but there is still a lot to do. This task has
low priority because my experiments show that SSE2 hardly speeds up optimized double
precision FPU codes. (Specifically: matrix multiplication was not faster than iForth
built-in words.) Follows an example:
CODE ddot_sse2 ( x{ y{ n -- ) ( F: -- r ) rpush, xmm7 -> xmm7 xorps, ecx pop, \ n ebx pop, \ y{ eax pop, \ x{ ecx -> edx mov, xmm7 -> xmm0 movapd, xmm7 -> xmm1 movapd, xmm7 -> xmm2 movapd, xmm7 -> xmm3 movapd, xmm7 -> xmm4 movapd, xmm7 -> xmm5 movapd, xmm7 -> xmm6 movapd, 1 b# -> edx shr, 7 b# -> edx and, @@1 offset NEAR je, [eax] -> xmm6 movapd, [ebx] -> xmm6 mulpd, 3 b# -> edx cmp, @@2 offset NEAR jg, @@3 offset NEAR jne, [eax $20 +] -> xmm4 movapd, [ebx $20 +] -> xmm4 mulpd, [eax $10 +] -> xmm5 movapd, [ebx $10 +] -> xmm5 mulpd, @@4 offset NEAR jmp, @@3: 2 b# -> edx cmp, @@4 offset NEAR jne, [eax $10 +] -> xmm5 movapd, [ebx $10 +] -> xmm5 mulpd, @@4 offset NEAR jmp, @@2: [eax $30 +] -> xmm3 movapd, [eax $20 +] -> xmm4 movapd, [ebx $30 +] -> xmm3 mulpd, [eax $10 +] -> xmm5 movapd, [ebx $20 +] -> xmm4 mulpd, [ebx $10 +] -> xmm5 mulpd, 5 b# -> edx cmp, @@5 offset NEAR jg, @@4 offset NEAR jne, [eax $40 +] -> xmm2 movapd, [ebx $40 +] -> xmm2 mulpd, @@4 offset NEAR jmp, @@5: [eax $50 +] -> xmm1 movapd, [ebx $50 +] -> xmm1 mulpd, [eax $40 +] -> xmm2 movapd, [ebx $40 +] -> xmm2 mulpd, xmm1 -> xmm3 addpd, 6 b# -> edx cmp, @@4 offset NEAR je, [eax $60 +] -> xmm0 movapd, [ebx $60 +] -> xmm0 mulpd, xmm0 -> xmm2 addpd, @@4: 4 b# -> edx shl, edx -> ebx add, edx -> eax add, -- set up for primary loop which is unrolled 8 times @@1: ecx -> edx mov, 4 b# -> ecx shr, @@6 offset NEAR je, [eax] -> xmm0 movapd, [eax $10 +] -> xmm1 movapd, ALIGN ( each loop does 16 add+multiply ) @@7: [ebx] -> xmm0 mulpd, xmm2 -> xmm6 addpd, [eax $20 +] -> xmm2 movapd, [ebx $10 +] -> xmm1 mulpd, xmm3 -> xmm7 addpd, [eax $30 +] -> xmm3 movapd, [ebx $20 +] -> xmm2 mulpd, xmm0 -> xmm4 addpd, [eax $40 +] -> xmm0 movapd, [ebx $30 +] -> xmm3 mulpd, xmm1 -> xmm5 addpd, [eax $50 +] -> xmm1 movapd, [ebx $40 +] -> xmm0 mulpd, xmm2 -> xmm6 addpd, [eax $60 +] -> xmm2 movapd, [ebx $50 +] -> xmm1 mulpd, xmm3 -> xmm7 addpd, [eax $70 +] -> xmm3 movapd, [ebx $60 +] -> xmm2 mulpd, xmm0 -> xmm4 addpd, [eax $80 +] -> xmm0 movapd, [ebx $70 +] -> xmm3 mulpd, xmm1 -> xmm5 addpd, [eax $90 +] -> xmm1 movapd, $80 d# -> ebx add, $80 d# -> eax add, ecx dec, @@7 offset NEAR jne, @@6: xmm2 -> xmm6 addpd, xmm3 -> xmm7 addpd, xmm5 -> xmm4 addpd, xmm6 -> xmm7 addpd, xmm7 -> xmm4 addpd, xmm4 -> xmm0 movapd, 1 d# :: xmm4 -> xmm4 shufpd, xmm4 -> xmm0 addsd, 1 b# -> edx and, @@8 offset NEAR je, [eax] -> xmm1 movsd, [ebx] -> xmm1 mulsd, xmm1 -> xmm0 addsd, @@8: fpush, xmm0 -> [esp -8 +] movsd, [esp -8 +] qword fld, rpop, ebx jmp, END-CODE 4 DOUBLE ARRAY x{ 4 DOUBLE ARRAY y{ 1e 2e 3e 4e x{ #=> 5e 6e 7e 8e y{ #=> CR x{ }print CR y{ }print
./include/backtrac.frt does not work because of a trivial error.
Documentation and clean up (on line help) of ./include has started. Processed so far:
2.4k Dec 15 23:09 elip.frt 5.1k Dec 15 22:38 newton.frt 53k Dec 15 19:57 fsl_util.frt 10k Dec 14 23:44 dates.frt 28k Dec 14 23:15 floatest.frt 11k Dec 14 21:27 dlstroke.frt 5.6k Dec 14 20:33 dde.frt 3.1k Dec 14 20:25 cvfind.frt 898 Dec 14 20:15 fcbrt.frt 4.5k Dec 14 19:20 cubic.frt 21k Dec 14 19:18 xmatrix.frt 8.2k Dec 14 19:00 complex.frt 2.3k Dec 14 18:37 buffers.frt 30k Dec 14 18:29 bignum.frt 5.8k Dec 14 17:59 banner.frt 5.3k Dec 14 07:45 backtrac.frt 7.8k Dec 13 22:07 assert.frt 4.2k Dec 13 21:42 arraysx.frt 6.5k Dec 13 21:39 arrays.frt 3.2k Dec 13 21:30 aitken.frt 25k Dec 11 23:46 strings.frt 52k Dec 8 23:33 see.frt
Noticed garbage text in the TEXTFIELD items from menus.frt. This was a problem with modes @ba_@ea and @ba_@ba for "> IF". This is a serious issue but can not have happened too often, regarding the history record of this part of the optimizer.
It was possible for (E.) etc. to return non-zero delimited strings. Fixed computations involving HLD, and compare with PAD CELL- instead of PAD
The OS word failed when the command contained quoted strings (because the file names of paths had spaces).
Found a bug in S~ and S" when they were were used together very frequently. Added CELLCHAR+ to add a single character to a long string. (See CELLPLACE+)
Bug in SEEK-FILE appears when the file is buffered in memory (e.g. when a file is seeked after a previous operation on the file). Note that SEEK-FILE is not an ANS word and is very seldom used.
gaussj_test.frt: bug in SVDFIT and SVBKSB (extra parameter M needed). The size of the u matrix in SVD is a very difficult problem!
Added a *conditional* 0tmp in :NONAME . When using FORGET> , a :noname definition is used to do the work. The compilation of this :NONAME executed 0tmp (which promptly destroys the fpatch information needed at the visible ; at the end of the create forget> does> word).
RESIZE ALWAYS fails on Windows XP64. (strcat.frt from shootout). This was a bug in realloc4 in the C server.
The iForth timer functions do not work on a machine with hyperthreading or multiple cores. The indication that something is wrong can be seen when running:
CD /dfwforth/examples/benchmar/ NEEDS -bdriver ALL-TESTSIn some cases you may notice odd or irregular timings, and sometimes even crashes when a timing difference becomes negative and the number formatting routine overflows. The solution for AMD CPU's can be found on the AMD website. For Intel machines you should make sure that the boot.ini file does not contain the
/usepmtimer
switch.
Check RESIZE again please!
100 ALLOCATE ?ALLOCATE =: addr addr -1 RESIZE ( returns no error and a valid new address?! )(This is OK :-) It allocates 16 bytes more than -1 bytes = +15 bytes)
Jxxxxx Fxxxxxxx It seems mpdiv ( BLAS ) is wrong, run LESSNUM.frt and test 20 .CONSTANTS .
Image size increased to 8 MBytes, removed a bug that prevented a dictionary
SIZE larger than the load absolute ADDRESS. (Would this do something for the
Darwin load problems?)
Windows Implemented Build a Goto BLAS dll for the Prescott architecture: libgoto_prescott-r1.23.dll .
This one is verified to work for the Intel Pentium D 945 cpu (this is a dual-core
3.4 GHz type with 16K level 1 and 2 * 2 MBytes level 2 cache). The Pentium D crashed
for the libgoto_northwood-r1.23.dll, which works for a hyperthreaded Pentium IV
(Northwood, 8kB Synchronous, Write-Thru, 4-way set, 64 byte line size, 2 lines per
sector L1, 512kB 8-way set, 64 byte line size, 2 lines per sector, L2)
Changed Fixed two thread related bugs.
Carry bug in bignum.frt, inner . Only for relatively large numbers.
In help.frt, parsing is for '#####', but when spaces or tabs are added to it,
the parsing will fail. Consistency check should look for this, or the parser made smarter.
I noticed similar problems for "{" and "}".
The =RSIZE field was not defined in the meta sources (without consequences). It is
not possible to increase the size of the return stack arbitrarily. Currently it is
4kB, and 12 kB is possible, but not more. (This has to do with the new task switching
code, which obviously is more important.) As a result of this, deep recursion may lead to
iForth silently quitting. I have implemented the word RDEPTH so this can at least be
checked. ( ?STACK now contains RDEPTH to check for overflow ).
The word FORGET> can not be used inside a definition that not also has a DOES> part.
The DOES> part should follow the FORGET> code.
On Windows XP, HERE 100000 2DUP 'a' FILL TYPE does not work, nothing is
printed. Apparently the screen print functions are limited to ~ 40Kbytes!
Consequence of debugging iForth64: bug found in iForth32.
Linux: CATCHing SIGSEGV or SIGFPE only worked once, e.g. -1 ? -1 ? still crashed
to the OS. Solved by using sigjmp_buf.
Bugs in opengl.frt: certain calls, specifically goldm etc., are only allowed inside
a callback and must be issued by :[ goldm ] . In opengl.frt. goldm was called directly.
This works in 32bit Windows and Linux, but not for OSX and 64 bit iForth.
Also, :[ was wrong: it should wait at least 10 ms for the reset callback to actually
execute. This resulted in goldm (sometimes) not really executing.
With the changes, resetting the colormap works. However, it is still not possible
to reliably reset the OpenGL to a satisfactory initial state. It is simply not known
what this state is :-)
An immediate constant doesn't work well with [IF] . I.e., avoid constructs like
iForth will make CREATE-d words IMMEDIATE . However, in definitions CREATE
does not do this. This makes sure that CREATE .. DOES> works correctly.
See the neural-net demo, examples/nn/nn50.frt.
You may notice that nn50 sets up the parameters for its
graphics window inside the callback, the first time it is called.
The graphics pen and the window coordinates are USER values.
After quite a while I realized there was nothing wrong with iForth.
A callback is a special thing. It has a USER area, but this area
can't remember anything as it is re-initialized by a block move
from the currently interrupted task, each time the callback appears!
So what happened was that the first time the callback ran it set
up a nice graphics window ... but the next time it again ran, these
parameters had disappeared and it tried to draw in a zero size window
(FPU exception raised). (Luckily the main task was not doing any
scaled graphics, or the problem would have been much harder to
diagnose.)
After some fiddling around, the initial error disappeared (I'm
not sure why, maybe I had done some graphics in the main task),
but now the line graph ( DRAW-SCALED-LINE ) was not a smooth line,
but a set of vectors originating from (0,0). This was of course
because the main task never changed PenX and PenY, so the callback
handler alway moved 0,0 into the callback's USER area.
There is no real solution for this problem. If you want to do something
inside a CALLBACK, you need global / special memory to keep state
information.
Here's how I hacked nn50.frt :
Changed doWORDS to have a count of matched WORDLIST entries ( xt -- count ).
This was done so that HELP does not print a stupid remark in the following case:
Also some minor changes to .ABOUT .
.ABOUT Instead of saying there is no module named `-foo'.
The sequence
Fixed bug in
1.0e123456789123456789 crashes iForth. (Exponent > 0 should not have more than
11 digits). Also made sure that
Fixed
The following is a valid double, but iForth will not parse it (gForth can).
(Ad 1)
With the current efforts to get IEEE-compatible floating-point, I saw coming
that some hard-noses would come down unfavorably on the iForth model
(80-bit calculations but 64-bit memory float stack and default F@ / F! of
64 bits.) Although I could have put up a fight (the current standard considers
the internal float model to be unspecified), I decided to evaluate the speed
decrease and inconvenience of going to 80-bits first. Unexpectedly, my tests
showed that speed would not suffer (the special 32/64 float instructions are
only shorter, not faster), and that inconvenience was not really an issue --
all the code that I inspected explicitly used DF@ etc. when calling the OS or
libraries. I did fix a few problem (mm_old.frt., mm.frt) and introduced
DFLOCALS| because locals have an address, and this address is sometimes
used by !, F@, DF! etc..
A consequence of this change is that FCONSTANT, FVARIABLE and FVALUE are now
80-bits. This will sometimes show up in much higher default accuracy (i.e
a standard Forth benchmark or utility will be 1000 * more accurate than the
author claims, even if they wrote it assuming 64-bit precision and
accordingly limited the size of power series etc.).
Ad 2) Ad 3) Ad 4) Ad 5) Ad 6)
Bug in
Words like [IF] [ELSE] [THEN] are in a special class: they neither scan nor compile.
This means that the current mechanism in $COMPILE tried to tokenize [IF]. In the past
this bug was masked because inside a definition [IF] is preceded with something like
... [ a ] [IF] .. and [ a ] always turned off tokenizing. This behavior was
changed to allow [ a ] LITERAL to produce better code, exposing the bug.
Words constructed with POSTPONE are less efficient than colon definitions because the
tokenizer does not know how to handle POSTPONE. Example:
Maybe $COMPILE should special-case POSTPONE ?
Mouse.frt was using SERVE-EVENTS, a syscall in graphics.frt that is not
working for Windows (it is an X routine ). For the time being a warning is displayed
and the Windows SERVE-EVENTS is a no-op.
The mouse-coordinates delivered by wmouse.frt were full-screen (not application window
based) and origin and size were weird.
Possible issues.
1. settile() maybe upside down (Windows?) *** FIXED ***
2. @RECT and !RECT are matched, but maybe upside down *** FIXED ***
when used with external programs (Windows?)
3. There is a new IFORTHBIN64 environment variable, *** FIXED ***
Windows has IFORTH_GWIDTH IFORTH_GHEIGHT IFORTH_GNAME,
Windows has IFORTH_GXSIZE IFORTH_GYSIZE (initial size of graphics windows),
The Linux $DFWFORTH/config has become ~/config,
The Linux $DFWFORTH/config64 has become ~/config64,
The Linux filenamedatabase.dat has moved from $DFWFORTH/dataf to ~/config[64]
4. We should do something about the IBM charset (i.e can we define a *** FIXED ***
font that has all the [graphic] characters needed, in all sizes, which
looks ok on Windows/OSX/Linux (e.g. utf-8). Simplest would be to remove
all dependence on special graphics (line drawing) characters in
terminal.frt.
5. Are the graphics drivers on Linux and Windows matched completely (e.g. *** FIXED ***
does the fjack gui demo run unmodified on both).
6. Does iForth handle #! -- and I/O redirection correctly. *** NOT FIXED ***
[ Saturday, March 20, 2010, 18:22 -- #! works, redirection certainly not! ]
7. Should FFL and fjack use +INCLUDE . *** ~~~ FIXED ***
8a POSTPONE is broken, See freeimage2.frt: *** FIXED ***
8b [IF] [THEN] [ELSE] inside inlined colon definitions produce errors *** FIXED ***
8c [ ... ] inside colon definitions is buggy. *** FIXED ***
9. Could be related: In freeimage.frt nothing shows on the screen. Zeroing the top *** FIXED ***
byte of a pixel (alpha?) does not fix this problem (anymore).
[ seems to be a Windows bug: at least ONE @rect is needed before it works,
zeroing is not needed! ]
10. The assembler / disassembler have problems when handling 32-bit registers *** ~ FIXED ***
in 64-bit mode, e.g eax -> [rdx] mov, should work. As a minimum the MOV
instructions should work correctly.
[Saturday, March 20, 2010, 16:44 -- fixed for the modes that were
important for the original requester's use.]
10a q# and uq# don't work: *** FIXED ***
11. TITLE in gnuplot.frt has a bug. *** FIXED ***
[ was related to bug 8 ]
12. xlib (Linux iForth) Loading freeimage.frt (old) will run the demo directly. *** FIXED ***
If the GRAPHICS word in the file was disabled, the demo runs (time = 0).
If you then do GRAPHICS pic1 demo the program crashes.
Bug in $COMPILE
The iForth compiler tests if IMMEDIATE words ( here <
Fixed (potential) memory overwrite bugs in the C servers (getfilename4, pathname
buffers, open4, addpath).
Also potential bugs in ?FERR ?FILE LIST-OPEN-FILES (mainly for Windows).
Fixed a bug in benchmar/logs.frt (wrong use of [THEN] in comment )
Fixed problem in }fmins ( gaussj.frt). This function worked with a temporary
array from a buffer pool. This array could "expire" after some heavy work,
resulting in rubbish values and eventually double faults in blas4.dll, crashing
the server.
Hash banging works.
Paste the following text in file test1 (no dashed lines):
bug in FILE-STATUS for Linux (file could stay open).
I/O redirection does NOT work for Linux ( #! works, however)
The following does not work properly, probably because COMPILE, is too dumb
($COMPILE does too much).
Fixed a long-standing bug in 2+! ( -3. addr 2+! would be wrong).
Some problems with TABs in forth.hlp.
Changed FILE-STATUS in what is returns as useful information. See HELP FILE-STATUS.
Problems with blas4 compiled on windows 7.
The GotoBLAS is not needed anymore for Windows 7 or Windows XP.
I couldn't get the 32/64-bit source compile to a 32-bit DLL that loads
on Windows XP. Therefore there is now a blas4.dll (1.011 Mbytes) and a
blas4_windows7.dll (1.465 Mbytes).
The blas4 32-bit sources differ from the 32/64-bit sources. Any bugs fixed
meanwhile in the 32/64-bit sources aren't transferred to the old (1.011 MB)
32-bit dll.
IF POSSIBLE, USE THE BLAS4_WINDOWS7.DLL (1.465 MBYTES).
Added detection of TERM=xlinux for Linux. This combines the keyboard handling of a
Linux console with the graphics of an X terminal. ( a Konsole in OpenSuSE ).
Bug: "n LSHIFT m RSHIFT" was shortened to n-m LSHIFT (which can even disappear).
Unfortunately, an important side-effect of such shifts is that n low or m high bits
are cleared, so this particular optimization is invalid.
The pattern only existed for
miscutil.frt(1190): 'OF x @ 1 LSHIFT 1 RSHIFT ( clear top bit 63) neg? IF 1- ELSE 1+ ENDIF
miscutil.frt(1191): DUP 0< ( carry) >R 1 LSHIFT 1 RSHIFT 'OF x !
C:\dfwforth\examples\numeric\fnextup.frt(14): ( x) 1 LSHIFT 1 RSHIFT x F0< IF 1- ELSE 1+ ENDIF
C:\dfwforth\examples\UM\cmachine.frt(38): 13 OF w 7 LSHIFT 7 RSHIFT w #25 RSHIFT 7 AND regs! ENDOF
The last occurrence was no problem.
Result: F-/ULP now works in 64-bit mode again.
Solved several bugs in ASM64.frt: movq, was wrong and several instructions reported a
pointer size problem where the actual problem was that the FPU does not support extended
floats for that operation. Also, "mov [rsp -8 +], rax," wrongly reported a too large
address.
Fixed {FNUMBER} so that it can correctly input numbers with 63 valid mantissa bits
(i.e. 19 .. 20 decimal digits of precision). Any extra bits are (always) rounded
to nearest with even ties. However, it is possible to come up with decimal numbers
that have an exact binary representation, but that need hundreds of decimal digits
to express it. Such numbers (where #decimal_digits > 19) can not be converted exactly.
The overhead to do this in Forth is large: Clinger's algorithm with David Gay's
improvements ftp://ftp.ccs.neu.edu/pub/people/will/howtoread.ps . At the least,
this needs dd-fp and some bignum facility in the kernel.
Noted ( the original lagroots.fs from the FSL, Algorithm 61 ) that
[ Dec 30, 2010: A diagnostic message appears when this happens.
The diagnostic can be turned off with __fpustack__ OFF ]
Some of the FP number I/O words are limited to about 15..16 decimal digits. This is
because F>D delivers a 64 bit double that can hold at most 9.2e18 or 18 decimal digits.
Together with some elbow room and the need of engineering notation, SET-PRECISION
internally clips at 18 places, leading to 15 places for e.g. +E.
These problems are fixed. It is now possible to output with at least 19 correct decimal
places, rounded to nearest with even ties.
While working on getting a new complex-ieee-test-xf to pass with
complex-kahan and iForth, I ran across this:
I don't know without searching in the spec what is required by
IEEE 754, but gforth and pfe both return exact -0e, and -1e-50
to high precision, with OS X.
[ for "small" u, make u FASINH => u FLNP1 -mhx ]
Also:
On Windows 7, before doing !RECT at least ONE @RECT is needed. (1 pixel is enough).
If this wasn't done, no bitmap is shown (but the rectangle is erased).
However, according to my notes, on Windows XP @RECT causes a weird problem when
done in _GRAPHICS. Made the call conditionally. (This is transparently for users.)
In the graphics routines, there are similar @RECTs done at various pattern fill
places, apparently with a similar purpose. Don't remove without testing.
The problem can only arise while interpreting, and then the semantics of S" as described by the Standard in the FILE wordset apply. There, the guaranteed size of the string is said to be 80 characters.
Just like any other Forth author, I agree that this would result in an unusable S". However, for portability reasons I decided to write S" in high-level, to be loaded on demand. Although I do not intend to write a DWIM system, your feedback may lead to reconsidering this S" decision.
Note that PAD resides above HERE, and a small area at a lower address than PAD is used to print or format numbers. Depending on how you create objects, this may or may not be an additional problem.
Hypothesis: CLOSE-FILE takes a while. R/O OPEN tries to read all of the file in memory. Maybe it times out (0 file length) and then starts to read from an invalid buffer?
The bug is not present under Windows anymore. Reason: An explicit flush-file / commit in the server when closing a file.
A callback inherits its user area from the task it interrupts. When the CALLBACK finishes its user area is thrown away.
Obviously, the setup? flag enables to setup the callback's font for a first Window event, but, as the foreground task has a user area with no font info, callbacks resulting from further events don't have font info in their user areas.
This caused a debugging session of several hours, therefore I document the error here.
There might be a compiler bug in the VC++ 2008 64-bit compiler. The *optimized* code contains instructions that the disassembler doesn't know, and zbrak and zbrent don't work. The unoptimized code runs Ok.
For now, I have put in #pragma's to turn off optimization for these two functions.
On Win32 the built-in OpenGL runs fast, but color and lights have problems and
BYE doesn't work. It might be a pointer size problem, or the SYSCALL interface is (still) wrong.
The transfer time dropped to less than a 1 ms, giving and integer division exception. Added UMAX, and also increased the moved bytes to 3 MB to get reasonable resolution.
A few calls still use the Fortran interface instead of C-style. This is because I
am uncomfortable with the possible transpositions that are to be added/removed when going to C calls only.
The source should be automatically 32-bit ready, but I want to go 64bit only.
I found a 32bit/64bit bug in the Windows blas4 sources. This might be the root cause
why the 32bit blas4.dll can't be built on Windows 7.
Apparently the CREATE DOES> optimization fails here. The problem is with array X (run numerov.frt after loading xopg.frt)
However, as FORTH-PROCESSes are in a round-robin loop with the CONSOLE process
( TASK 0 ), it is nice when the CONSOLE does an occasional PAUSE. This can (now) be
done with ' PAUSE PAUSING ! which makes _KEY execute PAUSE.
Comments appreciated:
> regularly I come back to iForth :-) and I try some code. I have a
> problem with catwalk.frt (see below) . Could you tell me what is going on ?
Replace ,S" in catwalk.frt with the following code:
: ,S" (
In the current iForth -- ) \ COMPILE A STRING AT HERE
interp-S" HERE 2DUP 2>R OVER 1+ CHARS ALLOT CHAR+ SWAP CMOVE 2R> C! ;
S"
is not an immediate word anymore, and POSTPONE
ing
it causes its compile-time behavior to be executed (which is not what you want
in this case, among other undesirable things it causes an empty stack and then
an ALLOT
of a very large number). In the above I select the interpreting version
of S"
explicitly.
Sunday, September 23, 2007, 16:05 PM *** FIXED ***
Tuesday, January 01, 2008, 15:56 PM *** FIXED ***
M.?ATPRESS
fixed (volatile bug in MS-VC compiler).
Saturday, February 02, 2008, 19:13 PM *** FIXED ***
PARSE-NAME ( -- c-addr u )
.
Implemented X:deferred, X:defined, X:ekeys, X:extension-query, X:number-prefix, X:parse-name
(But did NOT implement X:required, X:structures, and X:throw-iors.)
Implemented EKEY>FKEY
and all key constants (ALT SHIFT and CONTROL masks only for Windows).
Sunday, February 03, 2008, 22:49 PM *** FIXED ***
Sunday, February 10, 2008, 15:30 PM *** FIXED ***
DIGIT?
to recognize lowercase HEX. This was done so that S\"
and S\~
could
be implemented. The main parts of the latter two words are in miscutil.frt, so iForth
is not ANS 200x conforming until miscutil.frt is loaded. Before loading, S\"
is equal
to S"
.
Saturday, March 22, 2008, 8:40 AM *** FIXED ***
Thursday, May 01, 2008, 13:21 PM *** FIXED ***
Tuesday, May 13, 2008, 6:53 AM *** NOT FIXED ***
Sunday, June 01, 2008, 9:14 AM *** NOT FIXED ***
Sunday, June 01, 2008, 9:14 AM *** NOT FIXED ***
Friday, June 13, 2008, 18:29 PM *** NOT FIXED ***
Jens-Hanno Schwalm
Saturday, June 14, 2008, 12:13 PM *** NOT FIXED ***
Wednesday, June 25, 2008, 0:55 AM *** FIXED ***
-- line 887 of mkernel2.inc -----------
TMAC D>
Good test programs are in dfwforth/examples/misc/4thtester .
Wednesday, July 09, 2008, 0:24 AM *** FIXED ***
Wednesday, July 09, 2008, 0:24 AM *** FIXED ***
Monday, July 28, 2008, 23:21 PM *** NOT FIXED ***
: [64BIT] true ;
: test [64bit] [if] ." Yes" [ELSE] ." no" [THEN] ;
Error: [IF] searches past EOF.
Tuesday, July 29, 2008, 17:20 PM *** NOT FIXED ***
Why NOT-IMMEDIATE ?
The mechanism to detect that we are in a definition may fail when using
['] CREATE $PROCESS instead of CREATE . The resulting words are immediate
and behave not like intended.
iForth should not make CREATEd words IMMEDIATE (this is done to be able to
optimize the addresses compilation of variables and constants). Until this
happens, NOT-IMMEDIATE can be used. Sorry :-)
Saturday, August 02, 2008, 23:26 PM *** NOT FIXED ***
0e FVALUE px <--- global memory to store PenX and PenY between callbacks.
0e FVALUE py <---
:NONAME ( epoch -- -stop? )
DUP TO epoch #100000 > IF ( stop! ) 0 EXIT ENDIF
1 +TO refresh refresh refreshrate >
IF CLEAR refresh
GRAPHICS HOME ." Epoch: " epoch DEC.
." -- RMS error: " RMSE F.N1 8 SPACES TEXT
---> px TO PenX py TO PenY
epoch S>F RMSE F2DUP red DRAW-SCALED-LINE
---> TO py TO px
ENDIF
1 ( continue ) ; 1 PASCAL-CALLBACK CallBackEpoch
Tuesday, December 09, 2008, 19:11 *** NOT FIXED ***
mhx@iae.nl (Marcel Hendrix) writes:
>> This did not work on iForth, apparently because iForth keeps such
>> temporary return stack values in registers and because it apparently
>> delays updating the return stack pointer (and does not know to end the
>> delay and spill out the registers on SP@).
>
>This is no accident. I like the Standard when it fits me :-)
I.e., you like the lack of a standard when it fits you;-).
Still, it would be nice if you did either of the following:
1) Implement RP@ with the de-facto-standard meaning. I guess this
would be relatively easy, because: a) You probably force the return
stack into the canonical representation at some points anyway, so you
only need to make rp@ one of the points. b) In your own uses of RP@,
you probably force the return stack into the canonical representation
in some way; the only new thing would be that RP@ would do this by
itself.
2) Or you don't implement a word called RP@. Rename the word that's
currently known as RP@ into something else. After all, it does not
quite do what RP@ normally does.
- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
Thursday, January 08, 2009, 23:58 *** FIXED ***
FORTH> HELP IHELP
`ihelp' has no help, try one of the following words instead:
IHELP
ok
---
FORTH> help IHELP
IHELP <- If this is what you typed, then there is no help for it. ok
FORTH> .about -foo
There is no module named: `.about'. ok
Saturday, March 07, 2009, 22:06 *** FIXED ***
3 CHOOSE 1- 3 CHOOSE 1- OR
triggered an optimizer bug (wrong code generated and 3 stray numbers left on the
stack at compile time).
Sunday, April 19, 2009, 09:17 *** FIXED ***
F~
for negative zero, i.e. +0e -0e 0e F~
now returns FALSE
,
-0e -0e 0e F~
now returns TRUE
.
Also fixed FSIGN
and (F.N1)
in order that -0e gets printed correctly. There is
no guarantee (yet) that all FP output words always recognize -0e correctly.
Tuesday, May 05, 2009, 20:12 *** FIXED ***
>FLOAT
accepts leading and trailing spaces.
Wednesday, May 27, 2009, 06:49 *** FIXED ***
F**
: 0^0 returns 1, 0^a with a negative returns Inf.
Zeroed *UPPOOL
before running COLD
.
Added AtCold
and an AtCold-chain
. Note that zeroing UPPOOL
as AtCold
code,
or in SAVE-SYS
, would not work as a 0 UPPOOL
may crash running threads.
Tuesday, June 23, 2009, 18:28 *** FIXED ***
-NAN
is wrong for iForth64.
F<>
is wrong when one or both the arguments are NaN.
( fixed June 26, 2009 )
Friday, July 03, 2009, 06:56 *** ~~~ FIXED ***
: timesc, 0 ?do DUP C, LOOP drop ;
5000 constant digs
CREATE large '1' C,
'0' digs timesc,
'e' C, '-' C, '4' C, '8' C, '0' C, '0' C,
large digs 7 + dump
large digs 7 + >FLOAT . FE.
Tuesday, July 07, 2009, 09:59 *** FIXED ***
REPRESENT
produces trailing garbage when handling +Inf, -Inf, +NaN, or -NaN.
*** Sunday, August 09, 2009, 07:31 ***
Pre-release candidate iForth 3.1
Changes
FALOG
and F**
.
CMOVE
.
The reasons to use 64-bit floats were efficiency (80-bit floats are slower
to fetch and store, and the instruction does not have the special memory
accesses that are there for 32/64 bit IEEE floats), and the fact that all
OS code and libraries use 64-bit exclusively (probably because SSE2 *only*
knows 32/64 bit instructions).
This was a lot of work, because printing an 80-bit float using 80-bit instructions
is a lot harder than print a 64-bit datum using 80-bit instructions.
In fact, the present iForth does not print the 18th digit of an 80-bit float
correctly when the exponent is "large" ( > 100 ). E.g. Win32Forth can do this,
but SwiftForth can not:
SwiftForth i386-Win32 3.1.3 29-Feb-2008
18 set-precision ok
precision . 17 ok
1.00000000000000e4300 fe. 10.000000000000001E+4299 ok
Note that SwiftForth "fixes" the issue by limiting precision to 17 digits.
I'd love to improve iForth, but it is not possible given the iForth feature
that PRECISION sets the number of digits printed AFTER the decimal dot.
[ One can do worse, as VFX demonstrates/demonstrated.
VFX Forth for Windows IA32
© MicroProcessor Engineering Ltd, 1998-2007
Version: 4.01 [build 2390]
Build date: 12 February 2007
Free dictionary = 7684218 bytes [7504kb]
18 set-precision ok
precision . 16 ok
1.00000000000000e4300 fe. +10.00000000000000E+4299 ok
1.00000000000000e4300 1e4300 f- fe. +3.812753632652879E+4284 ok ]
iForth input is (now) indeed accurate to 18 decimal digits.
Made more consistent: 12e FALOG
and 10e 12e F**
and 1e12 result in
the same bit patterns ( PAD F! PAD 12 DUMP
).
A local can be very slow, and I decided to investigate why. It took a huge
amount of time in experimenting, but it seems to be an alignment issue.
Putting the locals stack at a very specific location (alignment) increases
speed by almost a factor of 3. I can do this for the main task's locals,
but for threads the programmer must (re)locate it by himself (if he cares).
I can not guarantee the alignment I chose is hardware-independent, but it
does work on all of my 32/64 machines (Athlon X64, Intel PIV, Intel Core2 Duo).
Found when analysing why MPE's VFX is a hair faster than iForth on their
benchmrk.fth. The biggest reason is that their simple CMOVE is much faster
for small areas than iForth's OS call, which is unbeatable for large amounts
of data. BTW, note that "large" on the Core2 is only 32 bytes :-)
The second reason was slightly more efficient code for "indexed addressing"
like ( CREATE ape 16 ALLOT ) ... ape 3 CELLS + ... iForth now knows how to
better optimize these sequences.
See 4).
See David Williams' CLF postings. His 'reasonable' word proposals have flown
into iForth. The most difficult to write were (S/D/X)FNEXTUP. Also wrote
./dfwforth/include/hexfloat.frt which works for 32 and 64bit Forth alike.
The IEEE exception wordset proposal has not been implemented yet.
Sunday, September 13, 2009, 15:02 *** FIXED ***
REPRESENT
FORTH> 1e-3 pad precision 3 + represent ok
[3]FORTH> .s
Data: -3 0 -1 ---
System: ---
Float: --- ok
[3]FORTH> pad 8 dump
$005C6750 31 30 30 30 30 30 30 30 10000000
ok
That should be -2 0 1 ( 0.10000e-2 == 1.0000e-3 )
( not using the special BCD instructions fixed it )
Saturday, December 26, 2009, 21:01 *** FIXED ***
: FIELD2 ( offset size -- new-offset )
>r >r : r@ postpone literal postpone + postpone ; r> r> + ;
The code for 8 FIELD2 .bbb is quite good, but .bbb is NOT tokenized. This costs
a lot of speed.
Tuesday, December 29, 2009, 08:09 *** FIXED ***
Tuesday, December 29, 2009, 08:09 *** FIXED ***
Tuesday, January 19, 2010, 23:48
: comp-pic-obj, POSTPONE cur-pic POSTPONE @ @ POSTPONE LITERAL POSTPONE + ; PRIVATE
FORTH> see comp-pic-obj,
Flags: TOKENIZE, ANSI, PRIVATE
: comp-pic-obj, @ ; ok
xmm0 -> [rdx] mov,
$FFFFFFFF00FFFFFF uq# -> r8 and,
r8 -> [rdx] mov,
see:
( wrong: rax <-> xmm0 )
$012D75EA mov [rdx] qword, rax
( uq# and q# don't work )
$012D75ED and r8, $00FFFFFF d#
Tuesday, March 09, 2010, 00:28 *** FIXED ***
-- ---------------------------------------------------------------------
: DEBUG>> ;
: <<#DEBUG>> \ creates a <
Saturday, March 20, 2010, 16:38 *** FIXED ***
Saturday, March 20, 2010, 16:38 *** FIXED ***
-- -----------------------------------------------------------
#! /home/marcel/dfwforth/iflinux/linux-bin/iforth include
CR .( HELLO WORLD!)
CR .( 3 + 4 = ) 3 4 + .
BYE
-- -----------------------------------------------------------
Make the file executable with "chmod +x test1" (no quotes).
Now do:
marcel@hyperius:~> ./test1
HELLO WORLD!
3 + 4 = 7
marcel@hyperius:~>
The essential tricks here are:
0. Set up the environment variables IFORTH IFORTHBIN IFORTH_VERBOSE
globally (normally this is done by the i4 script for the duration
of iForth's runtime)
1. At least one space between #! and /home/...
2. An absolute path to the iForth executable (not a script!)
3. The word "include" after the executable
If you need the iforth.prf file to execute, just do
-- -----------------------------------------------------------
#! /home/marcel/dfwforth/iflinux/linux-bin/iforth include
INCLUDE iforth.prf
CR .( HELLO WORLD!)
CR .( 3 + 4 = ) 3 4 + .
BYE
-- -----------------------------------------------------------
This is not so nice, as the modules announce being loaded, which
might not be wanted for this application. The only solution I see
now is to revector TYPE with 2DROP temporarily.
-marcel
( more info at
http://blogs.operationaldynamics.com/andrew/software/build-systems/hash-bang.html )
Sunday, March 21, 2010, 08:35 *** FIXED ***
Sunday, March 21, 2010, 08:35 *** NOT FIXED ***
Saturday, May 22, 2010, 12:59 *** FIXED ***
FORTH> BENCHMARK
\ plural1: 1+ 0 1.439 seconds elapsed.
\ plural1: 1 2 3 4 5 6 7 8 8 +es1 0 0.179 seconds elapsed.
\ plural2: 1+ 800000000 2.615 seconds elapsed.
\ plural2: 1 2 3 4 5 6 7 8 8 +es2 3600000000 3.580 seconds elapsed. ok
FORTH> see tests1
Flags: TOKENIZE, ANSI
: TESTS1 0 ?DO LOOP ; ok
DOC
(*
anton@mips.complang.tuwien.ac.at (Anton Ertl) wrote Re: [newbie question] xt and 'tick' - is it wrong, or I didn't get it?
Newsgroups: comp.lang.forth
Date: Fri, 21 May 2010 09:49:51 GMT
Message-ID: <2010May21.114951@mips.complang.tuwien.ac.at>
[..]
> The solutions differ in their properties: The : solution will tend to
> consume more space and run faster. Which one is simpler depends on
> how data has to be passed around. In this case the : solution is as
> follows:
> : plural ( xt "name" -- ; run-time: ... u -- ... )
> >r : 0 postpone literal postpone ?do r> compile, postpone loop postpone ; ;
[..]
> 2) The resulting word is faster, because the xt is compiled directly
> into it instead of being called by EXECUTE. E.g., in Gforth a test
> with "' 1+ plural my-+" took 3.368s for the CREATE...DOES> solution
> and 2.024s for the : solution.
*)
ENDDOC
ANEW -plural
: plural1 ( xt "name" -- ; run-time: ... u -- ... )
>r : 0 postpone literal postpone ?do r> compile, postpone loop postpone ; ;
: plural2 ( xt "name" -- ; run-time: ... u -- ... )
create , does> @ local xt 0 ?do xt execute loop ;
' + plural1 +es1
' 1+ plural1 TESTS0a
: TEST1 ( -- ) 1 2 3 4 5 6 7 8 8 +es1 ;
' TEST1 plural1 TESTS1
' + plural2 +es2
' 1+ plural2 TESTS0b
: TEST2 ( -- ) 1 2 3 4 5 6 7 8 8 +es2 ;
' TEST2 plural2 TESTS2
: BENCHMARK CR ." \ plural1: 1+ " TIMER-RESET 0 #800000000 TESTS0a . .ELAPSED
CR ." \ plural1: 1 2 3 4 5 6 7 8 8 +es1 " TIMER-RESET 0 #100000000 TESTS1 . .ELAPSED
CR ." \ plural2: 1+ " TIMER-RESET 0 #800000000 TESTS0b . .ELAPSED
CR ." \ plural2: 1 2 3 4 5 6 7 8 8 +es2 " TIMER-RESET 0 #100000000 TESTS2 . .ELAPSED ;
Saturday, June 19, 2010, 19:53 *** FIXED ***
Thursday, June 24, 2010, 20:57 *** FIXED ***
Jens-Hanno Schwalm
Sunday, July 04, 2010, 12:08 *** FIXED ***
Friday, July 23, 2010, 15:27 *** FIXED ***
Tuesday, August 17, 2010, 23:24 *** FIXED ***
Thursday, August 19, 2010, 00:37 *** FIXED ***
Sunday, November 07, 2010, 11:34 *** FIXED ***
Sunday, November 07, 2010, 15:23 *** FIXED ***
Tuesday, November 09, 2010, 20:42 *** FIXED ***
> 2. Is there a way to turn off the return stack dump when I CATCH
> a word that throws an exception? In my testing, I like to do
> CATCHes just to see that an exception is actually thrown, and
> with the right code; and the dump is distracting.
__rstackdump__ ON
__rstackdump__ OFF
Sunday, December 05, 2010, 10:15 *** ~ FIXED ***
Sunday, December 05, 2010, 10:15 *** ~ FIXED ***
: Z2DUP ZOVER ZOVER ; ( F: z1 z2 -- z1 z2 z1 z2 )
potentially leads to FPU stack overflow. This seems NOT to be noticed by the optimizer,
leading to wrong results. Need to find out, and install an IRQ handler to push the
overflow element(s) to the memory stack. As the optimizer never assumes more than
8 FPU stack elements, this should work without other changes.
Sunday, December 05, 2010, 10:15 *** FIXED ***
Monday, December 13, 2010, 00:52 *** FIXED ***
FORTH> 0.0e flnp1 f. 0.000000 ok
FORTH> 0.1e flnp1 f. 0.095310 ok
FORTH> 0.2e flnp1 f. 0.182322 ok
FORTH> 0.3e flnp1 f. 0.262364 ok
FORTH> 0.4e flnp1 f. 0.336472 ok
FORTH> 0.5e flnp1 f. -NAN ok
[ bug in 32bit iForth only? -mhx ]
This I can work around with by redefining FLNP1 as 1E F+ FLN.
And:
FORTH> -0e fasinh fs. 0.000000e0 ok
FORTH> -1e-50 fasinh fs. 0.000000e0 ok
The +0 output is exact AFAICT.
FORTH> -1.7e fasinh f. -NAN ok
[ Real bug, must test sign. -mhx ]
Wednesday, December 29, 2010, 15:09 *** FIXED ***
Tuesday, March 08, 2011, 20:45 *** NOT FIXED ***
Date: Tue, 8 Mar 2011 16:05:18 +0100
Subject: Re: iForth evaluation copy
From: mhx@iae.nl
To:
Cc: mhx@iae.nl
xxxx writes:
> I've just been testing my regular expression software
> with the Windows evaluation copy of iForth (32 bit)
> and it failed the test program in many places in
> rather mysterious ways. Eventually I tracked it down
> to the fact that the S" buffer seems to be situated in
> dataspace as little as 337 bytes (although the number
> does vary) above the address returned
> by HERE.
I think you are starting iForth directly, bypassing the loading of electives (i.e. you didn't do "include iforth.prf"). In this case, `S" hello" drop here - .` returns 337, indeed.
The standard electives redefine S" (try locate S").
> In the test programs a typical pattern is:
>
> S" " regex$ ...
>
> where regex$ processes the regular expression and
> creates objects in dataspace as appropriate. In many
> cases these objects then collide with the S" buffer
> thereby corrupting it - hence the failures.
The redefined S" works (also) in interpret state and allows at least four independent 32K wide S" invocations that reside at least 32K above HERE.
> The fix is easy, copy the strings to another buffer
> before applying regex$ but...
> Given that all the tests work with several other
> Forths, including VFX Forth, SwiftForth, Win32 Forth,
> GForth and BigForth, without the need to copy S"
> strings to another buffer, it seems rather a
> shortcoming of iForth that copying is necessary (337
> bytes above is a bit low anyway).
> The problem is a general one, any user processing an
> S" string and alloting space could hit the S" buffer.
> There are warnings in the ANS Forth standard
> (A.11.6.1.2165) about EVALUATE, LOAD, INCLUDE-FILE
> and INCLUDED possibly invalidating the S"
> buffer - but the code executed by regex$ doesn't
> call any of those words. So it could be argued that
> iForth is not ANS Forth compliant in this respect.
> The section is referred to is rather woolly however
> so I'm not sure about this
> Any thoughts on the matter?
Monday, April 25, 2011, 20:16 *** FIXED ***
Assume aa exists.
s" aa" R/W OPEN-FILE ?FILE ( x)
( x) CLOSE-FILE ?FILE
s" aa" R/O OPEN-FILE ?FILE \ seems to crash?
Sunday, June 19, 2011, 08:01 *** FIXED ***
Apparently PACK stores the count FIRST, then moves the string. It may work as intended when storing the count LAST.
FORTH> : TEST S" ABCDEF" >R PAD R@ CMOVE PAD R@ PAD PACK DROP PAD R> 1+ DUMP ; ok
FORTH> test
$01235088 06 06 42 43 44 45 46 ..BCDEF
Sunday, September 11, 2011, 10:40 *** FIXED ***
- blas4.dll had problems loading on non-Windows 7 systems
- extended use of fstat -> FILE-EXISTS?
- new #416 syscall -> FILE-TIME FILE-BIRTH ( only Windows for now! )
- Bug in allocating memory -> iForth64 now allows allocating > 2 GBytes
- New syscalls 417 .. 420 to (better) handle named pipes on Windows. No equivalent
on Linux/OSX yet.
Sunday, September 18, 2011, 11:37 *** FIXED ***
The following code ( ./dfwforth/include/windows/hello1.frt )
is wrong. Why?
Note that we initialize a font INSIDE DO-PAINT, which
is inside the Windows callback. Also note that a font
description is kept in USERs.
: SETUPFONT ( -- )
setup? IF exit ENDIF
TEXTMODE? $FF AND DUP >R IF GRAPHICS ENDIF
white SETTCOLOR
black SETBCOLOR
>BOLD< TextAttr TO StrokedAttr >BOLD<
S" Arrus BT" SFONT
1 font.italic? C!
#8000 #1000 XCHARSIZE!
#8000 #1000 YCHARSIZE!
R> IF TEXT ENDIF
TRUE TO setup? ;
\ Wrong!
\ : DO-PAINT ( -- ) SETUPFONT 0 1 GAT-XY S" Hello World!" |TYPE ;
\ OK
SETUPFONT -- update user area of main task.
: DO-PAINT ( -- ) 0 1 GAT-XY S" Hello World!" |TYPE ;
I have fixed a hard to find bug in dfwforth/examples/statevars/artemis.frt .
Saturday, October 15, 2011, 12:10 *** FIXED ***
Fixed many bugs in the 64-bit version of the SDLlib package.
The problems were caused by the MS-C requirement to provide space
on the stack for four registers, independent of the actual number of
parameters.
Linux/OSX has a similar problem with the 'RED ZONE'. This has not been
fixed yet. The red zone is 128 bytes. Also, RAX is not properly initialized.
Saturday, October 15, 2011, 12:10 *** FIXED ***
Artemis is a simple circuit simulator that directly works with state variables.
A 32/64 bit bug was in this structure:
STRUCT cell% 2* PFIELD NEXTFIELD \ body of previous component in the list
dfloat% FIELD >VALUE \ component's value (e.g. 3 Ohms)
dfloat% PFIELD >INIT \ initial value of state variable (e.g. 1.004 V or 0.55 A)
cell% FIELD >VOLTS \ voltage (e.g. 1.004 V), index in system array
cell% FIELD >AMPS \ current (e.g. 1.004 A), index in system array
dcell% PFIELD >NODES \ nodepair (user names OR invalid names to disable)
cell% PFIELD >HELPNODE
dcell% PFIELD >ORIGNODES \ original nodepair names (user names)
cell% PFIELD >CTYPE \ 'R', 'L', 'C', ...
cell% PFIELD >BRANCH# \ branch number
cell% PFIELD >INDEX \ index in svar array
cell% PFIELD >TDEP \ xt for dependent source
cell% PFIELD >BACKLINK \ address of switch body (for E or J sources)
END-STRUCT component% PRIVATE
In the distribution the first field is wrong. It says:
STRUCT dfloat% PFIELD NEXTFIELD
...
This works/worked in 32-bit mode because a dfloat is 64 bits, which happens
to be 2 32-bit integer words. In 64-bit mode all the fields were off by 32-bits.
The reason I used dfloat% is probably because I didn't know (the structure
package is based on Anton Ertl's work) that it is possible to say cell% 2*
without bothering to define a new field size.
Sunday, October 30, 2011, 21:27 *** FIXED ***
With blas4.dll for Windows 7 64 bit, SMAS.frt didn't work in iForth 64, while it was fine in iForth 32bit.
Wednesday, November 09, 2011, 06:55 *** FIXED ***
> e.g a variant from a recent topic to detect if a word called FOO
> is undefined could be:
> ' ' catch foo [if] : foo ( ... ) ; [then]
> Most systems work but iForth doesn't
Sunday, November 13, 2011, 14:13 *** NOT FIXED ***
Win32 Win64 Linux32 Linux64
glutlib.frt x x x x
glutdemo.frt x x x x
syscall OpenGL ~yes crash no x
Sunday, December 04, 2011, 22:23 *** FIXED ***
Using ddot_SSE2 etc. will fail when the vectors are unaligned, which happens when they are rows of a matrix where #rows is ODD.
Friday, December 30, 2011, 17:32 *** FIXED ***
examples/benchmar/movspeed.frt needed to be adapted because the CMOVE speed is approaching Gbytes/seconds with modern processsors.
Friday, December 30, 2011, 17:32 *** FIXED ***
Rewrote blas4.so for Linux Ubuntu. BLAS4 now uses the ACML for Linux 64bit, just as on
Windows. The ATLAS and GotoBLAS ports have become unnecessary (halleluja!).
Thursday, Aug 8, 2012, 21:02 *** FIXED ***
Added DAXPY_sse2, SAXPY_sse2, DDOT_sse2 and SDOT_sse2. These routines work for unaligned
data, too (and are therefore slightly slower than needed).
Wednesday, December 26, 2012, 21:27 *** FIXED ***
A very old bug in the mouse interface was found. Hanno's mouse driver for Linux/OSX/Windows finally works cross-platform.
Thursday, December 27, 2012, 21:02 *** FIXED ***
Debugged mouse facilities, added scrollwheel. Hanno's mouse driver (mouse.frt) now fully
works on Windows. Try fotoapp.frt for a GUI test. The graphic calls are
apparently / finally pixel-perfect now.
Tuesday, January 08, 2013, 00:57 *** FIXED ***
Exposed the word IS-LOCAL?. Main use is in XOPG.frt.
New arbitrary precision locals: Z#LOCALS| F#LOCALS|. These locals rely on mpfr.frt
and mpc.frt ( in gmpfr ) to set the vectors cmd_F#LOCAL and cmd_Z#LOCAL.
Saturday, February 02, 2013, 19:03 *** FIXED ***
See examples/gmpf/xopg.frt
-- Oh shame! Caught to be state-dependent.
: EXECUTE-IN-STATE-0 ( xt -- )
STATE @ >R 0 STATE !
EXECUTE
R> STATE ! ; PRIVATE
-- We can do this at compile time for static arrays.
-- Assume Word-Holder holds the name.
-- An illegal ID means a LOCAL.
: ?fetch/store ( xt -- c-addr u )
\ DUP array/matrix? IF EXECUTE-IN-STATE-0 DUP /mid \ non-local ugh!
DUP array/matrix? IF >BODY 5 CELL[] DUP /mid \ non-local
ELSE DROP 0 -1 \ local
ENDIF LOCALS| id head |
assigning? IF CASE id
A_ID OF head /address #WH! $arraystore COUNT ->WH ENDOF
DA_ID OF head #WH! S" /address " ->WH $arraystore COUNT ->WH ENDOF
M_ID OF head #WH! $matrixstore COUNT ->WH ENDOF
DM_ID OF head #WH! $matrixstore COUNT ->WH ENDOF
( local) $matrixstore COUNT ->WH
ENDCASE
ELSE CASE id
A_ID OF head /address #WH! $arrayfetch COUNT ->WH ENDOF
DA_ID OF head #WH! S" /address " ->WH $arrayfetch COUNT ->WH ENDOF
M_ID OF head #WH! $matrixfetch COUNT ->WH ENDOF
DM_ID OF head #WH! $matrixfetch COUNT ->WH ENDOF
( local) $matrixfetch COUNT ->WH
ENDCASE
ENDIF
Word-Holder COUNT ; PRIVATE
: do-(DM/DA) ( id | "name" -- addr )
CREATE 0 , ( link)
, ( id)
0 , ( daddr)
0 , ( rows)
0 , ( cols)
HERE 0 , ( rowaddr)
FORGET> 5 CELL[] do-FREE
DOES> 5 CELL[] ; PRIVATE
Saturday, April 27, 2013, 17:03 *** FIXED ***
The word EXIT prevented the definition from being inlined.
Now it is possible to inline words that contain EXIT. Note that words containing LOCAL can NOT be inlined yet, although EXIT will do the right thing. PARAMS| can be inlined, even when EXIT is used.
Saturday, April 27, 2013, 17:03 *** FIXED ***
Fixed a serious buffer-overwrite bug in include/locate.frt. Trying to reload a file gave an error that that file did not exist.
Saturday, April 27, 2013, 17:03 *** FIXED ***
Fixed bugs in include/dd-fp.frt that led to overflow on the FPU stack. The compiler is much more conservative now.
Saturday, April 27, 2013, 17:03 *** FIXED ***
Problems with hpgl.frt and pscript.frt. Neither was included by include/graphbase.frt, making slbench3d.frt fail. Including them pointed out errors with the global VALUEs
Xmax and Ymax. These values should be read-only, and they should be defined in the drivers, not in the graphbase global section.
Friday, May 10, 2013, 09:21 *** FIXED ***
BELL in backspace
^char cleared in INIT-BUFFER
Saturday, May 18, 2013, 09:42 *** FIXED ***
Extensive changes to threads.frt and semaphor.frt -- large parts have moved
into the kernel and speed has increased orders of magnitude. Starting a thread
now takes only about 100 - 300 ns. (i7 2.7 GHz)
Saturday, May 18, 2013, 09:42 *** NOT FIXED ***
examples/misc/wildcard.frt is wrong (examples don't work and ^^ in MATCH? shows very weird bitmasks).
Saturday, August 17, 2013, 09:14 *** FIXED ***
Fixed >HEAD -- it didn't work for TOKENIZEd definitions and needed XT@@? additionally.
Saturday, August 17, 2013, 09:14 *** FIXED ***
Fixed the FONT-selection and -sizing words. One of the results is that xlinuxgr.frt will
need to be carefully rewritten, and that possibly xlib.c needs additions.
Saturday, August 17, 2013, 09:14 *** FIXED ***
Added bitmap file reading and manipulation words that allow to use LaTeX to format strings.
The METAFILE (clipboard) and PRINTER words are improved.
See include/graphics/eptest (matrix1.txt)
Improved pscript.frt and deleted hpgl.frt, but additional work is needed.
Saturday, August 17, 2013, 09:14 *** FIXED ***
The native Windows GUI examples in include/windows now work for iForth64. The interface
has changed. Because in graphics mode many console I/O words are overloaded, it is
not really possible to run the console and the GUI in parallel. In most cases it works.
Friday, October 04, 2013, 22:16 *** FIXED ***
xlinuxgr.frt is now completely up-to-date. When used with "export TERM=xilinux",
the Linux and Windows text and graphics terminals behave exactly the same.
Windows: Added rar64.dll. examples/rar/rar.frt now works.
Wednesday, October 09, 2013, 22:03 *** FIXED ***
None of the I/O words executed PAUSE. This proved to be a good thing as this enabled
Knuth-style coroutines using PAUSE ( see examples/misc/coroutines{1,2,3}.frt. )
Sunday, March 02, 2014, 07:58 *** NOT FIXED ***
: BETWEEN ( n1|u1 n2|u2 n3|u3 -- flag ) OVER - -ROT - U< 0= ;
This is the same code as WITHIN. WITHIN and BETWEEN should be compiler MACRO's as the advantage is then to reduce the enormous stack pressure.