If Syntax - Spicery/Nutmeg GitHub Wiki

Overview

if is the first word of a conditional expression and must be matched by a corresponding end or endif. For example:

    if tough(steak) then
        fry(steak)
    else
        grill(steak)
    endif

When this code is executed, the Nutmeg runner first executes the condition (i.e. tough(steak)). If this evaluates to false then grill(steak) is executed, otherwise fry(steak) is executed. The full syntax of allowable conditional commands is quite complex. An if statement has the form:


    if CONDITION then 
        CONSEQUENT
    elseif CONDITION then 
        CONSEQUENT
    ...
    [any number of additional elseif ... then ... clauses]
    ...
    else
        CONSEQUENT
    endif

The else CONSEQUENT can be omitted if desired. The elseif CONDITION then CONSEQUENT can be either omitted or repeated as many times as required. A CONDITION is any expression, and a CONSEQUENT is any sequence of Nutmeg statements.

The condition should, when executed, produce a result. If the result is false, then the corresponding consequent is ignored, and the program moves on to the next elseif, or if there isn't one, to the else clause. If there is no elseif or else, then the program moves on to the code following the endif.

If the result of executing a condition is anything other than true or false, then an error is raised.

if statements can be nested inside one another, i.e. a CONDITION or a CONSEQUENT of an if statement may itself contain if statements. For example:

    if isnumber(n) then
        if n > 0 then
            'positive'
        else
            'less than or equal to zero'
        endif
    endif

It is permissible, but unusual, for a CONSEQUENT to contain no code at all, but this must be flagged with an explicit pass or ()

    def prlist( list );
        if list.isEmpty then
            pass
        else
            println( head(list) )
            prlist( tail(list) )
        endif
    enddef

Reversing the test - ifnot

Sometimes it is more natural to reorder the if-statement so the false condition is dealt with first. Nutmeg provides the ifnot variant, which is equivalent to negating the whole condition with not. The syntax is identical to that of a normal if except that it starts with the ifnot keyword and finishes with end or endifnot.

ifnot tough(steak) then grill else fry endifnot( steak )

And that's equivalent to:

if not(tough(steak)) then grill else fry endif( steak )

Why provide this version, given that it's not even any shorter? The primary motivation is making the language self-consistent. Everywhere in the language where there is a condition, Nutmeg always provides both positive and negative versions e.g. while/whilenot, return if/ifnot. And this consistency makes the language easier to remember. Another, lesser motivation is to reduce the number of parentheses.

As a good example of this, there is also an alternative form of elseifnot, which is equivalent to elseif with the whole condition negated.

EBNF Grammar

IfExpression ::= 
    'if' IfCore ('endif'|'end') |
    'ifnot' IfCore ('endifnot'|'end')

Railroad diagram for EBNF grammar

IfCore ::=
    Expression ('then'|':') Statements 
    ( ('elseif'|'elseifnot') Expression ('then'|':') Statements )* ('else' ':'? Statements)? 

Railroad diagram for EBNF grammar

Behaviour

An if statement is essentially a sequence of condition-action pairs together with an optional default action. The conditions are evaluated in order and must evaluate to true or false. As soon as a condition evaluates to true the matching action is evaluated and then the statement finishes. If no conditions match then the default action, if provided, is evaluated and the statement finishes.

The Statements of an if-statement introduce their own lexical scopes that enclose the statement and no more. This ensures that variables introduced by the statements are only in scope where their definition is guaranteed to be executed.

⚠️ **GitHub.com Fallback** ⚠️