Is it me, or is the simulator awry?

rnetzlof

New Member
When I present the following to the simulator, it runs forever. The outer loop seems to never notice that b0 has become zero.

Code:
#picaxe 14m

let b0 = 2
do while b0 <> 0
 let b1 = 3
 do
  let b2 = b1 * b0
  dec b1
 loop while b1 <> 0
 dec b0
loop
stop
Have I stumbled over a problem in the simulator, or is the difficulty in my grasp of the way things are supposed to work? I actually ran into the problem in a more useful program, but this (mis)behaves in the same way.
 

BCJKiwi

Senior Member
The problem is in your program.

In the simulator use the step rather than the run and you will very quickly see where the problem is.
 

rnetzlof

New Member
I see what's happening, and saw that before posting. What happens doesn't make much sense to me.

The inner loop executes 3 times. Control passes to the loop statement at the end of the outer loop, back to the outer do. b0 is then equal to 1.

The inner loop executes 3 times, control passes to the loop statement at the end of the outer loop, back to the outer do. b0 is then equal to 0.

Control then passes to the loop statement at the end of the inner loop. That seems an odd thing to have happen. I would have thought the loop statement at the end of the outer loop would be the place control goes to when the while condition is not satisfied.

Can loops not be nested?

It seems they can be, for if I avoid placing the while clause on the do, using only do and loop while ..., all works as I would expect.
 

BCJKiwi

Senior Member
The do...loop conditions can be at the top or the bottom.
Where they should be depends on what you want to have happening.

This works the way I think you want it;

Code:
#picaxe 14m
let b0 = 2
do 
 let b1 = 3
 do
  let b2 = b1 * b0
  dec b1
 loop while b1 <> 0
 dec b0
loop while b0 <> 0
stop
 

Dippy

Moderator
Good point BCJ, though Bob's code does 'appear' to run strangely in the simulator.

I'd have used a slightly more logical code structure (to help my addled brain).

Code:
#picaxe 14m

let b0 = 2

do
 let b1 = 3
 do
  let b2 = b1 * b0
  dec b1
 loop until b1=0
 dec b0
loop until b0=0
stop
Haven't checked bytes used etc.
 

hippy

Ex-Staff (retired)
Control then passes to the loop statement at the end of the inner loop. That seems an odd thing to have happen. I would have thought the loop statement at the end of the outer loop would be the place control goes to when the while condition is not satisfied.
Although I didn't test it, I presume that 'step' then continues down the program rather than going back to the inner DO loop, so everything is actually working as expected ?

This is one of those areas like "should END IF ever be seen as executed" within the simulator ? There's arguments for never, always or only if the ELSE executes or there is no ELSE clause. The simulator designer's decision doesn't always match what we'd like.

With any simulator it's saying "your program got to here", trying to make program flow meaningful when what is in source is often very much different to what is being executed within the chip even though the result is the same.

Like travel directions, "don't go left at the shop on the corner", the shop is largely irrelevant to progress but having got there and going by it gets flagged up.
 

BCJKiwi

Senior Member
Initially it seemed a logical process to me.
If the condition is at the top with the Do, then the program has to return to the top for the test. However it should then return to it's own loop, whereas it actually seems to just drop down to the first 'loop' it finds, rather than its true pair.

So I would say it is a bug - but is it only in the the simulator or is the behaviour the same in the chip? SOB's (Sweet Old Bob!) first post suggests the problem is in the chip as well.

Technical - How about some input on this one.
 
Last edited:

Dippy

Moderator
It does seem odd. Sorry I couldn't follow what hippy was saying, I think my hippy-analogy simulator got stuck :)

PS. Is there a simple button stroke for 'step' or do I have to use the mouse dropdown each time?
 

hippy

Ex-Staff (retired)
I ran the simulation and agree there is a bug in simulation. A simpler example ...

Code:
b0 = 0
do while b0 <> 0
 do
 loop ' <-- Gets stuck here
loop
It shouldn't be getting stuck where it does. Indeed it should never be getting there. I hadn't fully appreciated what rnetzlof was saying.
 

rnetzlof

New Member
Initially it seemed a logical process to me.
If the condition is at the top with the Do, then the program has to return to the top for the test. However it should then return to it's own loop, whereas it actually seems to just drop down to the first 'loop' it finds, rather than its true pair.
Bingo! That's what it's doing.

The silly little loops I posted were just to illustrate the problem. I had written a program using IF ... THEN GOTO ... statements all over the place which simulated just fine. Then I thought to do it in a Dijkstra-pleasing GOTO-less way. That's when the problem bit me.

As you say, when the condition is stated on the DO, condition = false seems to cause control to pass to the first LOOP following the DO, never mind what loop that LOOP is in. That doesn't seem to happen when all the conditions are on the LOOP statements, but in the instant case, I need to test at the head of a loop, a loop which has two or three other loops inside it.

Without going into a lot of extraneous detail, the original problem was something like this:

Code:
read prom_addr,servo_pos         ; value retrieved may be zero
do while servo_pos <> 0
  servo servo_number,servo_pos  ; move servo to default position
  do                                  ; stall here until user presses 1 of 3 buttons
    let data_in = pins AND 7
  loop while data_in < 1 OR data_in > 3
  if data_in = 1 then
    dec servo_pos
  elseif data_in = 2 then
    inc servo_pos
  else
    write prom_addr,servo_pos  ; record refined value
    let servo_pos = 0              ; which will cause the loop to end
  endif
  do                                    ; stall here until user gets off the button
    let data_in = pins AND 7
  loop while data_in <> 0
loop
The idea is that eeprom contains a nominal value for a servo position. Executing this routine allows the servo to be positioned, the user looks at the position of the servo and using buttons 1 or 2 nudges the servo one way or the other until he's happy. Then he presses button 3, the refined value is stored (to be used elsewhere in the program, and the loop ends.

What actually happened after sending in a 3 was that the program ended up looping on the "stall here until user presses 1 of 3" statements, when it should have exited the outer loop and gone on to execute code not shown here.

I avoided the problem (but not neatly) by the following barbarism:
Code:
read prom_addr,servo_pos         ; value retrieved may be zero
do while servo_pos <> 0
  servo servo_number,servo_pos  ; move servo to default position
x1: let data_in = pins AND 7       ; stall here until user presses 1 of 3 buttons
     if data_in < 1 OR data_in > 3 then goto x1
  if data_in = 1 then               
    dec servo_pos
  elseif data_in = 2 then
    inc servo_pos
  else
    write prom_addr,servo_pos  ; record refined value
    let servo_pos = 0              ; which will cause the loop to end
  endif
x2: let data_in = pins AND 7  ; stall here until user gets off the button
    if data_in <> 0 then goto x2:
loop
That, gross looking though it is, worked fine. However, the labels and branches to them inside a DO ... LOOP structure sets my teeth on edge. It apparently works because the first LOOP statement following the DO WHILE ... is in fact the one the failed test is supposed to find.
 

Technical

Technical Support
Staff member
Yes, this is a bug in the screen simulator we will look into - sorry for any confusion, however the real chip will work ok.
 

rnetzlof

New Member
Technical
Bob's first post indicates the problem is in the chip as well!
Caution! Misunderstanding in progress!

I don't even have a chip.

I've been writing and simulating programs to see if there's any chance I can do what I want to do using an 08m or 14m.

As it happens, there's a good chance, provided I can come up with the ancilliary hardware.
 

BCJKiwi

Senior Member
OK, my misunderstanding - thought this "I actually ran into the problem in a more useful program" indicated a working program as in a chip! Thanks for clearing that up - I'm sure Technical will be relieved.
 
Top