reading a concatenated string
eiboyd
Posts: 14
Hello, I am a new propeller user transitioning from Basic Stamp experience.
Question:
I am trying to access a data table (stored in a DAT format) and I have named each entry in the DAT table with a name:
DAT
scrn1 byte {list of comma delimited datas}
scrn2 byte {}
scrn3 byte {}
etc.
Within the body of the program I have a variable (crntscrn) that is an integer corresponding to the number after scrn.
I have the following code to concatenate two strings to make the name tag in the DAT table.
ascii := NUM.ToStr(crntscrn, NUM#DEC) 'string representation of crntscrn
ascii2 := string("scrn") 'zero terminated string
bytemove(@ascii2+strsize(@ascii2),@ascii,strsize(@ascii)) 'hopefully the concatenated string (e.g., scrn2)
I now need a way to read the string into a variable (e.g. dattag) that I can reference to get data from the correct line of the DAT table.
so:
dattag = ??????????
value of interest := dattag 'where dattag is the 6th entry in the DAT table on line corresponding to scrnX
if scrn is zero terminated it might make more sense to replace the bytemove line with:
bytemove(@ascii2+strsize(@ascii2)-1,@ascii,strsize(@ascii)) { -1 added to attach the number(ascii) right after the scrn eliminating the 0? but accessing the
concatenated string as a variable is my primary concern }
I am brand new to spin so if this is giberish I appologize.
Thank you
Question:
I am trying to access a data table (stored in a DAT format) and I have named each entry in the DAT table with a name:
DAT
scrn1 byte {list of comma delimited datas}
scrn2 byte {}
scrn3 byte {}
etc.
Within the body of the program I have a variable (crntscrn) that is an integer corresponding to the number after scrn.
I have the following code to concatenate two strings to make the name tag in the DAT table.
ascii := NUM.ToStr(crntscrn, NUM#DEC) 'string representation of crntscrn
ascii2 := string("scrn") 'zero terminated string
bytemove(@ascii2+strsize(@ascii2),@ascii,strsize(@ascii)) 'hopefully the concatenated string (e.g., scrn2)
I now need a way to read the string into a variable (e.g. dattag) that I can reference to get data from the correct line of the DAT table.
so:
dattag = ??????????
value of interest := dattag 'where dattag is the 6th entry in the DAT table on line corresponding to scrnX
if scrn is zero terminated it might make more sense to replace the bytemove line with:
bytemove(@ascii2+strsize(@ascii2)-1,@ascii,strsize(@ascii)) { -1 added to attach the number(ascii) right after the scrn eliminating the 0? but accessing the
concatenated string as a variable is my primary concern }
I am brand new to spin so if this is giberish I appologize.
Thank you
Comments
It is best to allocate ample space in the DAT section for string maniputalation, e.g.
or such
What I am trying to do is simply build up the name tag from a string (scrn) and a number (turned into a string). Being that the scrn is static I can count on the memory size used to be constant. The attached "number" is also going to be a fixed size (in memory).
I will allocate sufficient memory for a stringspace as deSilva recommends; however, I still need a way to reference the concatenated name tag. I was thinking of building the tag up byte by byte with a loop but I am unsure how to do this.
much thanks
DAT
· byte buf 0[noparse][[/noparse]200] 'reserve space
OBJ
· fmt: "Format"
PUB
· fmt.sprintf(@buf,string("scrn%1.1d"),crntscrn)
If crntscrn is 1, 2 or 3 then buf will hold null terminated strings
"scrn1", "scrn2" or "scrn3"
The Format object is in the Object Exchange under Tools.
regards peter
My propeller and an LCD screen arrive today, this stuff is code I am developing without the chip so it will be a few days until I can test things.
Code snipet:
OBJ
fmt : "Format"
PUB gui | crntscrn, temp
crntscrn := 1
fmt.sprintf(@buf,string("scrn%1.1d"),crntscrn)
temp := @buf
updated := temp
DAT
buf word 0[noparse][[/noparse]200] 'reserve space
scrn1 word 2, 2, 2, 10, 100, 2
scrn2 word 2, 1, 2, 10, 100, 3, 50, 100, 1
scrn3 word 3, 1, 3, 10, 100, 2, 50, 100, 1, 100, 100, 3
The above code does not set updated to 10 as expected/desired? @buf does hold scrn1 as desired and putting in a line:
updated := scrn1 does generate 10
It would appear I am missing something...
Do I need to use the sscanf command in format (it so, how do I use that?)
much thanks
and Format did that for you.
You then assign the address of buf to temp.
And then you assign temp to updated.
So updated holds the address of buf but you could do that with just updated := @buf.
Why do you expect updated to hold 10?
Where does this 10 come from, or is supposed to come from?
regards peter
updated := scrn1
should have been:
updated := scrn1 thereby referencing the third word in the DAT line starting with scrn1
perhaps I am completely misunderstanding the uses of the DAT structure?
I want to have a list of numbers associated with tags (scrn#) and refer to certain values in the table by using:
scrn#[noparse][[/noparse]#]
I was trying to assign the actual information at the address of buf (i.e., scrn1 or scrn2 etc.) to temp so I could access a value with scrn1(for example and get 10)
perhaps this is not possible in spin? I may have to just implement a lookup table approach (not as pleasing as using the labels DAT appears to afford but....)
thanks again
PUB getValue(scrn,index):value | buf
· case scrn
··· 1: buf := @scrn1
··· 2: buf := @scrn2
··· 3: buf := @scrn3
· return word[noparse][[/noparse]buf+index]
and to write a value
PUB putValue(scrn,index,value) | buf
· case scrn
··· 1: buf := @scrn1
··· 2: buf := @scrn2
··· 3: buf := @scrn3
··word[noparse][[/noparse]buf+index] := value
regards peter
When you post code fragments with numbers in brackets [noparse]/noparse, leave a space between the left bracket and the number so the forum software doesn't mistake it for a font size tag.
Thanks,
Phil
Peter, thanks for the code snipet, I will give it a try.
cheers
() = parentheses
[noparse]/noparse = brackets
{} = braces
<> = ? ... oh, right: "angle" brackets
Yeah, just the square ones. You can also use [ in place of a left bracket, but if you reedit your post, you have to keep replacing the [noparse][[/noparse] again and again.
-Phil
I sometimes have a similar requirement in my own code - what I generally do is to create a small index array at runtime, which I can refer to when needed. An initialisation routine in Spin places the addresses of various blocks of data into the array. I can then pass the base address of the array to a new cog, which can then locate any block of data it needs.
Please note that this code is written completely off the top of my head and is almost certainly syntactically incorrect, it's just to look at to get a better idea of what I'm trying to explain.
What I do not understand is what you want to say with your first sentence I quoted here, and how it relates to your program (or to the OP's problem)?
As far as I could tell from the OP, he (she? - sorry if I'm making an incorrect assumption)·wanted to access a memory location by name, but he wanted to determine the name at runtime. He was attempting to·construct a string and pass it·as a parameter to bytemove. I was explaining why it wasn't giving the result he wanted.
I am aware that there are many ways to solve the problem. Peter solved it with a case statement, I solved it with an array of pointers. I'm sure there are more, each of which has·advantages and shortcomings. We offer suggestions, and it's up to the OP to determine which is best suited to his application.
I have to admit that I did not understand the objective of the OP before your recent posting here
I had not recognized the true root for the confusion!
Long live TCL and Perl!
Regarding Peter's code...
PUB getValue(scrn,index):value | buf
case scrn
1: buf := @scrn1
2: buf := @scrn2
3: buf := @scrn3
return word[noparse][[/noparse] buf+index]
My understanding is that the getValue method is passed two variables: scrn and index from the main routine and returns a variable named value. In addition it locally declares a variable buf. The case statement evaluates the variable scrn and matches it to 1, 2 or 3. buf is then assigned the pointer to an address.
The form of the return statement puzzles me? I would have thought it would look like:
return word buf[noparse][[/noparse] index]
This does not work and of course Peter's code does...
I read the whole spin manual (not the assembly section) and this obviously did not stick, what is going on?
Would return word[noparse][[/noparse] buf] give the word at the start of the address? I.e., is it the same as return word[noparse][[/noparse] buf+0] ????
As I am writing this the light is starting to turn on regarding the idea of pointers to addresses and the inability to reference them by name....
the light is dim, bear with me and thanks again
cheers
Your interpretation of "GetValue" is quite correct.
When reading through the manual, don't overlook chapter 4! Look for LONG, WORD and BYTE: There are three (or four) different meanings and situations described how to use them.
Peter's code however can be a little bit confusing to you, as index in not what you might think; his last line should better look like this
which is functonally equivalent to
value := WORD[noparse][[/noparse] buf+2*index]
works but I am in the dark as to how?
I did read chapter 4 but reading and doing are vastly different. I will try and implement Ziggy's suggestion for the purposes of learning the pointer stuff better.
Then you could use "lookup" too?
Nick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Never use force, just go for a bigger hammer!
The DIY Digital-Readout for mills, lathes etc.:
YADRO