if construct


Even though block can do things that if can do, Wat provides if directly. if also creates a block so you cannot see existing values of the stack. You can declare the result type of if. If not, remember to empty the new stack before leaving the block.

if pops a number from the stack. Run the block if the number is not 0. Run the else block else.

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        i32.const 1
        if (result i32)
            i32.const 10
        else
            i32.const 20
        end
        call $log
    )
    (start $main)
)

You can ignore else if it's not necessary. For example, the following code set $var to 10 first. Because there's a number 1 on the stack when executing if, the if block is executed and $var would be 20.

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        (local $var i32)
        (set_local $var (i32.const 10))
        i32.const 1
        if
            (set_local $var (i32.const 20))
        end
        get_local $var
        call $log
    )
    (start $main)
)

You can give if a label for being used with br or br_if.

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        i32.const 1
        if $IF0
            i32.const 1
            if $IF1
                br $IF1
            else
                br $IF0
            end
            i32.const 10
            call $log
        end
        i32.const 20
        call $log
    )
    (start $main)
)

You can combine if with block.

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        block $IF0
            i32.const 1
            if $IF1
                br $IF1
            else
                br $IF0
            end
            i32.const 10
            call $log
        end
        i32.const 20
        call $log
    )
    (start $main)
)

In Block and branch instructions, I've mentioned that block can combine with if and loop. The above code is an example. You may also use the style of S-expression. For example, given a C program.

#include <stdio.h>

int main() {
    int a = 10;
    int b = 20;
    if((a - b) == 10) {
         printf("%d", 1);
    }
    else {
        printf("%d", 0);
    }
}

The corresponding Wat with instructions one line by one line is:

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        (local $a i32) (local $b i32)
        i32.const 10
        tee_local $a
        i32.const 20
        tee_local $b
        i32.sub
        i32.const 10
        i32.eq      
        if
            i32.const 1
            call $log
        else
            i32.const 0
            call $log
        end
    )
    (start $main)
)

Using the style of S-expression and block will be:

(module
    (import "env" "log" (func $log (param i32)))
    (func $main
        (local $a i32) (local $b i32)
        (set_local $a (i32.const 10))
        (set_local $b (i32.const 20))
        (if (block (result i32)
                (i32.eq 
                    (i32.sub (get_local $a) (get_local $b)) 
                    (i32.const 10)
                )   
            )
            (then
                i32.const 1
                call $log)
            (else
                i32.const 0
                call $log)
        )
    )
    (start $main)
)

As you can see, block can be used to group instructions. With suitable formatting, the readability will be as good as high-level programming languages. Notice the then instruction, it is necessary when using the style of S-expression.