Menu
JAQForum Ver 19.10.27

Forum Index : Microcontroller and PC projects : interesting DO...LOOP anomaly in mmbasic (MX170, 5.05.05)

Posted: 01:36pm
14 Jun 2025
Copy link to clipboard
robert.rozee
Guru

i don't know if this has been brought up before, but... while adding a pause/resume ability to a program, i found an interesting anomaly in the way the MX170 version of mmbasic handles DO...LOOP within single-line if statements. here is a quick works/fails example i put together:

Print "expanded - works correctly"
n=1
Do
 i=1
 Print ">";
 If n>0 Then
             Do : Print n,: i=i+1: n=n+1: Loop Until (i>8) Or (n>52)
 EndIf
 Print
Loop Until n>52

Print
Print "compact - Do's get mixed up"
n=1
Do
 i=1
 Print ">";
 If n>0 Then Do : Print n,: i=i+1: n=n+1: Loop Until (i>8) Or (n>52)
 Print
Loop Until n>52

End


and here are the results of running the example:

> Micromite MKII MMBasic Ver 5.05.05
Copyright 2011-2022 Geoff Graham

> RUN
expanded - works correctly
> 1      2       3       4       5       6       7       8
> 9      10      11      12      13      14      15      16
> 17     18      19      20      21      22      23      24
> 25     26      27      28      29      30      31      32
> 33     34      35      36      37      38      39      40
> 41     42      43      44      45      46      47      48
> 49     50      51      52

compact - Do's get mixed up
> 1     > 2     > 3     > 4     > 5     > 6     > 7     > 8     > 9     > 10
> 11    > 12    > 13    > 14    > 15    > 16    > 17    > 18    > 19    > 20
> 21    > 22    > 23    > 24    > 25    > 26    > 27    > 28    > 29    > 30
> 31    > 32    > 33    > 34    > 35    > 36    > 37    > 38    > 39    > 40
> 41    > 42    > 43    > 44    > 45    > 46    > 47    > 48    > 49    > 50
> 51    > 52
[20] Loop Until n>52
Error : LOOP without a matching DO
>


essentially, the interpreter is picking up the wrong DO when the IF...THEN DO...LOOP is all on a single line.

i don't really consider this a bug as such, but perhaps the manual should be appended to say that IF...THEN DO...LOOP all on one line should be avoided!

btw: the code where i encountered this problem was along the lines of:
Do
 key = Asc(Inkey$)
 If key=Asc("p") Then Do :Loop Until Inkey$<>""
 Print Timer
Loop



cheers,
rob   :-)
 
Posted: 01:46pm
14 Jun 2025
Copy link to clipboard
Mixtel90
Guru


I think I've seen that come up before. The error checking on the MX170 version can be a bit lax in some places, probably due to the available memory - you can't trap everything. As it's really an embedded control version this sort of error is only really an item during development.
 
Posted: 05:25pm
14 Jun 2025
Copy link to clipboard
vegipete
Guru


What happens if you put a ":" after "THEN" and finish the single line with "ENDIF"?
 
Posted: 09:34pm
14 Jun 2025
Copy link to clipboard
phil99
Guru


@vegipete is right.
As far as I can tell all versions of MMBasic need both  "THEN :" and "ENDIF" in multi statement lines. Without them the implied EndIf could belong anywhere, not just the end of the line.
If key=Asc("p") Then : Do :Loop Until Inkey$<>"" : ENDIF
 
Posted: 10:28pm
14 Jun 2025
Copy link to clipboard
TassyJim
Guru


THEN followed by DO has a problem.
Inserting a ":" will fix the problem without any need for the ENDIF
In all other cases the ":" is not required as per the manual
 
Posted: 03:48am
15 Jun 2025
Copy link to clipboard
phil99
Guru


  Quote  Inserting a ":" will fix the problem without any need for the ENDIF
Yes, tried on MM2 v5 05.05 and PicoMite v6.00.02.
n=1:do:i=1:?">",:If n>0 Then : Do : ? n,: i=i+1: n=n+1: Loop Until (i>8) Or (n>52):?:Loop Until n>52
 
Posted: 01:57pm
15 Jun 2025
Copy link to clipboard
robert.rozee
Guru

Jim, Phil, Pete: the colon does fix the example i gave, but not the one generated by this code:

Do
 If Inkey$="p" Then:Do :Print ".";:Loop Until Inkey$<>""
 Print "#";
Loop


> Micromite MKII MMBasic Ver 5.05.05
Copyright 2011-2022 Geoff Graham

> RUN
[2] If Inkey$="p" Then:Do :Print ".";:Loop Until Inkey$<>""
Error : No matching ENDIF
>


and with the colon removed again, we are back to:

>
> list
Do
 If Inkey$="p" Then Do :Print ".";:Loop Until Inkey$<>""
 Print "#";
Loop
>
> RUN
#
[4] Loop
Error : LOOP without a matching DO
>


i really do think a "do not do this" note in the manual is the best solution!


cheers,
rob   :-)
Edited 2025-06-16 00:01 by robert.rozee
 
Posted: 03:13pm
15 Jun 2025
Copy link to clipboard
robert.rozee
Guru

but this DOES work, even though it shouldn't:

Do
  If Inkey$="p" Then:Do :Print ".";:Loop Until Inkey$<>"":EndIf
  Print "#";
Loop



cheers,
rob   :-)
 
Posted: 03:39pm
15 Jun 2025
Copy link to clipboard
Mixtel90
Guru


It's always better to make your programs readable though. Complex single-line statements get very confusing. Anyone would think that you had to pay for CRLF and pretty-printing. :)
 
Posted: 04:10pm
15 Jun 2025
Copy link to clipboard
robert.rozee
Guru

  Mixtel90 said  It's always better to make your programs readable though. Complex single-line statements get very confusing. Anyone would think that you had to pay for CRLF and pretty-printing. :)


  true, the code presented here is deliberately crafted just to isolate the behavior of interest; when identifying such 'corner cases' you often have to do unexpected/odd things that the average user should NOT normally be doing anyway. but it IS still important to know about these corner cases, so as to document them so others don't accidentally get caught out.


cheers,
rob   :-)
 
Posted: 09:34pm
15 Jun 2025
Copy link to clipboard
phil99
Guru


  Quote  but this DOES work, even though it shouldn't:
After encountering similar errors I had found the EndIf fixed it and assumed it to always be necessary in multi-statement IF lines. Until Jim showed it isn't always the case.

It works because with the EndIf included it becomes a regular multi-line IF with the ":" replacing CRLFs
 


To reply to this topic, you need to log in.

The Back Shed's forum code is written, and hosted, in Australia.
© JAQ Software 2025