Shop OBEX P1 Docs P2 Docs Learn Events
I know basic and need the 'MID', 'LEFT', 'RIGHT' and 'LEN'How to do the same in spin? — Parallax Forums

I know basic and need the 'MID', 'LEFT', 'RIGHT' and 'LEN'How to do the same in spin?

seconikaseconika Posts: 18
edited 2011-02-02 21:27 in Propeller 1
Hi,

Im a Basic stamp, VB, and all the other basic dialect person.

I got a Propeller board some weeks ago and now I'm trying to learn the SPIN programing.

Can anyone help me find help how to do the same in SPIN as the LEN, MID, LEFT, RIGHT command in standard basic.

I would like to read the second and sometime the first "Letter", "Data" in a string that holds the HEX data from a PS2 controller.


Regards,
Niklas

Comments

  • $WMc%$WMc% Posts: 1,884
    edited 2011-01-30 13:59
    seconika wrote: »
    Hi,

    Im a Basic stamp, VB, and all the other basic dialect person.

    I got a Propeller board some weeks ago and now I'm trying to learn the SPIN programing.

    Can anyone help me find help how to do the same in SPIN as the LEN, MID, LEFT, RIGHT command in standard basic.

    I would like to read the second and sometime the first "Letter", "Data" in a string that holds the HEX data from a PS2 controller.


    Regards,
    Niklas
    '
    Take a look at PropBasic.Its about as close as you can get to basic with the propeller.
    Its different then what your use to but its Ballistic in speed.

    http://www.fnarfbargle.com/bst/Latest/
    http://www.fnarfbargle.com/PropBasic/
    '
    Heres a link to the post to help get started
    '
    http://forums.parallax.com/showthread.php?107051-Mac-Linux-Windows-IDE-Ver-0.19.3-quot-Now-with-new-improved-PropBasic-quot-release
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-30 14:07
    The built-in Spin function STRSIZE does the same thing as LEN. There's no built-in LEFT / MID / RIGHT. There are several string manipulation libraries in the Propeller Object Exchange. Have a look at Kye's here.
  • Mike GreenMike Green Posts: 23,101
    edited 2011-01-30 14:23
    It's also quite easy to do LEFT / MID / RIGHT using STRSIZE and BYTEMOVE, particularly if you don't do error checking. Remember that, in Spin, strings are byte arrays. You have to allocate a large enough array for the string allowing an extra byte for the zero byte that terminates the string.

    a := LEFT$(b, size)

    would be

    BYTEMOVE(@a, @b, size)
    BYTE[ @a+size ]~

    and

    a := RIGHT$(b, size)

    would be

    BYTEMOVE( @a, @b+STRSIZE( @b )-size, size+1)

    a := MID$(b, theStart, theEnd)

    would be

    BYTEMOVE( @a, @b+theStart-1, theEnd-theStart+1 )
    BYTE[ @a+theEnd-theStart+1 ]~

    I'm assuming that theStart and theEnd begin at 1.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-30 14:26
    String manipulation in Spin is *hard*. It isn't just a lack of Left and Mid, but also the way you store the strings.

    I have some code that does the functions you want - I'll see if I can find it when I get home.
  • Oldbitcollector (Jeff)Oldbitcollector (Jeff) Posts: 8,091
    edited 2011-01-30 14:26
    Here's part of an answer.. At least a StrRight
    VAR
         byte mydata[30] 
         byte strbuff[30]
    
    PUB StrRight(str,len) | i,l,z
    
      l:=strSize(str)
      z:=0
      repeat i from l-len to l
        strbuff[z] := byte[@mydata][i]
        z++
      return @strbuff
    

    Your byte sizes may vary, but this works for me.

    OBC
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-30 14:32
    PUB Left(Source, Destination,Number)   ' returns the left number of characters
       repeat Number
          byte[Destination] := byte[Source]
          Source++
          Destination++
       byte[Destination] :=0 ' add in the zero terminator
    
    PUB Len(Source) ' returns the length of the string
      return strsize(Source)
    
    PUB Mid(Source,Destination,Start,Number) ' returns strings starting at start with number characters
      Start-- ' so starts at the right position
      Source += Start ' position 1 is the first character
      repeat Number
        byte[Destination] := byte[Source]
        Source++
        Destination++
      byte[Destination] :=0 'add in the zero terminator  
    
    PUB Copy(Source,Destination) ' reverse order to stringcopy. Can also use to create strings eg copy(string("test"),@lineoftext1)
      bytemove(Destination, Source, (strsize(Source) + 1))
    
    PUB Str(Destination,Number) | n' convert a number to a string representation. Uses Basic syntax, ie leading character is a space if +ve, and is - if negative  
        n := number ' temp store for at the end when add the + or -
        Destination += 10 
        byte[Destination] := 0 ' terminator
        Destination--
        repeat result from 10 to 1
          byte[Destination] := ((||(number // 10)) + "0")
          number /= 10
          Destination--
    
        destination++    ' points to start again
    
        repeat while byte[destination] == "0"  ' while equal to zero remove this leading zero
          repeat result from 0 to 11 ' include the zero terminator as well
            bytemove(destination+result,destination+result+1,1)' shuffle to left
        repeat result from 11 to 1 
          bytemove(destination+result,destination+result-1,1) ' shuffle once to right - leading space or -
        byte[destination] :=" " ' leading space if positive. Can use trim to remove this
        if (n<0)
          byte[destination] := "-"
    
    PUB Stringfill(Destination, Number,AsciiValue)' fill string with a string, eg 3,65 is"AAA" and 2,32 is "  "
        bytefill(destination,AsciiValue,Number) ' same as Basic "string$" function and can also replicate space$ 
        byte[destination+number] :=0 ' zero terminator
    
    PUB Instr(Source,AsciiValue) | j ' find asciivalue in Source. Returns 0 if not found
        j := 0
        repeat result from 0 to strsize(Source)
          if byte[source+result] == AsciiValue
            j := result + 1 ' basic format where 1 is the last first character of a string
        return j 
    
    

    At the beginning of your 'main' code, reserve some memory for string space
    VAR
    
       byte LineOfText1[80] ' general purpose string buffer
       byte LineOfText2[80] ' general purpose string buffer
       byte LineOfText3[80] ' general purpose string buffer
    

    This is some of the code I used to test out these functions
          'printstring(@lineoftext1)                         ' testing string functions
          'str.left(@lineoftext1,@lineoftext2,3)  ' find leftmost characters in a string
          'printstring(@lineoftext2)
          'str.trimstring(@lineoftext1)
          'printstring(@lineoftext1)
          'str.trimstring(@lineoftext1)
          'str.mid(@lineoftext1,@lineoftext2,4,2) ' find middle characters in a string
          'printstring(@lineoftext2)
          'printstring(str.integertodecimal(str.len(@lineoftext2),5))
          'str.copy(string("hello"),@lineoftext1) ' copy fixed value into a string
          'printstring(@lineoftext1)
          'str.str(@lineoftext1,55) ' decimal to string with no leading zeros
          'printstring(@lineoftext1)
          'str.stringfill(@lineoftext1,10,65)
          'printstring(@lineoftext1)
          'str.str(@lineoftext1,1234)' convert to string
          'str.str(@lineoftext1,str.decimaltointeger(@lineoftext1)) ' convert back
          'printstring(@lineoftext1)
          ' str.left(@lineoftext1,@lineoftext2,str.len(@lineoftext1)-4) ' remove extension
          ' printstring(@lineoftext2) ' print it out
    

    Attached is Kye's string engine with the above Left Mid added at the end.
  • JonnyMacJonnyMac Posts: 9,208
    edited 2011-01-30 14:52
    You can also use bytemove for sub strings -- I do it like this (where I pass the destination and source addresses):
    pub left(destpntr, srcpntr, len)
    
    '' Copies left len characters from src string to destination str 
    
      bytemove(destpntr, srcpntr, len)
      byte[destpntr][len] := 0
    
    
    pub right(destpntr, srcpntr, len) | sl
    
    '' Copies right len characters from src string to destination str
    
      sl := strsize(srcpntr)                                        ' length of source
      bytemove(destpntr, srcpntr+(sl-len), len+1)                   ' include terminating 0
    
    
    pub mid(destpntr, srcpntr, start, len)
    
    '' Copies middle len characters from src to dest
    '' -- start is zero indexed
    
      bytemove(destpntr, srcpntr+start, len)
      byte[destpntr][len] := 0
    
  • jazzedjazzed Posts: 11,803
    edited 2011-01-30 15:19
    Good answer Jon. Also fastest since most of the work is done in PASM in the Spin interpreter.
  • Dr_AculaDr_Acula Posts: 5,484
    edited 2011-01-30 15:45
    Isn't this forum amazing? Post some code, and within a few minutes someone posts some improved code that is faster and shorter! Thanks Jon - I'll make those changes to my code when I get home.
  • seconikaseconika Posts: 18
    edited 2011-02-02 21:27
    Thank you all,

    This really is, a amazing forum!
    I will mark this as "Solved".


    Best regards.
    Niklas
Sign In or Register to comment.