It is greatly appreciated if some one would comment on this 32bit
Forth system that I came across.
The executable, ur4.exe, is only 4,608 bytes. 16bit mini4th (v4.15) is
3636 bytes.
Barry Mark's version, that was extended so that it can load file is
6024 bytes.
So it looks like ur4.exe beats mini4th nicely and we don't need a time
machine to look for a really small Forth ;-)
This system has only this many words coded in assembly:
imported? pinvoke using : ( literal ;; [ ; word? tib last reset parse
eval do,
compile ] >number >string lookup entry inline self macro
forth .data .macro
.self .forth .inline .class whitespace which state class > in base h0
(Stack, arithmatic/logic words like dup swap + - and or ... are high
level colon words !!! )
WIth these words it can be extended (after rx.4, rf.4 and rfans.4 are
loaded) to be almost ANS compatible, with these missing words:
>>> Wordsets not implemented:
BLOCK FACILITY FILE (except S") FLOATING LOCAL MEMORY
Missing from CORE: ACCEPT SOURCE MOVE (present but non-Standard)
>IN (present but non-Standard)
Missing from CORE EXT: #TIB CONVERT EXPECT MARKER QUERY REFILL RESTORE-
INPUT
SAVE-INPUT SOURCE-ID SPAN UNUSED [COMPILE]
Missing from TOOLS: SEE
Missing from TOOLS EXT: ;CODE ASSEMBLER CODE CS-PICK CS-ROLL EDITOR
FORGET
Please find appended a session of this Forth:
Cheers,
123forth
D:\DLR\R4\bin\ur4>dir
Volume in drive D is Windows 7
Volume Serial Number is 58E8-9285
Directory of D:\DLR\R4\bin\ur4
04/04/2010 05:05 AM <DIR> .
04/04/2010 05:05 AM <DIR> ..
04/04/2010 04:36 AM 4,608 ur4.exe
1 File(s) 4,608 bytes
2 Dir(s) 93,287,313,408 bytes free
D:\DLR\R4\bin\ur4>ur4 ..\rx.4 ..\rf.4
ok
words
callback import-var include -f load save reload use choose kernel32
docstring:
help ? :: | edit v --> \ ia i s e el eb x d n p shadow (line) block
(block) \f
new #-of-blocks there current-block b0 <#blocks> <buffer> <buffer-
start> exit how
ui prefix-handler remove-prefix prefix: patchlevel version .vocab voc:
^ switch
break case: (case) .s words u. . # #! does> class> ." bye spaces space
cr clear
type emit key < > <> = toggle off on zt true false unpack >entry octal
binary
decimal hex ]] [[ { s" $, now d: default: is: (is) is devector z" "
pad copy move
fill section: expose ;section ;loc loc: list alias allot -! +!
constant variable
: variable vector: class: self: forth: macro: create create: f t t/f
0; later 2dup
tuck over -rot rot execute literal? literal, vector if; ;then then if
>if <if
=if <>if (if) for next again repeat rdrop r r> >r as c: ['] x:
reclass: reclass
' x' lnparse wsparse here w! c! ! w@ c@ @ :name :doc :class :xt :link
word- word+
cell- cell+ cells not xor or and mod / /mod negate * + << >> - 1- 1+
dup nip
swap 2drop drop 3, 2, 1, , imported? pinvoke using : ( literal ;; [ ;
word? tib
last reset parse eval do, compile ] >number >string lookup entry
inline self macro
forth .data .macro .self .forth .inline .class whitespace which state
class >
in base h0
249 words defined
ok
-f ..\ans\rfans.4
ok
words
rf needs include dump endcase endof of case environment? accept move
cmove> cmove
search compare -trailing m*/ to value ? roll pick .s pad hide >number
j loop +
loop ?do do leave unloop abort" abort catch quit exception: c" .
( s" (s") " (
parse last-parsed blank [char] char bl word place, place search-
wordlist find
(find) xt>flag forth previous also definitions order case-sensitivity
vocabulary
set-order only get-order set-wordlist-name .wordlist forth-wordlist
get-current
set-current wordlist current-name u. . d. u.r ud.r .r d.r (ud.) #s #
sign #> hold
<# digit? char>num >lower num>char spaces >body create does> 2variable
variable
variable: base >in state false true 2constant constant :noname :: ; :
recurse
again until repeat while else then begin ahead if orig? dest? erase
enough? 2literal
dmin dmax d0= d0< d= du< d2/ dabs d< d- dnegate d2* m+ d+ within u> u<
signsdiffer?
2/ highbit lowbits */ */mod mu/mod mu* um/mod sm/rem fm/mod um* m* s>d
2rot 2nip
2swap 2over ?dup /string max min align aligned 2r@ 2r> 2>r postpone ?
immediate ['] '
throw 2! 2@ abs 2* 0<> 0> 0< 0= chars (u.) count sliteral compile, d>s
c, evaluate
lshift rshift i r@ exit char+ invert [else] [then] [if] depth rp! rp@
sp! sp@ \
immediate callback import-var include -f load save reload use choose
kernel32
docstring: help ? :: | edit v --> \ ia i s el x n p shadow (line)
block (block) \f
new #-of-blocks there current-block <#blocks> <buffer> <buffer-start>
exit how ui
prefix-handler remove-prefix prefix: patchlevel version .vocab voc: ^
switch break
case: (case) .s words u. . # #! does> class> ." bye spaces space cr
clear type emit
key < > <> = toggle off on zt true false unpack >entry octal binary
decimal hex ]] [[
{ s" $, now d: default: is: (is) is devector z" " pad copy move fill
section: expose
;section ;loc loc: list alias allot -! +! constant variable: variable
vector: class:
self: forth: macro: create create: t t/f 0; later 2dup tuck over -rot
rot execute
literal? literal, vector if; ;then then if >if <if =if <>if (if) for
next again repeat
rdrop r r> >r as c: ['] x: reclass: reclass ' x' lnparse wsparse here
w! c! ! w@ c@ @
:name :doc :class :xt :link word- word+ cell- cell+ cells not xor or
and mod / /mod
negate * + << >> - 1- 1+ dup nip swap 2drop drop 3, 2, 1, , imported?
pinvoke using :
( literal ;; [ ; word? tib last reset parse eval do, compile ] >number
>string lookup
entry inline self macro forth .data .macro .self .forth .inline .class
whitespace which
state class >in base h0
451 words defined
ok
' see
see <- Exception: undefined word
Backtrace:
$436553 throw
D:\DLR\R4\bin\ur4>
> It is greatly appreciated if some one would comment on this 32bit
> Forth system that I came across.
>
> The executable, ur4.exe, is only 4,608 bytes. 16bit mini4th (v4.15) is
> 3636 bytes.
Do you have a link? Googling ur4.exe gave nothing useful
Have you looked at Buzzard? See various files at
Gerry
It appears to be a variant of an older RetroForth (I'm guessing an
offshoot of 9.x, based on the word names, assembly primitives, and a
couple of the filenames you provided), but it's not one of the
official releases. I'd love to take a closer look.
-- crcx
Same here, google can't find it even it's sitting right on drive
D: ;-)
Cheers,
123forth
I will post a link here as soon as I can find a home for 'ur4' or
better yet, is there any place where I can upload these files.
I think you are right on, 'ur4' is just a variety of 'RetroForth',
maybe 'u' stands for 'micro'.
(and 'ur4' can also stand for 'Your Forth' ;-)
'rx.4', 'rf.4' are just the 2 files embedded in (older) RetroForth
(with different names) and rfans.4 is just 'retro-ans.fs' written by
Neal Bridges.
Best regards,
123forth
Thanks, for the simple solution.
I upload ur4.7z to http://drop.io/ur4_upload
That 7z archive contains ur4.exe, rx.4 and rf.4
rx.4 must be loaded before rf.4:
ur4 rx.4 rf.4
Please try to see if you can access ur4.7z
http://quartus.net/retro/rfans.zip has ans files.
To make it work, I had to insert a 'reset' after definition of 'quit':
: quit 0 state ! rp0 rp! ['] boot >r ;
reset
and changed 'external' to 'expose' in all 'section:' ';section'
section: \ MEMORY words
using kernel32.dll
3 pinvoke HeapAlloc
3 pinvoke HeapFree
4 pinvoke HeapReAlloc
0 pinvoke GetProcessHeap
GetProcessHeap constant process-heap
\ external
expose
-524 exception: unspecified heap allocation error
: ALLOCATE process-heap 0 rot HeapAlloc dup 0= -524 and ;
: RESIZE process-heap 0 2swap HeapReAlloc dup 0= -524 and ;
: FREE process-heap 0 rot HeapFree 0= -524 and ;
;section
Cheers,
123forth
Now that I could load rfans.4, I am trying to use 'help.data' from
RetroForth:
-f help.data
ok
help .forth
Sorry, no help was found
ok
In the help.data there is this:
: help-.forth
." .forth ( xt
-- ) V .class" cr
." This is the class handler for forth words." cr
;
How can I get some help?
Thanks,
123forth
While I'm away from my Windows box until tomorrow, the code doesn't
quite look correct. The help data should be making use of docstring
words. In my help.data I have:
docstring: .forth
." .forth ( xt
-- ) V .class" cr
." This is the class handler for forth words." cr
;
Try it with the help.data from 9.2.10 (http://s3.retroforth.org/
download/9.2/9.2.10-hosted-source.tar.gz; the help.data is located in
the extensions directory) and see if that works.
-- crc
Yes, that works, thanks.
OK, so I got some help for the RetroForth.
Would some kind soul please help me with the retro-ans.fs, how can I
debug the 'stack depth' problem?
I have narrowed down to this definition of 'quit' with:
0 . cr .s
: quit 0 state ! rp0 rp! ['] boot >r ;
1 . cr .s
reset
2 . cr .s
and got this:
D:\DLR\R4\bin>ur4 rx.4 rf.4 ans\retro-ans.fs
0
0 0 0 0 0 0 0 0 0 0
1
0 0 0 0 0 0 0 0 0 -4356624
2
0 0 0 0 0 0 0 0 0 0
ok
What should I do next to fix this increase in stack depth after the
definition of 'quit' ?
Thanks,
123forth
Hi,
Would you not simply have something like this in RESET ?
SP0 SP!
Sorry, I don't know retro forth.
Regards
Mark
Many thanks for the hint.
As soon as the word 'constant' is available and the stack depth is 0:
sp@ constant sp0
then:
: reset SP0 SP! ;
seems to work. So, now I can remove 'reset' from the kernel of 'ur4'
My goal is to reduce the kernel words to the minimum.
Regards,
123forth
Forth's vary in size from 3 to over 2500 words... Sorry, the 3 instruction
Forth is a bit of deception.
So, the question is how minimal?
Are compiled words acceptable?
Do you only want low-level (or primitive) words?
You can implement Forth with only a few words, say 9 to 16. One of the
smallest is Mikael Patel's 9 word wordset in old comp.lang.forth posts. It
not likely that it'll be quick.
A small realistic set is around 23 for Mark Hayes' MRForth, or 36 for C.H.
Ting's eForth, or 46 for 8086 GFORTH. You can probably figure on that range
for a useable Forth.
Do you know what a "primitive" is?
Any word that you can't (or won't) break down, i.e., factor, into other
words is a "primitive". There are many reasons why a word should be
implemented as a primitive. E.g., microprocessors implement logical-and,
logical-or, and logical-xor as assembly instructions. You _can_ implement
them with even simpler logic, but why should you? The cpu already
implements them. If you do factor them, they'll be real slow. So, you'll
usually find AND, OR, and XOR as three of the primitives in most low-level
wordsets. Since Forth is a stack machine, you'll frequently find stack
manipulation words like DUP, DROP, SWAP and OVER as primitives, as well as
fetch @, store !, >R, R>, etc. It turns out that other stack manipulation
words, such as NIP, TUCK, and ROT, can be implemented in terms of those four
and/or R> and >R. IIRC, all of the 2___ words, like 2DUP, 2DROP, etc can be
built from them also. You'll need words to build words in the dictionary,
for the parts of the interpreters, and for parts of the control flow words.
This post of mine lists primitives for some of those Forth's that I
mentioned (at the bottom). It's also just about the only reference on Forth
wordset size (at the top):
http://groups.google.com/group/comp.lang.forth/msg/10872cb68edcb526?hl=en
Rod Pemberton
It is not my intention to create yet another Forth. I have been
looking for the smallest 32bit Forth available that can load file to
extend itself and can 'see' the words. All of these are just for
educational purpose. Mini4th has a really nice decompiler.
So far, RetroForth seems to be the best, to me. Unfortunately the
version of RetroForth that I like is no longer actively maintained. It
already had an ANS layer (still with missing words, the most
important , to me, is the decompiler).
I hope experts on this list will help to give RetroForth a decompiler
and improve the ANS layer.
123forth
P.S: I don't know why, but Forth's implemented in C don't fascinate me
(and of course, C stands for Cobol).
my forth don't have SEE, not have ANS layer AND is write in C.
http://code.google.com/p/reda4/
Pablo
This looks like the starting point for lina (ciforth),
small but not smaller than practical. Not going out of the way
to define AND by using XOR and that silliness.
Some words are easier in assembler:
CODE ROT
POP AX POP BX POP CX
PUSH BX PUSH AX PUSH CX
ENDCODE
CODE SM/REM
POP BX POP DX POP AX
IDIV BX
PUSH DX PUSH AX
ENDCODE
Replacing a single assembler instruction with a load of crap
is just silly.
I don't think a "SEE" facility should be built-in. At least in
ciforth it is a loadable extension.
lina uses BLOCK words to extend itself. The kernel contains
FILE words that could alternatively be used to extend.
I could do away with FILE in the kernel too and have them
loadable from blocks. So neither is the FILE wordset essential
in the kernel of an extensible Forth.
I don't think even a small Forth can do without a comprehensive
error philosophy. Mine is based on CATCH THROW. That cannot be
removed and works nicely together with blocks to provide
mnemonic error messages.
>
>So far, RetroForth seems to be the best, to me. Unfortunately the
>version of RetroForth that I like is no longer actively maintained. It
>already had an ANS layer (still with missing words, the most
>important , to me, is the decompiler).
One of my starting points was that the ANSI core set must be
in the kernel. The result is that it contains word like ACCEPT
FIND WORD ENVIRONMENT? that are not used, nor useful for the kernel.
They are easy to trim though.
<SNIP>
>123forth
>
>P.S: I don't know why, but Forth's implemented in C don't fascinate me
>(and of course, C stands for Cobol).
Interesting word to use: "fascinate". I'm fascinated by Forth's defined
in assembler but not by those defined in C. True.
(Currently porting Renesas R16C ciforth to R32C. I have to extend the
headers with a 0 word because 32 bits addresses are inevitable even in
a 16 bit Forth. If Elektor had ordered the RAM that goes with that ...
That was the latest bug discovered, i.e. past the syntactic assembler
errors stage. It may not be a great way to learn Forth, but I learn
something: R32C assembler programming. )
Groetjes Albert
--
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst
While I can't help with the ANS layer (that was written by Neal;
developer of Quartus Forth), I might be able to get a simple
decompiler working for the 9.x branch this weekend.
-- crc
Hi,
>
> I don't think even a small Forth can do without a comprehensive
> error philosophy. Mine is based on CATCH THROW. That cannot be
> removed and works nicely together with blocks to provide
> mnemonic error messages.
>
Yes, I think that this pair is really invaluable and worth to be in
the kernel.
Is it hard to implement and would it work without block ?
Does the whole system have to be rewritten to take advantages of
that ?
For example, RetroForth 9.2.10 introduced a new link in the header for
docstring to support help and I think the old source could just be
loaded/compiled and help is available. (Please correct me if I am
wrong.)
Many thanks for sharing,
123forth
Hooray, thanks for making part of my dream comes true.
Cheers,
123forth
Hi,
'reda4' is a bit too 'fat' for my taste ;-)
Thanks for the link.
123forth
<snip>
> P.S: I don't know why, but Forth's implemented in C don't fascinate me
> (and of course, C stands for Cobol).
Some of the first code that Chuck Moore used to implement of Forth was
writen in COBOL.
--
Coos
CHForth, 16 bit DOS applications
http://home.hccnet.nl/j.j.haak/forth.html
Of course, why do you think blocsk are needed for CATCH and THROW ?
Ciforth uses blocks for its library. So there it is needed
> Does the whole system have to be rewritten to take advantages of
> that ?
Most ISO-Forths have CATCH and THROW in the kernel, I assume.
> For example, RetroForth 9.2.10 introduced a new link in the header for
> docstring to support help and I think the old source could just be
> loaded/compiled and help is available. (Please correct me if I am
> wrong.)
My headers have pointers for LOCATE to display the part of the file
where the word is defined.
That's very interesting to know. I love to read more about that.
Cheers,
123forth
I don't think so. FORTRAN, certainly, but I don't know of any COBOL.
Cheers,
Elizabrth
--
==================================================
Elizabeth D. Rather (US & Canada) 800-55-FORTH
FORTH Inc. +1 310.999.6784
5959 West Century Blvd. Suite 700
Los Angeles, CA 90045
http://www.forth.com
"Forth-based products and Services for real-time
applications since 1973."
==================================================
> Coos Haak wrote:
>> Op Thu, 8 Apr 2010 18:26:18 -0700 (PDT) schreef 123forth:
>>
>> <snip>
>>> P.S: I don't know why, but Forth's implemented in C don't fascinate me
>>> (and of course, C stands for Cobol).
>>
>> Some of the first code that Chuck Moore used to implement of Forth was
>> writen in COBOL.
>>
>
> I don't think so. FORTRAN, certainly, but I don't know of any COBOL.
>
> Cheers,
> Elizabrth
There is scarce (1 screen only) evidence in his article 'FORTH, The
Last Ten Years and the Next Two Weeks', page 60 of Forth Dimensions
volume 1, number 6, figure 9.
1 MOVE "CONFIGURATION" TO IDENTIFY(40);
2 MOVE "DATA" TO IDENTIFY 5);
.. and some more of this awkward code as he calls it. More of a
pre-Forth I would say.
The other languages in this article, like 360 and 5500 assembler have
a more modern feeling.
CATCH/THROW is inherently a bit tricky, but in a simple Forth
like lina it only involves some manipulation with the data and
return stacks. Say 3 lines each.
Blocks are only needed to store the online messages,
so the kernel doesn't contain swads of text.
>Does the whole system have to be rewritten to take advantages of
>that ?
Probably not, but (you guessed!) it depends on the system.
>
>For example, RetroForth 9.2.10 introduced a new link in the header for
>docstring to support help and I think the old source could just be
>loaded/compiled and help is available. (Please correct me if I am
>wrong.)
lina has a field to point to the source, but you can configure it
out or in using the source generation tools. External doc's in a .pdf
may be preferred by some people.
>
>Many thanks for sharing,
>
>123forth
Groetjes Albert
The only real (non-hobby) work I ever did in Forth was many years ago,
to help me implement a project that management insisted be done in IBM
360 assembler and/or Cobol even though it needed something higher
level. As a work around, I researched high level things I could set up
in those, and found Forth; then I basically wrote it in Forth on top
of IBM 360 assembler, with a separate Cobol module for the I/O, using
assembler macros rather than a text interpreter and Forth source so
that technically I stayed within the permitted environment (it would
have gone quicker if I had been allowed the more interactive Forth
environment, though - I wouldn't have needed an editor etc. but just a
text interpreter, since I could have piped source into it from a PC
file). It was a triumph of misguided ingenuity, since the whole
project was clearly worthless from the beginning anyway (it was meant
to deskill the use of another package, but installing it in an IBM
mainframe environment was so awkward that the users would need to
learn installing skills that were just as hard to learn in the first
place). P.M.Lawrence.
>
> Most ISO-Forths have CATCH and THROW in the kernel, I assume.
>
I am quite willing to trade these 5 kernel words: .data forth self
macro inline for catch/throw.
I read somewhere that these 5 words can be defined as colon words in
terms of .class .macro .inline .self and .forth ?
I vaguely think that the concepts about the class of words is rather
powerful but cannot tell exactly why.
Would this concept make the defining words, compiling words and
vocabularies in Forth more powerful and organized (factored)?
>
> My headers have pointers for LOCATE to display the part of the file
> where the word is defined.
>
Considering that the embedded files in RetroForth are now externally
loaded, maybe the help file should be incorporated in the source files
(rx.4 and rf.4) and LOCATE is better suited than HELP. This ensure the
privilege of left paren in the kernel so that commnent and stack
diagrams are available for the first word in the loaded files. Maybe,
left paren can be extended to provide multi-line comments?
The help for the kernel words is still needed, though.
Let's hope there will be only a handful of these words.
Cheers,
123forth
<snip>
>
> I am quite willing to trade these 5 kernel words: .data forth self
> macro inline for catch/throw.
>
> I read somewhere that these 5 words can be defined as colon words in
> terms of .class .macro .inline .self and .forth ?
>
I don't know what .class .macro .inline .self and .forth are.
Perhaps these are defined by RetroForth what is as IUI quite a lot
different from ANS/ISO Forth's. I can't help you here.
> I vaguely think that the concepts about the class of words is rather
> powerful but cannot tell exactly why.
Standard Forth has no classes. It's not Python.
> Would this concept make the defining words, compiling words and
> vocabularies in Forth more powerful and organized (factored)?
>
Perhaps, I can't say, but Forth is powerful in itself by virtue of the
twins CREATE and DOES>. Contrary what someone in this newsgroup seems
to think.
>>
>> My headers have pointers for LOCATE to display the part of the file
>> where the word is defined.
>>
>
> Considering that the embedded files in RetroForth are now externally
> loaded, maybe the help file should be incorporated in the source files
> (rx.4 and rf.4) and LOCATE is better suited than HELP. This ensure the
> privilege of left paren in the kernel so that commnent and stack
> diagrams are available for the first word in the loaded files. Maybe,
> left paren can be extended to provide multi-line comments?
>
> The help for the kernel words is still needed, though.
> Let's hope there will be only a handful of these words.
>
> Cheers,
>
> 123forth
Good night!
These are words that take an xt and do something with it. Basically
they determine the runtime and compile-time behavior of particular
types ("classes") of words. It's an implementation technique I
encountered in Helmar's HelFORTH and have used ever since.
-- crc
This is similar to the situation with `` CREATE .. DOES> .. '' and
`` CREATE .. ;CODE .. '' words and goes back to `` BUILDS .. DOES ..''
Having this kind of classes, be it with only one method, accounts
for a good part of the power of early Forth's and ever since.
Combining data and code in Forth predates the oo hype by decennia.
Now of course Chuck Moore defines classes by their "color".
>
>-- crc
.data is now removed from dictionary of the kernel and defined, after
literal, as :
: literal, x: literal ;
: literal?
state @ if literal, ;then
;
: .data ( xt -- xt | )
state @ if literal, then
;
With this change alone, 'quit.t' (please see the thread 'How to trace
stack depth') crashed:
D:\DLR\R4\bin>ur4 rx.4 rf.4 help.ur4 ans/rfans.4
ok
include ans/quit.t
0 <0>
1 <1> -4403094
2 <1> -4403094
(CRASHED HERE)
In the retro-ans.fs, .data is redefined and exposed in this section:
section: \ Numeric conversion enhancements:
...
expose
:: state @ if is-double @ if swap literal, then literal, then
is-double off ; is .data
...
;section
If this re-definition of .data is commented out, 'quit.t' runs OK:
D:\DLR\R4\bin>ur4 rx.4 rf.4 help.ur4 ans/rfans.4
ok
include ans/quit.t
0 <0>
1 <1> -4403018
2 <1> -4403018
3 <1> -4403018
4 <1> -4403018
5 <0>
6 <0>
7 <0>
ok
I have 2 questions:
1/- After the redefinition of .data in retro-ans.fs, it's not used
anywhere. Why 'quit.t' crashed before that redefinition was commented
out?
2/- The following 2 words look very similar:
: literal?
state @ if literal, ;then
;
: .data
state @ if literal, then
;
Can that common phrase be factored out:
state @ if literal,
Thanks for your help,
123forth
This makes a subtle change: this .data is *not* a vector/deferred
word; the original assembly one is. (The macros I used in the assembly
make all of the initial primitives into vectors automatically).
> With this change alone, 'quit.t' (please see the thread 'How to trace
> stack depth') crashed:
>
> D:\DLR\R4\bin>ur4 rx.4 rf.4 help.ur4 ans/rfans.4
> ok
> include ans/quit.t
>
> 0 <0>
>
> 1 <1> -4403094
>
> 2 <1> -4403094
> (CRASHED HERE)
>
> In the retro-ans.fs, .data is redefined and exposed in this section:
>
> section: \ Numeric conversion enhancements:
> ...
> expose
>
> :: state @ if is-double @ if swap literal, then literal, then
> is-double off ; is .data
> ...
>
> ;section
>
> If this re-definition of .data is commented out, 'quit.t' runs OK:
To make this work, you need to alter the new .data; something like
this should work:
: .data ( xt -- xt | )
vector state @ if literal, then
;
> I have 2 questions:
>
> 1/- After the redefinition of .data in retro-ans.fs, it's not used
> anywhere. Why 'quit.t' crashed before that redefinition was commented
> out?
Not sure. My releases don't have a 'quit' word.
> 2/- The following 2 words look very similar:
>
> : literal?
> state @ if literal, ;then
> ;
>
> : .data
> state @ if literal, then
> ;
These are identical in functionality. literal? is a carryover from
before I added the word classes and never disappeared from the 9.x
branch. I'd probably take advantage of the colorforth-style multiple
entry points and do something like:
: literal? : .data vector state @ if literal, then ;
-- crc
>
> : .data ( xt -- xt | )
> vector state @ if literal, then
> ;
>
Yes, that works.
I also remove .forth ( because it's functionally the same as .class,
correct?) and startup default class is .class (i.e .forth):
var class, do_forth
These words are now dekernelized:
: forth ['] .class class ! ;
: macro ['] .macro class ! ;
: self ['] .self class ! ;
: inline ['] .inline class ! ;
So, there are 32 kernel words now:
imported? pinvoke using : ( literal ;; [ ; word? tib last parse eval
do,
compile ] >number >string lookup entry .macro .self .inline .class
whitespace
which state class >in base h0
Beside left paren, are there any other words that can be
dekernelized ?
Thanks,
123forth
.macro and .inline
: .macro ( a- ) vector state @ if .self ;then drop ;
.inline would be a bit harder, but exists solely for optimization
purposes and can safely be replaced by .class or .forth
-- crc
There seems to be a little problem with this:
>
> : .macro ( a- ) vector state @ if .self ;then drop ;
>
unless if and ;then can be defined as non-macro words.
>
> .inline would be a bit harder, but exists solely for optimization
> purposes and can safely be replaced by .class or .forth
>
Thanks for confirming this. I mixed together the forth and inline
words and it seemed OK.
.inline is used only in retro-ans.fs:
: constant >r : r> literal, postpone ; ['] .inline reclass ;
: 2constant 2>r : 2r> swap literal, literal, postpone ; ['] .inline
reclass ;
How would you eliminate .inline from these words.
BTW, is there any documentation on the use of these classes of words
in RetroForth?
Thanks,
123forth
I read somewhere that HelForth is a derivative of RetroForth and has a
small disassembler.
Can it be used to see the kernel code words in RetroForth.?
Cheers,
123forth
All of the .macro words should work if changed to .self. The .macro
class just adds a tiny bit to prevent use when the interpreter is
active.
(In my current implementations, I define equivalents to .forth, .self,
and .data in the kernel and then do the others later.)
>
> > .inline would be a bit harder, but exists solely for optimization
> > purposes and can safely be replaced by .class or .forth
>
> Thanks for confirming this. I mixed together the forth and inline
> words and it seemed OK.
>
> .inline is used only in retro-ans.fs:
>
> : constant >r : r> literal, postpone ; ['] .inline reclass ;
> : 2constant 2>r : 2r> swap literal, literal, postpone ; ['] .inline
> reclass ;
>
> How would you eliminate .inline from these words.
Try:
: constant >r : r> literal, postpone ; ;
: 2constant 2>r : 2r> swap literal, literal, postpone ; ;
Since .inline is just an optimization class you shouldn't need it.
> BTW, is there any documentation on the use of these classes of words
> in RetroForth?
>
> Thanks,
>
> 123forth
There may be something useful in http://retroforth.org/obs/book.html
-- crc
HelForth, while similar in some ways, is a quite different Forth; the
disassembler won't run on Retro without major changes.
-- crc
Is this a nested colon, is it Retro's or Standard feature ?
>
> All of the .macro words should work if changed to .self. The .macro
> class just adds a tiny bit to prevent use when the interpreter is
> active.
>
Yes, this works but somehow retro-ans.fs is broken, complaining:
*** ERROR: :noname was not found
*** ERROR: 2constant was not found
*** ERROR: 2variable was not found
...
...
*** ERROR: tp was not found
*** ERROR: (s") was not found
*** ERROR: ) was not found
(and exited)
D:\DLR\R4\bin>
In retro-ans.fs, macro and .macro are used :
: ?immediate ( -- flag ) which @ :class @ dup ['] .self = swap
['] .macro = or ;
...
...
' macro >entry :xt @ constant codestart \ a very early word in
retro's dictionary
Since retro-ans.fs already broken here, so I also tried to remove
literal from the kernel dictionary:
: literal vector $04ee83 3, $689 2, $b8 1, , ; ( auto-inlining
version of LITERAL )
Is this OK? would it break anything?
Now there are 30 kernel words:
imported? pinvoke using : ( ;; [ ; word? tib last parse eval do,
compile ] >number >string lookup entry .self .class white space
which state class >in base h0
>
> (In my current implementations, I define equivalents to .forth, .self,
Is this Retro 9.3 or 9.2.11 ?
> and .data in the kernel and then do the others later.)
>
I thought .data can be defined as a colon word?
Cheers,
123forth
It looks like HelForth is now superseded by p4.
Is classic HelForth still available somewhere?
Thanks,
123forth
The : in 9.x can be nested, but the ANS library redefines it to be non-
nesting. (Standard Forth does not allow for nested colon definitions).
In this case, it should be using the standard-compliant :
> > All of the .macro words should work if changed to .self. The .macro
> > class just adds a tiny bit to prevent use when the interpreter is
> > active.
>
> Yes, this works but somehow retro-ans.fs is broken, complaining:
>
> *** ERROR: :noname was not found
> *** ERROR: 2constant was not found
> *** ERROR: 2variable was not found
> ...
> ...
> *** ERROR: tp was not found
> *** ERROR: (s") was not found
> *** ERROR: ) was not found
> (and exited)
> D:\DLR\R4\bin>
I'm not sure why this would break things...
> In retro-ans.fs, macro and .macro are used :
>
> : ?immediate ( -- flag ) which @ :class @ dup ['] .self = swap
> ['] .macro = or ;
> ...
> ...
> ' macro >entry :xt @ constant codestart \ a very early word in
> retro's dictionary
Maybe this?
: ?immediate ( -- flag ) which @ :class @ ['] .self = ;
' self >entry :xt @ constant codestart
(I'm not too familiar with the workings of the ANS extension; it was
almost entirely the work of Neal Bridges)
> Since retro-ans.fs already broken here, so I also tried to remove
> literal from the kernel dictionary:
>
> : literal vector $04ee83 3, $689 2, $b8 1, , ; ( auto-inlining
> version of LITERAL )
>
> Is this OK? would it break anything?
It shouldn't hurt anything.
> Now there are 30 kernel words:
>
> imported? pinvoke using : ( ;; [ ; word? tib last parse eval do,
> compile ] >number >string lookup entry .self .class white space
> which state class >in base h0
>
>
>
> > (In my current implementations, I define equivalents to .forth, .self,
>
> Is this Retro 9.3 or 9.2.11 ?
10.5 is my latest stable release.
9.3 won't run the ANS extension; it was based on some earlier work and
isn't fully compatible with 9.2.x.
> > and .data in the kernel and then do the others later.)
>
> I thought .data can be defined as a colon word?
It is. My current implementation is metacompiled.
> Cheers,
>
> 123forth
-- crc
Yes, this works. I am still wondering why the new definition
for .macro broke the original ones.
Anyway, I also removed the word whitespace out of the kernel
dictionary and replace it with :
$20 constant whitespace
Again, this is only used by retro-ans.fs. >number is also used only by
retro-ans.fs, but I think I stop here ;-)
Now there are only 28 kernel words:
D:\DLR\R4\bin>ur4 rx.4 rf.4 help.ur4 ans\rfans.4
ok
words
time&date word-wrap window-size page get-xy get-xy at-xy free resize
allocate
....
....
imported? pinvoke using : ( ;; [ ; word? tib last parse eval do,
compile ]
>number >string lookup entry .self .class which state class >in base h0
475 words defined
ok
and ur4.exe is now exactly 4KB
D:\DLR\R4\bin>dir ur4.exe
Volume in drive D is Windows 7
Volume Serial Number is 58E8-9285
Directory of D:\DLR\R4\bin
04/15/2010 08:30 PM 4,096 ur4.exe
1 File(s) 4,096 bytes
0 Dir(s) 93,262,102,528 bytes free
Cheers,
123forth
I had a look at HelForth decompiler. It went all the way down to the
disassembler. It would be nicer if it can display the colon
definitions the way Mini4th did, IMHO.
What approach would your decompiler use?
Many thanks for everything.
123forth.
Both whitespace and >number are used in the interpreter loop in the
9.2.x sources, though whitespace isn't really crucial. (in 9.2 it is a
variable, allowing overriding of the whitespace character for the
parser)
> Now there are only 28 kernel words:
>
> D:\DLR\R4\bin>ur4 rx.4 rf.4 help.ur4 ans\rfans.4
> ok
> words
> time&date word-wrap window-size page get-xy get-xy at-xy free resize
> allocate
> ....
> ....
> imported? pinvoke using : ( ;; [ ; word? tib last parse eval do,
> compile ]>number >string lookup entry .self .class which state class >in base h0
>
> 475 words defined
> ok
>
> and ur4.exe is now exactly 4KB
Being a Windows app, there's only so much you can shrink without
resorting to tricks that may not work in the future :)
> D:\DLR\R4\bin>dir ur4.exe
> Volume in drive D is Windows 7
> Volume Serial Number is 58E8-9285
>
> Directory of D:\DLR\R4\bin
>
> 04/15/2010 08:30 PM 4,096 ur4.exe
> 1 File(s) 4,096 bytes
> 0 Dir(s) 93,262,102,528 bytes free
>
> Cheers,
>
> 123forth
-- crc
Currently it's providing disassembly.
Decompilation to something similar to the original source would be
possible, but it won't match up exactly. It was actually easier in the
older (7.x) implementations since the compiled code was more
consistent in structure.
-- crc
whitespace is only removed from the dictionary.
BTW, when I use a tab instead of spaces, wsparse doesn't seem to like
it.
Cheers,
123forth.
P.S: Is there a way to test the newly defined .macro to see if it
functions as expected?
When it is ready for testing, would you please give a link.
Thanks,
123forth
Originally parse only recognized space, cr, and lf. By 9.2.10 it was
modified to remap tab to space as well, though I'm not sure exactly
which release made this change.
In 9.2.10, this works to test the remapping:
: foo ( " " -- ) wsparse type cr wsparse type cr ;
foo words<tab>words<enter>
> Cheers,
>
> 123forth.
>
> P.S: Is there a way to test the newly defined .macro to see if it
> functions as expected?
macro
: foo 1 . ;
forth
foo ( should display nothing )
: bar foo ; ( should display 1 )
-- crc
D:\DLR\R4\bin>ur4 rx.4 rf.4
ok
: foo ( " " -- ) wsparse type cr wsparse type cr ;
ok
foo words words
words words
ok
: foo2 wsparse type cr wsparse type cr ;
ok
foo2
*** ERROR: foo2 was not found
ok
: foo3 wsparse type cr wsparse type cr ;
*** ERROR: : foo3 was not found
ok
bye
D:\DLR\R4\bin>
1/- foo : is each words supposed to be on one line
2/- foo2 : there is a tab between foo2 and wsparse
3/- foo3 : there is a tab between colon and foo3
Thanks,
123forth
I just tried RetroForth 9.2.10, it is working perfectly.
This is ur4 bug, NOT Retro.
I'm sorry for the confusion.
123forth.
This is different than 9.2.10:
1 - each 'words' is on a separate line
2 - no problems
3 - no problems
-- crc
No problem :)
-- crc
This kind of bug is rather annoying. It looks like the tab is taken as
a character of a word.
When I put a tab inside a definition, a loc: ;loc there are problems.
If the tabs are replaced with spaces, everything OK.
When I put more than 2 words like:
foo words words words words
then I start to get words. Any ideas what might cause this kind of
bug. Until that is fixed, I have to configure my editor to expands
tabs into spaces ;-)
Do you happen to have a test suite to test Retro before each release,
it would be invaluable.
Thanks,
123forth
Look at 'query' (or your equivalent) in the assembly source. Mine in
9.2.10 has a conditional structure to remap tab to space. Basically:
cmp byte [edi], 9 ; TAB
jne .notab ;
mov byte [edi], 32 ; Make the TAB a SPACE
.notab: cmp byte [edi], 10 ; Skip LF
You'll need to do something similar to take care of the conversion.
> Do you happen to have a test suite to test Retro before each release,
> it would be invaluable.
No; I never put together anything comprehensive; the language was
always a moving target, and no single test suite has ever existed.
> Thanks,
>
> 123forth
-- crc
Is there anything else that can cause this kind of bug, because Retro'
'query' is used verbatim.
Thanks,
123forth.
I'm not sure. Does this happen only after the ANS layer is loaded, or
does it happen before?
-- crc
It is reproducible with the version on drop.io:
D:\DLR\R4\drop.io\ur4>dir
Volume in drive D is Windows 7
Volume Serial Number is 58E8-9285
Directory of D:\DLR\R4\drop.io\ur4
04/19/2010 08:40 PM <DIR> .
04/19/2010 08:40 PM <DIR> ..
04/18/2010 09:38 PM <DIR> ans
04/19/2010 08:40 PM <DIR> mac
04/04/2010 05:48 PM 7,291 rf.4
04/06/2010 05:33 PM 4,948 rx.4
04/04/2010 04:36 AM 4,608 ur4.exe
04/19/2010 08:43 PM 196 wsparse.t
4 File(s) 17,043 bytes
4 Dir(s) 93,196,271,616 bytes free
D:\DLR\R4\drop.io\ur4>type wsparse.t
: foo ( " " -- ) wsparse type cr wsparse type cr ;
foo words words
foo words words
cr cr
: foo2 ( " " -- ) wsparse type cr wsparse type cr ;
foo2 words words
foo2 words words
D:\DLR\R4\drop.io\ur4>ur4 rx.4 rf.4 wsparse.t
*** ERROR: foo words words was not
found
words
words
*** ERROR: type was not found
*** ERROR: type was not found
*** ERROR: foo2 words words was not
found
ok
bye
D:\DLR\R4\drop.io\ur4>
Thanks,
123forth
I'm still trying to identify the cause.
In the meantime, a really bad stab at a decompiler can be seen at
http://retroforth.blogspot.com/2010/04/decompiling-code-in-9210.html
I'll be rewriting this once I get a chance - work + family matters are
occupying most of my time right now.
-- crc
It seems to work with both rf-win (9.2.10):
D:\DLR\R4\NOW\bin>rf-win include 4\see.4
: seven 3 4 + ;
5 see seven
428592 call <>
428597 add eax,[esi] ( )
428599 Unknown: 0
42859a Unknown: 0
42859b call <>
and ur4 identically:
D:\DLR\R4\NOW\bin>ur4 4\rx.4 4\rf.4
ok
include 4\see.4
ok
: seven 3 4 + ;
ok
5 see seven
425b6f call <>
425b74 add eax,[esi] ( )
425b76 Unknown: 0
425b77 Unknown: 0
425b78 call <>
ok
Your help is truly appreciated, now we have something to start with.
Cheers,
123forth
Now there are 23 words in the kernel (the last 2 lines):
D:\DLR\R4\NOW\bin>rf 4\rx.4 4\rf.4 4\ans\rfans.4
ok
words
time&date word-wrap window-size page get-xy get-xy at-xy free resize
allocate
...
...
...
( imported? pinvoke using : ;; [ ; word? parse eval do, compile ]
>number >string
lookup entry .inline .macro .self .class sysvars
481 words defined
ok
h0 base >in class state which whitespace last tib are now defined in
terms of the new kernel word sysvars :
: sysvarn sysvars swap cells + ;
: h0 1 sysvarn ;
: base 2 sysvarn ;
: >in 3 sysvarn ;
: class 4 sysvarn ;
: state 5 sysvarn ;
: which 6 sysvarn ;
: whitespace 7 sysvarn ;
: last 8 sysvarn @ ;
: tib 9 sysvarn @ ;
Are they OK?
These changes seem to be acceptable to rfans.4 but docstring: was
broken, the original version crashed:
: docstring:
x' if drop here @which :doc ! ]
;then word?
;
I could not locate the word @which , so I tried :
: docstring:
x' if drop here @ which :doc ! ]
;then word?
;
This does not crash but there were no help available:
D:\DLR\R4\NOW\bin>ur4 4\rx.4 4\rf.4 4\help.ur4
ok
help help
Sorry, no help was found
ok
The new colon definition for .macro is not quite working yet.
If .inline is meant for optimisation, it should stay for further
study.
word? looks so simple, this colon definition was tried:
: word? vector [ $e9 1, 0 , ] drop drop 0 ;
It seems to work with rx.4 and rf.4 but rfans.4 was broken.
Potentially the kernel words count can be down to 21 if .macro and
word? can be defined as colon words.
Left paren can be defined as colon word too but it is intentionally
left in the kernel, so the minimum number of kernel words is 20, or is
it ?
Cheers,
123forth
Good to hear. I'll do some cleanups soon and then try to cover more of
the x86 opcodes.
-- crc
Looks ok to me; just be careful to adjust this if you reorganize the
system variables later.
> These changes seem to be acceptable to rfans.4 but docstring: was
> broken, the original version crashed:
>
> : docstring:
> x' if drop here @which :doc ! ]
> ;then word?
> ;
>
> I could not locate the word @which , so I tried :
>
> : docstring:
> x' if drop here @ which :doc ! ]
> ;then word?
> ;
>
Try:
: docstring:
x' if drop here which @ :doc ! ]
;then word?
;
> This does not crash but there were no help available:
>
> D:\DLR\R4\NOW\bin>ur4 4\rx.4 4\rf.4 4\help.ur4
> ok
> help help
> Sorry, no help was found
> ok
>
> The new colon definition for .macro is not quite working yet.
> If .inline is meant for optimisation, it should stay for further
> study.
>
> word? looks so simple, this colon definition was tried:
>
> : word? vector [ $e9 1, 0 , ] drop drop 0 ;
>
> It seems to work with rx.4 and rf.4 but rfans.4 was broken.
>
> Potentially the kernel words count can be down to 21 if .macro and
> word? can be defined as colon words.
I'll have to take a look at this tomorrow.
> Left paren can be defined as colon word too but it is intentionally
> left in the kernel, so the minimum number of kernel words is 20, or is
> it ?
It may be possible to squeeze ; out of the kernel as well, defining it
in terms of ;; and [
It should also be possible to redo >string in higher-level forth as
well.
> Cheers,
>
> 123forth
-- crc
> Try this:
>
> : docstring:
> x' if drop here which @ :doc ! ]
> ;then word?
> ;
>
Yes, this works. BTW, where is that @which implemented?
> It may be possible to squeeze ; out of the kernel as well,
> defining it in terms of ;; and [
20 1-
ok
> It should also be possible to redo >string in higher-level forth as
> well.
1- .
18 ok ;-)
Cheers,
123forth
Something like:
: ; ( - )
[ ' ;; compile ' [ compile ] ;; [
' .self last @ :class !
But how are ' last @ :class and ! defined?
Cheers,
123forth
Up until you have these defined, you can terminate defintions with:
;; [
e.g.,
: h0 1 sysvarn ;; [
: base 2 sysvarn ;; [
: >in 3 sysvarn ;; [
: class 4 sysvarn ;; [
: state 5 sysvarn ;; [
: which 6 sysvarn ;; [
: whitespace 7 sysvarn ;; [
: last 8 sysvarn @ ;; [
: tib 9 sysvarn @ ;; [
Though after a bit more thought it does seem cleaner to leave ; in the
kernel, and move ;; out:
: ;; $c3 1, ;
' .self last @ :class ! ( make the last word immediate )
(does basically the same as the assembly, only without the tail call
elimination, which could be patched in later if needed.)
-- crc
> I just tried RetroForth 9.2.10, it is working perfectly.
> This is ur4 bug, NOT Retro.
> I'm sorry for the confusion.
Further investigation revealed that maybe ur4 picked up that trait
from RetroForth somewhere along the path.
A comment was added to the first line of the file rx\bootstrap from
RetroForth 9.2.10 like this:
inline ( optimized words )
There is a tab between inline and (
build windows
generated rf-windows.exe that crashed
Thanks,
123forth