-
Notifications
You must be signed in to change notification settings - Fork 57
/
fac.wast
109 lines (102 loc) · 3.14 KB
/
fac.wast
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
(module
;; Recursive factorial
(func (export "fac-rec") (param i64) (result i64)
(if (result i64) (i64.eq (local.get 0) (i64.const 0))
(then (i64.const 1))
(else
(i64.mul (local.get 0) (call 0 (i64.sub (local.get 0) (i64.const 1))))
)
)
)
;; Recursive factorial named
(func $fac-rec-named (export "fac-rec-named") (param $n i64) (result i64)
(if (result i64) (i64.eq (local.get $n) (i64.const 0))
(then (i64.const 1))
(else
(i64.mul
(local.get $n)
(call $fac-rec-named (i64.sub (local.get $n) (i64.const 1)))
)
)
)
)
;; Iterative factorial
(func (export "fac-iter") (param i64) (result i64)
(local i64 i64)
(local.set 1 (local.get 0))
(local.set 2 (i64.const 1))
(block
(loop
(if
(i64.eq (local.get 1) (i64.const 0))
(then (br 2))
(else
(local.set 2 (i64.mul (local.get 1) (local.get 2)))
(local.set 1 (i64.sub (local.get 1) (i64.const 1)))
)
)
(br 0)
)
)
(local.get 2)
)
;; Iterative factorial named
(func (export "fac-iter-named") (param $n i64) (result i64)
(local $i i64)
(local $res i64)
(local.set $i (local.get $n))
(local.set $res (i64.const 1))
(block $done
(loop $loop
(if
(i64.eq (local.get $i) (i64.const 0))
(then (br $done))
(else
(local.set $res (i64.mul (local.get $i) (local.get $res)))
(local.set $i (i64.sub (local.get $i) (i64.const 1)))
)
)
(br $loop)
)
)
(local.get $res)
)
;; Optimized factorial.
(func (export "fac-opt") (param i64) (result i64)
(local i64)
(local.set 1 (i64.const 1))
(block
(br_if 0 (i64.lt_s (local.get 0) (i64.const 2)))
(loop
(local.set 1 (i64.mul (local.get 1) (local.get 0)))
(local.set 0 (i64.add (local.get 0) (i64.const -1)))
(br_if 0 (i64.gt_s (local.get 0) (i64.const 1)))
)
)
(local.get 1)
)
;; Iterative factorial without locals.
(func $pick0 (param i64) (result i64 i64)
(local.get 0) (local.get 0)
)
(func $pick1 (param i64 i64) (result i64 i64 i64)
(local.get 0) (local.get 1) (local.get 0)
)
(func (export "fac-ssa") (param i64) (result i64)
(i64.const 1) (local.get 0)
(loop $l (param i64 i64) (result i64)
(call $pick1) (call $pick1) (i64.mul)
(call $pick1) (i64.const 1) (i64.sub)
(call $pick0) (i64.const 0) (i64.gt_u)
(br_if $l)
(drop) (return)
)
)
)
(assert_return (invoke "fac-rec" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-iter" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-rec-named" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-iter-named" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-opt" (i64.const 25)) (i64.const 7034535277573963776))
(assert_return (invoke "fac-ssa" (i64.const 25)) (i64.const 7034535277573963776))
(assert_exhaustion (invoke "fac-rec" (i64.const 1073741824)) "call stack exhausted")