Shop OBEX P1 Docs P2 Docs Learn Events
SPIN IF/ELSE block limit? — Parallax Forums

SPIN IF/ELSE block limit?

KDBrownKDBrown Posts: 13
edited 2014-10-10 05:36 in Propeller 1
I came upon a surprise yesterday, and that was an error message saying that I had exceeded a block limit of 8. I did not grab a snapshot of the message and I should have, but I was able to refactor the code to make this go away pretty quickly so it was not a big problem. But the question is this: is there any reference material about this? I read over the Prop Manual Pages 112...117 and found no mention of this limit

Comments

  • RaymanRayman Posts: 14,654
    edited 2014-10-09 08:53
    I found that the hard way too. I think it's for all loops. I think it is in the manual somewhere, but don't remember where..
  • Heater.Heater. Posts: 21,230
    edited 2014-10-09 08:56
    I don't recall such limits being documented anywhere. For example I found one can only have 256 branches in a case statement.
  • Mag748Mag748 Posts: 266
    edited 2014-10-09 09:21
    Is this the error you speak of?

    Capture.PNG


    Thanks,
    Marcus
    625 x 300 - 16K
  • Heater.Heater. Posts: 21,230
    edited 2014-10-09 09:32
    There are those who would argue that having code nested 8 levels deep is a sure sign of a bad design. It can certainly make it hard for people to read.
    I'm not sure I subscribe to that view, after all you may want to be traversing a 10 dimensional array or other data structure.
    But if you do, the the error on exceeding a nesting of 8 is perhaps a good thing not just an arbitrary compiler limitation.

    But what about the 256 limit on branches in a case statement?
    (Actually, now that I think about it it might be less than that. Like 64 or something. I hit the limit when switching on opcodes in my first 8080 simulator so 256 would have been enough. Anyone know the limit here?)

    Perhaps such a huge case statement is also a sign of bad design. But then there is no way of easily dispatching on a range of values in Spin. Like say a table full of function addresses than can be indexed and jumped to as in C.
  • Mag748Mag748 Posts: 266
    edited 2014-10-09 09:37
    Heater. wrote: »
    Anyone know the limit here

    Capture.PNG
    451 x 244 - 21K
  • Heater.Heater. Posts: 21,230
    edited 2014-10-09 09:47
    There we go. Thanks.

    Now, does it make sense to have cases bigger than that? Is it good style?
  • ratronicratronic Posts: 1,451
    edited 2014-10-09 09:58
    In Spin you can specify a range for a Case code block ie 100..500 :. Is this possible in C? I haven't found it so far.

    Didn't mean to go off topic but you guy's are talking about it.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-10-09 10:02
    Heater. wrote: »
    There we go. Thanks.

    Now, does it make sense to have cases bigger than that? Is it good style?
    Try to implement a bytecode interpreter with more than 64 byte codes. Actually, Andre' LaMothe ran into this problem when he was creating his Chameleon products because he had a bunch of opcodes that the PIC or AVR could send to the Propeller to perform various functions. When that number got larger than 64 he had to use nested case statements. Actually, you might want to do that anyway because I believe that case essentially compiles to a series of IF/THEN/ELSE statements so the later cases execute more slowly than the earlier ones.
  • lardomlardom Posts: 1,659
    edited 2014-10-09 10:06
    I prefer Case which is much easier to read and I think a bit faster.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-09 10:14
    Case statements are evaluated sequentially, and are essentially the same as performing IF/ELSEIF. The difference is that the case variable stays on the stack after each evaluation, and a single bytecode is used to perform the test and execute a jump. At least I think that's how it works. This results in more compact code, and faster execution than IF/ELSEIF.
  • Heater.Heater. Posts: 21,230
    edited 2014-10-09 10:15
    David,

    Yes, as I said above my first experiments into an 8080 emulation on the Prop were done in Spin. My first ever Prop program. Horrible slow but at least I wanted to see if I had the logic correct and could run some 8080 code. That is when I hit the limit.

    I have no idea how case gets compiled in Spin. The fact that it allows complicated ranges in each case suggests that it is compiled to a bunch of "if" statements basically.

    I always thought that the case statement (switch) in language like C was a way to do a fast look up on integer values to determine what code to execute next. So a switch involving cases 0,1, 2, 3 etc should not compile to a bunch of tests but rather a single lookup and jump. Very fast.

    Anyway, case (switch) is just something high level language designers had to dream up to get stuff done efficiently after Edsger Dijkstra pronounced "goto considered harmful"

    Exceptions are yet another work around to that ban on goto.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-09 10:22
    The case statement uses three bytecodes - casevalue, caserange and casedone. casevalue is used when a single value is specified, and caserange is used when a range is specified. I believe "0, 1, 2, 3:" will generate four casevalue bytecodes, and "0..3:" will generate a single caserange bytecode. casedone is used to purge the case variable from the stack and jump to the code after the case statements.
  • David BetzDavid Betz Posts: 14,516
    edited 2014-10-09 10:43
    Dave Hein wrote: »
    The case statement uses three bytecodes - casevalue, caserange and casedone. casevalue is used when a single value is specified, and caserange is used when a range is specified. I believe "0, 1, 2, 3:" will generate four casevalue bytecodes, and "0..3:" will generate a single caserange bytecode. casedone is used to purge the case variable from the stack and jump to the code after the case statements.
    So essentially it checks each value or range in sequence until it finds one that matches. This is essentially an if/then/else chain except with the optimization that it only evaluates the CASE expression once and has special opcodes to help with the search.
  • Dave HeinDave Hein Posts: 6,347
    edited 2014-10-09 10:55
    That's correct.
  • Phil Pilgrim (PhiPi)Phil Pilgrim (PhiPi) Posts: 23,514
    edited 2014-10-09 11:38
    Given the sequential nature of case, 64 choices is probably too many anyway for any kind of efficiency. For that many -- or more -- separate values, it would be better to factor them into sub-ranges, with another case group in each one. The ultimate limit would be a binary search tree (i.e. two cases at each level for log(n) comparisons), but the overhead would probably kill you before you got to that point.

    -Phil
  • Heater.Heater. Posts: 21,230
    edited 2014-10-09 12:15
    Phil,

    If your case is testing a bunch of numbers then one can see how that could be made into nested cases and a binary search tree is the limit of that idea. This works because numbers have an order.

    Now, if your cases are numbered sequentially then that can be reduced to a table look up. A constant time operation. Much better than serially testing each case or the nLog(n) time of a binary search.

    It's not clear to me how you would make a binary tree out of the general case of the "case" statement where the values switched on are not numbers but expressions. Like this from the Prop manual:
    case X+Y 'Test X+Y
        10 :    !outa[0] 'X = 10? Toggle P0 
        A*2 :   !outa[1] 'X = A*2? Toggle P1 
        30..40: !outa[2] 'X in 30 to 40? Toggle P2 
    

    By the way, I notice the manual has errors here. The code comments indicate we are testing X where as we are actually testing X+Y.
  • KDBrownKDBrown Posts: 13
    edited 2014-10-10 05:36
    Mag748 wrote: »
    Is this the error you speak of?

    Capture.PNG


    Thanks,
    Marcus
    That is indeed the message, however no way did I have more than 4 or 5 levels down! Not sure I could re-create what I did have, but the disparity between the depth (as shown by the indentation indicators) and the number 8 is why I sought to find what the message actually meant. It was certainly not as clear cut as your obvious example, but thanks for doing that. I see the topic has drifted a bit, and also that there is a LOT of feedback on this forum.
Sign In or Register to comment.