Shop OBEX P1 Docs P2 Docs Learn Events
Is there any easy way to assign a string to a byte? — Parallax Forums

Is there any easy way to assign a string to a byte?

Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
edited 2009-12-07 00:57 in Propeller 1
I know that you can use a DAT statement to assign a string to a byte like this:

DAT

name byte "This is a line of text.",0





But is there an easy way to do something like this?

VAR 

BYTE name[noparse][[/noparse]20]


PUB

BYTE[noparse][[/noparse]@name]:=string("This is a line of text.",0





Thanks!
OBC

▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
New to the Propeller?

Check out: Protoboard Introduction , Propeller Cookbook 1.4 & Software Index
Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us
Got an SD card connected? - PropDOS

Comments

  • BradCBradC Posts: 2,601
    edited 2009-01-17 04:56
    Will this work for you ?

    X := String("Fred was ere")
    repeat i from 0 to strsize(X)+1
      byte[noparse][[/noparse] @name ][noparse][[/noparse] i ] := byte[noparse][[/noparse] X ][noparse][[/noparse] i ]
    
    


    Remember all String("") does is return a pointer to the null terminated string in memory

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
  • Mike GreenMike Green Posts: 23,101
    edited 2009-01-17 04:57
    Use BYTEMOVE. For the byte count, use the length of the string + 1 (to account for the zero byte which is implied at the end).

    Like: BYTEMOVE(@name,string("This is a line of text."),24)
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-17 08:03
    Hello OBC,

    from the words chosen in your headline I assume there might be a misunderstanding about bytes and strings.

    a byte can carry values between 0 and 255. This space can carry ONLY ONE character.
    So all a byte can be assigned is a SINGLE character NOT a complete string (of more than one character)


    A codeline like this

    DAT
      name byte "ABC this is a text",0
    
    



    means
    hello compiler do the following:
    store in HUB-RAM a byte-SEQUENCE containing the following values: decimal 65,66,67,32,116,104

    where 65 is ASCII-Code for "A"
    where 66 is ASCII-Code for "B"
    where 67 is ASCII-Code for "C"
    where 32 is ASCII-Code for " "
    where 116 is ASCII-Code for "t"
    where 104 is ASCII-Code for "h"
    where 105 is ASCII-Code for "i"
    where 115 is ASCII-Code for "s"

    etc.
    last byteVALUE in this sequence zero (to terminate the string

    the HUB-RAM-adress can be referenced by the label "name"

    so the word "byte" says the compiler store the values that are following the word "byte" as bytes=8bit-values and NOT as words=16bit-values and NOT as longs=32bit-values

    the basic use for DAT is

    DAT
      name byte 65,66,67,32,116,104,......,0
    
    
    



    Here it is clear that integerNUMBERS are used and by using "byte" the compiler knows 8bitvalues are following.

    Now the compiler offers a variation to storing byte-SEQUENCES for strings
    that is much better readable than 65,66,67,32,116,104,......,0

    DAT
      name byte "ABC this is a text",0
    
    



    I'm NOT sure if the construction Brad suggested will work. Somewhere in the memory the bytesequence "Fred was here" has to be stored
    But there is nothing said about WHERE it should be stored. To know it REAL I / you would have to make a test-program
    maybe the compiler is clever enough that you can use variable "X" as reference-label AND the compiler reserves HUB-RAM-space
    for the bytesequence "Fred was here",0


    So there is no way to do something like in delphi or VB
    like variableB := variableA for strings


    know I have a question about bytemove

    Does the command bytemove in SPIN work the same way as in other programming-languages ?
    I mean does it copy a bytesequence from source to destination regardless of what the destination and source-adress is ?
    f.e.

    DAT
      MyStr byte 0,0,0,0,0
      Voltage long 0
      Current long 0
      MaxTemp long 1000
    
    



    reserves 5 bytes of HUB-RAM

      bytemove(@MyStr,string("12345667890",0)
    
    



    Will this bytemove-command write ELEVEN bytes starting at adress of MyStr overwriting the values of the DAT-variables Voltage, Current, MaxTemp ?

    best regards

    Stefan

    Post Edited (StefanL38) : 1/17/2009 8:15:24 AM GMT
  • BradCBradC Posts: 2,601
    edited 2009-01-17 08:30
    StefanL38 said...

    I'm NOT sure if the construction Brad suggested will work. Somewhere in the memory the bytesequence "Fred was here" has to be stored
    But there is nothing said about WHERE it should be stored. To know it REAL I / you would have to make a test-program
    maybe the compiler is clever enough that you can use variable "X" as reference-label AND the compiler reserves HUB-RAM-space
    for the bytesequence "Fred was here",0

    Hrm.. well I *am* sure.

    When you use STRING("XX") it compiles the null terminated string into the bytecode for that spin method. What is returned is an address pointer to that string.

    If you would like to verify that yourself, why not use one of the after-market compilers to inspect the bytecode disassembly listing and see how it works.

    Mikes suggestion does precisely the same thing, but as usual, in a smaller, faster and more code-efficient fashion [noparse]:)[/noparse]
    StefanL38 said...


    Does the command bytemove in SPIN work the same way as in other programming-languages ?
    I mean does it copy a bytesequence from source to destination regardless of what the destination and source-adress is ?
    f.e.

    DAT
      MyStr byte 0,0,0,0,0
      Voltage long 0
      Current long 0
      MaxTemp long 1000
    
    



      bytemove(@MyStr,string("12345667890",0)
    
    



    This won't work as you have not told bytemove how many bytes to copy. In addition STRING("") null terminates for you, so you can leave out the ",0" at the end.

    In any case, if you changed it to ...

    bytemove(@MyStr,String("12345667890"),12)
    
    



    .. it would do what you were originally suggesting, and yes it will quite happily trample over "Voltage" and "Current" also

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.
  • StefanL38StefanL38 Posts: 2,292
    edited 2009-01-17 19:33
    Hello Brad,

    thanks for clearing things up and the correction about the parameter telling how many bytes to move

    best regards

    Stefan
  • Beau SchwabeBeau Schwabe Posts: 6,568
    edited 2009-01-17 23:59
    Doesn't the STRING qualifier already format everything into a BYTE string that you can read or write to without having to use BYTEMOVE?

    TestString := string("Hello")
    
          BYTE[noparse][[/noparse]TestString][noparse][[/noparse]0] := 89      'Replace 'H' with 'Y'
          BYTE[noparse][[/noparse]TestString][noparse][[/noparse]5] := 119     'add a 'w' to the end of 'Hello'
          BYTE[noparse][[/noparse]TestString][noparse][[/noparse]6] := 0       'terminate string with a Zero
    
    gr.text(0,82,TestString)     ' this will print the word 'Yellow'
    
    

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Beau Schwabe

    IC Layout Engineer
    Parallax, Inc.

    Post Edited (Beau Schwabe (Parallax)) : 1/18/2009 1:52:10 AM GMT
  • BradCBradC Posts: 2,601
    edited 2009-01-18 00:21
    Beau Schwabe (Parallax) said...
    Doesn't the STRING qualifier already format everything into a BYTE string that you can read or write to without having to use BYTEMOVE?

    Yeah, it does. I assumed from the snippet that OBC posted he wanted a way of assigning that to another byte array defined elsewhere, thus the need for the copy.

    <edit> I did not see the "read or write to" in the above paragraph. Yes you can read from it, but as it is compiled into the spin method it is referenced from, if you write to it and get it wrong you can easily cause mayhem and destruction. Be careful with that!

    If you looked at a spin object.. you get something like this

    Header/Method Table
    DAT Section
    PUB Method 1
    PUB Method 1 string definitions
    PUB Method 2
    PRI Method 1
    PRI Method 1 string definitions
    End

    So each spin method that has STRING("") defs in it has them compiled in starting immediately after the final return() in the method. If you were to overwrite a string with a longer string you would quite probably bulldoze either into the next string() or over the bytecode of the next method. Either way, things won't turn out the way you want them to.
    On the other hand, if you were to define a Method like this

    DAT
      bytecode 0,1,2,3,4,5,6,7,8
      bytecode_end
    
    PUB MethA
      return String(1)
    PUB MethB
      return String(0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0)
    PUB MethC
      bytemove(MethA+2,@bytecode,@bytecode_end-@bytecode)
    
    
    



    You now have an efficient method for changing the runtime code in "MethB" on the fly.
    The address preceding the end of the value returned by MethA + 2 should be the start of MethB. You can just copy arbitrary bytecode in there and execute it with a call to MethB. Just make sure you end the bytecode with an explicit return/abort as you will trample the pre-compiled bytecode.

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    Cardinal Fang! Fetch the comfy chair.

    Post Edited (BradC) : 1/18/2009 1:46:40 AM GMT
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2009-01-18 01:00
    Wow.. I'm glad I asked..

    Several good methods presented for handling the problem.

    Thank you gentlemen!

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    New to the Propeller?

    Check out: Protoboard Introduction , Propeller Cookbook 1.4 & Software Index
    Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us
    Got an SD card connected? - PropDOS
  • softexsoftex Posts: 27
    edited 2009-01-31 18:01
    Boy, if even OBC is struggling somewhat with this then perhaps someone needs to create a good string handling object for the prop. I know I sure could use it. And esp. when it comes to converting a string like "123" into a decimal value. BTW after grappling with this stuff in PROTON BASIC (like PICBASIC) for a couple of years, they like to refer to a defined zero-terminated string as a byte ARRAY which, of course, is what it is.

    -Dave
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2009-01-31 21:33
    What would be nice is for Spin to recognize three kinds of string constructors and, in the process, deprecate string(). This would be replaced with:

    ····str0() for zero-terminated strings,
    ····nstr() for strings (limited to 255 characters) with a length byte in position 0, and
    ····str() and/or byte() for generic strings (simple byte arrays) with no length indicator.

    Zero-terminated strings can be a real nuisance in data transmission, for example, when you want to send a zero-valued byte, such as CLS. In such a case, you have to terminate the string, send the zero as a single character, then resume with another string. It's either that or define non-zero cognates for zero which, in itself, can lead to awkward situations.

    The above forms could easily be imitated for constructing inline word() and long() arrays, too, rather than having to declare them in a VAR or DAT section. There's also no reason that the elements of such arrays have to be constants, either. A statement of the form

    addr := byte("ABC", my_variable, "DEF")
    
    
    


    could easily be compiled to produce the bytecode equivalent of

    addr := byte("ABC", 0, "DEF")
    byte[noparse][[/noparse]addr + 3] := my_variable
    
    
    


    This would make possible the construction of variable-length parameter lists in method calls, viz:

    value := polynomial(nlong(x, a, b, c, d))
    
    
    


    By reading the long at the address passed, the method would know that there are five additional arguments: the independent variable and four coefficients, from which it could compute the result:

    ····ax3 +bx2 +cx + d

    All of these things can be accomplished without any changes to the Spin interpreter; only to the compiler.

    -Phil
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2009-01-31 21:47
    Right on! These would be nice additions.

    I guess one of the reasons that I've had so much trouble here is that I have
    no frame of reference to compare some of these things making them harder to absorb.
    For instance the fact that I've learned various dialects of BASIC did more to hinder
    my adapting to this than anything... You simply cannot directly compare directly to string$. [noparse]:)[/noparse]

    BTW, OBC does NOT claim to be an expert in EE or the Propeller for that matter.
    After two years I'm reasonable strong in many areas, but there are some holes I'm still
    working on guys. [noparse]:)[/noparse]

    OBC

    ▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
    New to the Propeller?

    Check out: Protoboard Introduction , Propeller Cookbook 1.4 & Software Index
    Updates to the Cookbook are now posted to: Propeller.warrantyvoid.us
    Got an SD card connected? - PropDOS
  • w8anw8an Posts: 176
    edited 2009-12-07 00:57
    Just came across this thread... Excellent ideas, PhiPi
Sign In or Register to comment.