Home
JAQForum Ver 24.01
Log In or Join  
Active Topics
Local Time 06:37 28 Nov 2024 Privacy Policy
Jump to

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 : MM ENDIF Important?

Author Message
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 11:52pm 01 Aug 2013
Copy link to clipboard 
Print this post

Sigh... no such thing as a silly question; but.... I can't see if it is mandatory to use ENDIF in my code. Is it mandatory? If not, is there a limit to the number of IF AND THEN statements? Thanks in Advance!

Currently code like this:

64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1
65 If M=15 And S=10 And Flag=0 Then X=1: Flag=1
66 If M=18 And S=10 And Flag=0 Then X=1: Flag=1
and
642 If MN=0 And S=30 Then CS$="VE":?@(00,30)" ":?@(00,50)"*"
643 If MN=0 And S=40 Then CS$="W6":?@(00,50)" ":?@(00,70)"*"
644 If MN=0 And S=50 Then CS$="KH":?@(00,70)" ":?@(00,90)"*"

So should it be:

64 If M=12 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1
65 If M=15 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1
66 If M=18 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1
and
642 If MN=0 And S=30 Then CS$="VE":ENDIF: ?@(00,30)" ":?@(00,50)"*"
643 If MN=0 And S=40 Then CS$="W6":ENDIF: ?@(00,50)" ":?@(00,70)"*"
644 If MN=0 And S=50 Then CS$="KH":ENDIF: ?@(00,70)" ":?@(00,90)"*"

Cheers, Nic.

 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 12:56am 02 Aug 2013
Copy link to clipboard 
Print this post

Nic, ENDIF makes sense if there are many (or at least two or more) lines of code enclosed in the IF...ENDIF structure. In your case since the operations after THEN end the line, there is no need to have a closing ENDIF.
This is a common rule for placing ENDIF in all BASIC dialects.
So in short - I don't think there is a need for you to change your current code. In fact placing an ENDIF as in your second example completely changes the logic - flag=1 executes always after the IF and does not depend on its result. I don't know is that what you want
KonEdited by kiiid 2013-08-03
http://rittle.org

--------------
 
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 02:33am 02 Aug 2013
Copy link to clipboard 
Print this post

Kon many thanks!
That is what I wanted to know. I have a couple of old books on a couple varieties of BASIC but they don't even mention ENDIF. Thanks for explaining the aspect of logic change too.
Much appreciated!
Cheers, Nic.
 
mbramwel

Regular Member

Joined: 10/07/2013
Location: Canada
Posts: 42
Posted: 12:56pm 02 Aug 2013
Copy link to clipboard 
Print this post

I could be mistaken but I thought these lines were basically the same:

#1 64 If M=12 And S=10 And Flag=0 Then X=1: ENDIF: Flag=1
#2 64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1

I thought I read somewhere that ALL commands on the same line are executed if the "IF" was true otherwise nothing is executed.

you would *think* this is another way of rewriting the above lines of code:
#1 64 If M=12 And S=10 And Flag=0 Then
X=1:
ENDIF:
Flag=1

#2 64 If M=12 And S=10 And Flag=0 Then
X=1:
Flag=1
ENDIF

But I think Flag = 1 is inside the IF/ENDIF in #1 because the rest of the line is ignored if the *IF* is false.

I am not near a mmbasic machine to test.

anyone out there know for sure what is the answer?

ps: I should load up the Linux mmbasic !
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 12:56pm 02 Aug 2013
Copy link to clipboard 
Print this post

My choice would be:

64 If M=12 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF
65 If M=15 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF
66 If M=18 And S=10 And Flag=0 Then X=1: Flag=1: ENDIF
and
642 If MN=0 And S=30 Then CS$="VE": ?@(00,30)" ":?@(00,50)"*": ENDIF
643 If MN=0 And S=40 Then CS$="W6": ?@(00,50)" ":?@(00,70)"*": ENDIF
644 If MN=0 And S=50 Then CS$="KH": ?@(00,70)" ":?@(00,90)"*": ENDIF


This way, all the statements after the condition are acted on.
The ENDIF is not required if you only have one statement after the condition and therefore no ":"

You might also be able to use ELSEIF to make more readable code which should run a bit faster. Using ELSEIF, once a condition is met, the remaining tests are skipped.

This is one example of using ELSEIF:
IF rwm>3.10 THEN
w= 17
ELSEIF rwm > 2.98 THEN : w = 12 'W
ELSEIF rwm > 2.81 THEN : w = 14 'NW
ELSEIF rwm > 2.73 THEN : w = 13
ELSEIF rwm > 2.60 THEN : w = 16 'N
ELSEIF rwm > 2.40 THEN : w = 15
ELSEIF rwm > 2.25 THEN : w = 10 'SW
ELSEIF rwm > 2.00 THEN : w = 11
ELSEIF rwm > 1.70 THEN : w = 2 'NE
ELSEIF rwm > 1.40 THEN : w = 1
ELSEIF rwm > 1.10 THEN : w = 8 'S
ELSEIF rwm > 0.90 THEN : w = 9
ELSEIF rwm > 0.70 THEN : w = 6 'SE
ELSEIF rwm > 0.50 THEN : w = 7
ELSEIF rwm > 0.40 THEN : w = 4 'E
ELSEIF rwm > 0.35 THEN : w = 3
ELSE
w = 5
ENDIF


