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.

