Create a new word from string on stack in Forth

110 Views Asked by At

I need to use create on a string that I got from parse-name. Possible? Perhaps using the word evaluate?

2

There are 2 best solutions below

2
On BEST ANSWER

To create a named definition programmatically, you have the following options:

  1. allow a defining word to take the name from the input stream;
  2. use the well-known word execute-parsing;
  3. compose a string and pass it to evaluate.

1. Using a defining word

If you need to create a word with a name that parse-name returns, just use a usual defining word instead of parse-name.

: foo ( "name" -- ) create  123 , ;
foo bar \ it creates "bar"
bar @ . \ it prints "123"

2. Using execute-parsing

There is a well-known word execute-parsing ( i*x c-addr u xt -- j*x ), which is provided by some systems, or can be loaded from a standard-compliant library, such as execute-parsing.fs.

This word executes given xt providing the given string as the input buffer. This word can be useful when you compose a name programmatically.

: foo ( "name" -- )
  parse-name
  ['] create execute-parsing
  123 ,
;

3. Composing a string

The standard means to compose a string are too low-level: you allocate a memory region and place sub-strings using move ( addr.src addr.dest u.length -- ). Therefore, a better way is to use some library (for example, ffl/str.fs).

Another way to compose a short string is to use the pictured numeric output mechanism and the word holds ( c-addr u -- ):

: foo ( "name" -- )
  <#  parse-name holds  s" create " holds   0 0 #>
  evaluate
  123 ,
;

In this mechanism, the new sub-string prepends the previous one (i.e., they are placed into the buffer from right to left).

The available buffer size can be obtained by:

s" /HOLD" environment? 0= throw .

The string returned by #> ( xd -- c-addr u ) is transient.

When you use evaluate, you must be sure that all names will be resolved correctly (due to late binding).

0
On

Something like this maybe:

s" create " parse-name foo $+ evaluate