SERIN string indexing
Archiver
Posts: 46,084
To grab, say, 5 characters with SERIN into an array of, say, 10 bytes
one uses code like:
Buffer VAR BYTE(10)
...
SERIN ....[noparse][[/noparse]STR Buffer\5]
This loads the 5 characters into the array <Buffer> starting at
index 0. How does one go about loading the 5 characters starting
at some other location within <Buffer>? In any old high level
language one would simply use something like, for example,
SERIN ....[noparse][[/noparse]STR Buffer(4)\5]
to load the 5 characters starting at index 4. However, this produces
a syntax error with the Stamp editor. The same thing occurs with the
DEBUG command.
Is there a way around this? I know I can do it using an alias to
define another variable name to refer to the location of (in the
above example) Buffer(4) in RAM, but I want to be able to generate
both the start location and the number of characters to grab AT
RUNTIME, so that solution is not usable.
Thanks, Steve
one uses code like:
Buffer VAR BYTE(10)
...
SERIN ....[noparse][[/noparse]STR Buffer\5]
This loads the 5 characters into the array <Buffer> starting at
index 0. How does one go about loading the 5 characters starting
at some other location within <Buffer>? In any old high level
language one would simply use something like, for example,
SERIN ....[noparse][[/noparse]STR Buffer(4)\5]
to load the 5 characters starting at index 4. However, this produces
a syntax error with the Stamp editor. The same thing occurs with the
DEBUG command.
Is there a way around this? I know I can do it using an alias to
define another variable name to refer to the location of (in the
above example) Buffer(4) in RAM, but I want to be able to generate
both the start location and the number of characters to grab AT
RUNTIME, so that solution is not usable.
Thanks, Steve
Comments
>To grab, say, 5 characters with SERIN into an array of, say, 10 bytes
>one uses code like:
>
>Buffer VAR BYTE(10)
>...
>SERIN ....[noparse][[/noparse]STR Buffer\5]
>
>This loads the 5 characters into the array <Buffer> starting at
>index 0. How does one go about loading the 5 characters starting at some other
location within <Buffer>? In any old high level language one would simply use
something like, for example,
>
>SERIN ....[noparse][[/noparse]STR Buffer(4)\5]
>
>to load the 5 characters starting at index 4. However, this produces a syntax
error with the Stamp editor. The same thing occurs with the DEBUG command.
Hi Steve -
Such is the often nature of interpretive languages. Were PBASIC a compiled
language, you would certainly be correct. As it was, even early variants of
BASIC had no
[noparse][[/noparse]Let] VARIABLE = MID$ (n,text,l ... ) etc
operations. Often one had to resort to all sorts of machinations with RIGHT$,
LEFT$, and TRIM$.
>Is there a way around this? I know I can do it using an alias to define
another variable name to refer to the location of (in the above example)
Buffer(4) in RAM, but I want to be able to generate both the start location and
the number of characters to grab AT RUNTIME, so that solution is not usable.
Somewhat unfortunately, RUNTIME is ALL TIMES for PBASIC. The Editor/Compiler is
apart from the "operating system" (actually the embedded PBASIC interpreter),
thus no "runtime" communication is possible, and there are limits which had to
be considered when PBASIC was designed.
Mainframes and PCs permit the programmer to obtain memory at will. PBASIC has a
tightly confined workspace, which it really manages quite well, and it enjoys no
such luxury. Considering what it does, I find still it a work of art (IMHO, of
course !). YMMV
>Thanks, Steve
Please see the information and notes on and near page 221 in the PBASIC Manual.
Part of the notes indicate using a null-delimited list as noted below:
QUOTE
‘ Example 2 (null-terminated string):
myText var byte(10) ‘ An array to hold the string.
myText(0) = “H”:myText(1) = “E” ‘ Store “HELLO” in first 5 cells...
myText(2) = “L”:myText(3) = “L”
myText(4) = “0”:myText(5) = 0 ‘ Put null (0) after last character.
debug str myText ‘ Show “HELLO” on the PC screen.
(*Note to experienced programmers: Counted strings normally store the count
value in their 0th cell. This kind of string won’t work with the STR prefix of
Debug and Serout. STR cannot be made to start read-ing
at cell 1;
debug str myText(1) causes a syntax error. [noparse][[/noparse]As you note !]
Since arrays have a fixed length anyway, it does no real harm to put the count
in the last cell.)
END QUOTE
There are other methods as well, but since the 0th element is available for use
(for "free") - why not use it and offset the array.
Hope that helps, although it's probably NOT what you wanted to hear : (
Regards,
Bruce Bates
> one uses code like:
>
> Buffer VAR BYTE(10)
> ...
> SERIN ....[noparse][[/noparse]STR Buffer\5]
>
> This loads the 5 characters into the array <Buffer> starting at
> index 0. How does one go about loading the 5 characters starting
> at some other location within <Buffer>? In any old high level
> language one would simply use something like, for example,
>
> SERIN ....[noparse][[/noparse]STR Buffer(4)\5]
>
I think the key to this is to realize that the Stamp does no range checking
at all. So it seems like you could do this:
BUFFER VAR BYTE(5)
SUBBUF VAR BYTE(5) ' wait a minute it gets better
SERIN ...[noparse][[/noparse]STR BUFFER\5]
SERIN ...[noparse][[/noparse]STR SUBBUF\5]
.
.
if BUFFER(9)="X" then yadda_yadda ' Buffer(9) is SUBBUF(4)
Not sure if that helps or not.
Regards,
Al Williams
AWC
* Floating point math for the Stamp, PIC, SX, or any microcontroller:
http://www.al-williams.com/awce/pak1.htm
>one uses code like:
>
>Buffer VAR BYTE(10)
>...
>SERIN ....[noparse][[/noparse]STR Buffer\5]
>
>This loads the 5 characters into the array <Buffer> starting at
>index 0. How does one go about loading the 5 characters starting
>at some other location within <Buffer>? In any old high level
>language one would simply use something like, for example,
>
>SERIN ....[noparse][[/noparse]STR Buffer(4)\5]
>
>to load the 5 characters starting at index 4. However, this produces
>a syntax error with the Stamp editor. The same thing occurs with the
>DEBUG command.
>
>Is there a way around this? I know I can do it using an alias to
>define another variable name to refer to the location of (in the
>above example) Buffer(4) in RAM, but I want to be able to generate
>both the start location and the number of characters to grab AT
>RUNTIME, so that solution is not usable.
No easy solution, but workarounds.
1) Capture the incoming data into a separate buffer, and then move it to
the destination you want. Takes time, and RAM.
2) Barrel roll the data buffer prior to the SERIN command. A pointer keeps
track of the logical start of the buffer.
roll=3[noparse]:p[/noparse]ointer=10-roll
gosub barrelroll ' barrelroll 3 places
SERIN ... [noparse][[/noparse]str buffer\5] ' the buffer is always rolled into position
to accept data.
3) Write your own loop SERIN, to take in one byte at a time and put it
where you want it. Won't work if the data streams in fast; works only if
the data comes in slowly or if hardware flow control is available.
4) Branch to a separate SERIN for each possible start position. Eats up
lots of program memory!
buf var byte ' can refer to implicitly as buf(0)
buf1 var byte
'...
buf9 var byte ' or buf(9)
branch start_position,[noparse][[/noparse]bf_in,bf1_in,...,bf9_in]
bf_in:
SERIN ...[noparse][[/noparse]buf\num_chars]
goto continue
bf1_in:
SERIN ...[noparse][[/noparse]buf1\num_chars]
goto continue
'... etc
continue:
good luck!
-- Tracy Allen
http://www.emesystems.com