R R> R@ 2R> etc. are a poor mans tool. Isn't it time toreplace them with >S S> S@ 2S> etc. and terminate all worries
In hindsight my locals definition is not convincing,
because carnal knowledge about the behaviour of
the return stack is required.
"
: 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
"
Imagine a RiscV processor. Every low level word, doesn't use
the return stack, but uses a link register, so the above
probably doesn't work on a riscV.
To abstract of this you need an extra stack, for example
the "system stack" from Marcel Hendrix.
In the above it is necessary to temporarily store the return
information
: local
R> \ Return address
SWAP DUP >R @ >R \ Abuse return stack for extra storage
>R \ Restore return address
CO
R> R> ! \ Further abuse
;
With the "system stack" it becomes :
"
: local DUP >S @ >S CO S> S> ! ;
VARIABLE A
VARIABLE B
: divide
A local
B local
B ! A ! A @ B @ /
. CR
;
15 3 divide
"
Don't ask me these questions:
If you have an extra stack, why not use a locals stack?
R R> R@ 2R> etc. are a poor mans tool. Isn't it time toreplace them with >S S> S@ 2S> etc. and terminate all worries
these facilities interfere with other stuff?
(I get 30 registers in RISCV that can serve as a stack pointer.)
Groetjes Albert.
In hindsight my locals definition is not convincing, because carnal
knowledge about the behaviour of the return stack is required.
(I get 30 registers in RISCV that can serve as a stack pointer.)
In some models of the RISCV, only 14, I think. And in almost all
models, 8 of them are more efficient to address than the rest, because
of the compressed instruction format.
albert@spenarnc.xs4all.nl writes:
(I get 30 registers in RISCV that can serve as a stack pointer.)
In some models of the RISCV, only 14, I think.
And in almost all
models, 8 of them are more efficient to address than the rest, because
of the compressed instruction format.
Anyway, it is hard to come up with code that needs more than 4+1
stacks in its critical path.
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal
knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having
trouble seeing is how the locals get popped in case of an exception.
Do you not need to implement something like (LOCAL) ?I don't use locals. If someone adds it to a ciforth application, let
Paul Rubin <no.email@nospam.invalid> writes:
albert@spenarnc.xs4all.nl writes:
(I get 30 registers in RISCV that can serve as a stack pointer.)
All 31 can serve as a stack pointer, but not all at the same time.
You want at least two registers for temporary values, for implementing
a word such as "+". And you typically want to keep the top-of-stack
of many stacks in a register, too. Or several stack items.
In some models of the RISCV, only 14, I think.
There is the E subspecification of the RISC-V specification with 16 >registers. I don't know if anybody has implemented this.
And in almost all
models, 8 of them are more efficient to address than the rest, because
of the compressed instruction format.
More efficient in code size. In instruction execution, typically the
same speed.
- anton
There is the E subspecification of the RISC-V specification with 16 registers. I don't know if anybody has implemented this.
More efficient in code size. In instruction execution, typically the
same speed.
In article <87semzmwok.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal
knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having
trouble seeing is how the locals get popped in case of an exception.
I showed it as an example of the pretty convincing usefulness
of CO. For this the example had to have to be portable.
A simpler example would be
\ Temporary set some-rounding-mode for the duration of this word.
: rounding set-rounding-mode CO truncate-mode set-rounding-mode ;
...
anton@mips.complang.tuwien.ac.at (Anton Ertl) writes:
There is the E subspecification of the RISC-V specification with 16
registers. I don't know if anybody has implemented this.
The CH32V003 uses it and is of some interest as a Forth target. It has
16k of flash and 2k of ram.
https://www.cnx-software.com/2022/10/22/10-cents-ch32v003-risc-v-mcu-offers-2kb-sram-16kb-flash-in-sop8-to-qfn20-packages/
https://dl.acm.org/doi/10.1145/3578360.3580261 indicates some minor
speed differences, not always favorable.
On 27/03/2025 11:02 pm, albert@spenarnc.xs4all.nl wrote:
In article <87semzmwok.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal
knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having
trouble seeing is how the locals get popped in case of an exception.
I showed it as an example of the pretty convincing usefulness
of CO. For this the example had to have to be portable.
A simpler example would be
\ Temporary set some-rounding-mode for the duration of this word.
: rounding set-rounding-mode CO truncate-mode set-rounding-mode ;
...
Actually it was that example which caused me to *not* go ahead
and implement ;: in the kernel despite a cost of only one header.
How many calls to 'rounding' will you encounter in an application?
My guess is one. The usual example is HEX: but I already had (H.N)
that's more flexible. For me at least locals was more credible but
again it fell into a range. For a single use I'd do it manually;
for extensive use (where exceptions etc are likely) a proper locals
may be the only option. OTOH such decision-making is exactly what
Forth has always been about.
In article <19029ff0c8e7cf53335fe62639308e7f92d10240@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 27/03/2025 11:02 pm, albert@spenarnc.xs4all.nl wrote:
In article <87semzmwok.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal
knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having
trouble seeing is how the locals get popped in case of an exception.
I showed it as an example of the pretty convincing usefulness
of CO. For this the example had to have to be portable.
A simpler example would be
\ Temporary set some-rounding-mode for the duration of this word.
: rounding set-rounding-mode CO truncate-mode set-rounding-mode ;
...
Actually it was that example which caused me to *not* go ahead
and implement ;: in the kernel despite a cost of only one header.
How many calls to 'rounding' will you encounter in an application?
`rounding: is an internal word in the fp package and it is used 4
times.
My guess is one. The usual example is HEX: but I already had (H.N)
that's more flexible. For me at least locals was more credible but
again it fell into a range. For a single use I'd do it manually;
for extensive use (where exceptions etc are likely) a proper locals
may be the only option. OTOH such decision-making is exactly what
Forth has always been about.
You can't argue with
:NONAME ." Before " .S CO ." After " .S ;
' proc_contains_Heisenbug decorated
Study python for the concept of decoration.
This alone makes CO a worthwhile addition.
I have (D.H) that uses CO. Undoubtedly your (H.N) is more complicated.
On 28/03/2025 8:38 pm, albert@spenarnc.xs4all.nl wrote:
In article <19029ff0c8e7cf53335fe62639308e7f92d10240@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 27/03/2025 11:02 pm, albert@spenarnc.xs4all.nl wrote:
In article <87semzmwok.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal >>>>>> knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having
trouble seeing is how the locals get popped in case of an exception.
I showed it as an example of the pretty convincing usefulness
of CO. For this the example had to have to be portable.
A simpler example would be
\ Temporary set some-rounding-mode for the duration of this word.
: rounding set-rounding-mode CO truncate-mode set-rounding-mode ;
...
Actually it was that example which caused me to *not* go ahead
and implement ;: in the kernel despite a cost of only one header.
How many calls to 'rounding' will you encounter in an application?
`rounding: is an internal word in the fp package and it is used 4
times.
My guess is one. The usual example is HEX: but I already had (H.N)
that's more flexible. For me at least locals was more credible but
again it fell into a range. For a single use I'd do it manually;
for extensive use (where exceptions etc are likely) a proper locals
may be the only option. OTOH such decision-making is exactly what
Forth has always been about.
You can't argue with
:NONAME ." Before " .S CO ." After " .S ;
' proc_contains_Heisenbug decorated
Study python for the concept of decoration.
This alone makes CO a worthwhile addition.
I have (D.H) that uses CO. Undoubtedly your (H.N) is more complicated.
Possibly though much of the complication lies in what it needs to do - as >opposed to radix save/restore.
\ Convert unsigned number u to a hexadecimal string c-addr2 u2 in the
\ HOLD buffer beginning with the least-significant digits. Exactly
\ +n hexadecimal characters are returned with any unused positions
\ being filled with character '0'. BASE is preserved.
: (H.N) ( u +n -- c-addr2 u2 )
base @ >r hex <# 0 tuck ?do # loop #> r> base ! ;
In article <4b84665e38d5a523efc2479f48338ed55d142185@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 28/03/2025 8:38 pm, albert@spenarnc.xs4all.nl wrote:
In article <19029ff0c8e7cf53335fe62639308e7f92d10240@i2pn2.org>,
dxf <dxforth@gmail.com> wrote:
On 27/03/2025 11:02 pm, albert@spenarnc.xs4all.nl wrote:
In article <87semzmwok.fsf@nightsong.com>,
Paul Rubin <no.email@nospam.invalid> wrote:
albert@spenarnc.xs4all.nl writes:
In hindsight my locals definition is not convincing, because carnal >>>>>>> knowledge about the behaviour of the return stack is required.
It's ok if it's for a specific implementation. But what I'm having >>>>>> trouble seeing is how the locals get popped in case of an exception. >>>>>
I showed it as an example of the pretty convincing usefulness
of CO. For this the example had to have to be portable.
A simpler example would be
\ Temporary set some-rounding-mode for the duration of this word.
: rounding set-rounding-mode CO truncate-mode set-rounding-mode ;
...
Actually it was that example which caused me to *not* go ahead
and implement ;: in the kernel despite a cost of only one header.
How many calls to 'rounding' will you encounter in an application?
`rounding: is an internal word in the fp package and it is used 4
times.
My guess is one. The usual example is HEX: but I already had (H.N)
that's more flexible. For me at least locals was more credible but
again it fell into a range. For a single use I'd do it manually;
for extensive use (where exceptions etc are likely) a proper locals
may be the only option. OTOH such decision-making is exactly what
Forth has always been about.
You can't argue with
:NONAME ." Before " .S CO ." After " .S ;
' proc_contains_Heisenbug decorated
Study python for the concept of decoration.
This alone makes CO a worthwhile addition.
I have (D.H) that uses CO. Undoubtedly your (H.N) is more complicated.
Possibly though much of the complication lies in what it needs to do - as
opposed to radix save/restore.
\ Convert unsigned number u to a hexadecimal string c-addr2 u2 in the
\ HOLD buffer beginning with the least-significant digits. Exactly
\ +n hexadecimal characters are returned with any unused positions
\ being filled with character '0'. BASE is preserved.
: (H.N) ( u +n -- c-addr2 u2 )
base @ >r hex <# 0 tuck ?do # loop #> r> base ! ;
Same idea.
( Generate string with hex format of DOUBLE of LEN digits)
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ;
: (DH.) HEX: <# 1- 0 ?DO # I 4? LOOP # #> ;
( Derive B. H. DH. from them)
Only HEX: DEC: is made a separate facility:
: HEX: R> BASE @ >R >R HEX CO R> BASE ! ;
: DEC: R> BASE @ >R >R DECIMAL CO R> BASE ! ;
To live on and fight another day, e.g. in formatting, or in at-xy that outputs a position in decimal.
The question then is can HEX: DEC: be justified. While you might because
CO exists, I'm not sure I could.
Sysop: | DaiTengu |
---|---|
Location: | Appleton, WI |
Users: | 1,030 |
Nodes: | 10 (1 / 9) |
Uptime: | 73:28:28 |
Calls: | 13,351 |
Calls today: | 3 |
Files: | 186,574 |
D/L today: |
5,670 files (1,490M bytes) |
Messages: | 3,358,854 |