Jim
VK7JH
MMedit   MMBasic Help
 
mbramwel

Regular Member

Joined: 10/07/2013
Location: Canada
Posts: 42
Posted: 01:23pm 02 Aug 2013
Copy link to clipboard 
Print this post

I just loaded mmbasic on my pc for a test of how the IF statement works


10 flag=0
20 a=1
30 if a=1 then x=1: flag=1
100 print flag

also changed line 30 to:
30 if a=1 then x=1: endif: flag=1

The ENDIF made no difference. The FLAG=1 is only executed if a=1. Adding the ENDIF in the middle did not change the displayed value of FLAG.

In essence, the above 2 versions of line 30 are this:
30 if a=1 then x=1: flag=1: endif

sorry kiid, I disagree with your statement. I think that is one of the quirks of basic. With a "c" like language, I think your statement would be true because of the required { } around blocks of code.
 
kiiid

Guru

Joined: 11/05/2013
Location: United Kingdom
Posts: 671
Posted: 01:46pm 02 Aug 2013
Copy link to clipboard 
Print this post

That's fine. I only said what is a rule. The exact realisation by Geoff might differ a bit but that is normal. They all do. Normally ENDIF should be expected to terminate the IF structure unconditionally.
But I am spending 99% of my programming time writing C code so it is quite possible I am looking from a different angle.
At least it is good to have that tested and known.
Thanks for making the tests and sharing the resultsEdited by kiiid 2013-08-03
http://rittle.org

--------------
 
TassyJim

Guru

Joined: 07/08/2011
Location: Australia
Posts: 6100
Posted: 01:47pm 02 Aug 2013
Copy link to clipboard 
Print this post

And if you place a ":" after the THEN

30 if a=1 then :x=1: flag=1: endif


The ENDIF does have an effect.
Try changing it's location.
The single line of code now acts exactly the same as a multiline IF

The strange behavior of single line IF's has always caused me grief....

Jim
VK7JH
MMedit   MMBasic Help
 
mbramwel

Regular Member

Joined: 10/07/2013
Location: Canada
Posts: 42
Posted: 01:50pm 02 Aug 2013
Copy link to clipboard 
Print this post

No problem. I spend most of my day in Linux and c-like languages (there seems to be lots of them) and although your comment makes sense in our world, I only read about the If statement structure a few nights ago and thought it odd when I read it.

I think Geoff's implementation is probably the same as all other Basics, just not what C/C++/python/perl/php people would expect.

But hey! I have only been an expert in mmbasic for 1 week, I am still learning!

 
Nixie
Regular Member

Joined: 19/02/2013
Location: Australia
Posts: 66
Posted: 10:49pm 02 Aug 2013
Copy link to clipboard 
Print this post

Gentlemen! Thanks for your input! From that acorn question I have an oak tree growing!

Jim, thanks for the ELSEIF info, beautiful. Your info has nicely solved a little problem that caused splinters in my fingers ( a lot of head scratching!! )

Nic. VK3COW
 
MicroBlocks

Guru

Joined: 12/05/2012
Location: Thailand
Posts: 2209
Posted: 11:36pm 02 Aug 2013
Copy link to clipboard 
Print this post

The implementation of MMBasic is different then some other basics where an endif is always the end of a IF/ELSE block.
The manual has two descriptions! One for single line and one for multiline IFs
The single line version:
[code]
IF expr THEN statement
or
IF expr THEN statement
ELSE statement

Evaluates the expression ‘expr' and performs the THEN statement if it is
true or skips to the next line if false. The optional ELSE statement is the
reverse of the THEN test. This type of IF statement is all on one line.
The ‘THEN statement’ construct can be also replaced with:
GOTO linenumber | label’
[/code]
As you can see the description limits it to ONE statement, not a block of statements!
You don't get an error when you use more then one statement and that can cause some problems.

The multiline version:
[code]
IF expression THEN
<statements>
[ELSE
<statements>]
[ELSEIF expression THEN
<statements>]
ENDIF

Multiline IF statement with optional ELSE and ELSEIF cases and
ending with ENDIF. Each component is on a separate line.
Evaluates 'expression' and performs the statement(s) following THEN if
the expression is true or optionally the statement(s) following the ELSE
statement if false.
The ELSEIF statement (if present) is executed if the previous condition
is false and it starts a new IF chain with further ELSE and/or ELSEIF
statements as required.
One ENDIF is used to terminate the multiline IF.
[/code]
Here you can have statements, notice the s to signify that more than one statement is possible.

The seen behavior is undocumented and can change in the future.
Until it is documented it can be seen as a bug or a feature. :)
It would be best to only choose one of the two documented styles depending on the needs. This will prevent future upgrades to break your code.

Edited by TZAdvantage 2013-08-04
Microblocks. Build with logic.
 
shoebuckle
Senior Member

Joined: 21/01/2012
Location: Australia
Posts: 189
Posted: 06:55pm 03 Aug 2013
Copy link to clipboard 
Print this post

