Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.
|
Forum Index : Microcontroller and PC projects : Maximum size of IF/ENDIF routines?
Author | Message | ||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
FULL SIZE MAXIMITE - NOT MICROMITE! I have run into this error a few times with large IF/ENDIF routines: [304]Error: IF without matching ENDIF This despite there being an endif at the end: [code] if asc(key$)=148 then MenuBox (Blue) Font 2:Print @(50,17) + CLR$(Yellow) "READ A LOG:":Font 1 Print @(25,65) + CLR$(Purple) "CURRENT LOGFILE IS:" Print @(25,75) + CLR$(White) Mid$(LFILE$,8,7) Print @(17,100) + CLR$(Green) "Enter date of logfile you want to" Print @(17,115) + CLR$(Green) "read. Press [ENTER] to read the" print @(17,130) + clr$(Green) "current log, or [ESC] to exit." Print @(25,160) + CLR$(White) "--> " GETIN (50,160,DEFAULT,1) if giflag<>0 then goto start if lin$="" then lin$=mid$(LFILE$,8,7) FN$="B:\LOG\" + lin$ + ".LOG" Mode 2,1:settick 0,DAT,1:Cls:FlagMode=1 Open FN$ For input As #3 If MM.Errno<>0 Then goto errors RESET (0) DO Font 2:Print @(150,5) + CLR$(Red,Yellow) "ACTIVITY LOG:":Font 1 Print "" For x=1 To 27 Line Input #3, T$ If T$="" Then close #3 Font 2 Print @(50,360) + CLR$(Red) "No more data in the logfile." Print @(1,380) + CLR$(Black,Yellow) "Press any key to return to the menu." timer=0 Do key$=Inkey$ if loc(#2)<>0 then mode 4:goto Activity Loop Until key$<>"" or Timer>=HALFMIN RESET (1):goto start else Print clr$(Green) T$ Next Font 2:Print @(1,380) + CLR$(Black,Yellow) "SPACE = more, any other key to abort." Font 1:timer=0 Do:key$=Inkey$:Loop Until key$<>"" or Timer>=HALFMIN If Asc(key$)<>32 Then RESET (1):goto start cls loop endif [/code] However, if I take this large routine, and plop it under a label, it runs fine: [code] ViewLog: MenuBox (Blue) Font 2:Print @(50,17) + CLR$(Yellow) "READ A LOG:":Font 1 Print @(25,65) + CLR$(Purple) "CURRENT LOGFILE IS:" Print @(25,75) + CLR$(White) Mid$(LFILE$,8,7) Print @(17,100) + CLR$(Green) "Enter date of logfile you want to" Print @(17,115) + CLR$(Green) "read. Press [ENTER] to read the" print @(17,130) + clr$(Green) "current log, or [ESC] to exit." Print @(25,160) + CLR$(White) "--> " GETIN (50,160,DEFAULT,1) if giflag<>0 then goto start if lin$="" then lin$=mid$(LFILE$,8,7) FN$="B:\LOG\" + lin$ + ".LOG" Mode 2,1:settick 0,DAT,1:Cls:FlagMode=1 Open FN$ For input As #3 If MM.Errno<>0 Then goto errors RESET (0) DO Font 2:Print @(150,5) + CLR$(Red,Yellow) "ACTIVITY LOG:":Font 1 Print "" For x=1 To 27 Line Input #3, T$ If T$="" Then close #3 Font 2 Print @(50,360) + CLR$(Red) "No more data in the logfile." Print @(1,380) + CLR$(Black,Yellow) "Press any key to return to the menu." timer=0 Do key$=Inkey$ if loc(#2)<>0 then mode 4:goto Activity Loop Until key$<>"" or Timer>=HALFMIN RESET (1):goto start else Print clr$(Green) T$ Next Font 2:Print @(1,380) + CLR$(Black,Yellow) "SPACE = more, any other key to abort." Font 1:timer=0 Do:key$=Inkey$:Loop Until key$<>"" or Timer>=HALFMIN If Asc(key$)<>32 Then RESET (1):goto start cls loop [/code] In the above example, I just have IF ASC(KEY$)=148 THEN GOTO ViewLog I was hunting around in the manual for MMBASIC - page 16 lists a lot of the can's and cant's, but I do not see anything there about the maximum length of an IF/ENDIF routine. Obviously, MMBASIC does not like the taste of these kinds of routines past a certain point, as I have had this "Error" several times, as routines get bigger and bigger, then trip that error saying there is no endif when there is. It is a very easy fix - move all the code under a label like I have done, and then refer the IF/THEN to the label, but I would be interested to know how long IF/ENDIF type routines can be.... Smoke makes things work. When the smoke gets out, it stops! |
||||
paceman Guru Joined: 07/10/2011 Location: AustraliaPosts: 1329 |
I think in the first listing you're missing an ENDIF in this section aren't you Grogs. If T$="" Then
close #3 Font 2 Print @(50,360) + CLR$(Red) "No more data in the logfile." Print @(1,380) + CLR$(Black,Yellow) "Press any key to return to the menu." timer=0 Do key$=Inkey$ if loc(#2)<>0 then mode 4:goto Activity Loop Until key$<>"" or Timer>=HALFMIN RESET (1):goto start else Print clr$(Green) T$ All the other IF's are one liners, apart from the first so they don't count. Greg |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
Bloody hell, Greg - you are so right - totally missed that one! Another bug squashed - thanks. I moved the routine back to within the IF/ENDIF, but with the extra ENDIF needed, and bugger me - it works fine! Yay! - Thanks for the prod. I would still like to know if there is any limitation on how big these routines can grow within a single IF/THEN/ELSE/ENDIF structure.... Smoke makes things work. When the smoke gets out, it stops! |
||||
TassyJim Guru Joined: 07/08/2011 Location: AustraliaPosts: 6102 |
I don't think the size would be a problem but there is a limit to the number of nested loops. From the micromite manual: Maximum number of nested FOR…NEXT loops is 10. Maximum number of nested DO…LOOP commands is 10. Maximum number of nested GOSUBs is 30. Maximum number of nested multiline IF…ELSE…ENDIF commands is 10. The Maximite also has limits. Jim VK7JH MMedit  MMBasic Help |
||||
Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3196 |
There is no limit to the number of lines that you can have within a single IF/THEN/ELSE/ENDIF structure (other than program memory space). Geoff Geoff Graham - http://geoffg.net |
||||
shoebuckle Senior Member Joined: 21/01/2012 Location: AustraliaPosts: 189 |
Running your code through one of the formatting programs, Format.bas in MMLib or loading into MMEdit, will often find an error for you, as in this case, as the resulting indentation will not be as expected. Cheers, Hugh |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
Hi there - entire code developed inside of MMEdit, with full indenting, but the bug was still missed. Smoke makes things work. When the smoke gets out, it stops! |
||||
panky Guru Joined: 02/10/2012 Location: AustraliaPosts: 1101 |
Hey Grog, Absolutely no offence meant but your code looks pretty convoluted - we used to call it spaghetti code1 It would be a lot easier for both yourself and anyone else assisting you if you made more use of subroutines and tried to limit multiple exits out of loops (the old contentious goto argument). Modular code, while taking some practise to get used to, makes program support just so much easier. Again, no offence meant. Regards, Doug. ... almost all of the Maximites, the MicromMites, the MM Extremes, the ArmMites, the PicoMite and loving it! |
||||
BobD Guru Joined: 07/12/2011 Location: AustraliaPosts: 935 |
Panky, that sounds like an opening for a smart young man. What about putting together a few tips for Grogs and the rest of us. Bob |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
Seconded, although, in MY case, it is planned to be closed source, so I don't really care that much if it is "Convoluted", so long as I can understand it! However, the above notwithstanding, please do impart your specific ideas. I already have the main parts inside subs, so thought it was reasonably slick anyway, considering that before, I had GOTO's all over the place... Example: NONE of the IF/THEN/ELSE/ENDIF routines existed at all - it was all goto this, and goto that. I understand that GOTO is considered bad coding practise, so I moved(and learnt how to) all the the major routines inside IF/THEN loops, and did away with the GOTO's. All this is working fine now, but apparently, I still am not doing it right... *sigh* Smoke makes things work. When the smoke gets out, it stops! |
||||
MOBI Guru Joined: 02/12/2012 Location: AustraliaPosts: 819 |
Its always a slap in the ego when someone picks on your hard thought out programming that you were immensely proud of, but if you can learn from it, you will be a better programmer for it. David M. |
||||
Grogster Admin Group Joined: 31/12/2012 Location: New ZealandPosts: 9308 |
Oh, I'm not offended, and panky was very clear that no offence was to be taken, so I fully acknowledge that obviously it needs some tidy up. I would still like panky to chime in here with thoughts on what parts of the code I listed, shuold be subs. I already have subs for getting the keypress with a timeout(GETIN) and for enabling or disabling the reset button(RESET). The RESET sub just enables and disables the interrupt on the reset button, which calls a WATCHDOG 1 command to reset the PIC32. I did it like this, cos we DON'T want someone pressing reset, while the SD card is being written primarily, but I simple elected to prevent the reset button from doing anything, if ANY card reading or writing was going on. I also use it in other parts of the code, like in the example above, so that you can disable the reset button in certain screens. Smoke makes things work. When the smoke gets out, it stops! |
||||
Print this page |