雖然可以使用 block
來達到程式語言中 if
的效果,然而,Wat 本身就提供有 if
,它與 block
同屬於區塊的一種,因此看不到區塊前對堆疊的置入的數值,可以定義結果型態,若沒有定義,那離開區塊前必須清空堆疊。
if
會從堆疊中取出一個數值,若不為 0 就執行 if
區塊,否則執行 else
區塊,因此底下顯示 10:
(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)
)
若不需要 else
,可以省略,例如,底下先將變數 $var
設為 10,若 if
成立,將 $var
設為 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)
)
if
區塊也可以如同 block
一樣設定標籤,可以使用 br
或 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)
)
if
可以與 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)
)
在〈區塊與分支〉中談過,block
可以用來搭配 if
、loop
等,上面是個範例,實際上區塊的語法,還可以進一步使用 S 運算式的風格來撰寫。
例如,對於底下的 C 程式:
#include <stdio.h>
int main() {
int a = 10;
int b = 20;
if((a - b) == 10) {
printf("%d", 1);
}
else {
printf("%d", 0);
}
}
要寫個對等的 Wat,中規中矩的寫法是:
(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)
)
使用 S 運算式,搭配 block
等來寫的話可以是:
(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)
)
可以看到 block
的另一應用,是將一組操作組織在一起,透過適當的 S 運算式排列,會比較接近高階語言的寫法,留意 if
的 S 運算式寫法,條件成立時必須寫在 then
之中,不成立時寫在 else
之中。