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.