Shop OBEX P1 Docs P2 Docs Learn Events
repeat <count> — Parallax Forums

repeat <count>

Please, can you define count ?

Is it decimal?
can be HEX?
is that signed, or unsigned?
What is the maximum value, and the minimum?

How can I loop the whole $00_00_00_00 to $FF_FF_FF_FF range?
or downwards (from $FFFFFFFF to 0)?

The following code does not do what I a expect it to do:

   repeat i from 0 to $FFFF_FFFF
     <print i>

   repeat i from $FFFF_FFFF to 0
     <print i>

I guess that currently it is signed. As when I try to do this:

  repeat j FROM $FFFFFFFF-1 TO 10
    ser.printf("j : %x \n", j)

It shows:

j : FFFFFFFE
j : FFFFFFFF
j : 00000000
j : 00000001
j : 00000002
j : 00000003
j : 00000004
j : 00000005
j : 00000006
j : 00000007
j : 00000008
j : 00000009
j : 0000000A

But when I do this:

  repeat j FROM -1 TO 0
    ser.printf("j : %x \n", j)

I get just only the following two counts:

j : FFFFFFFF
j : 00000000

Comments

  • I guess that currently it is signed.

    Yes. Integers in Spin are signed, so what you're seeing is correct. Negative values use 2s compliment, so -1 is in fact $FFFFFFFF. $FFFFFFFF-1 is -2, which in hex is $FFFFFFFE

  • Thanks! Is there any way in which I could 'force' the repeat command to loop in unsigned order all positions from 0 to fffffff (and in reverse)? or should I need PASM for that?

  • What happens if you add a

    repeat j from -1 to 0 step -1
    

    ???

  • JonnyMacJonnyMac Posts: 8,923
    edited 2021-04-10 16:15

    Here's a possible solution: using an unsigned comparison ( +< or +> ) to control the repeat loop. This code

      x := $7FFF_FFF7                       ' posx - 8
      repeat while (x +<= $8000_0008)       ' negx + 8
        term.fhex(x, 8)
        term.tx(13)
        x++
    

    ... produces this output:

    As you can see, the unsigned comparison fixes the posx/negx boundary issue with signed values. Now... how long is it going to take to loop through $1_0000_0000 values?

    I did verify that it works in both directions with this change:

      x := $8000_0008                       ' negx + 8
      repeat while (x +>= $7FFF_FFF7)       ' posx - 8
        term.fhex(x, 8)
        term.tx(13)
        x--
    
  • Clock LoopClock Loop Posts: 2,069
    edited 2021-04-10 16:24

    @Ramon said:
    The following code does not do what I a expect it to do:

       repeat i from 0 to $FFFF_FFFF
         <print i>
    
       repeat i from $FFFF_FFFF to 0
         <print i>
    

    Does C let you input decimal max and min numbers for a long?

    Like so?

            Repeat i from -2_147_483_648 to 2_147_483_647
    
            Repeat i from 2_147_483_648 to -2_147_483_647
    

    The prop manual says that is the range for a long.

  • MagIO2MagIO2 Posts: 2,243
    edited 2021-04-10 16:20

    Funny ... just out of curiosity I tried it myself ...

    @cgracey <- attention flag ;o)

    Adding "step -1" does not change anything compared to "step 1".
    Somehow I tend to say that this is a minor bug in the SPIN2 interpreter, because it is not doing, what is written there in code.

    If I add -1 to -1, I get -2 in my math. So, it should go the other way to come to 0.

    And written in the document:

    REPEAT < variable > FROM < first > TO < last > STEP < delta >        - Repeat while iterating <variable> from <first> to <last>, stepping by +/- < delta >
    

    Of course the code dealing with the step also needs to work with steps that do not exactly match ... for example if step is set to 2 the loop as given above should only give one output which is -1. That's the reason why the current implementation behaves like that. But I think it should be possible to deal with all these problems.

  • It's not a bug, Spin ignoring the sign of the STEP value is documented and intended behavior.

  • Ignoring is source of so many problems. So, I don't like it.

    Compiler should then throw an error or at least a warning with a pointer to the specs - which can be miss-interpreted as well. From the short line I copied from the specs, I thought it would be allowed to enter +/- values as delta. But actually it means, that SPIN is determining + or - by itself.

  • i refuse to learn spin because it is one more arm to wrestle with while learning a new cpu architecture :smile:

  • JonnyMacJonnyMac Posts: 8,923
    edited 2021-04-10 20:17

    It's a subtle thing in the documentation, but the sign of delta is meant to keep the loop control variable between the start and finish limits.

    The repeat command automatically determines whether the range suggested by Start and Finish is increasing or decreasing.

    The loop then terminates because ... Delta ... is outside the range of Start to Finish.

    If we coded a loop like this and the original sign of delta was maintained:

      repeat x from -5 to 0 step -1
        ' do something
    

    ...x would be forced outside the start and finish range. One could force the issue by re-coding repeat:

      x := -5
      repeat while x <= 0
        ' do something
        --x
    

    This works, but you get a runaway loop.

  • @JonnyMac said:
    Now... how long is it going to take to loop through $1_0000_0000 values?

    I get about nineteen and a half days. It would be MUCH faster without debug turned on. ;)

  • I guess that current unsigned mode would be good maybe for driving DACs, or CORDIC. (for something that has polarity).

    Would not be great if the repeat command is expanded to cover other many uses?

    Examples:

      repeat <variable> from $00 to $FF 
         print variable
    
      output: $00 $01 .. $FE $FF  (256 values)
    
      repeat <variable> from $00000000 to $FFFFFFFF 
         print variable
    
      output: $00000000 $00000001 .. $FFFFFFFE $FFFFFFFF  (4,294,967,296 values)
    
      repeat <variable> from $00 to $FF forever
         print variable
    
      output: $00 $01 .. $FE $FF $00 $01 .. $FE $FF $00 .. (infinite values)
    
      repeat <variable> from %11 to %00 forever
         print variable
    
      output: %11 %10 %01 %00 %11 %10 %01 %00 .. (infinite values)
    
      repeat <variable> (from %00 to %11) << 3
         print variable
    
      output: %00000 %01000 %10000 %11000 (4 values)
    
      repeat <variable> (from %00 to %11) << 3 forever
         print variable
    
      output: %00000 %01000 %10000 %11000 %00000 %01000 %10000 %11000 ..  (infinite values)
    

    Repeat is one of the main control instructions for SPIN2.

    Wouldn't be great if there is some option to choose behavior (signed, unsigned, max/min limits, behavior on rollover (stop, or keep loop forever), etc ...? Imagination is the limit !

    Or maybe this is not possible because the spin2 repeat is 'tied' to the assembler rep instruction (or any other) and it doesn't allow those different modes?

  • RamonRamon Posts: 484
    edited 2021-04-11 04:48

    @Surac said:
    i refuse to learn spin because it is one more arm to wrestle with while learning a new cpu architecture :smile:

    PASM is as single arm, but it is the arm of a Sumo wrestler. I don't dare, yet. :smile:

    (A step-by-step debugger/assembler/disassembler for P2 would be very helpful. I learned x86 opcodes just with MS-DOS debug.com)

  • JonnyMacJonnyMac Posts: 8,923
    edited 2021-04-11 05:15

    Would not be great if the repeat command is expanded to cover other many uses?

    No. I've been coding the Propeller for over 16 years and have never once -- in the course of dozens of commercial projects -- ever wanted anything different from the options currently available for repeat.

    This already works

      repeat <variable> from $00 to $FF 
         print variable
    
      output: $00 $01 .. $FE $FF  (256 values)
    

    You can get past the posx/negx boundary by using repeat while as I demonstrated earlier.

    Adding forever is not needed when you can already do this:

      repeat
        repeat <variable> from $00 to $FF
           print variable
    
      output: $00 $01 .. $FE $FF $00 $01 .. $FE $FF $00 .. (infinite values)
    

    This is unnecessary syntax

    repeat <variable> (from %00 to %11) << 3
         print variable
    
      output: %00000 %01000 %10000 %11000 (4 values)
    

    You can do it like this

      repeat <variable> from %00000 to %11000 step %01000
        print variable
    

    or...

      repeat <variable> from %00 to %11 step %01
        print (variable << 3)
    

    And, finally, drop the new syntax and use what's available and documented

      repeat
        repeat <variable> from %00000 to %11000 step %01000
          print variable
    

    To me, Spin's simplicity is a virtue and there are far more important priorities for Parallax than to redefine something that already works well.

    Or maybe this is not possible because the spin2 repeat is 'tied' to the assembler rep instruction (or any other) and it doesn't allow those different modes?

    If you ever downloaded PNut you have a copy of the interpreter source code. Have a look.

  • Clock LoopClock Loop Posts: 2,069
    edited 2021-04-11 05:22

    I just swap the two when I want to go the other way.
    Keeping my custom range, I did this exact thing when i needed to play the bytes of a 8-bit wav backwards to extend the middle,
    or skip the middle of the wave to make the sound very short. I used variables so i can change it in the loop.

      repeat i from b to n
    
        If i > 6_000 And Short == 1
          i := 27_000
          Short := 0
    
        If i > 26_000 And Sustain == 1
          RevSw := 1
          b := n
          n := 0
    
        If i < 14_000 And RevSw == 1
          RevSw := 0
          n := b
          b := 0
    
  • JonnyMacJonnyMac Posts: 8,923
    edited 2021-04-11 05:25

  • RamonRamon Posts: 484
    edited 2021-04-11 06:36

    Surac was right. Definitively PASM is the way to go, no matter how hard the task would seems to be.

    Thank you for pointing about the SPIN2 interpreter code. Was not aware about that. It is there (Here just in front of me!). Hope that reading the code will help me as I was about to start another thread about how to do a simple string comparison. I get compile error on any attempt to try STRCMP, and could not find any example out there. How could it be that I am not able to find out something so simple as a string compare? Edit: Found it !!!

Sign In or Register to comment.