I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals.
: H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
: HEX:
BASE @ >R
HEX CO
R> BASE !
;
This doesn't work. The return address is in the way,
assuming there is a return address on the stack.
This also makes the code implementation dependant.
(Marcel Hendrix's >S and S> however would work.)
: HEX:
R> BASE @ >R >R
HEX CO
R> BASE !
;
I hate TUCK ( a b -- b a b )
but I like RTUCK
"save the top of the stack under the return address of a high
level word."
: HEX:
BASE @ RTUCK
HEX CO
R> BASE !
;
Groetjes Albert
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals.
: H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals.
: H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
go back to regular methods?
: (H.N) ( u +n -- a2 u2 )
base @ >r hex <# 0 tuck ?do #
i 1+ 4 mod 0= if [char] , hold then loop #>
over c@ [char] , = 1 and /string r> base ! ;
: (H.) ( u -- adr len ) [ 2 cells ] literal (h.n) ;
: (HW.) ( u -- adr len ) 4 (h.n) ;
: (HB.) ( u -- adr len ) 2 (h.n) ;
: (HD.) ( ud -- adr len ) (h.) dup >r holds (h.) r> 1+ negate /string ;
-1 (h.) type FFFF,FFFF,FFFF,FFFF ok
-1 (hw.) type FFFF ok
-1 (hb.) type FF ok
-1 -1 (hd.) type FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF ok
In article <69b99106$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals. >>> : H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
go back to regular methods?
: (H.N) ( u +n -- a2 u2 )
base @ >r hex <# 0 tuck ?do #
i 1+ 4 mod 0= if [char] , hold then loop #>
over c@ [char] , = 1 and /string r> base ! ;
: (H.) ( u -- adr len ) [ 2 cells ] literal (h.n) ;
: (HW.) ( u -- adr len ) 4 (h.n) ;
: (HB.) ( u -- adr len ) 2 (h.n) ;
: (HD.) ( ud -- adr len ) (h.) dup >r holds (h.) r> 1+ negate /string ;
-1 (h.) type FFFF,FFFF,FFFF,FFFF ok
-1 (hw.) type FFFF ok
-1 (hb.) type FF ok
-1 -1 (hd.) type FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF ok
HEX: was the proposal. The other words are illustration.
Exercise for the reader:
give an example where HEX: would be useful for number
input.
A free stack >S S> (mhx) or an extra stack defined for this
purpose (Bezemer) helps to define HEX: without RTUCK.
The ugly solution (using BASE-TEMP) could be adequate.
Re-entrancy is overrated anyway.
Groetjes Albert
On 18/03/2026 10:47 pm, albert@spenarnc.xs4all.nl wrote:
In article <69b99106$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals. >>>> : H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
go back to regular methods?
: (H.N) ( u +n -- a2 u2 )
base @ >r hex <# 0 tuck ?do #
i 1+ 4 mod 0= if [char] , hold then loop #>
over c@ [char] , = 1 and /string r> base ! ;
: (H.) ( u -- adr len ) [ 2 cells ] literal (h.n) ;
: (HW.) ( u -- adr len ) 4 (h.n) ;
: (HB.) ( u -- adr len ) 2 (h.n) ;
: (HD.) ( ud -- adr len ) (h.) dup >r holds (h.) r> 1+ negate /string ; >>>
-1 (h.) type FFFF,FFFF,FFFF,FFFF ok
-1 (hw.) type FFFF ok
-1 (hb.) type FF ok
-1 -1 (hd.) type FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF ok
HEX: was the proposal. The other words are illustration.
As a proposal what does HEX: fix? The words you use to illustrate
don't appear to offer advantage. Poorly factored hex output words
are not a good use case for HEX: . Do you have any other examples?
On 19/03/2026 11:51 am, dxf wrote:<SNIP>
On 18/03/2026 10:47 pm, albert@spenarnc.xs4all.nl wrote:
In article <69b99106$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote: >>>> On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
HEX: was the proposal. The other words are illustration.
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
As a proposal what does HEX: fix? The words you use to illustrate
don't appear to offer advantage. Poorly factored hex output words
are not a good use case for HEX: . Do you have any other examples?
In article <69b99106$1@news.ausics.net>, dxf <dxforth@gmail.com> wrote:
On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:
I recall the definition of coroutine call:
CO :
Return to the caller, suspending interpretation of the current
definition, such that when the caller exits, this definition is
resumed
HEX: " temparily switch to HEX for the duration of the current
definition."
A typical use of HEX: is as follows
( print BYTE in hex )
: B. HEX: S>D <# # # #> TYPE ;
( print SINGLE in hex )
: 4? 1+ 4 MOD 0= IF &, HOLD THEN ; \ print &, at regular intervals. >>> : H. HEX: S>D <# 2 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
( print DOUBLE in hex )
: DH. HEX: <# 4 CELLS 1- 0 DO # I 4? LOOP # #> TYPE ;
HEX: is an example use of the use of CO (coroutine).
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
This is ugly so you are tempted to do
go back to regular methods?
: (H.N) ( u +n -- a2 u2 )
base @ >r hex <# 0 tuck ?do #
i 1+ 4 mod 0= if [char] , hold then loop #>
over c@ [char] , = 1 and /string r> base ! ;
: (H.) ( u -- adr len ) [ 2 cells ] literal (h.n) ;
: (HW.) ( u -- adr len ) 4 (h.n) ;
: (HB.) ( u -- adr len ) 2 (h.n) ;
: (HD.) ( ud -- adr len ) (h.) dup >r holds (h.) r> 1+ negate /string ;
-1 (h.) type FFFF,FFFF,FFFF,FFFF ok
-1 (hw.) type FFFF ok
-1 (hb.) type FF ok
-1 -1 (hd.) type FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF,FFFF ok
HEX: was the proposal. The other words are illustration.
Exercise for the reader:
give an example where HEX: would be useful for number
input.
A free stack >S S> (mhx) or an extra stack defined for this
purpose (Bezemer) helps to define HEX: without RTUCK.
The ugly solution (using BASE-TEMP) could be adequate.
Re-entrancy is overrated anyway.
Groetjes Albert
: HEX:
BASE @ RTUCK
HEX CO
R> BASE !
;
The deeper question: is CO worth the return stack gymnastics?
The alternative -- a VARIABLE like BASE-TEMP -- is ugly but
at least it doesn't care what's on R.
It has to be on a stack so you can nest such words. The RTUCK / CO
trick there was very clever!
It has to be on a stack so you can nest such words. The RTUCK / CO
trick there was very clever!
On 18/03/2026 1:31 am, albert@spenarnc.xs4all.nl wrote:Groetjes Albert
VARIABLE BASE-TEMP
: HEX:
BASE @ BASE-TEMP !
HEX CO
BASE-TEMP @ BASE !
;
[UNDEFINED] base&exec [IF] ( xt n -- )
: base&exec base @ >r base ! execute r> base ! ;
[THEN]
Does the same thing:
: B. [: S>D <# # # #> TYPE ;] 16 base&exec ;
BTW - alternative solution. I don't claim it's fundamentally better.
Hans Bezemer
albert@spenarnc.xs4all.nl wrote:
: HEX:
BASE @ RTUCK
HEX CO
R> BASE !
;
RTUCK is interesting because it names a pattern that most Forth
programmers do manually with R> ... >R shuffling. The fact that
you need it at all is telling -- the return stack is doing double
duty as both control flow and temporary storage, and those two
uses fight each other whenever you try to combine them.
CO makes it worse because it manipulates the return address as
data. So you've got three things on the return stack: addresses
that are control flow, values you're temporarily storing, and
the address that CO needs to swap. RTUCK at least makes the
intent clear -- "I know there's a return address on top and I
want to get under it."
but I like RTUCK
"save the top of the stack under the return address of a high
level word."
albert@spenarnc.xs4all.nl writes:
but I like RTUCK
"save the top of the stack under the return address of a high
level word."
Does this work?
: rtuck ( a r:x -- r:a r:x ) r> r> rot >r >r >r ;
albert@spenarnc.xs4all.nl writes:
but I like RTUCK
"save the top of the stack under the return address of a high
level word."
Does this work?
: rtuck ( a r:x -- r:a r:x ) r> r> rot >r >r >r ;
CO : Save temporily such that it can be recovered by CO>after an optional coroutine call. Can be nested.
: Recover what has been temporarily saved with >CO
CO and CO> are short slightly larger than >R R>.
This ciforth code should be readable given i86, and
HIP (high level interpreter pointer)
RPO (Return stack pointer)
POP / PUSH (implies data stack)
_C{ } comment
CODE_HEADER(name towards Forth, name in assembler source)
BX is BX, EBX OR RBX depending on cell width.
CODE_HEADER({CO},{CO})
XCHG HIP,[RPO]
_NEXT
Compare >CO with >R
CODE_HEADER({>R},{TOR}) _C{ (R1) <- (S1)}
POP BX _C{GET STACK PARAMETER}
LEA RPO,[RPO - _CELLS(1)] _C{MOVE RETURN STACK DOWN}
MOV [RPO],BX _C{ADD TO RETURN STACK}
_NEXT
CODE_HEADER({>CO},{TOCO})
MOV AX, [RPO]
LEA RPO,[RPO - _CELLS(1)] _C{HOLE IN RETURN STACK }
MOV [RPO], AX
POP BX _C{GET STACK PARAMETER}
MOV [RPO + _CELLS(1)],BX _C{FILL HOLE}
_NEXT
This hardly make sense to code this in high level "portable"
because high level makes it harder, and slower.
--_ R> DROP
Groetjes Albert
| Sysop: | DaiTengu |
|---|---|
| Location: | Appleton, WI |
| Users: | 1,105 |
| Nodes: | 10 (0 / 10) |
| Uptime: | 492369:17:44 |
| Calls: | 14,160 |
| Calls today: | 2 |
| Files: | 186,285 |
| D/L today: |
2,035 files (639M bytes) |
| Messages: | 2,503,450 |