Sysop: | Amessyroom |
---|---|
Location: | Fayetteville, NC |
Users: | 28 |
Nodes: | 6 (0 / 6) |
Uptime: | 47:58:12 |
Calls: | 422 |
Files: | 1,024 |
Messages: | 90,420 |
This is gonna get me lose a lot of subscribers, but it has been a hot
topic on YT. So I had to address it sooner or later.
Still, there is a little known implementation of Locals that looks like
Chuck Moore could have invented it - if he had wanted to.
Anyways, I expanded it into a fully Forth 2012 compliant 4tH
implementation, which essentially means you can now port your locals
infested programs to 4tH without ever changing a line.
I hope you are happy now :)
https://www.youtube.com/watch?v=Y7cax2fDS84
Hans Bezemer--
This is gonna get me lose a lot of subscribers, but it has been a hot
topic on YT. So I had to address it sooner or later.
Still, there is a little known implementation of Locals that looks like
Chuck Moore could have invented it - if he had wanted to.
Anyways, I expanded it into a fully Forth 2012 compliant 4tH
implementation, which essentially means you can now port your locals
infested programs to 4tH without ever changing a line.
I hope you are happy now :)
https://www.youtube.com/watch?v=Y7cax2fDS84
Hans Bezemer
On 08-01-2025 17:27, albert@spenarnc.xs4all.nl wrote:
I was impressed with the Behringer solution.
(I didn't care about the politically correct solution.)
====================================
: local{ R> SWAP DUP >R @ >R >R ;
: }global R> R> R> ! >R ;
=================
But I can do you one better.
Remember the word ;: from colorforth. That is actually a coroutine call.
I call it CO. (Present in ciforth since the year 00)
<snipped>
With CO the example become
---------------------------------------
: LOCAL R> SWAP DUP >R @ >R >R CO R> R> ! ;
VARIABLE A
VARIABLE B
: divide
A LOCAL
B LOCAL
B ! A ! A @ B @ /
. CR
;
15 3 divide
---------------------------------------
This saves a definition and a word-of-code, and a line for every
LOCAL used. Now that is closer to what Chuck Moore would have used.
Remember for Moore CO aka ;: is a standard word.
CO is not standard but it should be, and it is elementary as hell.
Couldn't find the source for either CO or ;: but I got some primitive,
high level form of co-routine in 4tH:
====================================
: yield r> r> swap >r >r ; \ remember that ; compiles EXIT!
aka rdrop grab \ so add a [FORCE] when needed. >====================================
Can't say how they measure up. But I guess co-routines is something--
Chuck would like - since it's something you can implement quite easily.
So yes, I agree Chuck wouldn't waste that line ;-)
Hans Bezemer
This specific version of XCHG causes an implicit LOCK on the bus and
will
execute slower than (probably) expected. (For those readers that were
getting fancy ideas).
On 9/01/2025 9:50 am, dxf wrote:
On 9/01/2025 5:11 am, Hans Bezemer wrote:
On 08-01-2025 17:27, albert@spenarnc.xs4all.nl wrote:
( my CO variant, using the return address)
: LOCAL R> SWAP DUP >R @ >R EXECUTE R> R> ! ;
VARIABLE A
VARIABLE B
\ I'm paranoid :)
8 a !
7 b !
: divide
A LOCAL
B LOCAL
B ! A ! A @ B @ /
. CR
;
15 3 divide a ? b ?
\ it doesn't mean they're not out to get you
Wow! This works! Can't say how solid it is.. but still!
Alas not portable.
...
R EXECUTE doesn't work for ciforth.There is no guarantee that a saved interpreter pointer on the
More portable
: (lx) >R ;
: LOCAL R> SWAP DUP >R @ >R (lx) R> R> ! ;
VARIABLE A
VARIABLE B
8 A !
7 B !
: divide ( a b -- )
A LOCAL
B LOCAL
B ! A ! A @ B @ /
. CR
;
15 3 divide A ? B ?
On 9/01/2025 9:50 am, dxf wrote:
More portable
: (lx) >R ;
On 09-01-2025 13:42, dxf wrote:
There is no guarantee that a saved interpreter pointer on the
stack is an execution token.
Nope - in ANS-Forth it is listed as:
nest-sys; definition calls; implementation dependent
So - that's obvious. But in 4tH it works out. And defining it as >R
works out as well. BTW, I've tested the thing - and it holds up.
I got my work cut out for a next episode! On co-routines! ;-)
Hans Bezemer
BTW, I've heard there are implementations where nest-sys aren't even on
the return stack. The standard seems to confirm this:
return stack: A stack that _MAY_BE_ used for program execution nesting, >do-loop execution, temporary storage, and other purposes.
.. and sorry to spoil the fun, but what we're doing here is illegal anyways:
"A program shall _NOT_ access values on the return stack (using R@, R>,
2R@ or 2R>) that it _DID_NOT_ place there using >R or 2>R;"
In other words: your mileage may (be) very, very illegal.
, or DO and LOOP .
Hans Bezemer
In article <nnd$75b7a2a4$616fdd6b@4f60b314ce95c9b9>,<SNIP>
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
Orhttps://www.youtube.com/watch?v=Y7cax2fDS84
I was impressed with the Behringer solution.
(I didn't care about the politically correct solution.)
====================================
: local{ R> SWAP DUP >R @ >R >R ;
: }global R> R> R> ! >R ;
=================
But I can do you one better.
Remember the word ;: from colorforth. That is actually a coroutine call.
I call it CO. (Present in ciforth since the year 00)
An example of its use is the following:
:NONAME .S ; ' LIST decorated
decorated is not the point. The noname decorates LIST with
the anonymous function, so that the stack is printed, before LIST.
Now we go one step further:
:NONAME .S CO ." AFTER " .S ; ' LIST decorated
The noname decorates LIST with the anonymous function, so that the
stack is printed, before, but now noname is suspended, LIST is
executed as a coroutine, and afterword the stack is printed once more.
With CO the example become
---------------------------------------
: LOCAL R> SWAP DUP >R @ >R >R CO R> R> ! ;
VARIABLE A
VARIABLE B
: divide
A LOCAL
B LOCAL
B ! A ! A @ B @ /
. CR
;
15 3 divide
---------------------------------------
Groetjes Albert--
Great. While I've seen co-routines mentioned, examples were rare so I
tended to ignore it.
On 14-03-2025 13:51, albert@spenarnc.xs4all.nl wrote:
Because it is a design mistake of a language to give the same name to
two different functionalities, merely because they happen to have the
same behaviour in a certain implementation.
COUNT? For C@+? Anybody? ;-)
Hans Bezemer
On 14-03-2025 13:51, albert@spenarnc.xs4all.nl wrote:
COUNT? For C@+? Anybody? ;-)
On 14-03-2025 13:51, albert@spenarnc.xs4all.nl wrote:
COUNT? For C@+? Anybody? ;-)
here 1 c, 2 c, 3 c, 4 c,
{ 4 0 do count . loop drop }
i. {} --> 1 2 3 4No what is that supposed to mean?
FigForth COUNT normally operates on a 'byte' counted string but
can also be used to fetch a character and bump address.
meGroetjes Albert
i. {} --> 1 2 3 4No what is that supposed to mean?
On 9/01/2025 6:13 am, albert@spenarnc.xs4all.nl wrote:
In article <nnd$032b844d$734ee136@776df242e330d1d2>,
Hans Bezemer <the.beez.speaks@gmail.com> wrote:
On 08-01-2025 17:27, albert@spenarnc.xs4all.nl wrote:
I was impressed with the Behringer solution.
(I didn't care about the politically correct solution.)
====================================
: local{ R> SWAP DUP >R @ >R >R ;
: }global R> R> R> ! >R ;
=================
But I can do you one better.
Remember the word ;: from colorforth. That is actually a coroutine call. >>>> I call it CO. (Present in ciforth since the year 00)
<snipped>
With CO the example become
---------------------------------------
: LOCAL R> SWAP DUP >R @ >R >R CO R> R> ! ;
VARIABLE A
VARIABLE B
: divide
A LOCAL
B LOCAL
B ! A ! A @ B @ /
. CR
;
15 3 divide
---------------------------------------
This saves a definition and a word-of-code, and a line for every
LOCAL used. Now that is closer to what Chuck Moore would have used.
Remember for Moore CO aka ;: is a standard word.
CO is not standard but it should be, and it is elementary as hell.
Couldn't find the source for either CO or ;: but I got some primitive,
high level form of co-routine in 4tH:
====================================
: yield r> r> swap >r >r ; \ remember that ; compiles EXIT!
aka rdrop grab \ so add a [FORCE] when needed.
====================================
That is the equivalent in high level code.
In assembler, assuming ESI is the interpreter pointer and EBP is the return >> stack pointer:
CODE CO
XCHG ESI,[EBP]
NEXT,
END-CODE
In assembler the return stack is uncluttered.
...
Just to clarify CO (coroutines) and
: ;: >r ;
are different albeit related beasts. So which one is Moore's?
BTW the latter is equivalent to the 'docol' run-time in most DTC forth.
In my case I'd just need to give the code fragment a name. But is this >latter ;: worth it? Its use seems to be restricted to restoring state
when a word completes. It's not a "coroutine.
Can't say how they measure up. But I guess co-routines is something
Chuck would like - since it's something you can implement quite easily.
So yes, I agree Chuck wouldn't waste that line ;-)
Hans Bezemer
On 12/03/2025 8:14 am, Hans Bezemer wrote:the data stack, ;: works.. In an earlier version I moved the return
...
Since the LOCAL definition has already moved the return address to
But of equal value? As you say YIELD can be made to do ;:
On 12-03-2025 11:29, albert@spenarnc.xs4all.nl wrote:
In article <858080e0b3faa16a4b9ba24e3b34e12a555494b4@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 12/03/2025 8:14 am, Hans Bezemer wrote:
...
This discussion is typical of Forth. A specification of a word
is essential, then I can implement it.
I quarrel about the meaning of ;: , and you casually mention
"do ;:" as if everybody knows what this is supposed to mean.
This is the specification of CO .
Note how the stack effect is ( -- ) .
For most Forthers this is a apparently a sufficient specification.
Oh, it clarifies everything!
If we assume ;: to be "EXECUTE" and YIELD to be "R> EXECUTE" then ;: can
be coded as ">R YIELD" and YIELD (aka CO) as "R> ;:".
And I can assure you that works.. No matter which definition you apply
to those words - either inlined or high level.
I think that definitely proves the two words are intimately related ;-)
Hans Bezemer
On 12/03/2025 9:29 pm, albert@spenarnc.xs4all.nl wrote:
In article <858080e0b3faa16a4b9ba24e3b34e12a555494b4@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 12/03/2025 8:14 am, Hans Bezemer wrote:the data stack, ;: works.. In an earlier version I moved the return
...
Since the LOCAL definition has already moved the return address to
address back to the return stack and executed YIELD. Which (of course) >> worked. So they're not that far apart IMHO.
But of equal value? As you say YIELD can be made to do ;:
This discussion is typical of Forth. A specification of a word
is essential, then I can implement it.
I quarrel about the meaning of ;: , and you casually mention
"do ;:" as if everybody knows what this is supposed to mean.
This is the specification of CO .
Note how the stack effect is ( -- ) .
For most Forthers this is a apparently a sufficient specification.
"
CO
STACKEFFECT:
DESCRIPTION: []
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed. The return stack must not be engaged, such as between >R and
R> , or DO and LOOP .
It seems a digression to formally specify something you previously
commented on and whose implementation worked on all popular forths.
But to borrow yours, the definition would go something like:
;: ( nest-sys -- )
Return to the caller specified by nest-sys, suspending [etc etc]
On 13-03-2025 00:04, dxf wrote:
On 12/03/2025 9:29 pm, albert@spenarnc.xs4all.nl wrote:
In article <858080e0b3faa16a4b9ba24e3b34e12a555494b4@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 12/03/2025 8:14 am, Hans Bezemer wrote:the data stack, ;: works.. In an earlier version I moved the return >>> address back to the return stack and executed YIELD. Which (of course)
...
Since the LOCAL definition has already moved the return address to
worked. So they're not that far apart IMHO.
But of equal value? As you say YIELD can be made to do ;:
This discussion is typical of Forth. A specification of a word
is essential, then I can implement it.
I quarrel about the meaning of ;: , and you casually mention
"do ;:" as if everybody knows what this is supposed to mean.
This is the specification of CO .
Note how the stack effect is ( -- ) .
For most Forthers this is a apparently a sufficient specification.
"
CO
STACKEFFECT:
DESCRIPTION: []
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed. The return stack must not be engaged, such as between >R and >>> R> , or DO and LOOP .
It seems a digression to formally specify something you previously
commented on and whose implementation worked on all popular forths.
But to borrow yours, the definition would go something like:
;: ( nest-sys -- )
Return to the caller specified by nest-sys, suspending [etc etc]
I tend to agree with both of you. Albert-wise, yes, if there is no
formal specification it's hard to identify - or not to identify. AKA -
it isn't the same or it isn't.
IMHO, we've been far too comfortable with the fact that when we call a
word, we create a nest-sys on the Return stack, e.g. (from the ANS-Forth >standard):
6.1.1370 EXECUTE
CORE
( i*x xt -- j*x )
Remove xt from the stack and perform the semantics identified by it.
Aren't we missing anything? Like:
( R: -- nest-sys)
Call me stupid, but I have had trouble wrapping my head around the
inlined and word definitions of YIELD - and why they worked identically
(at least on 4tH):
inline: R> EXECUTE
word: : YIELD R> R> SWAP >R >R ;
Or ;: for that matter:
inline: EXECUTE
word: : ;: >R ;
And unless we express the definitions of CO and YIELD formally in these
terms (defining and specifying return stack effects), we shall never
agree whether they're the same or not. And that is where I agree with DXF..
When I abstract both ;: and YIELD, I'd say they're "identical" -
*except* ;: takes its nest-sys|xt from the data stack, while YIELD gets
its net-sys from the return stack.
Ok, roast me.. ;-)
Hans Bezemer--
Code equivalence is nothing new. It's for sake of clarity that Fig-forth defined both I and R@ despite them sharing the same code. Forth-83 made
On 14/03/2025 1:35 am, sjack wrote:
dxf <dxforth@gmail.com> wrote:
Code equivalence is nothing new. It's for sake of clarity that Fig-forth >>> defined both I and R@ despite them sharing the same code. Forth-83 made >>>
To be a little more correct FigForth v1.0 did indeed define
I and R (not R@) to share same code. My FigForth still does.
I believe R@ comes from one of the standards,e.g. Forth-83
AFAIK there was no R or R@ prior to FigForth. MicroForth, Kitt Peat Forth, >'Starting Forth' simply used I for that. It's unclear how FigForth came to >have R or Forth-79 came to have R@ .
Because it is a design mistake of a language to give the same name to
two different functionalities, merely because they happen to have the
same behaviour in a certain implementation.
1FOO 2BAT 3boo 4CAT 5BAR--
GOO 1FOO 2BAT 3boo 4CAT 5BAR GU