2
Condition statement
Bartłomiej Przemysław Pluta edited this page 2020-04-01 21:13:19 +02:00

SMNP language has support for good old condition statement and its syntax is inspired by Java language.

if statement

The simplest form consists only of if keyword followed by condition bounded on both sides with parentheses (( and )) and statement (or block of code):

if (2 > 3) println("It gonna never be displayed!");

# or (using block of code)

if (2 > 3) {
    println("It gonna never be displayed!");
}

Just like in Java condition must be of bool type.

# Correct examples
if (true) println();
if (false) println();
if (not false) println();
if (0 == 0) println();
if ("hello".length > 0) println();
if (true and not true or not false and true) println();
if (true and (not true or not false) and true) println();

# Incorrect examples
if () println();
if (0) println();
if (1) println();
if ("hello") println();
if (true.toString()) println();

if-else statement

You can use additional else clause which is always executed when condition is resolved to false.

Example:

if (2 > 3) println("It gonna never be displayed!");
else println("but this always will be displayed");

# or you can use blocks of code to increase readability

if (2 > 3) {
    println("It gonna never be displayed!");
} else {
    println("but this always will be displayed");
}

Remember that only one condition statement branch (if or else) can be executed in single statement. There is no possibility to execute both clauses:

x = 1;

if (x > 0) {
    println(true);
} else {
    println(false);
}

if (x < 0) {
    println(false);
} else {
    println(true);
}

Above example will print true twice. First statement's condition is met, so if clause did execute, but second statement's condition is resolved to false so else clause did execute.

if-else-if-else-if-... statement

Above constructions are sufficient to create if-else-if-... pseudo-construction. Thanks to it, you are able to put additional execution branches to existing condition statement. Pseudo in this case means that there is no special parsing rules nor evaluators related to this construction. It is just a combination of if and if-else statements presented above.

Example:

x = 3;
if (x == 0) {
    println("x is zero");
} else if (x == 1) {
    println("x is one");
} else if (x == 2) {
    println("x is two");
} else if (x == 3) {
    println("x is three");
} else {
    println("x is neither zero, one, two nor three");
}

# its technically equivalent of

if (x == 0) {
    println("x is zero");
} else { 
    if (x == 1) {
        println("x is one");
    } else {
        if (x == 2) {
            println("x is two");
        } else {
            if (x == 3) {
                println("x is three");
            } else {
                println("x is neither zero, one, two nor three");
            }
        }
    }
}

Thanks to its tree-like construction control flow falls through all conditions. A branch first matched branch is executed and following conditions are not checked anymore:

x = 0
if (x == 1) {
    println();           # Condition is resolved to false
} else if (x == 0) {
    println();          # Condition is met
} else if (x == 0) {
    println();           # Condition is also met, 
}                       # but it hasn't been even checked because above
                        # branch has been already matched and executed

Lazy evaluation

It's also good place to mention, that both and and or operators support lazy evaluation of their operands.

It means that:

  • in case of A and B expression, B expression will be evaluated only when A expression is evaluated to true
  • in case of A or B expression, B expression will be evaluated only when A expression is evaluated to false.

It allows you for example to keep availability-check with actual condition together, for example:

function test(x: string) {
  # You are allowed to use following if-statement:
  if(x.length >= 5 and x.charAt(4) == "o") {
     println(x);
  }
}

# Now, let's check:
test("Hello");

# In this case x.length == 5 so the second operand 
# will be evaluated to true and the "Hello" message will be displayed.

# However, in the following case:
test("abc");

# x.length < 5 and so we don't need to evaluate 
# the second operand to know the value of condition.
# Thanks to that, there is no risk to end up 
# with error, that we're trying to get not existing character of string