Token: | Break |
Type: | Program Flow |
Usage: |
Break |
Lbl 0 Do Break Goto 0 LpWhile 1
That causes an infinite loop requiring a reset. There are variations however...
Do Break Goto 0 LpWhile 1 Lbl 0
only causes an infinite loop occasionally. Sometimes it works fine.
Do Break 'Goto 0 LpWhile 1
actually causes a Go error in a comment. The previous code fragments also have the same effect even if the Gotos are commented out.
This is the best effect I've had so far though:
Do Break '"+Goto 0 LpWhile Lbl 1
With that code I actually got a syntax error... wait for it... three bytes into the next program! Unfortunately, this bug is so screwed that it depends on your calc's current memory state, and it's not happening any more on my calc. If anyone else finds any other side-effects, I'd be interested to hear about them.
The basic buggy-code structure is:
[Lbl <label number>] <start looping construct> ;Do, While, For..To[..Step] Break [<statements>] ['<comment text>]{Goto |"}[<label number>] [<statements>] <end looping construct> ;LpWhile, WhileEnd, Next [Lbl <label number>]
As you can see, there are a lot of possible variants. The <end looping construct> is probably not needed either. As you can see, this code is extremely simple and often completely legal and common. Basically, the Break command has more bugs than a swarm of locusts and isn't safe to use in programs. (The {Goto |"} indicates that dodgy effects can be got by using a Goto or a single quote mark (or combinations)).
A similar effect can probably be got from:
For <start> To <end> [Step <step>] [<statements>] ['<comment text>]Goto [<statements>] [Next]
where <start> is originally greater than <end> (or less than <end> if <step> is negative).
The programmmers at Casio were faced with a difficulty. This was how to program the "exit from loop" internal command (as called by Break) so that it could cope with code such as this:
For 1 -> A To 10 A = 4 => Break Goto 1 ... ... Lbl 1 "HELLO WORLD" Next
What that code should do is print "HELLO WORLD" three times and then exit. But when they were programming the jump which Break uses, one of them must have realised that with Gotos around things would get complicated. So they made their "exit from loop" routine "follow" Goto and Prog jumps. Which doubtless seemed like a good idea at the time.
The problem was that their implementation was terrible. Firstly, it followed every Goto or Prog that it found. This includes ones such as:
A = 666 => Goto 0
If A was never 666 in the previous example, that Goto would never be followed except by Casio's routine which ignores the fact that the Goto follows an If. In fact, it ignores the fact that a Goto might be commented out entirely.
Secondly, they forgot one small problem. It is quite possible to make a Goto jump to a label which occurs before it in a program to create a loop. If this happens, their routine goes on forever looking for the end of the loop which it was trying to jump out of.
Thirdly, they forgot that looping constructs can be nested. Their method is simply to jump to immediately after the first "end of loop" line that they find, after following any Progs or Gotos. In code such as this, however, the first Next matches the second, not the first For:
For 1 -> A To 10 Break For 1 -> B To 10 Next "WRONG!" Next
Fourthly, they tried to keep this process hidden from the user. This meant that when it got stuck in an infinite loop, the user-level error handler didn't catch it. There was also the unfortunate side-effect that it also fails to catch the pressing of [AC] which means that you have to press the reset button on the back of your calc just to restore it to working order.
So there you have it. My theory of why the looping constructs are not to be trusted. As the situation stands, there are two solutions to the problem. You can either use these constructs in the nice, simple ways which the Casio programmers considered, cross your fingers and hope, or you can replace your looping constructs with "Lbl X...Goto X"s. The latter is slightly slower and makes your code less readable, but it doesn't suffer from this bug. It's up to you.
Written in notepad and compiled with WTA, for clean, consistent HTML.