Digest #310 2025-08-17

Contributions

[402] 2025-08-17 00:00:26 EricBlake wrote:

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

[r1495] 2025-08-13 13:00:47 EricBlake replies:

comment - `?:`?

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 ?;

[r1496] 2025-08-15 13:29:00 ruv replies:

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.


[r1497] 2025-08-15 14:42:10 ruv replies:

proposal - New words: latest-name and latest-name-in

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 @ produce 0 after the anonymous definition (ie. using : latest-name LAST @ ; would not comply with the current version of the proposal); similarly, gforth 0.7.9 has LATEST produce 0 after the anonymous definition, while LATESTNT produces an nt that is identical to the xt returned by the :NONAME (that is, gforth's implementation of LATEST specifically checks whether name>string produces an empty string; and neither LATEST nor LATESTNT 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>, or IMMEDIATE.


[r1498] 2025-08-17 00:39:27 EricBlake replies:

referenceImplementation - Possible reference implementation

DUP 'a' < IF BL + THEN \ convert to lowercase, exploiting ASCII can be shortened to BL OR