How can I use a word, which parses its input inside a definition of another word?

82 Views Asked by At

Suppose there is a word string which works like so: 64 string var$, and the result of var$ execution is an address of the first byte of the allocated memory and '0' to reflect the used space of the 64 bytes being allocated for a string. Now you can use it like this, s" Hallo" var$ $!, and this gives back the starting address of the memory and a '5' for the length of the string being stored there.

Now the problem, defining a word like so:

: HelloWorld 64 string HW$ s" HelloWorld!" HW$ $! ;

will not work, because HW$ is evaluated of an (not defined) word.

How can I get out of this?

I tried what I have described before with ESP32Forth, and it doesn't work, which lead to my question.

1

There are 1 best solutions below

0
ruvim On

To parse the input inside a definition you have to use an immediate word (a Forth definition whose compilation semantics are to perform its execution semantics in compilation state, see immediate), or temporary switch to interpretation state via [ ... ] (see 3.4.5 Compilation). But in any case, you cannot create a new Forth definition using standard means while compiling of another definition (except a local variable or quotation).


A typical approach to have local strings is to use dynamic memory allocation and local variables.

A small library:

: str@ ( addr.str -- addr.data u.len )
  dup cell+ swap @
;
: str! ( addr.data u.len  addr.str -- ) >r
  dup r@ cell- @ u> abort" string buffer overflow"
  dup r@ ! \ store the length
  r> cell+ swap ( addr.data addr.buffer u.len )
  2dup + 0 swap c! \ place zero at the end to make ASCIIZ
  move \ store data
;
: new-str ( u.size -- addr.str )
  dup 2 cells + char+ allocate throw tuck ! cell+ ( addr.str )
  dup 0 0 rot str!
;
: free-str ( addr.str -- )
  cell- free throw
;

A usage example:

: HelloWorld ( -- )
  {: | hw :}
  64 new-str to hw
  s" HelloWorld!" hw str!
  hw str@ cr type cr
  hw free-str
;