TZ is right. Sorry, this is going to be a long story!!

Single-line vs multi-line IF format
-----------------------------------
The rule is that:
- if both the THEN clause and optional ELSE clause each have a single statement following them, you can use EITHER the single-line OR the multi-line IF structure but
- if either the THEN or the ELSE needs more than one statement you MUST use the multi-line IF format.
Sometimes it would appear that multiple statements in a single-line IF format work, but for the wrong reasons. Don't do it. It will come back to bite you.

Let me demonstrate some cases I found.

Print "IfTest1"
a=2
b=2: c=3
If a=1 Then b=5: c=9: Else b=8: c=9
Print "a=";a, "b=";b, "c=";c

Run this code and you might think that, because the test fails, b becomes 8 and c becomes 9. It doesn't. When the test fails, the whole of the rest of the line is flushed. What you get is:
Iftest1
a= 2 b= 2 c= 3


Next is a case where the test passes but the ELSE doesn't do what was intended.

Print "IfTest2"
a=1
b=2: c=3
If a=1 Then b=5 Else b=8: c=9
Print "a=";a, "b=";b, "c=";c

With this code you might have intended c to remain unchanged as part of the ELSE, but it isn't. What you get is:
Iftest2
a= 1 b= 5 c= 9

(Incidentally, I had to remove ": c=9:" from the THEN clause in IfTest1 as you get an error when the test returns true.)

The other thing that this shows is that the manual is slightly misleading when describing the single-line IF in that it says that it "skips to the next line if false". The example above shows that the second statement after the ELSE (: c=9) is interpreted as being "on the next line".

OK so now let's make the IF statement multi-line and it all works as expected.

Print "IfTest3"
a=1
b=2: c=3
If a=1 Then: b=5: c=7: Else: b=8: c=9: endif
Print "a=";a, "b=";b, "c=";c


Print "IfTest4"
a=2
b=2: c=3
If a=1 Then: b=5: c=7: Else: b=8: c=9: endif
Print "a=";a, "b=";b, "c=";c


IfTest3 is the true case and sets b to 5 and c to 7 whereas
IfTest4 is false and sets b to 8 and c to 9.


Multi-statement lines vs multi-line statements
----------------------------------------------

If you are coding for speed, then the multi-statement line (as in IfTest5 below) is about 1% faster than when each statement is coded on its own line (IfTest6). On my MonoMM the times were 3883 and 3924 respectively. (Runs under DOS were inconsistent, depending upon what else the computer was doing. Sometimes IfTest5 was slower than IfTest6.)

Print "IfTest5"
Timer=0
For i=1 to 20000
a=2
b=2: c=3
If a=1 Then: b=5: c=7: Else: b=8: c=9: endif
Next
Print Timer


Print "IfTest6"
Timer=0
For i=1 to 20000
a=2
b=2: c=3
If a=1 Then
b=5
c=7
Else
b=8
c=9
endif
Next
Print Timer


Now for those who like to cram as many statements on a line as possible, you can have multiple statements on a line BEFORE a single-line IF, but not AFTER. Thus the first example below is ok but the second isn't.

Print "IfTest7":a=2:b=2:c=3:If a=1 Then b=5 Else c=9
Print "a=";a, "b=";b, "c=";c


Print "IfTest7":a=2:b=2:c=3:If a=1 Then b=5 Else c=9: Print "a=";a, "b=";b, "c=";c


Statements AFTER a multi-line IF are ok as in IfTest8.

Print "IfTest8"
Timer=0
For i=1 to 20000:a=2:b=2:c=3:If a=1 Then:b=5:c=7:Else:b=8:c=9:endif:Next:Print Timer


I hope this clears up the single-line vs multi-line IF question.
Cheers,
Hugh
 
Geoffg

Guru

Joined: 06/06/2011
Location: Australia
Posts: 3194
Posted: 03:09pm 04 Aug 2013
Copy link to clipboard 
Print this post

Part of the confusion comes from Bill Gates who added the multi line IF statement to Microsoft Basic. The original BASIC had just the single line version. I think that the multi line version is good but he could have removed or simplified the single line version and that would have reduced the confusion.

In MMBasic the ENDIF command is just a marker, it does not actually do anything if the interpreter runs into it. Take this bit of code:
IF <condition> THEN
<statement 1>
<statement 2>
ELSE
<statement 3>
<statement 4>
ENDIF

If the condition is true the interpreter starts executing Statement 1 and when it reached the ELSE it searches for the ENDIF and continues with the code after the ENDIF.

If the condition is false the interpreter searches for the ELSE or ENDIF (whichever comes first) and starts executing the code after that (ie, Statement 3). When the interpreter reaches the ENDIF it just skips over it because it actually does nothing.

When the ENDIF is executed it should check if it is part of a multi line IF statement and throw an error if it is not but that would have added to the bulk of the interpreter and slowed it down a little so I just left it doing nothing. The result is that you can sprinkle extra ENDIFs around with gay abandon and it will have little effect on your program.

Geoff
Geoff Graham - http://geoffg.net
 
Print this page


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

© JAQ Software 2024