PNut/Spin2 Latest Version (v34s)

1235719

Comments

  • Thank you. I have a file that is big enough that the lack of editing niceties in PNut is getting in the way of productivity. I have code that runs fin on the P1 that I'm really struggling on the P2; the problem seems to be with nested if/elseif/else. For the moment, I'm assuming the error is mine -- I may call for help later, though.
  • JonnyMac wrote: »
    ...
    For the moment, I'm assuming the error is mine -- I may call for help later, though.

    No, it's not your fault, I reported the elseif error already for verson 34b and it got not fixed since then.

    Andy
  • Ariba wrote: »
    JonnyMac wrote: »
    ...
    For the moment, I'm assuming the error is mine -- I may call for help later, though.

    No, it's not your fault, I reported the elseif error already for verson 34b and it got not fixed since then.

    Andy

    Sorry, Andy! I never noticed your message. I will fix it today.
  • cgracey wrote: »
    cgracey wrote: »
    > @Ariba said:
    > Sorry, the dec methode from my example does still not work correct with the version 34c.
    > But this time I have found the problematic codeline. It's the elseif that does weird things.
    > If I write: else if r or i==1 tx("0")
    >
    > then it works. If I write elseif r or i==1 tx("0")
    >
    > then i gets overwritten with 0 or -1
    >
    > Andy

    Andy, Thanks for trying it. I will be back in the shop in a few minutes and will address this. Should be fixed in an hour.

    Whoa! I did see your message, but forgot all about it. I will be back home in about 3 hours and I'll get this fixed.

  • Okay, when you look at this please check also these problems:
      case i
        0: quit
    
    gives an error: internal.
    and quit is highlighted
      dirb[60] := 1
      repeat
        outb[60] ^= 1
        waitms(500)
    
    does not blink my LED on P60. I also tried [60-32].

    Andy
  • JonnyMacJonnyMac Posts: 6,727
    edited 2020-02-25 - 00:32:04
    No, it's not your fault, I reported the elseif error already for version 34b and it got not fixed since then.
    Thank you, Andy -- I have been pulling my hair out for the last three days trying to make code that has a bunch of elseif statement work. Thankfully, I have a lot of hair! :smiley:
  • cgraceycgracey Posts: 12,809
    edited 2020-02-25 - 01:17:05
    Jon, I'm sorry you guys have been suffering through this. I'll get it fixed soon.

    By the way, Andy, you need to use a period in front of the bracket if you want to call out a bit. Otherwise, it looks like an index to the compiler.

    DIRB.[60]
  • roglohrogloh Posts: 2,342
    edited 2020-02-25 - 01:52:39
    cgracey wrote: »
    By the way, Andy, you need to use a period in front of the bracket if you want to call out a bit. Otherwise, it looks like an index to the compiler.

    DIRB.[60]

    Unfortunately I suspect that will catch out a lot of people. Particularly if there is no warning, which there probably won't be because it is still valid syntax. People will just have to adapt I guess.

    Update: Actually maybe if the name of the register being referenced is a special one, like OUTA, OUTB, DIRA, DIRB etc there could be a warning eventually shown in these cases because it is unlikely you'd be using an index this way with the special registers.
  • Okay, with DIRB.[60] and OUTB.[60] it works.

    This syntax is incompatible to Spin1, but makes some sense. In Spin1 the [index] means bits for SFRs, but bytes/word/longs for variables.

    Now you can access a bit from PortA or PortB with the same command:
      n := 60                   'blink LED on P60
      dira[n>>5].[n] := 1
      repeat
        outa[n>>5].[n] ^= 1
        waitms(250)
    
  • Yes that use case is handy to avoid worrying which port is which and coding cases for both dira and dirb etc everywhere.
  • Remember, for bit addresses, bits 4..0 form the base bit number and bits 9..5 form the additional bits above the base.
  • AribaAriba Posts: 2,337
    edited 2020-02-25 - 03:25:06
    So the above code also affects P61. It must be:
      n := 60                   'blink LED on P60
      dira[n>>5].[n & 31] := 1
      repeat
        outa[n>>5].[n & 31] ^= 1
        waitms(250)
    

    For single bits PINWRITE (or PINW) may be the better alternative.
  • rogloh wrote: »
    Yes that use case is handy to avoid worrying which port is which and coding cases for both dira and dirb etc everywhere.

    That's why we have instructions which handle pinfields instead of bitfields:

    PINLOW(pinfield)
    PINHIGH(pinfield)
    PINTOGGLE(pinfield)
    PINREAD(pinfield)
    PINWRITE(pinfield, value)
    etc.

    The pinfield just can't cross 32-pin ports.

    In Spin2, it's better to use the PINxxxx instructions than mess with DIRA/DIRB/OUTA/OUTB/INA/INB.
  • Ariba wrote: »
    So the above code also affects P61. It must be:
      n := 60                   'blink LED on P60
      dira[n>>5 & 1].[n & 31] := 1
      repeat
        outa[n>>5 & 1].[n & 31] ^= 1
        waitms(250)
    

    For single bits PINWRITE (or PINW) may be the better alternative.

    I added '& 1' to your example above to make it failsafe.

    The PINxxx instructions can handle up to 32 pins, with the number of additional pins in pinfield[10:6].
  • cgraceycgracey Posts: 12,809
    edited 2020-02-25 - 09:02:18
    I just posted v34k at the top of this thread.

    The ELSEIF/ELSEIFNOT and NEXT/QUIT bugs were fixed:

    https://drive.google.com/file/d/1FYBsZJrqYjXI7dyoOQHHn1HQrZ-a4lJw/view?usp=sharing

    The bugs were due to a register not being preserved during reuse.
  • cgraceycgracey Posts: 12,809
    edited 2020-02-25 - 18:54:25
    Jon and Andy, does v34k fix the problems you were seeing?
  • Yes, my code with the elseif and quit works now.
    Thank you Chip.
  • Ariba wrote: »
    Yes, my code with the elseif and quit works now.
    Thank you Chip.

    Thanks, Andy.
  • JonnyMacJonnyMac Posts: 6,727
    edited 2020-02-26 - 02:09:00
    I may have missed this detail somewhere, but it seems like with Spin2 I have to explicitly declare a variable on the method slug-line.
    This
        return someValue
    
    ...always throws an error in Spin2. Is this restriction in place due the ability to return multiple values?
  • Yes, you need to declare all return variables
  • cgraceycgracey Posts: 12,809
    edited 2020-02-26 - 05:50:22
    JonnyMac wrote: »
    I may have missed this detail somewhere, but it seems like with Spin2 I have to explicitly declare a variable on the method slug-line.
    This
        return someValue
    
    ...always throws an error in Spin2. Is this restriction in place due the ability to return multiple values?

    Yes. As Rayman said, you need to name all return values after the parameters. You can either do a 'RETURN x,y,z' to return specific values, or just do a RETURN to return the values as last written. All return values are initialized to zero on method entry.

    If a method has no return variables specified, it cannot return anything.
  • JonnyMacJonnyMac Posts: 6,727
    edited 2020-02-27 - 02:26:43
    cgracey wrote: »
    Jon and Andy, does v34k fix the problems you were seeing?

    I don't know if I am looking past a simple coding error, or if there's still a problem with if/elseif/else. This code -- which compiles on P1 and P2 -- only works on P1; there is no output using the P2.
    pub format(p_str, p_args) | idx, c, asc, field, digits
    
    '' Emit formatted string with escape sequences and embedded values
    '' -- p_str is a pointer to the format control string
    '' -- p_args is pointer to array of longs that hold field values
    ''    * field values can be numbers, characters, or pointers to strings
    
      idx := 0
    
      repeat
        c := byte[p_str++]
        if (c == "\")
          c := byte[p_str++]
          if (c == "\")
            tx("\")
          elseif (c == "%")
            tx("%")
          elseif (c == "r")
            tx(CR)
          elseif (c == "n")
            tx(LF)
          elseif (c == "t")
            tx(TAB)
          elseif (c == "q")
            tx(34)
    
        elseif (c == 0)
          quit
    
        else
          tx(c)
    
    Note: There is more to this method, but I started putting it back a small chunk a a time for testing. If I comment out the section that handles "\" and change elseif (c ==0) to if (c == 0) it will print the raw string.
  • I decided to write a simple test to get away from my project code -- I still think there is a problem with if/elseif/else. In this simple little demo, the problem seems to be in the X (outer) layer. I don't understand the internal mechanics, but it seems like there is a jump error and the code is not exiting properly from the Y layer; it goes back to X and sometimes runs again, often getting trapped in a loop.
    dat
    
      TooLow        byte    "? is too low.", 13, 0
      TooHigh       byte    "? is too high.", 13, 0
    
    
    pub main() | x, y, z, total
    
      setup()
      
      ' open PST, enable, then press Enter
      
      wait_for_terminal(true)
      
      term.str(string("P2 Testing", 13))
    
      ' looking for 25x
      
      x := 2
      y := 5
      z := 7
      
      if (x == 0)
        TooLow[0] := "X"
        term.str(@TooLow)
      
      elseif (x == 1)
        TooLow[0] := "X"
        term.str(@TooLow)
      
      elseif (x == 2)
        if (y < 5)
          TooLow[0] := "Y"
          term.str(@TooLow)
    
        elseif (y == 5)
          total := (x * 100) + (y * 10) + z
          term.str(string("Total is "))
          term.dec(total)
    
        elseif (y == 6)
          TooHigh[0] := "Y"
          term.str(@TooHigh)
    
        else
          TooHigh[0] := "Y"
          term.str(@TooHigh)
      
      else
        TooHigh[0] := "X"
        term.str(@TooHigh)
    
  • Jon, I can see that something is going wrong with your code. I'm disassembling it now to try to figure out what is wrong.
  • Jon, it looks like the conditional branching is all right. I think something is going on with some other bytecodes, but I'm not sure what.

    I've made this little program to test nested IF structures and I can't get it to fail. You can change a..f values to get different results on the LEDs:
    con
    
      leds = 56 addpins 7
    
    pub main() | a,b,c,d,e,f
    
      a := 0
      b := 0
      c := 1
      d := 0
      e := 0
      f := 0
      
      if a
        pinwrite(leds,!1)
      elseif b
        pinwrite(leds,!2)
      elseif c
        if d
          pinwrite(leds,!3)
        elseif e
          pinwrite(leds,!4)
        elseif f
          pinwrite(leds,!5)
        else
          pinwrite(leds,!6)
      else
        pinwrite(leds,!7)
    
      repeat
        pintoggle(63)
        waitms(100)
    

    I will work on this more in the morning.
  • Jon, this program fails:
    con
    
      leds = 56 addpins 7
    
    pub main() | a,b,c,d,e,f
    
      a := 1
      b := 0
      c := 0
      d := 0
      e := 0
      f := 0
      
      if a
        pinwrite(leds,!1)
      elseif b == 1
        pinwrite(leds,!2)
      elseif c
        if d
          pinwrite(leds,!3)
        elseif e
          pinwrite(leds,!4)
        elseif f
          pinwrite(leds,!5)
        else
          pinwrite(leds,!6)
      else
        pinwrite(leds,!7)
    
      repeat
        pintoggle(63)
        waitms(100)
    

    instead of 'ELSEIF b', it does 'ELSEIF b == 1'. Your code was doing this, too, but I'm not seeing where there's a problem with the '==' operator.
  • I see the problem now. The branches use RFVARS data for relative offsets and I was not compiling the RFVARS data correctly. When the branch became 64+, it became negative to the hardware. Fixing it now. Sorry about this.
  • cgraceycgracey Posts: 12,809
    edited 2020-02-28 - 14:35:41
    I just posted v34L which fixes this problem of RFVARS not being compiled correctly. This was affecting all branches between 64..128 bytes in IF/ELSEIF/ELSE/CASE/REPEAT blocks. This must have given a real sense of flakiness to anyone using Spin2.
  • JonnyMacJonnyMac Posts: 6,727
    edited 2020-02-28 - 15:57:02
    Thanks, Chip, that seems to have fixed things. I'm using a largish if/elseif/else structure in my formatted strings routine for serial output (demo attached)
  • cgraceycgracey Posts: 12,809
    edited 2020-03-01 - 12:30:46
    Jeff Martin and I were talking about the status of the PropellerTool which he's updating to accommodate P2 and we had a neat idea...

    We were thinking about how to facilitate rapid development and it occurred to us that we could swap in new Spin2 methods DURING program execution, complete with special debug commands. Modifying a method during application execution is possible because there's an atomic long pointer to each method within each object. If we reserve a few KB of workspace in the hub, we could load new methods into that space and modify the long pointer in the object structure to point to the new method. The next time it gets called, the NEW method runs.

    This is neat because it lets you change functionality in critical methods without having to restart your application. The swap-in time, including compilation and download will be just a fraction of a second.

    Meanwhile, I started documenting Spin2. Nothing really new here, yet. Just getting what I've already got into Google Doc format:

    https://docs.google.com/document/d/16qVkmA6Co5fUNKJHF6pBfGfDupuRwDtf-wyieh_fbqw/edit?usp=sharing
Sign In or Register to comment.