Fundamentals: Branching and Looping
Branching and Looping are two very common and very powerful logic control operations. With them the programmer can control what macro commands get executed and which macro commands do not, they allow the program to jump to different parts of the macro, and they allow some parts of the macro to be run multiple times in succession.
Conditional Branching
The IF
, ELSEIF
, ELSE
, ENDIF
construction is
used for conditional branching. It allows the macro to make a decision about which block of code
to run, based on a condition.
IF
statements are used when macro code should only be run if a given
condition exists.
An IF
block has the following format:
IF (evaluation)
... macro code to run if evaluation is true
ELSEIF (evaluation)
... macro code to run if evaluation is true
ELSE
... macro code to run if evaluation is false
ENDIF
- If the conditions inside the brackets test true, SmartCAM performs the MCL commands that
immediately follow the
IF()
command. - If the conditions inside the brackets, of the
ELSEIF
evaluation test true, SmartCAM performs the MCL commands that immediately follow theELSEIF()
command. - If the conditions test false, SmartCAM will either continue with the next MCL command, after
the
ENDIF
or perform the commands after theELSE
, if supplied.
The evaluation, within the parenthesis, must result in a TRUE or FALSE answer. The evaluation is based on the supported list of condition-test operators.
When you use a IF()
check, the ENDIF
statement is required.
Use any of the following condition-test operators.
Operator | Description |
---|---|
= | is equal to |
<> | is not equal to |
< | is less than |
> | is greater than |
<= | is ess than or equal to |
>= | is greater than or equal to |
,AND | AND operator (Be sure to include the comma). Example:\
The |
&& | Modern syntax for ",AND ". Example:
The |
,OR | OR operator (Be sure to include the comma). Example:\
The |
|| | Modern syntax for ",OR ". Example:
The |
If the evaluation inside the parenthesis test true, SmartCAM performs the MCL
command that immediately follows the IF()
command.
If the evaluation tests false, SmartCAM performs the MCL command immediately following
the optional ELSE
command or the MCL command immediately after the ENDIF
,
if the ELSE
block was not provided.
// Check value of #ITST, display message if value is 0 or not.
INTEGER:#ITST=0
IF(#ITST = 0)
PAUSE[TX="#ITST is set to 0."]
ELSE
PAUSE[TX="#ITST is not set to 0."]
ENDIF
When this macro is run, the message box will contain the text: #ITST is set to 0.
As mentioned previously, the IF
statement checks whether the expression
evaluates to True or False. In this case, #ITST was set to 0, so it evaluated as True. Therefore,
the macro command right after the IF
statement is run and the appropriate message
box contents are displayed.
Change the macro and instead use: INTEGER:#ITST=1
Run the macro and this time the expression evaluates to false. Therefore, the message that
is displayed is: #ITST is not set to 0.
The ELSE
block is optional. If the program needs to run code if a given
condition exists, but does not need to do anything if it does not exist, then the
ELSE
block is not needed.
// Check value of #IST, display message if value is 0, otherwise do nothing
INTEGER:#ITST=0
IF (#ITST = 0)
PAUSE[TX="#ITST is set to 0."]
ENDIF
In this case, since #ITST is set to 0, the message is display. If #ITST is set to an integer other than 0, nothing will be displayed.
The ELSEIF
construction allows the programmer to do multiple checks in a
single IF
block. The syntax is:
IF (evaluation)
... macro code to run if evaluation is true
ELSEIF (another evaluation)
... macro code to run if 2nd evaluation is true
ELSE
... macro code to run if first evaluation is false
ENDIF
Consider the case where the program needs to check and see whether a string variable contains a specific string, but there are multiple possible responses.
// Check for orbit location and return planet name
// Value of ORBIT can be strings: one, two, three, four, five, six, seven, or eight
STRING:#ORBIT="three"
STRING:#PLANET
IF (#ORBIT="one")
#PLANET="Mercury"
ELSEIF (#ORBIT="two")
#PLANET="Venus"
ELSEIF (#ORBIT="three")
#PLANET="Earth"
ELSEIF (#ORBIT="four")
#PLANET="Mars"
ELSEIF (#ORBIT="five")
#PLANET="Jupiter"
ELSEIF (#ORBIT="six")
#PLANET="Saturn"
ELSEIF (#ORBIT="seven")
#PLANET="Uranus"
ELSEIF (#ORBIT="eight")
#PLANET="Neptune"
ELSE
#PLANET="World"
ENDIF
PAUSE[TX="Hello " + #PLANET]
When run, a message box with "Hello Earth
" will be displayed. If the
contents of #ORBIT
is changed to one of the eight possible strings, the other
planet names are used. If the variable does not contain one of the eight possible strings, the
message box contains "Hello World
".
For string comparisons, you can also use the STREQUAL() macro function. With STREQUAL(), the two strings to compare are provided as arguments. The following two comparisons are the same.
STRING:#A="One"
IF (#A = "One")
PAUSE[TX="String is Matched"]
ENDIF
IF (STREQUAL(#A, "One"))
PAUSE[TX="String is Matched"]
ENDIF
Both string comparisons are case-sensitive. So checking "One" against "one" will not match, as the cases of the two strings to not exactly match.
Expression with Multiple evaluations
The expression can include multiple evaluations, with the overriding rule that the sum total of the evaluations should result in either True or False.
INTEGER:#I1=0
DECIMAL:#D1=3.14
// Display a message if #T1 is 0 and #D1 is greater than 3.0
IF(#T1=0 && #D1 > 3.0)
PAUSE[TX="Expression is true"]
ENDIF
The &&
characters are called logical evaluators and they stand
for "AND". The expression is saying if #T1 is equal to 0 AND
#D1 is greater than 3.0, then display the message. In this example both subexpressions
evaluated to True so the full expression evaluated as true.
INTEGER:#I1=0
DECIMAL:#D1=13.0
// Display a message if #T1 is 0 and #D1 is greater than 3.0
IF(#T1=0 && #D1 < 12.0)
PAUSE[TX="Expression is true"]
ENDIF
For this example, the value of #D1 is changed to 13 and the second half of the expression is changed to test to see if #D1 is less than 12. When running this macro, no message will be displayed. While #T1 is equal to 0, #D1 is not less than 12; therefore, the entire expression evaluates to False.
There are cases where you have multiple checks, but only care whether one or the other
subexpression evaluates as true. These use the ||
logical evaluator, which stands
for OR.
INTEGER:#I1=0
DECIMAL:#D1=13.0
// Display a message is #T1 is 0 or #D1 is greater than 3.0
IF(#T1=0 || #D1 < 12.0)
PAUSE[TX="Expression is true"]
ENDIF
This is the same expression as above, except the logical evaluator is changed to OR. In this case the message is displayed. The check is to see whether #T1=0 OR #D1 < 12; while #D1 is false, #T1 is true and thus the entire expression is true.
You can nest up to 32 IF()
and WHILE()
checks within a
macro.
Conditional Looping
The WHILE
, ENDW
construction is used to continually execute a
block of statements until a particular condition is met. It is useful in cases where the
program needs to repeat a series of steps several times; such as searching the process
model data list for particular elements or element types, or for creating repeating
elements.
A WHILE
block has the following format:
WHILE (evaluation)
... macro code to run while evaluation is true
ENDW
The evaluation, within the parenthesis, must result in a TRUE or FALSE answer. The
evaluation is based on the supported list of condition-test operators. When the evaluation
is true, the block of macro code between the WHILE
and ENDW
statements
is run. When the ENDW
statement is reached, the macro jumps back up to the
WHILE
statement and re-checks the expression, if the expression is still True, the
block of code will be run again. When the expression is false, the block of code is skipped and
execution continues on the first command after the ENDW
statement. When WHILE()
is used, the ENDW
statement is required, to tell SmartCAM where the end of the
WHILE() statement commands resides.
Expression evaluation works exactly the same as it does for the IF
statement.
Be sure that the comparison arguments, in the WHILE()
statement, eventually will
test as FALSE. An endless loop occurs if the argument always tests true.
// A simple counter. Starts at zero and leaves the loop at five
INTEGER:#ICOUNTER=0
WHILE(#ICOUNTER < 5)
#ICOUNTER = #ICOUNTER + 1
ENDW
PAUSE[TX="ICOUNTER is " + ITOA(#ICOUNTER)]
When run, the message box text will be: ICOUNTER is 5
.
ICOUNTER
starts at 0 and then enters the WHILE loop. Each time through the
loop the value of the counter is incremented by one. On the fifth pass through the loop the
value of ICOUNTER reaches 5. At this point ICOUNTER is no longer less than 5 and therefore the
expression evaluates as False. So the loop is ended and the next line run is the PAUSE statement.
Since the expression is evaluated before the loop is run, there is a chance the code in
between the WHILE
and ENDW
statements is never run.
INTEGER:#ICOUNTER=6
WHILE(#ICOUNTER < 5)
#ICOUNTER = #ICOUNTER + 1
ENDW
PAUSE[TX="ICOUNTER is " + ITOA(#ICOUNTER)]
This is the same example as above, except the initial seed value of ICOUNTER is set to
six. In this instance the loop is never run, ICOUNTER is not less than 5 so the expression is
evaluated to false. The macro jumps to the first statement after the ENDW
statement
and runs from there.
Unconditional Branching
The GOTO
, @LABEL
construction is used to cause an unconditional
branch or jump to another section of a macro program. When a GOTO
command is
encountered, SmartCAM jumps to the referenced label and continues to process macro commands
from there. The macro commands between the GOTO and the LABEL are not run.
GOTO is called an unconditional branch because unlike the IF
and
WHILE
commands, there is no expression to evaluate.
A GOTO
command has the following format:
GOTO(LABEL)
... macro code that is jumped over
@LABEL
... macro code that is run
GOTO
is often used to jump out of a WHILE
loop before the
expression evaluates to false or to jump to an area to gracefully exit a macro when an
error is encountered.
INTEGER:#ICNTR=0
// This is an infinite loop - it will run forever
WHILE(1)
#ICNTR = #ICNTR + 1
// When ICNTR > 100 jump out of infinite loop
IF (#ICNTR > 100)
GOTO(DONE)
ENDIF
ENDW
@DONE
In this example, the WHILE
loop will run forever. In the loop the
variable ICNTR
gets incremented by one on each loop. The IF
expression checks to see if ICNTR is greater than 100, if so, it used GOTO
to jump
out of the loop down to the @DONE
label. At which time, the macro ends.
The WHILE(1)
is a little trick. In SmartCAM TRUE is defined as 1 and FALSE
as 0. So just having the number "1" in the expression always evaluates to TRUE.
Related Topics