Skip to content

Commit 5549e1b

Browse files
abelstukertolauwae
authored andcommitted
Add multi-value tutorial example
1 parent d011803 commit 5549e1b

1 file changed

Lines changed: 287 additions & 0 deletions

File tree

tutorials/wat/main/multi_value.wat

Lines changed: 287 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,287 @@
1+
(module
2+
(import "env" "print_string" (func $print.string (param i32 i32)))
3+
(import "env" "print_int" (func $print.int (param i32)))
4+
5+
(memory $mem 1)
6+
(export "memory" (memory $mem))
7+
8+
(data (i32.const 0) "Test 1: Basic swap\n")
9+
(data (i32.const 20) "Test 2: Triple return\n")
10+
(data (i32.const 43) "Test 3: Nested calls\n")
11+
(data (i32.const 65) "Test 4: Block multi-value\n")
12+
(data (i32.const 92) "Test 5: Loop multi-value\n")
13+
(data (i32.const 118) "Test 6: If multi-value\n")
14+
(data (i32.const 142) "Test 7: Branch with values\n")
15+
(data (i32.const 170) "Result: ")
16+
(data (i32.const 179) "Test 8: br_table multi-value\n")
17+
(data (i32.const 208) "Test 9: Complex composition\n")
18+
19+
;; Test 1: two return values (swap)
20+
(func $swap (param i32 i32) (result i32 i32)
21+
(local.get 1)
22+
(local.get 0)
23+
)
24+
25+
(func $test_swap (export "test_swap")
26+
(call $print.string (i32.const 0) (i32.const 19))
27+
28+
(i32.const 5)
29+
(i32.const 10)
30+
(call $swap)
31+
32+
(call $print.string (i32.const 170) (i32.const 8))
33+
(call $print.int)
34+
35+
(call $print.string (i32.const 170) (i32.const 8))
36+
(call $print.int)
37+
)
38+
39+
;; Test 2: three return values
40+
(func $triple (param i32) (result i32 i32 i32)
41+
;; returns (x, x+10, x+20)
42+
(local.get 0)
43+
(local.get 0)
44+
(i32.const 10)
45+
(i32.add)
46+
(local.get 0)
47+
(i32.const 20)
48+
(i32.add)
49+
)
50+
51+
(func $test_triple (export "test_triple")
52+
(call $print.string (i32.const 20) (i32.const 22))
53+
54+
(i32.const 5)
55+
(call $triple)
56+
57+
(call $print.string (i32.const 170) (i32.const 8))
58+
(call $print.int)
59+
(call $print.string (i32.const 170) (i32.const 8))
60+
(call $print.int)
61+
(call $print.string (i32.const 170) (i32.const 8))
62+
(call $print.int)
63+
)
64+
65+
;; Test 3: nested multi-value calls
66+
(func $add_pair (param i32 i32) (result i32)
67+
(local.get 0)
68+
(local.get 1)
69+
(i32.add)
70+
)
71+
72+
(func $test_nested (export "test_nested")
73+
(call $print.string (i32.const 43) (i32.const 21))
74+
75+
(i32.const 3)
76+
(i32.const 7)
77+
(call $swap)
78+
(call $add_pair)
79+
80+
(call $print.string (i32.const 170) (i32.const 8))
81+
(call $print.int)
82+
)
83+
84+
;; Test 4: block with multi-value type
85+
(func $test_block (export "test_block")
86+
(call $print.string (i32.const 65) (i32.const 26))
87+
88+
(block (result i32 i32)
89+
(i32.const 42)
90+
(i32.const 99)
91+
)
92+
93+
(call $print.string (i32.const 170) (i32.const 8))
94+
(call $print.int)
95+
(call $print.string (i32.const 170) (i32.const 8))
96+
(call $print.int)
97+
)
98+
99+
;; Test 5: loop with multi-value
100+
(func $test_loop (export "test_loop")
101+
(local $counter i32)
102+
(local $val1 i32)
103+
(local $val2 i32)
104+
(call $print.string (i32.const 92) (i32.const 25))
105+
106+
(i32.const 0)
107+
(local.set $counter)
108+
109+
(i32.const 10)
110+
(local.set $val1)
111+
(i32.const 20)
112+
(local.set $val2)
113+
114+
;; loop that accumulates
115+
(block $exit
116+
(loop $continue
117+
118+
(local.get $counter)
119+
(i32.const 3)
120+
(i32.ge_u)
121+
(br_if $exit)
122+
123+
;; incr both values
124+
(local.get $val1)
125+
(i32.const 1)
126+
(i32.add)
127+
(local.set $val1)
128+
129+
(local.get $val2)
130+
(i32.const 2)
131+
(i32.add)
132+
(local.set $val2)
133+
134+
;; incr counter
135+
(local.get $counter)
136+
(i32.const 1)
137+
(i32.add)
138+
(local.set $counter)
139+
140+
(br $continue)
141+
)
142+
)
143+
144+
;; get results from loop
145+
(block (result i32 i32)
146+
(local.get $val1)
147+
(local.get $val2)
148+
)
149+
150+
(call $print.string (i32.const 170) (i32.const 8))
151+
(call $print.int)
152+
(call $print.string (i32.const 170) (i32.const 8))
153+
(call $print.int)
154+
)
155+
156+
;; Test 6: if/else with multi-value result
157+
(func $test_if (export "test_if") (param i32)
158+
(call $print.string (i32.const 118) (i32.const 23))
159+
160+
(local.get 0)
161+
(if (result i32 i32)
162+
(then
163+
(i32.const 100)
164+
(i32.const 200)
165+
)
166+
(else
167+
(i32.const 300)
168+
(i32.const 400)
169+
)
170+
)
171+
172+
(call $print.string (i32.const 170) (i32.const 8))
173+
(call $print.int)
174+
(call $print.string (i32.const 170) (i32.const 8))
175+
(call $print.int)
176+
)
177+
178+
;; Test 7: branch with multi-value preversation
179+
(func $test_branch (export "test_branch") (param i32)
180+
(call $print.string (i32.const 142) (i32.const 27))
181+
182+
(block (result i32 i32)
183+
(i32.const 10)
184+
(i32.const 20)
185+
186+
(local.get 0)
187+
(br_if 0)
188+
189+
;; if we don't branch, we replace the values
190+
(drop)
191+
(drop)
192+
(i32.const 30)
193+
(i32.const 40)
194+
)
195+
196+
(call $print.string (i32.const 170) (i32.const 8))
197+
(call $print.int)
198+
(call $print.string (i32.const 170) (i32.const 8))
199+
(call $print.int)
200+
)
201+
202+
;; Test 8: br_table with multi-value
203+
(func $test_br_table (export "test_br_table") (param i32)
204+
(local $result1 i32)
205+
(local $result2 i32)
206+
(call $print.string (i32.const 179) (i32.const 29))
207+
208+
(block (result i32 i32)
209+
(block (result i32 i32)
210+
(block (result i32 i32)
211+
(i32.const 1)
212+
(i32.const 2)
213+
214+
(local.get 0)
215+
(br_table 0 1 2 2) ;; this will branch to case 0, 1, or 2 based on input (with default to 2)
216+
)
217+
;; case 0
218+
(i32.const 10)
219+
(i32.add)
220+
(i32.const 10)
221+
(i32.add)
222+
(br 1)
223+
)
224+
;; case 1
225+
(i32.const 20)
226+
(i32.add)
227+
(i32.const 20)
228+
(i32.add)
229+
)
230+
;; case 2 (and default)
231+
(local.set $result2)
232+
(local.set $result1)
233+
234+
(call $print.string (i32.const 170) (i32.const 8))
235+
(local.get $result1)
236+
(call $print.int)
237+
(call $print.string (i32.const 170) (i32.const 8))
238+
(local.get $result2)
239+
(call $print.int)
240+
)
241+
242+
;; Test 9: complex composition
243+
(func $complex (param i32 i32) (result i32 i32 i32)
244+
;; returns (a+b, a-b, a*2)
245+
(local.get 0)
246+
(local.get 1)
247+
(i32.add)
248+
249+
(local.get 0)
250+
(local.get 1)
251+
(i32.sub)
252+
253+
(local.get 0)
254+
(i32.const 2)
255+
(i32.mul)
256+
)
257+
258+
(func $test_complex (export "test_complex")
259+
(call $print.string (i32.const 208) (i32.const 28))
260+
(i32.const 10)
261+
(i32.const 3)
262+
(call $complex)
263+
264+
(i32.add) ;; 20 + 7 = 27
265+
(i32.mul) ;; 27 * 13 = 351
266+
267+
(call $print.string (i32.const 170) (i32.const 8))
268+
(call $print.int)
269+
)
270+
271+
272+
(func $main (export "main")
273+
(call $test_swap)
274+
(call $test_triple)
275+
(call $test_nested)
276+
(call $test_block)
277+
(call $test_loop)
278+
(call $test_if (i32.const 1))
279+
(call $test_if (i32.const 0))
280+
(call $test_branch (i32.const 1))
281+
(call $test_branch (i32.const 0))
282+
(call $test_br_table (i32.const 0))
283+
(call $test_br_table (i32.const 1))
284+
(call $test_br_table (i32.const 2))
285+
(call $test_complex)
286+
)
287+
)

0 commit comments

Comments
 (0)