Digest #310 2025-08-17
Contributions
referenceImplementation - Possible reference implementation
The following uses a couple of words from the double and string sets; the alternative using only words in core is more verbose.
: >digit ( char -- d true | 0 ) \ "to-digit"
\ convert char to a digit according to base followed by true, or false if out of range
DUP [ '9' 1+ ] LITERAL <
IF '0' - \ convert '0'-'9'
DUP 0< IF DROP 0 EXIT THEN \ reject < '0'
ELSE
DUP 'a' < IF BL + THEN \ convert to lowercase, exploiting ASCII
'a' -
DUP 0< IF DROP 0 EXIT THEN \ reject non-letter < 'a'
#10 + \ convert 'a'-'z'
THEN
DUP BASE @ < DUP 0= IF NIP THEN ( d true | false ) \ reject beyond base
;
: >NUMBER ( ud1 c-addr1 u1 -- ud2 c-addr2 u2 ) \ "to-number"
2SWAP 2>R
BEGIN ( c-addr u ) ( R: ud.accum )
DUP WHILE \ character left to inspect
OVER C@ >digit
WHILE \ digit parsed within base
2R> BASE @ 1 M*/ ( c-addr u d.digit ud.accum ) \ scale accum by base
ROT M+ 2>R \ add current digit to accum
1 /STRING ( c-addr1+1 u1-1 )
REPEAT THEN
2R> 2SWAP ( ud2 c-addr2 u2 )
;
Replies
In one of Jim's posts, he had a typo that suggested writing ?: -ROT -ROT -ROT ;
, which doesn't do what you want.
With just a bit of playing around in gforth, I was able to come up with this that identifies the problem (note that this is specific to gforth; as parse-name
, noname
, and others are not standard):
: nop ;
defer cleanup
' nop ' cleanup defer!
: unknown-word -13 throw ;
: ?:
>in @ >r ['] parse-name perform find-name 0=
if r> >in ! : exit then
noname marker latestxt ['] cleanup defer! \ install marker
r@ >in ! : postpone unknown-word postpone ; immediate \ hide existing word
r> >in ! : \ proceed to parse as normal, ; will clean up
;
: ;
postpone ;
cleanup \ undo ?: if needed, otherwise a nop
['] nop ['] cleanup defer! \ restore nop cleanup
; immediate
?: a ." in a, v1" ;
?: a ." in a, v2" ;
a
=> in a, v1
?: -rot -rot -rot ;
*the terminal*:17:9: error: Undefined word
?: -rot >>>-rot<<< -rot ?;
requestClarification - May OF modify the enclosing case-sys on the control stack?
An occurence of the same name (wether it contains a number or not) before and after the
--
means that the value is the same
This is not formally specified in the Stack notation, it only says: "«before» represents the stack-parameter data types before execution of the definition and «after» represents them after execution".
(e.g.,
dup
,swap
).
In all such cases, including dup
, 2dup
, etc,
the fact that two actual parameters in the stack at different positions or at different times are identical formally follows only from the prose, not from the stack diagram.
I think that indices on data type symbols in stack diagrams are used only to avoid ambiguity when referencing an anonymous formal stack parameter in the prose. They don't need if there is no ambiguity. And they don't have any formal meaning.
EricBlake wrote in the contribution [401] (to the does>
glossary entry):
By my understanding of the current wording in the
LATEST-NAME
proposal, we are supposed to have the situation that:[UNDEFINED] latest-name [IF] .( latest-name proposal not yet implemented) [THEN] : named ; LATEST-NAME \ refers to named :NONAME ; LATEST-NAME \ _still_ refers to named
Yes, this is intended, because LATEST-NAME
returns the nt of the latest definition from the compilation word list, and it shall consider only the definitions that are available for TRAVERSE-WORDLIST
.
If a Forth system places an anonymous definition in some word list, this is its own internal business, and the corresponding nt cannot be accessible by the standard means.
even though in testing, in SwiftForth 3.12.0 has
LAST @
produce0
after the anonymous definition (ie. using: latest-name LAST @ ;
would not comply with the current version of the proposal); similarly, gforth 0.7.9 hasLATEST
produce0
after the anonymous definition, whileLATESTNT
produces an nt that is identical to the xt returned by the:NONAME
(that is, gforth's implementation ofLATEST
specifically checks whethername>string
produces an empty string; and neitherLATEST
norLATESTNT
would comply with the current version of the proposal).
Thank you for this investigation! These system-specific last @
, latest
, latestnt
cannot be used to implement latest-name
also because they return the same value regardless of changing the compilation word list.
Note that as far as IMMEDIATE
and DOES>
are concerned, this nuance does not matter because it is not allowed to change the compilation word list, as 16.3.3 says:
An ambiguous condition exists if a program changes the compilation word list during the compilation of a definition or before modification of the behavior of the most recently compiled definition with
;CODE
,DOES>
, orIMMEDIATE
.
referenceImplementation - Possible reference implementation
DUP 'a' < IF BL + THEN \ convert to lowercase, exploiting ASCII
can be shortened to BL OR