Shop OBEX P1 Docs P2 Docs Learn Events
P1 to P2 conversion question - solved — Parallax Forums

P1 to P2 conversion question - solved

DiverBobDiverBob Posts: 1,114
edited 2021-10-15 18:04 in Propeller 2

I have a piece of parsing code that I have used successfully for a long time on a P1 but am getting strange results running the code on the P2.

pub extractfield(n, pstr, sep):result | len, val, sign, flag, k                        'routine designed by Jon McPhalen
' returns decimal value of filed n
' pstr is source string/buffer
' sep is seperator character
   ' look for start of field
  len :=  strsize(pstr)                                                         ' maximum length to search
  repeat while (n > 0)
    if byte[pstr++] == sep                                                      ' if character is seperator
      --n                                                                       ' decrement field count
    if (--len == 0)                                                             ' if end of string
      return 0
  ' extract value
  val := 0
  sign := 1
  flag := false
  repeat len
    k := byte[pstr++]                                                           ' get character from string
    case k
      " " : if (flag)                                                           ' if already in field
              quit
      "-" : ifnot (flag)                                                        ' if not in field
              sign := -1                                                        ' set sign
            else
              quit
      "0".."9" : val := (val * 10) + (k - "0")                                  ' convert ascii to decimal
                 flag := true                                                   ' mark entry to field
      other : quit
  return val * sign

When feeding a string ( n = '4' pstr = "$,900,0,0,-4,0,0" sep = ",") into the function it works perfectly until it gets to a negative entry (-4 in this case). It returns a value like 5532 instead of -4. if I remove the '* sign' from the final return statement then I get the positive value of the entry (4).
So it appears to be a problem with the "return val * sign" code. Does the P2 not process returns the same as the P1? I did try putting 'val := val * sign' just before the return statement with return only returning val but got the same response which makes me feel the problem may be in the sign variable instead. But the code is pretty straightforward so I'm not seeing where to go from here. Anyone see what I am missing?

Comments

  • I have a vague recollection about spin2 having numeric variables unsigned by default. Not specifically remembering, though.

    Are you using Prop Tool, Pnut, or FlexSpin?

  • Using PropTool 2.5.3

  • AribaAriba Posts: 2,690

    If I call your methode from this main program, I get -4 as the result.

    PUB main() | x
      x := extractfield(4,string("xx,yy,123,55,-4,e"),",")
      debug(sdec(x))
      repeat
    

    Andy

  • I’ll try that out and report back. I didn’t try using Debug, I’ve been sending the results to PST, could that be an issue….

  • Is this in a secondary cog? Are you running out of stack?

  • JonnyMacJonnyMac Posts: 9,159
    edited 2021-10-14 21:10

    I did a little clean-up of my old formatting and it seems to work.

    pub run_extraction() | x
    
      repeat x from 0 to 4
        term.dec(extract_field(x, @Message, ","))
        term.tx(13)
    
      term.tx(13)
    
      repeat x from 0 to 6
        term.dec(extract_field(x, @BobTest, ","))
        term.tx(13)
    
    
    dat
    
      Message       byte    "10, -5, 167, -2000, Jon", 0
      BobTest       byte    "$,900,0,0,-4,0,0", 0
    
    
    pub extract_field(n, p_str, sep) : value | len, sign, flag, k  
    
      len := strsize(p_str)                                     
      repeat while (n > 0)
        if byte[p_str++] == sep                                  
          --n                                                   
        if (--len == 0)                                         
          return 0
    
      sign, flag := 1, false
    
      repeat len
        k := byte[p_str++]                                       
        case k
          " " :
            if (flag)                                       
              quit
    
          "-" :
            ifnot (flag)                                    
              sign := -1                                    
            else
              quit
    
          "0".."9" :
             value := (value * 10) + (k - "0")              
             flag := true
    
          other :
            quit
    
      value *= sign
    

  • Thanks for looking at the code Jon, I’ll re-enter the routine with your changes.

  • Jon, I ran your update with some sample data and it output correctly when running it by itself as a test. However I still get the erroneous response to negative numbers when I run it in my program. The input data looks good when I examine the string and Cluso's multiport serial driver program display to the PST works with the test data. I increased the input buffer size with no change. I need to come up with another idea since obviously it isn't the extraction code or display code.
    I've tried several variations of the code but keep getting the same output value of 5532 when a -4 is the parsed value. I'm sure it's a mistake on my part so now I just have to narrow it down. Time to hang it up for the night and come at it fresh tomorrow. Thanks for the help so far everyone.

  • JonnyMacJonnyMac Posts: 9,159
    edited 2021-10-15 15:16

    I think it may have to do with your output variable type, or something that's affecting it. I did this:

      x := -4
      term.dec(x & $FFFF) ' truncate to word
    

    ...and the output is 65532. If you're doing some sort of formatted display that is only using four digits, you'd get 5532.

  • @JonnyMac said:
    I think it may have to do with your output variable type, or something that's affecting it. I did this:

      x := -4
      term.dec(x & $FFFF) ' truncate to word
    

    ...and the output is 65532. If you're doing some sort of formatted display that is only using four digits, you'd get 5532.

    I hadn’t thought of that Jon. I’ll get down and check that out.

  • I did try to figure out how you'd ever get from -4 to 5532. Truncating to 16 bit first and then to 4 digits did not come to mind...
    Though that's a cascade of two unrelated things going very wrong, which seems unlikely.

  • I'm of the idea this is a set of events that would be easy to encounter.

  • @JonnyMac said:

    I'm of the idea this is a set of events that would be easy to encounter.

    That’s exactly the code layout for the PST to display the value. I changed the display string to display 5 digits and got 65532 as a value. Once I changed the variables to longs, I get the correct output.
    Jon, you are a Spin coding savant! Last night after I got into bed I thought the only thing I hadn't checked was the type of variable. You had the answer when I checked this morning. Thank you once again for the heads up!

  • I'm glad you got things sorted, Bob.

    Jon, you are a Spin coding savant!

    That's kind, but the truth is that I've stumbled through enough potholes that I can spot them more easily now.

    Once I changed the variables to longs, I get the correct output.

    There can be a valid reason to use a word instead of a long, but still recover the sign. On a control project for JonyJib we send signed words over RS-485 from the controller to the driver. You can use signx in the P2 to convert to a long or correct for display.

  • Test post

Sign In or Register to comment.