I tried to implement a word that produces a string from an array when given a number on the stack in Forth.
My first naive attempt was:
create myarray s" Alpha" , s" Beta" , s" Charlie" ,
This was accepted, but it did not work as expected — myarray @ type produces inconsistent output (instead of my naive expectation that it might print “Alpha”).
When searching the web, I found in Gforth documentation that a string created with s" has a limited lifetime which means that my ansatz is bound to fail from the beginning. On the other hand, even arrays of regular objects seem to be not standardized according to Arrays in Forth section in Len’s Forth Tutorial.
<Update> Apparently, this is not a trivial problem with Forth. There are libraries on the web that implement missing string functionality: FFL (str module) and String Functions by Bernd Paysan. This is a good starting point, although it still requires work to go from there to an array of strings. </Update>
So how can I implement a word that returns a string from a given array?
To address parts of your code,
s"leavesaddr uon the stack, an address and the length of the string.,only stores one value so you won’t get the desired results that way.2,might do it as that would store both of the stack items that represent the string. Once you have done that you need to get both values back too so2@is what you want.My rewrite would look like this:
Getting at the other elements of your array is a bit trickier. When you type
myarrayyou get the address of the start of the data in that dictionary entry, and you can then use 2@ to get the the things that the first two addresses point to (which are the address and length of “Alpha”). If you want “Beta you need the next pair of addresses. So you can useTo get the addresses that point to “Beta” and so on. So in order to access “Beta” you would enter
I have tested this with gforth and it seems to all work, although I am not sure how to rigorously test for persistence.
Your word would need to be able to do the address incrementing based on what is on the stack to start with. You might want to get into some more
create does>stuff. I can give some pointers but I don’t want to spoil the fun of discovery.If I am skipping too many details of what this actually means just say, and I will try again.
Maybe this is too crude, but I had a go at making a “string type” of sorts a while ago.
It defines a word with a name of your choosing (in this case “words”) that will push length and start address of your string (in this case “some words”) when it is interpreted. As far as I know when the string is in a definition like this it is persistent.
This doesn’t answer you question fully, but it might help.
I have had another go at a persistent string, this one definitely
allots memory within a dictionary entry and will be safe as long as that word exists. Before the string “type” only stored the address and length thats"created which is only any good until something else writes over that region of memory. This now copies the string from wheres"creates it into a dictionary item called “name” where it is guaranteed to last as long as “name” itself.For amusement, I thought I might show how little sense this makes without helpful formatting