Hello,
I'm in no way an expert in the Forth langage. I've just begun to learn
it and it pleases me so far. Because of my lack of expertise in this
field, maybe I'm not the ideal target for DuskOS, but I'd like to try
anyway.
I was wondering about the inclusion of ANS forth implementation into
DuskOS. I don't know much about Forth, but I already know it's a "touchy"
subject, and some people just believe forth shouldn't be standardised
and people can just customise Forth for their own needs.
But at least some basic words can help to get into the OS. For example I
couldn't just use a basic DO LOOP which is described in the "Starting
Forth" book by Leo Brodie. I understand we can use a BEGIN WHILE REPEAT
structure, but it's a bit more complicated:
> : SIMPLELOOP CR 0 BEGIN DUP 11 < WHILE DUP 5 * . CR 1+ REPEAT ;
instead of just
> : SIMPLELOOP CR 11 0 DO 5 I * . CR LOOP ;
Other typical forth words are not implemented: SEE, WORDS...
is it planned in a later stage?
Since I'm also interested in Uxn, I've found the UF Forth rather easy to
start with, and it also support most ANS Forth words.
Well, here's the magic of forth. You could implement those words! Just add the necessary definitions into a file, and then if you wanted to use them, theoretically one could just `f<<? /lib/ans.fs` to use them.
On Sun, Feb 12, 2023, at 10:21 AM, farfadet10@gmx.fr wrote:
> Hello,>> I'm in no way an expert in the Forth langage. I've just begun to learn > it and it pleases me so far. Because of my lack of expertise in this > field, maybe I'm not the ideal target for DuskOS, but I'd like to try > anyway.
Dusk's documentation begins where Starting Forth ends. If you're interested in
diving into Dusk OS, I guess that makes you a target :)
> I was wondering about the inclusion of ANS forth implementation into > DuskOS. I don't know much about Forth, but I already know it's a "touchy" > subject, and some people just believe forth shouldn't be standardised > and people can just customise Forth for their own needs.
I'm not emotionally involved in this decision, so it can be discussed openly. My
opinion is that the main benefit of ANS conformity is compatibility with
existing ANS Forth code and its main drawback is noise.
I don't know of any existing ANS Forth code that would be worth the trouble, so
I didn't give myself the trouble. I hadn't though of the education angle before,
so that's new to me. I would gladly discuss it, but because I have answers for
the specific examples below, I thought we could begin by evacuating those
questions first.
> But at least some basic words can help to get into the OS. For example I > couldn't just use a basic DO LOOP which is described in the "Starting > Forth" book by Leo Brodie. I understand we can use a BEGIN WHILE REPEAT > structure, but it's a bit more complicated:>>> : SIMPLELOOP CR 0 BEGIN DUP 11 < WHILE DUP 5 * . CR 1+ REPEAT ; >> instead of just>>> : SIMPLELOOP CR 11 0 DO 5 I * . CR LOOP ;
Dusk has counted loops. Until recently, it only had the "countdown" version
( >r begin .. next, decreasing RS+0 until zero ), but I've recently added
generic iterators to Dusk and it now has a functional equivalent to DO .. LOOP,
but it's "for2 .. next" instead. See doc/iter for details.
> Other typical forth words are not implemented: SEE, WORDS...>> is it planned in a later stage?
"words" already exists in lib/meta (see doc/lib/meta), but it's of dubious
utility. I really don't see the point of printing this list which is really
verbose.
"see" is a more interesting subject. Dusk's implementation is a bit peculiar.
It's a STC forth[1] that takes full advantage of being a STC by sprinkling a lot
of native (x86, etc.) code around. This makes the implementation of "see" a bit
less straightforward. But not impossible! It's just that such an implementation
is basically the equivalent of a disassembler. There is no disassembler yet in
Dusk, but this is certainly planned and a high priority item. Once Dusk has a
disassembler, a word like "see" will be easier to implement.
> Since I'm also interested in Uxn, I've found the UF Forth rather easy to > start with, and it also support most ANS Forth words.
I agree that if you're inexperienced and trying to follow along Starting Forth
in Dusk, you might end up having an unnecessarily bad time. It might be worth it
to maintain some kind of "lib/ans" library, as Arcade Wise suggests, for this
purpose.
Regards,
Virgil
[1]: https://www.bradrodriguez.com/papers/moving1.htm
Ok, so I guess creating a specific file with code for ANS is the way to go. I don't think I could do it myself, but I'll have a look anyway... it can be an interesting challenge...
> but I've recently added generic iterators to Dusk and it now has a functional equivalent to DO .. LOOP, but it's "for2 .. next" instead. See doc/iter for details.
yes, it works, if I type
: foo 1 11 for2 5 i * . spc> next ;
The doc also said "for2" takes 2 arguments, a "high" number and then a "low" number and counts
from "low" up to "high".
but in your exemple the low number comes first:
: foo 12 18 for2 i . spc> next ;
I've tried to mimic the original ans for do loop, by adding a ans.fs file.
it just contains
:iterator do ( lo hi -- )
swap 2dup < if to j to i begin yield 1 to+ i i j >= until else 2drop then unyield ;
: loop [compile] yield [compile] again [compile] then
12 r+, 4 [rcnt] +! 0 to@! _breaklbl ?dup drop ; immediate
: cr nl> ;
(I've added a swap after the do to have it behave like in ANS forth, but for the rest I've just copied your code)
I called it with:
f<< lib/ans.fs
: foo 11 0 do 5 i * . cr loop ;
and now it works :)
On Fri, Feb 24, 2023, at 11:42 AM, farfadet10@gmx.fr wrote:
> Ok, so I guess creating a specific file with code for ANS is the way to > go. I don't think I could do it myself, but I'll have a look anyway... > it can be an interesting challenge...>>> but I've recently added generic iterators to Dusk and it now has a functional equivalent to DO .. LOOP, but it's "for2 .. next" instead. See doc/iter for details.>> yes, it works, if I type >> : foo 1 11 for2 5 i * . spc> next ;>>> The doc also said "for2" takes 2 arguments, a "high" number and then a > "low" number and counts> from "low" up to "high".>> but in your exemple the low number comes first:>> : foo 12 18 for2 i . spc> next ;>>>> I've tried to mimic the original ans for do loop, by adding a ans.fs file.>> it just contains>> :iterator do ( lo hi -- )> swap 2dup < if to j to i begin yield 1 to+ i i j >= until else 2drop > then unyield ;>> : loop [compile] yield [compile] again [compile] then> 12 r+, 4 [rcnt] +! 0 to@! _breaklbl ?dup drop ; immediate>> : cr nl> ;>> (I've added a swap after the do to have it behave like in ANS forth, > but for the rest I've just copied your code)>> I called it with:>> f<< lib/ans.fs>>> : foo 11 0 do 5 i * . cr loop ;>>> and now it works :)
Copy-pasting is so barbaric :) you could have achieved the same with:
: do compile swap [compile] for2 ; immediate
alias next loop immediate
Regards,
Virgil
On Fri, Feb 24, 2023, at 11:52 AM, Virgil Dupras wrote:
> On Fri, Feb 24, 2023, at 11:42 AM, farfadet10@gmx.fr wrote:>> Ok, so I guess creating a specific file with code for ANS is the way to >> go. I don't think I could do it myself, but I'll have a look anyway... >> it can be an interesting challenge...>>>>> but I've recently added generic iterators to Dusk and it now has a functional equivalent to DO .. LOOP, but it's "for2 .. next" instead. See doc/iter for details.>>>> yes, it works, if I type >>>> : foo 1 11 for2 5 i * . spc> next ;>>>>>> The doc also said "for2" takes 2 arguments, a "high" number and then a >> "low" number and counts>> from "low" up to "high".>>>> but in your exemple the low number comes first:>>>> : foo 12 18 for2 i . spc> next ;>>>>>>>> I've tried to mimic the original ans for do loop, by adding a ans.fs file.>>>> it just contains>>>> :iterator do ( lo hi -- )>> swap 2dup < if to j to i begin yield 1 to+ i i j >= until else 2drop >> then unyield ;>>>> : loop [compile] yield [compile] again [compile] then>> 12 r+, 4 [rcnt] +! 0 to@! _breaklbl ?dup drop ; immediate>>>> : cr nl> ;>>>> (I've added a swap after the do to have it behave like in ANS forth, >> but for the rest I've just copied your code)>>>> I called it with:>>>> f<< lib/ans.fs>>>>>> : foo 11 0 do 5 i * . cr loop ;>>>>>> and now it works :)>> Copy-pasting is so barbaric :) you could have achieved the same with:>> : do compile swap [compile] for2 ; immediate> alias next loop immediate>> Regards,> Virgil
Oh, and just to be clear: I think it's cool that you're looking into building this layer. It's a good, useful task.