summaryrefslogtreecommitdiff
path: root/test/parse
diff options
context:
space:
mode:
Diffstat (limited to 'test/parse')
-rw-r--r--test/parse/assert/assert-after-module.txt5
-rw-r--r--test/parse/assert/assertinvalid.txt13
-rw-r--r--test/parse/assert/assertreturn.txt9
-rw-r--r--test/parse/assert/assertreturnnan.txt8
-rw-r--r--test/parse/assert/bad-assert-before-module.txt6
-rw-r--r--test/parse/assert/bad-assertinvalid-succeeds.txt8
-rw-r--r--test/parse/assert/bad-assertreturn-non-const.txt14
-rw-r--r--test/parse/assert/bad-assertreturn-too-few.txt9
-rw-r--r--test/parse/assert/bad-assertreturn-too-many.txt9
-rw-r--r--test/parse/assert/bad-assertreturn-unknown-function.txt7
-rw-r--r--test/parse/assert/bad-assertreturnnan-invalid-return-type.txt10
-rw-r--r--test/parse/assert/bad-assertreturnnan-too-few.txt9
-rw-r--r--test/parse/assert/bad-assertreturnnan-too-many.txt9
-rw-r--r--test/parse/assert/bad-assertreturnnan-unknown-function.txt7
-rw-r--r--test/parse/assert/bad-invoke-no-module.txt6
-rw-r--r--test/parse/assert/bad-invoke-too-few.txt9
-rw-r--r--test/parse/assert/bad-invoke-too-many.txt9
-rw-r--r--test/parse/assert/bad-invoke-unknown-function.txt10
-rw-r--r--test/parse/assert/invoke.txt9
-rw-r--r--test/parse/bad-single-semicolon.txt8
-rw-r--r--test/parse/bad-string-eof.txt6
-rw-r--r--test/parse/bad-string-escape.txt5
-rw-r--r--test/parse/bad-string-hex-escape.txt5
-rw-r--r--test/parse/bad-toplevel.txt7
-rw-r--r--test/parse/basic.txt3
-rw-r--r--test/parse/empty-file.txt1
-rw-r--r--test/parse/expr/bad-binary-empty.txt5
-rw-r--r--test/parse/expr/bad-binary-one-expr.txt5
-rw-r--r--test/parse/expr/bad-break-bad-depth.txt9
-rw-r--r--test/parse/expr/bad-break-defined-later.txt7
-rw-r--r--test/parse/expr/bad-break-name-undefined.txt5
-rw-r--r--test/parse/expr/bad-break-name.txt5
-rw-r--r--test/parse/expr/bad-break-no-label.txt5
-rw-r--r--test/parse/expr/bad-break-undefined.txt5
-rw-r--r--test/parse/expr/bad-call-too-few.txt7
-rw-r--r--test/parse/expr/bad-call-too-many.txt7
-rw-r--r--test/parse/expr/bad-callimport-too-few.txt8
-rw-r--r--test/parse/expr/bad-callimport-too-many.txt8
-rw-r--r--test/parse/expr/bad-callindirect-empty.txt8
-rw-r--r--test/parse/expr/bad-callindirect-too-few.txt8
-rw-r--r--test/parse/expr/bad-callindirect-too-many.txt8
-rw-r--r--test/parse/expr/bad-compare-empty.txt5
-rw-r--r--test/parse/expr/bad-compare-one-expr.txt5
-rw-r--r--test/parse/expr/bad-const-f32-trailing.txt6
-rw-r--r--test/parse/expr/bad-const-i32-garbage.txt6
-rw-r--r--test/parse/expr/bad-const-i32-just-negative-sign.txt7
-rw-r--r--test/parse/expr/bad-const-i32-overflow.txt5
-rw-r--r--test/parse/expr/bad-const-i32-trailing.txt6
-rw-r--r--test/parse/expr/bad-const-i32-underflow.txt5
-rw-r--r--test/parse/expr/bad-const-i64-overflow.txt5
-rw-r--r--test/parse/expr/bad-convert-empty.txt5
-rw-r--r--test/parse/expr/bad-convert-float-sign.txt6
-rw-r--r--test/parse/expr/bad-convert-int-no-sign.txt6
-rw-r--r--test/parse/expr/bad-convert-too-many.txt5
-rw-r--r--test/parse/expr/bad-getlocal-empty.txt5
-rw-r--r--test/parse/expr/bad-getlocal-name-undefined.txt5
-rw-r--r--test/parse/expr/bad-getlocal-name.txt6
-rw-r--r--test/parse/expr/bad-getlocal-too-many.txt6
-rw-r--r--test/parse/expr/bad-getlocal-undefined.txt5
-rw-r--r--test/parse/expr/bad-if-no-then.txt5
-rw-r--r--test/parse/expr/bad-if-too-many.txt5
-rw-r--r--test/parse/expr/bad-label-name-empty.txt5
-rw-r--r--test/parse/expr/bad-label-name.txt5
-rw-r--r--test/parse/expr/bad-label.txt5
-rw-r--r--test/parse/expr/bad-load-align-misspelled.txt7
-rw-r--r--test/parse/expr/bad-load-align-negative.txt5
-rw-r--r--test/parse/expr/bad-load-align-not-pot.txt5
-rw-r--r--test/parse/expr/bad-load-align.txt5
-rw-r--r--test/parse/expr/bad-load-float-sign.txt6
-rw-r--r--test/parse/expr/bad-load-offset-negative.txt5
-rw-r--r--test/parse/expr/bad-load-type.txt6
-rw-r--r--test/parse/expr/bad-loadglobal-empty.txt6
-rw-r--r--test/parse/expr/bad-loadglobal-name-undefined.txt5
-rw-r--r--test/parse/expr/bad-loadglobal-name.txt7
-rw-r--r--test/parse/expr/bad-loadglobal-too-many.txt6
-rw-r--r--test/parse/expr/bad-loadglobal-undefined.txt5
-rw-r--r--test/parse/expr/bad-nop.txt5
-rw-r--r--test/parse/expr/bad-return-multi.txt6
-rw-r--r--test/parse/expr/bad-return-too-few.txt7
-rw-r--r--test/parse/expr/bad-return-too-many.txt7
-rw-r--r--test/parse/expr/bad-setlocal-name-undefined.txt5
-rw-r--r--test/parse/expr/bad-setlocal-name.txt8
-rw-r--r--test/parse/expr/bad-setlocal-no-value.txt7
-rw-r--r--test/parse/expr/bad-setlocal-too-many.txt7
-rw-r--r--test/parse/expr/bad-setlocal-undefined.txt5
-rw-r--r--test/parse/expr/bad-store-align-not-pot.txt5
-rw-r--r--test/parse/expr/bad-store-align.txt5
-rw-r--r--test/parse/expr/bad-store-float.sign.txt6
-rw-r--r--test/parse/expr/bad-store-offset-negative.txt5
-rw-r--r--test/parse/expr/bad-store-type.txt6
-rw-r--r--test/parse/expr/bad-storeglobal-empty.txt6
-rw-r--r--test/parse/expr/bad-storeglobal-name-undefined.txt5
-rw-r--r--test/parse/expr/bad-storeglobal-name.txt7
-rw-r--r--test/parse/expr/bad-storeglobal-too-many.txt6
-rw-r--r--test/parse/expr/bad-storeglobal-undefined.txt5
-rw-r--r--test/parse/expr/bad-tableswitch-invalid-case.txt10
-rw-r--r--test/parse/expr/bad-tableswitch-invalid-default-case.txt9
-rw-r--r--test/parse/expr/bad-unary-empty.txt5
-rw-r--r--test/parse/expr/bad-unary-too-many.txt5
-rw-r--r--test/parse/expr/bad-unexpected.txt5
-rw-r--r--test/parse/expr/binary.txt42
-rw-r--r--test/parse/expr/block-named.txt5
-rw-r--r--test/parse/expr/block-return.txt5
-rw-r--r--test/parse/expr/block.txt1
-rw-r--r--test/parse/expr/br.txt4
-rw-r--r--test/parse/expr/break-block.txt6
-rw-r--r--test/parse/expr/break-loop.txt7
-rw-r--r--test/parse/expr/break-named.txt3
-rw-r--r--test/parse/expr/break.txt3
-rw-r--r--test/parse/expr/brif-named.txt4
-rw-r--r--test/parse/expr/brif.txt4
-rw-r--r--test/parse/expr/call-defined-later.txt5
-rw-r--r--test/parse/expr/call-empty.txt1
-rw-r--r--test/parse/expr/call-name-prefix.txt5
-rw-r--r--test/parse/expr/call-named.txt3
-rw-r--r--test/parse/expr/call.txt2
-rw-r--r--test/parse/expr/callimport-defined-later.txt4
-rw-r--r--test/parse/expr/callimport-named.txt4
-rw-r--r--test/parse/expr/callimport-type.txt5
-rw-r--r--test/parse/expr/callimport.txt4
-rw-r--r--test/parse/expr/callindirect-named.txt3
-rw-r--r--test/parse/expr/callindirect.txt3
-rw-r--r--test/parse/expr/cast.txt7
-rw-r--r--test/parse/expr/compare.txt34
-rw-r--r--test/parse/expr/const.txt43
-rw-r--r--test/parse/expr/convert.txt23
-rw-r--r--test/parse/expr/expr-break.txt6
-rw-r--r--test/parse/expr/getlocal-index-after-param.txt1
-rw-r--r--test/parse/expr/getlocal-index-mixed-named-unnamed.txt11
-rw-r--r--test/parse/expr/getlocal-named.txt1
-rw-r--r--test/parse/expr/getlocal-param-named.txt1
-rw-r--r--test/parse/expr/getlocal-param.txt1
-rw-r--r--test/parse/expr/getlocal.txt1
-rw-r--r--test/parse/expr/if-return.txt5
-rw-r--r--test/parse/expr/if-then-else.txt1
-rw-r--r--test/parse/expr/if.txt1
-rw-r--r--test/parse/expr/label-name.txt1
-rw-r--r--test/parse/expr/label.txt2
-rw-r--r--test/parse/expr/load-aligned.txt16
-rw-r--r--test/parse/expr/load-offset.txt31
-rw-r--r--test/parse/expr/load.txt16
-rw-r--r--test/parse/expr/loadglobal-name.txt2
-rw-r--r--test/parse/expr/loadglobal.txt2
-rw-r--r--test/parse/expr/loop-empty.txt1
-rw-r--r--test/parse/expr/loop-named.txt5
-rw-r--r--test/parse/expr/loop.txt3
-rw-r--r--test/parse/expr/memory-size.txt3
-rw-r--r--test/parse/expr/nop.txt1
-rw-r--r--test/parse/expr/resize-memory.txt3
-rw-r--r--test/parse/expr/return-block.txt6
-rw-r--r--test/parse/expr/return-empty.txt2
-rw-r--r--test/parse/expr/return-if.txt6
-rw-r--r--test/parse/expr/return-void.txt1
-rw-r--r--test/parse/expr/return.txt3
-rw-r--r--test/parse/expr/select.txt6
-rw-r--r--test/parse/expr/setlocal-index-after-param.txt1
-rw-r--r--test/parse/expr/setlocal-index-mixed-named-unnamed.txt11
-rw-r--r--test/parse/expr/setlocal-named.txt3
-rw-r--r--test/parse/expr/setlocal-param-named.txt1
-rw-r--r--test/parse/expr/setlocal-param.txt1
-rw-r--r--test/parse/expr/setlocal.txt2
-rw-r--r--test/parse/expr/store-aligned.txt11
-rw-r--r--test/parse/expr/store-offset.txt22
-rw-r--r--test/parse/expr/store.txt11
-rw-r--r--test/parse/expr/storeglobal-name.txt2
-rw-r--r--test/parse/expr/storeglobal.txt2
-rw-r--r--test/parse/expr/tableswitch-default-br.txt6
-rw-r--r--test/parse/expr/tableswitch-empty-case.txt7
-rw-r--r--test/parse/expr/tableswitch-empty.txt5
-rw-r--r--test/parse/expr/tableswitch-multi.txt9
-rw-r--r--test/parse/expr/tableswitch-named.txt6
-rw-r--r--test/parse/expr/tableswitch-table-br.txt6
-rw-r--r--test/parse/expr/tableswitch-unreferenced.txt7
-rw-r--r--test/parse/expr/tableswitch.txt6
-rw-r--r--test/parse/expr/unary.txt23
-rw-r--r--test/parse/expr/unreachable.txt1
-rw-r--r--test/parse/func/bad-func-name.txt6
-rw-r--r--test/parse/func/bad-local-binding-no-type.txt5
-rw-r--r--test/parse/func/bad-local-binding.txt5
-rw-r--r--test/parse/func/bad-local-name.txt5
-rw-r--r--test/parse/func/bad-local-type-list.txt5
-rw-r--r--test/parse/func/bad-local-type.txt5
-rw-r--r--test/parse/func/bad-param-after-local.txt5
-rw-r--r--test/parse/func/bad-param-binding.txt5
-rw-r--r--test/parse/func/bad-param-name.txt5
-rw-r--r--test/parse/func/bad-param-redefinition.txt5
-rw-r--r--test/parse/func/bad-param-type-list.txt5
-rw-r--r--test/parse/func/bad-param.txt5
-rw-r--r--test/parse/func/bad-result-empty.txt5
-rw-r--r--test/parse/func/bad-result-multi.txt5
-rw-r--r--test/parse/func/bad-result-type.txt6
-rw-r--r--test/parse/func/bad-sig-param-type-mismatch.txt7
-rw-r--r--test/parse/func/bad-sig-params-empty.txt7
-rw-r--r--test/parse/func/bad-sig-result-type-mistmatch.txt7
-rw-r--r--test/parse/func/bad-sig-result-type-not-void.txt7
-rw-r--r--test/parse/func/bad-sig-result-type-void.txt7
-rw-r--r--test/parse/func/bad-sig-too-few-params.txt7
-rw-r--r--test/parse/func/bad-sig-too-many-params.txt7
-rw-r--r--test/parse/func/func-named.txt1
-rw-r--r--test/parse/func/local-empty.txt1
-rw-r--r--test/parse/func/local-multi.txt1
-rw-r--r--test/parse/func/local.txt1
-rw-r--r--test/parse/func/no-space.txt4
-rw-r--r--test/parse/func/param-binding.txt1
-rw-r--r--test/parse/func/param-multi.txt1
-rw-r--r--test/parse/func/param-type-1.txt1
-rw-r--r--test/parse/func/param-type-2.txt1
-rw-r--r--test/parse/func/result.txt1
-rw-r--r--test/parse/func/sig-match.txt12
-rw-r--r--test/parse/func/sig.txt3
-rw-r--r--test/parse/line-comment.txt3
-rw-r--r--test/parse/module/bad-export-empty.txt5
-rw-r--r--test/parse/module/bad-export-name-undefined.txt5
-rw-r--r--test/parse/module/bad-export-name.txt6
-rw-r--r--test/parse/module/bad-export-no-string.txt5
-rw-r--r--test/parse/module/bad-export-too-many.txt5
-rw-r--r--test/parse/module/bad-export-undefined.txt5
-rw-r--r--test/parse/module/bad-func-redefinition.txt7
-rw-r--r--test/parse/module/bad-global-binding.txt5
-rw-r--r--test/parse/module/bad-global-redefinition.txt5
-rw-r--r--test/parse/module/bad-global-too-many.txt5
-rw-r--r--test/parse/module/bad-global-type-list.txt5
-rw-r--r--test/parse/module/bad-import-not-param.txt6
-rw-r--r--test/parse/module/bad-import-not-result.txt6
-rw-r--r--test/parse/module/bad-import-one-string.txt5
-rw-r--r--test/parse/module/bad-import-redefinition.txt7
-rw-r--r--test/parse/module/bad-memory-empty.txt5
-rw-r--r--test/parse/module/bad-memory-init-size-negative.txt5
-rw-r--r--test/parse/module/bad-memory-init-size.txt6
-rw-r--r--test/parse/module/bad-memory-max-less-than-init.txt5
-rw-r--r--test/parse/module/bad-memory-max-size-negative.txt5
-rw-r--r--test/parse/module/bad-memory-max-size.txt5
-rw-r--r--test/parse/module/bad-memory-segment-address-negative.txt5
-rw-r--r--test/parse/module/bad-memory-segment-address-oob.txt5
-rw-r--r--test/parse/module/bad-memory-segment-address.txt6
-rw-r--r--test/parse/module/bad-memory-segment-end-oob.txt5
-rw-r--r--test/parse/module/bad-memory-segment-overlap.txt5
-rw-r--r--test/parse/module/bad-memory-too-many.txt7
-rw-r--r--test/parse/module/bad-module-no-close.txt5
-rw-r--r--test/parse/module/bad-table-invalid.txt6
-rw-r--r--test/parse/module/bad-table-too-many.txt8
-rw-r--r--test/parse/module/export-multi.txt4
-rw-r--r--test/parse/module/export-named.txt3
-rw-r--r--test/parse/module/export.txt3
-rw-r--r--test/parse/module/global-empty.txt1
-rw-r--r--test/parse/module/global-many.txt1
-rw-r--r--test/parse/module/global-named.txt1
-rw-r--r--test/parse/module/global.txt1
-rw-r--r--test/parse/module/import-no-param.txt1
-rw-r--r--test/parse/module/import-type.txt3
-rw-r--r--test/parse/module/import.txt10
-rw-r--r--test/parse/module/memory-init-max-size.txt1
-rw-r--r--test/parse/module/memory-init-size.txt1
-rw-r--r--test/parse/module/memory-segment-1.txt1
-rw-r--r--test/parse/module/memory-segment-many.txt6
-rw-r--r--test/parse/module/module-empty.txt1
-rw-r--r--test/parse/module/table-named.txt5
-rw-r--r--test/parse/module/table.txt5
-rw-r--r--test/parse/module/type-empty-param.txt1
-rw-r--r--test/parse/module/type-empty.txt1
-rw-r--r--test/parse/module/type-multi-param.txt1
-rw-r--r--test/parse/module/type-no-param.txt1
-rw-r--r--test/parse/module/type.txt1
-rw-r--r--test/parse/nested-comments.txt6
-rw-r--r--test/parse/string-escape.txt1
-rw-r--r--test/parse/string-hex.txt1
266 files changed, 1535 insertions, 0 deletions
diff --git a/test/parse/assert/assert-after-module.txt b/test/parse/assert/assert-after-module.txt
new file mode 100644
index 00000000..068c3108
--- /dev/null
+++ b/test/parse/assert/assert-after-module.txt
@@ -0,0 +1,5 @@
+;;; FLAGS: --spec
+(module
+ (export "f" 0)
+ (func (result i32) (return (i32.const 0))))
+(assert_return (invoke "f") (i32.const 0))
diff --git a/test/parse/assert/assertinvalid.txt b/test/parse/assert/assertinvalid.txt
new file mode 100644
index 00000000..2092de9a
--- /dev/null
+++ b/test/parse/assert/assertinvalid.txt
@@ -0,0 +1,13 @@
+;;; FLAGS: --spec
+(assert_invalid
+ (module (func (i32.const 1)) (export "foo" 1))
+ "unknown function 1") ;; string is ignored
+(assert_invalid
+ (module (func (result i32) (nop)))
+ "type mismatch")
+(;; STDOUT ;;;
+assert_invalid error:
+ parse/assert/assertinvalid.txt:3:46: function variable out of range (max 1)
+assert_invalid error:
+ parse/assert/assertinvalid.txt:6:30: type mismatch in nop. got void, expected i32
+;;; STDOUT ;;)
diff --git a/test/parse/assert/assertreturn.txt b/test/parse/assert/assertreturn.txt
new file mode 100644
index 00000000..b1394fab
--- /dev/null
+++ b/test/parse/assert/assertreturn.txt
@@ -0,0 +1,9 @@
+;;; FLAGS: --spec
+(module
+ (func $foo (result i32) (i32.const 0))
+ (export "foo" $foo)
+ (func $bar (param f32) (result f32) (get_local 0))
+ (export "bar" $bar))
+
+(assert_return (invoke "foo") (i32.const 0))
+(assert_return (invoke "bar" (f32.const 0)) (f32.const 0))
diff --git a/test/parse/assert/assertreturnnan.txt b/test/parse/assert/assertreturnnan.txt
new file mode 100644
index 00000000..5b73a364
--- /dev/null
+++ b/test/parse/assert/assertreturnnan.txt
@@ -0,0 +1,8 @@
+;;; FLAGS: --spec
+(module
+ (func $foo (param f32) (result f32)
+ (f32.div (get_local 0) (f32.const 0)))
+ (export "foo" $foo))
+
+(assert_return_nan
+ (invoke "foo" (f32.const 0)))
diff --git a/test/parse/assert/bad-assert-before-module.txt b/test/parse/assert/bad-assert-before-module.txt
new file mode 100644
index 00000000..eb60206e
--- /dev/null
+++ b/test/parse/assert/bad-assert-before-module.txt
@@ -0,0 +1,6 @@
+;;; FLAGS: --spec
+;;; ERROR: 1
+(assert_return (invoke "f") (i32.const 0))
+(;; STDERR ;;;
+parse/assert/bad-assert-before-module.txt:3:17: invoke must occur after a module definition
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertinvalid-succeeds.txt b/test/parse/assert/bad-assertinvalid-succeeds.txt
new file mode 100644
index 00000000..38a457e9
--- /dev/null
+++ b/test/parse/assert/bad-assertinvalid-succeeds.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(assert_invalid
+ (module (func (result i32) (i32.const 0)))
+ "success")
+(;; STDERR ;;;
+parse/assert/bad-assertinvalid-succeeds.txt:4:4: expected module to be invalid
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturn-non-const.txt b/test/parse/assert/bad-assertreturn-non-const.txt
new file mode 100644
index 00000000..dc45832d
--- /dev/null
+++ b/test/parse/assert/bad-assertreturn-non-const.txt
@@ -0,0 +1,14 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $bar (param f32) (result f32) (get_local 0))
+ (export "bar" $bar))
+
+;; NOT ok to use more complex exprs
+(assert_return
+ (invoke "bar"
+ (f32.add (f32.const 1) (f32.const 10)))
+ (f32.const 11))
+(;; STDERR ;;;
+parse/assert/bad-assertreturn-non-const.txt:10:6: syntax error, unexpected BINARY, expecting CONST
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturn-too-few.txt b/test/parse/assert/bad-assertreturn-too-few.txt
new file mode 100644
index 00000000..cac62e4f
--- /dev/null
+++ b/test/parse/assert/bad-assertreturn-too-few.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $foo (param i32) (result i32) (get_local 0))
+ (export "foo" $foo))
+(assert_return (invoke "foo") (i32.const 0))
+(;; STDERR ;;;
+parse/assert/bad-assertreturn-too-few.txt:6:17: too few parameters to function. got 0, expected 1
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturn-too-many.txt b/test/parse/assert/bad-assertreturn-too-many.txt
new file mode 100644
index 00000000..2c5e0eee
--- /dev/null
+++ b/test/parse/assert/bad-assertreturn-too-many.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $foo (result i32) (i32.const 0))
+ (export "foo" $foo))
+(assert_return (invoke "foo" (i32.const 0)) (i32.const 0))
+(;; STDERR ;;;
+parse/assert/bad-assertreturn-too-many.txt:6:17: too many parameters to function. got 1, expected 0
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturn-unknown-function.txt b/test/parse/assert/bad-assertreturn-unknown-function.txt
new file mode 100644
index 00000000..4284d2a8
--- /dev/null
+++ b/test/parse/assert/bad-assertreturn-unknown-function.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module)
+(assert_return (invoke "foo") (i32.const 0))
+(;; STDERR ;;;
+parse/assert/bad-assertreturn-unknown-function.txt:4:17: unknown function export "foo"
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt b/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt
new file mode 100644
index 00000000..1de5bed6
--- /dev/null
+++ b/test/parse/assert/bad-assertreturnnan-invalid-return-type.txt
@@ -0,0 +1,10 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $foo (result i32) (i32.const 0))
+ (export "foo" $foo))
+
+(assert_return_nan (invoke "foo"))
+(;; STDERR ;;;
+parse/assert/bad-assertreturnnan-invalid-return-type.txt:7:21: type mismatch. got i32, expected f32 or f64
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturnnan-too-few.txt b/test/parse/assert/bad-assertreturnnan-too-few.txt
new file mode 100644
index 00000000..bd414adb
--- /dev/null
+++ b/test/parse/assert/bad-assertreturnnan-too-few.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $foo (param i32) (result f32) (f32.const 0))
+ (export "foo" $foo))
+(assert_return_nan (invoke "foo"))
+(;; STDERR ;;;
+parse/assert/bad-assertreturnnan-too-few.txt:6:21: too few parameters to function. got 0, expected 1
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturnnan-too-many.txt b/test/parse/assert/bad-assertreturnnan-too-many.txt
new file mode 100644
index 00000000..572b3539
--- /dev/null
+++ b/test/parse/assert/bad-assertreturnnan-too-many.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func $foo (result f32) (f32.const 0))
+ (export "foo" $foo))
+(assert_return_nan (invoke "foo" (f32.const 0)))
+(;; STDERR ;;;
+parse/assert/bad-assertreturnnan-too-many.txt:6:21: too many parameters to function. got 1, expected 0
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-assertreturnnan-unknown-function.txt b/test/parse/assert/bad-assertreturnnan-unknown-function.txt
new file mode 100644
index 00000000..cfdffa04
--- /dev/null
+++ b/test/parse/assert/bad-assertreturnnan-unknown-function.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module)
+(assert_return_nan (invoke "foo"))
+(;; STDERR ;;;
+parse/assert/bad-assertreturnnan-unknown-function.txt:4:21: unknown function export "foo"
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-invoke-no-module.txt b/test/parse/assert/bad-invoke-no-module.txt
new file mode 100644
index 00000000..52eb24d3
--- /dev/null
+++ b/test/parse/assert/bad-invoke-no-module.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(invoke "foo")
+(;; STDERR ;;;
+parse/assert/bad-invoke-no-module.txt:3:2: invoke must occur after a module definition
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-invoke-too-few.txt b/test/parse/assert/bad-invoke-too-few.txt
new file mode 100644
index 00000000..8c64ef02
--- /dev/null
+++ b/test/parse/assert/bad-invoke-too-few.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func (param i32))
+ (export "foo" 0))
+(invoke "foo")
+(;; STDERR ;;;
+parse/assert/bad-invoke-too-few.txt:6:2: too few parameters to function. got 0, expected 1
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-invoke-too-many.txt b/test/parse/assert/bad-invoke-too-many.txt
new file mode 100644
index 00000000..adb2a283
--- /dev/null
+++ b/test/parse/assert/bad-invoke-too-many.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (func (param i32))
+ (export "foo" 0))
+(invoke "foo" (i32.const 0) (i32.const 1))
+(;; STDERR ;;;
+parse/assert/bad-invoke-too-many.txt:6:2: too many parameters to function. got 2, expected 1
+;;; STDERR ;;)
diff --git a/test/parse/assert/bad-invoke-unknown-function.txt b/test/parse/assert/bad-invoke-unknown-function.txt
new file mode 100644
index 00000000..191a6f81
--- /dev/null
+++ b/test/parse/assert/bad-invoke-unknown-function.txt
@@ -0,0 +1,10 @@
+;;; ERROR: 1
+;;; FLAGS: --spec
+(module
+ (export "foo" $foo)
+ (func $foo))
+
+(invoke "bar")
+(;; STDERR ;;;
+parse/assert/bad-invoke-unknown-function.txt:7:2: unknown function export "bar"
+;;; STDERR ;;)
diff --git a/test/parse/assert/invoke.txt b/test/parse/assert/invoke.txt
new file mode 100644
index 00000000..d55148fc
--- /dev/null
+++ b/test/parse/assert/invoke.txt
@@ -0,0 +1,9 @@
+;;; FLAGS: --spec
+(module
+ (export "test" $test)
+ (func $test (param i32) (result i32)
+ (i32.add (get_local 0) (i32.const 100))))
+
+(invoke "test" (i32.const 1))
+(invoke "test" (i32.const 100))
+(invoke "test" (i32.const -30))
diff --git a/test/parse/bad-single-semicolon.txt b/test/parse/bad-single-semicolon.txt
new file mode 100644
index 00000000..7a82bc4f
--- /dev/null
+++ b/test/parse/bad-single-semicolon.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+; foo bar
+(module)
+(;; STDERR ;;;
+parse/bad-single-semicolon.txt:2:1: unexpected char
+parse/bad-single-semicolon.txt:2:3: unexpected token "foo"
+parse/bad-single-semicolon.txt:2:7: unexpected token "bar"
+;;; STDERR ;;)
diff --git a/test/parse/bad-string-eof.txt b/test/parse/bad-string-eof.txt
new file mode 100644
index 00000000..ad3ec5d7
--- /dev/null
+++ b/test/parse/bad-string-eof.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func) (export "
+(;; STDERR ;;;
+parse/bad-string-eof.txt:3:25: newline in string
+parse/bad-string-eof.txt:3:25: syntax error, unexpected EOF, expecting TEXT
+;;; STDERR ;;)
diff --git a/test/parse/bad-string-escape.txt b/test/parse/bad-string-escape.txt
new file mode 100644
index 00000000..70d3647e
--- /dev/null
+++ b/test/parse/bad-string-escape.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func) (export "foobar\r\n" 0))
+(;; STDERR ;;;
+parse/bad-string-escape.txt:2:31: bad escape "\r"
+;;; STDERR ;;)
diff --git a/test/parse/bad-string-hex-escape.txt b/test/parse/bad-string-hex-escape.txt
new file mode 100644
index 00000000..dea7b401
--- /dev/null
+++ b/test/parse/bad-string-hex-escape.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func) (export "foo\az" 0))
+(;; STDERR ;;;
+parse/bad-string-hex-escape.txt:2:28: bad escape "\a"
+;;; STDERR ;;)
diff --git a/test/parse/bad-toplevel.txt b/test/parse/bad-toplevel.txt
new file mode 100644
index 00000000..9b1fe064
--- /dev/null
+++ b/test/parse/bad-toplevel.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(foo bar)
+(;; STDERR ;;;
+parse/bad-toplevel.txt:2:2: unexpected token "foo"
+parse/bad-toplevel.txt:2:6: unexpected token "bar"
+parse/bad-toplevel.txt:2:9: syntax error, unexpected )
+;;; STDERR ;;)
diff --git a/test/parse/basic.txt b/test/parse/basic.txt
new file mode 100644
index 00000000..8a49c2dd
--- /dev/null
+++ b/test/parse/basic.txt
@@ -0,0 +1,3 @@
+(module
+ (func (result i32)
+ (return (i32.const 42))))
diff --git a/test/parse/empty-file.txt b/test/parse/empty-file.txt
new file mode 100644
index 00000000..2f8bfc07
--- /dev/null
+++ b/test/parse/empty-file.txt
@@ -0,0 +1 @@
+;; empty file
diff --git a/test/parse/expr/bad-binary-empty.txt b/test/parse/expr/bad-binary-empty.txt
new file mode 100644
index 00000000..61ba1f31
--- /dev/null
+++ b/test/parse/expr/bad-binary-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.add)))
+(;; STDERR ;;;
+parse/expr/bad-binary-empty.txt:2:23: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-binary-one-expr.txt b/test/parse/expr/bad-binary-one-expr.txt
new file mode 100644
index 00000000..042310d3
--- /dev/null
+++ b/test/parse/expr/bad-binary-one-expr.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.add (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-binary-one-expr.txt:2:37: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-bad-depth.txt b/test/parse/expr/bad-break-bad-depth.txt
new file mode 100644
index 00000000..1a666eb8
--- /dev/null
+++ b/test/parse/expr/bad-break-bad-depth.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+(module
+ (func
+ (label ;; 1
+ (label ;; 0
+ (break 2)))))
+(;; STDERR ;;;
+parse/expr/bad-break-bad-depth.txt:6:16: label variable out of range (max 2)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-defined-later.txt b/test/parse/expr/bad-break-defined-later.txt
new file mode 100644
index 00000000..c1879bde
--- /dev/null
+++ b/test/parse/expr/bad-break-defined-later.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module (func
+ (break 0)
+ (label (nop))))
+(;; STDERR ;;;
+parse/expr/bad-break-defined-later.txt:3:10: label variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-name-undefined.txt b/test/parse/expr/bad-break-name-undefined.txt
new file mode 100644
index 00000000..c02125ee
--- /dev/null
+++ b/test/parse/expr/bad-break-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (break $n)))
+(;; STDERR ;;;
+parse/expr/bad-break-name-undefined.txt:2:22: undefined label variable "$n"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-name.txt b/test/parse/expr/bad-break-name.txt
new file mode 100644
index 00000000..1f8eed9e
--- /dev/null
+++ b/test/parse/expr/bad-break-name.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (label $foo (break foo))))
+(;; STDERR ;;;
+parse/expr/bad-break-name.txt:2:34: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-no-label.txt b/test/parse/expr/bad-break-no-label.txt
new file mode 100644
index 00000000..52261560
--- /dev/null
+++ b/test/parse/expr/bad-break-no-label.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (break)))
+(;; STDERR ;;;
+parse/expr/bad-break-no-label.txt:2:16: label variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-break-undefined.txt b/test/parse/expr/bad-break-undefined.txt
new file mode 100644
index 00000000..7b9e61e2
--- /dev/null
+++ b/test/parse/expr/bad-break-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (break 0)))
+(;; STDERR ;;;
+parse/expr/bad-break-undefined.txt:2:22: label variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-call-too-few.txt b/test/parse/expr/bad-call-too-few.txt
new file mode 100644
index 00000000..10d3c5c7
--- /dev/null
+++ b/test/parse/expr/bad-call-too-few.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func (param i32) (param f32)
+ (call 0 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-call-too-few.txt:4:5: too few parameters to function. got 1, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-call-too-many.txt b/test/parse/expr/bad-call-too-many.txt
new file mode 100644
index 00000000..8d1720c6
--- /dev/null
+++ b/test/parse/expr/bad-call-too-many.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func (param i32 i64)
+ (call 0 (i32.const 0) (i64.const 0) (f32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-call-too-many.txt:4:5: too many parameters to function. got 3, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-callimport-too-few.txt b/test/parse/expr/bad-callimport-too-few.txt
new file mode 100644
index 00000000..c93a6b65
--- /dev/null
+++ b/test/parse/expr/bad-callimport-too-few.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (import "foo" "bar" (param i32 i32))
+ (func
+ (call_import 0 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-callimport-too-few.txt:5:5: too few parameters to function. got 1, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-callimport-too-many.txt b/test/parse/expr/bad-callimport-too-many.txt
new file mode 100644
index 00000000..9bee19a0
--- /dev/null
+++ b/test/parse/expr/bad-callimport-too-many.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (import "foo" "bar" (param i32 i32))
+ (func
+ (call_import 0 (i32.const 0) (i32.const 1) (i32.const 2))))
+(;; STDERR ;;;
+parse/expr/bad-callimport-too-many.txt:5:5: too many parameters to function. got 3, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-callindirect-empty.txt b/test/parse/expr/bad-callindirect-empty.txt
new file mode 100644
index 00000000..30cb99ad
--- /dev/null
+++ b/test/parse/expr/bad-callindirect-empty.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32 i32)))
+ (func
+ (call_indirect $t)))
+(;; STDERR ;;;
+parse/expr/bad-callindirect-empty.txt:5:22: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-callindirect-too-few.txt b/test/parse/expr/bad-callindirect-too-few.txt
new file mode 100644
index 00000000..85993a4d
--- /dev/null
+++ b/test/parse/expr/bad-callindirect-too-few.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32 i32)))
+ (func
+ (call_indirect $t (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-callindirect-too-few.txt:5:5: too few parameters to function. got 0, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-callindirect-too-many.txt b/test/parse/expr/bad-callindirect-too-many.txt
new file mode 100644
index 00000000..bd2f6453
--- /dev/null
+++ b/test/parse/expr/bad-callindirect-too-many.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32 i32)))
+ (func
+ (call_indirect $t (i32.const 0) (i32.const 1) (i32.const 2) (i32.const 3))))
+(;; STDERR ;;;
+parse/expr/bad-callindirect-too-many.txt:5:5: too many parameters to function. got 3, expected 2
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-compare-empty.txt b/test/parse/expr/bad-compare-empty.txt
new file mode 100644
index 00000000..19605f82
--- /dev/null
+++ b/test/parse/expr/bad-compare-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.eq)))
+(;; STDERR ;;;
+parse/expr/bad-compare-empty.txt:2:22: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-compare-one-expr.txt b/test/parse/expr/bad-compare-one-expr.txt
new file mode 100644
index 00000000..db6c75e7
--- /dev/null
+++ b/test/parse/expr/bad-compare-one-expr.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.lt_s (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-compare-one-expr.txt:2:38: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-f32-trailing.txt b/test/parse/expr/bad-const-f32-trailing.txt
new file mode 100644
index 00000000..dd3196f1
--- /dev/null
+++ b/test/parse/expr/bad-const-f32-trailing.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (f32.const 1234.5678foo)))
+(;; STDERR ;;;
+parse/expr/bad-const-f32-trailing.txt:2:26: unexpected token "1234.5678foo"
+parse/expr/bad-const-f32-trailing.txt:2:38: syntax error, unexpected ), expecting INT or FLOAT
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i32-garbage.txt b/test/parse/expr/bad-const-i32-garbage.txt
new file mode 100644
index 00000000..ccf6814e
--- /dev/null
+++ b/test/parse/expr/bad-const-i32-garbage.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (i32.const one-hundred)))
+(;; STDERR ;;;
+parse/expr/bad-const-i32-garbage.txt:2:26: unexpected token "one-hundred"
+parse/expr/bad-const-i32-garbage.txt:2:37: syntax error, unexpected ), expecting INT or FLOAT
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i32-just-negative-sign.txt b/test/parse/expr/bad-const-i32-just-negative-sign.txt
new file mode 100644
index 00000000..141c66fd
--- /dev/null
+++ b/test/parse/expr/bad-const-i32-just-negative-sign.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func (i32.const -)))
+(;; STDERR ;;;
+parse/expr/bad-const-i32-just-negative-sign.txt:3:20: unexpected token "-"
+parse/expr/bad-const-i32-just-negative-sign.txt:3:21: syntax error, unexpected ), expecting INT or FLOAT
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i32-overflow.txt b/test/parse/expr/bad-const-i32-overflow.txt
new file mode 100644
index 00000000..0ea686a2
--- /dev/null
+++ b/test/parse/expr/bad-const-i32-overflow.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.const 4294967296)))
+(;; STDERR ;;;
+parse/expr/bad-const-i32-overflow.txt:2:26: invalid literal "4294967296"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i32-trailing.txt b/test/parse/expr/bad-const-i32-trailing.txt
new file mode 100644
index 00000000..b6f9188f
--- /dev/null
+++ b/test/parse/expr/bad-const-i32-trailing.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (i32.const 100x)))
+(;; STDERR ;;;
+parse/expr/bad-const-i32-trailing.txt:2:26: unexpected token "100x"
+parse/expr/bad-const-i32-trailing.txt:2:30: syntax error, unexpected ), expecting INT or FLOAT
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i32-underflow.txt b/test/parse/expr/bad-const-i32-underflow.txt
new file mode 100644
index 00000000..682d4a37
--- /dev/null
+++ b/test/parse/expr/bad-const-i32-underflow.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.const -2147483649)))
+(;; STDERR ;;;
+parse/expr/bad-const-i32-underflow.txt:2:26: invalid literal "-2147483649"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-const-i64-overflow.txt b/test/parse/expr/bad-const-i64-overflow.txt
new file mode 100644
index 00000000..8c8f9a35
--- /dev/null
+++ b/test/parse/expr/bad-const-i64-overflow.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i64.const 18446744073709551616)))
+(;; STDERR ;;;
+parse/expr/bad-const-i64-overflow.txt:2:26: invalid literal "18446744073709551616"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-convert-empty.txt b/test/parse/expr/bad-convert-empty.txt
new file mode 100644
index 00000000..1ba099a4
--- /dev/null
+++ b/test/parse/expr/bad-convert-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (f32.convert_s/i32)))
+(;; STDERR ;;;
+parse/expr/bad-convert-empty.txt:2:33: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-convert-float-sign.txt b/test/parse/expr/bad-convert-float-sign.txt
new file mode 100644
index 00000000..be0bcee6
--- /dev/null
+++ b/test/parse/expr/bad-convert-float-sign.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (f32.converts.f64 (f32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-convert-float-sign.txt:2:16: unexpected token "f32.converts.f64"
+parse/expr/bad-convert-float-sign.txt:2:33: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-convert-int-no-sign.txt b/test/parse/expr/bad-convert-int-no-sign.txt
new file mode 100644
index 00000000..8c32a050
--- /dev/null
+++ b/test/parse/expr/bad-convert-int-no-sign.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (i32.convert.i32 (i32.const))))
+(;; STDERR ;;;
+parse/expr/bad-convert-int-no-sign.txt:2:16: unexpected token "i32.convert.i32"
+parse/expr/bad-convert-int-no-sign.txt:2:32: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-convert-too-many.txt b/test/parse/expr/bad-convert-too-many.txt
new file mode 100644
index 00000000..4789d1cc
--- /dev/null
+++ b/test/parse/expr/bad-convert-too-many.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.trunc_s/f32 (f32.const 0) (nop))))
+(;; STDERR ;;;
+parse/expr/bad-convert-too-many.txt:2:46: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-getlocal-empty.txt b/test/parse/expr/bad-getlocal-empty.txt
new file mode 100644
index 00000000..a16d0792
--- /dev/null
+++ b/test/parse/expr/bad-getlocal-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local i32) (get_local)))
+(;; STDERR ;;;
+parse/expr/bad-getlocal-empty.txt:2:37: syntax error, unexpected ), expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-getlocal-name-undefined.txt b/test/parse/expr/bad-getlocal-name-undefined.txt
new file mode 100644
index 00000000..7b8d89c3
--- /dev/null
+++ b/test/parse/expr/bad-getlocal-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (get_local $n)))
+(;; STDERR ;;;
+parse/expr/bad-getlocal-name-undefined.txt:2:26: undefined local variable "$n"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-getlocal-name.txt b/test/parse/expr/bad-getlocal-name.txt
new file mode 100644
index 00000000..fa805e7d
--- /dev/null
+++ b/test/parse/expr/bad-getlocal-name.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (local $f f32) (get_local f)))
+(;; STDERR ;;;
+parse/expr/bad-getlocal-name.txt:2:41: unexpected token "f"
+parse/expr/bad-getlocal-name.txt:2:42: syntax error, unexpected ), expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-getlocal-too-many.txt b/test/parse/expr/bad-getlocal-too-many.txt
new file mode 100644
index 00000000..4565951d
--- /dev/null
+++ b/test/parse/expr/bad-getlocal-too-many.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (local $foo f64)
+ (get_local $foo (nop))))
+(;; STDERR ;;;
+parse/expr/bad-getlocal-too-many.txt:3:19: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-getlocal-undefined.txt b/test/parse/expr/bad-getlocal-undefined.txt
new file mode 100644
index 00000000..ece6a3ea
--- /dev/null
+++ b/test/parse/expr/bad-getlocal-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (get_local 0)))
+(;; STDERR ;;;
+parse/expr/bad-getlocal-undefined.txt:2:26: local variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-if-no-then.txt b/test/parse/expr/bad-if-no-then.txt
new file mode 100644
index 00000000..17b75f83
--- /dev/null
+++ b/test/parse/expr/bad-if-no-then.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (if (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-if-no-then.txt:2:32: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-if-too-many.txt b/test/parse/expr/bad-if-too-many.txt
new file mode 100644
index 00000000..579fb885
--- /dev/null
+++ b/test/parse/expr/bad-if-too-many.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (if_else (i32.const 0) (nop) (nop) (nop))))
+(;; STDERR ;;;
+parse/expr/bad-if-too-many.txt:2:50: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-label-name-empty.txt b/test/parse/expr/bad-label-name-empty.txt
new file mode 100644
index 00000000..c0cac924
--- /dev/null
+++ b/test/parse/expr/bad-label-name-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (label $foo)))
+(;; STDERR ;;;
+parse/expr/bad-label-name-empty.txt:2:26: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-label-name.txt b/test/parse/expr/bad-label-name.txt
new file mode 100644
index 00000000..a8541fbe
--- /dev/null
+++ b/test/parse/expr/bad-label-name.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (label foo (nop))))
+(;; STDERR ;;;
+parse/expr/bad-label-name.txt:2:22: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-label.txt b/test/parse/expr/bad-label.txt
new file mode 100644
index 00000000..ff7d1934
--- /dev/null
+++ b/test/parse/expr/bad-label.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (label)))
+(;; STDERR ;;;
+parse/expr/bad-label.txt:2:21: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-align-misspelled.txt b/test/parse/expr/bad-load-align-misspelled.txt
new file mode 100644
index 00000000..239300f4
--- /dev/null
+++ b/test/parse/expr/bad-load-align-misspelled.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func
+ (i32.load aline=64 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-align-misspelled.txt:4:15: unexpected token "aline=64"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-align-negative.txt b/test/parse/expr/bad-load-align-negative.txt
new file mode 100644
index 00000000..15e93ba9
--- /dev/null
+++ b/test/parse/expr/bad-load-align-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.load8_s align=-1 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-align-negative.txt:2:28: unexpected token "align=-1"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-align-not-pot.txt b/test/parse/expr/bad-load-align-not-pot.txt
new file mode 100644
index 00000000..71b318f7
--- /dev/null
+++ b/test/parse/expr/bad-load-align-not-pot.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.load align=3 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-align-not-pot.txt:2:25: alignment must be power-of-two
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-align.txt b/test/parse/expr/bad-load-align.txt
new file mode 100644
index 00000000..7002a232
--- /dev/null
+++ b/test/parse/expr/bad-load-align.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.load align=foo (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-align.txt:2:25: unexpected token "align=foo"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-float-sign.txt b/test/parse/expr/bad-load-float-sign.txt
new file mode 100644
index 00000000..2eade442
--- /dev/null
+++ b/test/parse/expr/bad-load-float-sign.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (f32.loads (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-float-sign.txt:2:16: unexpected token "f32.loads"
+parse/expr/bad-load-float-sign.txt:2:26: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-offset-negative.txt b/test/parse/expr/bad-load-offset-negative.txt
new file mode 100644
index 00000000..be5d678d
--- /dev/null
+++ b/test/parse/expr/bad-load-offset-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.load8_s offset=-1 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-offset-negative.txt:2:28: unexpected token "offset=-1"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-load-type.txt b/test/parse/expr/bad-load-type.txt
new file mode 100644
index 00000000..2a0d269b
--- /dev/null
+++ b/test/parse/expr/bad-load-type.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (load.x32 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-load-type.txt:2:16: unexpected token "load.x32"
+parse/expr/bad-load-type.txt:2:25: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-loadglobal-empty.txt b/test/parse/expr/bad-loadglobal-empty.txt
new file mode 100644
index 00000000..bc911760
--- /dev/null
+++ b/test/parse/expr/bad-loadglobal-empty.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (global $n i32)
+ (func (load_global)))
+(;; STDERR ;;;
+parse/expr/bad-loadglobal-empty.txt:3:21: syntax error, unexpected ), expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-loadglobal-name-undefined.txt b/test/parse/expr/bad-loadglobal-name-undefined.txt
new file mode 100644
index 00000000..428a3cc4
--- /dev/null
+++ b/test/parse/expr/bad-loadglobal-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (load_global $n)))
+(;; STDERR ;;;
+parse/expr/bad-loadglobal-name-undefined.txt:2:28: undefined global variable "$n"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-loadglobal-name.txt b/test/parse/expr/bad-loadglobal-name.txt
new file mode 100644
index 00000000..c2bf688c
--- /dev/null
+++ b/test/parse/expr/bad-loadglobal-name.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module (global $n f32)
+ (func (load_global n)))
+(;; STDERR ;;;
+parse/expr/bad-loadglobal-name.txt:3:22: unexpected token "n"
+parse/expr/bad-loadglobal-name.txt:3:23: syntax error, unexpected ), expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-loadglobal-too-many.txt b/test/parse/expr/bad-loadglobal-too-many.txt
new file mode 100644
index 00000000..75203ec6
--- /dev/null
+++ b/test/parse/expr/bad-loadglobal-too-many.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (global i32)
+ (func (load_global 0 (nop))))
+(;; STDERR ;;;
+parse/expr/bad-loadglobal-too-many.txt:3:24: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-loadglobal-undefined.txt b/test/parse/expr/bad-loadglobal-undefined.txt
new file mode 100644
index 00000000..3631bce8
--- /dev/null
+++ b/test/parse/expr/bad-loadglobal-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (load_global 0)))
+(;; STDERR ;;;
+parse/expr/bad-loadglobal-undefined.txt:2:28: global variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-nop.txt b/test/parse/expr/bad-nop.txt
new file mode 100644
index 00000000..4a1bde67
--- /dev/null
+++ b/test/parse/expr/bad-nop.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (nop foo)))
+(;; STDERR ;;;
+parse/expr/bad-nop.txt:2:20: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-return-multi.txt b/test/parse/expr/bad-return-multi.txt
new file mode 100644
index 00000000..eae7808d
--- /dev/null
+++ b/test/parse/expr/bad-return-multi.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (result f32 f32)
+ (return (f32.const 0) (f32.const 3.14))))
+(;; STDERR ;;;
+parse/expr/bad-return-multi.txt:2:27: syntax error, unexpected VALUE_TYPE, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-return-too-few.txt b/test/parse/expr/bad-return-too-few.txt
new file mode 100644
index 00000000..2505ba8c
--- /dev/null
+++ b/test/parse/expr/bad-return-too-few.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func (result i32)
+ (return)))
+(;; STDERR ;;;
+parse/expr/bad-return-too-few.txt:4:5: type mismatch of function result. got void, expected i32
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-return-too-many.txt b/test/parse/expr/bad-return-too-many.txt
new file mode 100644
index 00000000..db9e7a0e
--- /dev/null
+++ b/test/parse/expr/bad-return-too-many.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func (result i32 i32)
+ (return (i32.const 0) (i32.const 0) (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-return-too-many.txt:3:21: syntax error, unexpected VALUE_TYPE, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-setlocal-name-undefined.txt b/test/parse/expr/bad-setlocal-name-undefined.txt
new file mode 100644
index 00000000..1a602730
--- /dev/null
+++ b/test/parse/expr/bad-setlocal-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (set_local $n (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-setlocal-name-undefined.txt:2:26: undefined local variable "$n"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-setlocal-name.txt b/test/parse/expr/bad-setlocal-name.txt
new file mode 100644
index 00000000..a9f76297
--- /dev/null
+++ b/test/parse/expr/bad-setlocal-name.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module (func
+ (local $n i32)
+ (set_local n (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-setlocal-name.txt:4:14: unexpected token "n"
+parse/expr/bad-setlocal-name.txt:4:16: syntax error, unexpected (, expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-setlocal-no-value.txt b/test/parse/expr/bad-setlocal-no-value.txt
new file mode 100644
index 00000000..233dfacf
--- /dev/null
+++ b/test/parse/expr/bad-setlocal-no-value.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module (func
+ (local i32)
+ (set_local 0)))
+(;; STDERR ;;;
+parse/expr/bad-setlocal-no-value.txt:4:15: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-setlocal-too-many.txt b/test/parse/expr/bad-setlocal-too-many.txt
new file mode 100644
index 00000000..8cf3278b
--- /dev/null
+++ b/test/parse/expr/bad-setlocal-too-many.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module (func
+ (local i32 i32)
+ (set_local 0 (i32.const 0) (nop))))
+(;; STDERR ;;;
+parse/expr/bad-setlocal-too-many.txt:4:30: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-setlocal-undefined.txt b/test/parse/expr/bad-setlocal-undefined.txt
new file mode 100644
index 00000000..979e701f
--- /dev/null
+++ b/test/parse/expr/bad-setlocal-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (set_local 0 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-setlocal-undefined.txt:2:26: local variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-store-align-not-pot.txt b/test/parse/expr/bad-store-align-not-pot.txt
new file mode 100644
index 00000000..38c102ac
--- /dev/null
+++ b/test/parse/expr/bad-store-align-not-pot.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (f32.store align=3 (i32.const 0) (f32.const 0.0))))
+(;; STDERR ;;;
+parse/expr/bad-store-align-not-pot.txt:2:26: alignment must be power-of-two
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-store-align.txt b/test/parse/expr/bad-store-align.txt
new file mode 100644
index 00000000..1e9043f9
--- /dev/null
+++ b/test/parse/expr/bad-store-align.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.store align=foo (i32.const 0) (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-store-align.txt:2:26: unexpected token "align=foo"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-store-float.sign.txt b/test/parse/expr/bad-store-float.sign.txt
new file mode 100644
index 00000000..5eac056f
--- /dev/null
+++ b/test/parse/expr/bad-store-float.sign.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (f32.storeu (i32.const 0) (f32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-store-float.sign.txt:2:16: unexpected token "f32.storeu"
+parse/expr/bad-store-float.sign.txt:2:27: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-store-offset-negative.txt b/test/parse/expr/bad-store-offset-negative.txt
new file mode 100644
index 00000000..63529e12
--- /dev/null
+++ b/test/parse/expr/bad-store-offset-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (i32.store8 offset=-1 (i32.const 0) (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-store-offset-negative.txt:2:27: unexpected token "offset=-1"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-store-type.txt b/test/parse/expr/bad-store-type.txt
new file mode 100644
index 00000000..fc212cbb
--- /dev/null
+++ b/test/parse/expr/bad-store-type.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (store.float32 (i32.const 0) (f32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-store-type.txt:2:16: unexpected token "store.float32"
+parse/expr/bad-store-type.txt:2:30: syntax error, unexpected (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-storeglobal-empty.txt b/test/parse/expr/bad-storeglobal-empty.txt
new file mode 100644
index 00000000..c010f789
--- /dev/null
+++ b/test/parse/expr/bad-storeglobal-empty.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (global i32)
+ (func (store_global 0)))
+(;; STDERR ;;;
+parse/expr/bad-storeglobal-empty.txt:3:24: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-storeglobal-name-undefined.txt b/test/parse/expr/bad-storeglobal-name-undefined.txt
new file mode 100644
index 00000000..771c7296
--- /dev/null
+++ b/test/parse/expr/bad-storeglobal-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (store_global $n (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-storeglobal-name-undefined.txt:2:29: undefined global variable "$n"
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-storeglobal-name.txt b/test/parse/expr/bad-storeglobal-name.txt
new file mode 100644
index 00000000..de6055da
--- /dev/null
+++ b/test/parse/expr/bad-storeglobal-name.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module (global $n i32)
+ (func (store_global n (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-storeglobal-name.txt:3:23: unexpected token "n"
+parse/expr/bad-storeglobal-name.txt:3:25: syntax error, unexpected (, expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-storeglobal-too-many.txt b/test/parse/expr/bad-storeglobal-too-many.txt
new file mode 100644
index 00000000..087171fe
--- /dev/null
+++ b/test/parse/expr/bad-storeglobal-too-many.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (global i32)
+ (func (store_global 0 (i32.const 0) (nop))))
+(;; STDERR ;;;
+parse/expr/bad-storeglobal-too-many.txt:3:39: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-storeglobal-undefined.txt b/test/parse/expr/bad-storeglobal-undefined.txt
new file mode 100644
index 00000000..65949fe1
--- /dev/null
+++ b/test/parse/expr/bad-storeglobal-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (store_global 0 (i32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-storeglobal-undefined.txt:2:29: global variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-tableswitch-invalid-case.txt b/test/parse/expr/bad-tableswitch-invalid-case.txt
new file mode 100644
index 00000000..15a2c5f1
--- /dev/null
+++ b/test/parse/expr/bad-tableswitch-invalid-case.txt
@@ -0,0 +1,10 @@
+;;; ERROR: 1
+(module
+ (func
+ (label
+ (tableswitch (i32.const 0)
+ (table (case 2)) (br 0)
+ (case (nop))))))
+(;; STDERR ;;;
+parse/expr/bad-tableswitch-invalid-case.txt:6:22: case variable out of range (max 1)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-tableswitch-invalid-default-case.txt b/test/parse/expr/bad-tableswitch-invalid-default-case.txt
new file mode 100644
index 00000000..b4aed7bd
--- /dev/null
+++ b/test/parse/expr/bad-tableswitch-invalid-default-case.txt
@@ -0,0 +1,9 @@
+;;; ERROR: 1
+(module
+ (func
+ (tableswitch (i32.const 0)
+ (table (case 0)) (case 3)
+ (case (nop)))))
+(;; STDERR ;;;
+parse/expr/bad-tableswitch-invalid-default-case.txt:5:30: case variable out of range (max 1)
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-unary-empty.txt b/test/parse/expr/bad-unary-empty.txt
new file mode 100644
index 00000000..6eccf037
--- /dev/null
+++ b/test/parse/expr/bad-unary-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (f32.neg)))
+(;; STDERR ;;;
+parse/expr/bad-unary-empty.txt:2:23: syntax error, unexpected ), expecting (
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-unary-too-many.txt b/test/parse/expr/bad-unary-too-many.txt
new file mode 100644
index 00000000..0cfce75e
--- /dev/null
+++ b/test/parse/expr/bad-unary-too-many.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (f32.neg (f32.const 0) (f32.const 0))))
+(;; STDERR ;;;
+parse/expr/bad-unary-too-many.txt:2:38: syntax error, unexpected (, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/expr/bad-unexpected.txt b/test/parse/expr/bad-unexpected.txt
new file mode 100644
index 00000000..c0c69791
--- /dev/null
+++ b/test/parse/expr/bad-unexpected.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (module)))
+(;; STDERR ;;;
+parse/expr/bad-unexpected.txt:2:16: syntax error, unexpected MODULE
+;;; STDERR ;;)
diff --git a/test/parse/expr/binary.txt b/test/parse/expr/binary.txt
new file mode 100644
index 00000000..f4d01090
--- /dev/null
+++ b/test/parse/expr/binary.txt
@@ -0,0 +1,42 @@
+(module
+ (func
+ (i32.add (i32.const 0) (i32.const 0))
+ (i64.add (i64.const 0) (i64.const 0))
+ (f32.add (f32.const 0) (f32.const 0))
+ (f64.add (f64.const 0) (f64.const 0))
+ (i32.sub (i32.const 0) (i32.const 0))
+ (i64.sub (i64.const 0) (i64.const 0))
+ (f32.sub (f32.const 0) (f32.const 0))
+ (f64.sub (f64.const 0) (f64.const 0))
+ (i32.mul (i32.const 0) (i32.const 0))
+ (i64.mul (i64.const 0) (i64.const 0))
+ (f32.mul (f32.const 0) (f32.const 0))
+ (f64.mul (f64.const 0) (f64.const 0))
+ (i32.div_s (i32.const 0) (i32.const 0))
+ (i64.div_s (i64.const 0) (i64.const 0))
+ (i32.div_u (i32.const 0) (i32.const 0))
+ (i64.div_u (i64.const 0) (i64.const 0))
+ (f32.div (f32.const 0) (f32.const 0))
+ (f64.div (f64.const 0) (f64.const 0))
+ (i32.rem_s (i32.const 0) (i32.const 0))
+ (i64.rem_s (i64.const 0) (i64.const 0))
+ (i32.rem_u (i32.const 0) (i32.const 0))
+ (i64.rem_u (i64.const 0) (i64.const 0))
+ (f32.min (f32.const 0) (f32.const 0))
+ (f64.min (f64.const 0) (f64.const 0))
+ (f32.max (f32.const 0) (f32.const 0))
+ (f64.max (f64.const 0) (f64.const 0))
+ (i32.and (i32.const 0) (i32.const 0))
+ (i64.and (i64.const 0) (i64.const 0))
+ (i32.or (i32.const 0) (i32.const 0))
+ (i64.or (i64.const 0) (i64.const 0))
+ (i32.xor (i32.const 0) (i32.const 0))
+ (i64.xor (i64.const 0) (i64.const 0))
+ (i32.shl (i32.const 0) (i32.const 0))
+ (i64.shl (i64.const 0) (i64.const 0))
+ (i32.shr_u (i32.const 0) (i32.const 0))
+ (i64.shr_u (i64.const 0) (i64.const 0))
+ (i32.shr_s (i32.const 0) (i32.const 0))
+ (i64.shr_s (i64.const 0) (i64.const 0))
+ (f32.copysign (f32.const 0) (f32.const 0))
+ (f64.copysign (f64.const 0) (f64.const 0))))
diff --git a/test/parse/expr/block-named.txt b/test/parse/expr/block-named.txt
new file mode 100644
index 00000000..24eefe1a
--- /dev/null
+++ b/test/parse/expr/block-named.txt
@@ -0,0 +1,5 @@
+(module
+ (func
+ (block $foo
+ (nop)
+ (nop))))
diff --git a/test/parse/expr/block-return.txt b/test/parse/expr/block-return.txt
new file mode 100644
index 00000000..fd334522
--- /dev/null
+++ b/test/parse/expr/block-return.txt
@@ -0,0 +1,5 @@
+(module
+ (func (result i32)
+ (block
+ (nop)
+ (return (i32.const 1)))))
diff --git a/test/parse/expr/block.txt b/test/parse/expr/block.txt
new file mode 100644
index 00000000..adacdde2
--- /dev/null
+++ b/test/parse/expr/block.txt
@@ -0,0 +1 @@
+(module (func (block (nop) (block (nop) (nop)))))
diff --git a/test/parse/expr/br.txt b/test/parse/expr/br.txt
new file mode 100644
index 00000000..80ca81a9
--- /dev/null
+++ b/test/parse/expr/br.txt
@@ -0,0 +1,4 @@
+(module
+ (func
+ (label
+ (br 0))))
diff --git a/test/parse/expr/break-block.txt b/test/parse/expr/break-block.txt
new file mode 100644
index 00000000..40f9892b
--- /dev/null
+++ b/test/parse/expr/break-block.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (block $exit1
+ (break 0))
+ (block $exit2
+ (break $exit2))))
diff --git a/test/parse/expr/break-loop.txt b/test/parse/expr/break-loop.txt
new file mode 100644
index 00000000..9bc1fc49
--- /dev/null
+++ b/test/parse/expr/break-loop.txt
@@ -0,0 +1,7 @@
+(module
+ (func
+ (loop $exit
+ (break $exit))
+ (loop $outer $inner
+ (break $inner)
+ (break $outer))))
diff --git a/test/parse/expr/break-named.txt b/test/parse/expr/break-named.txt
new file mode 100644
index 00000000..829f0ac2
--- /dev/null
+++ b/test/parse/expr/break-named.txt
@@ -0,0 +1,3 @@
+(module (func
+ (label $foo
+ (break $foo))))
diff --git a/test/parse/expr/break.txt b/test/parse/expr/break.txt
new file mode 100644
index 00000000..0b03258e
--- /dev/null
+++ b/test/parse/expr/break.txt
@@ -0,0 +1,3 @@
+(module (func
+ (label
+ (break 0))))
diff --git a/test/parse/expr/brif-named.txt b/test/parse/expr/brif-named.txt
new file mode 100644
index 00000000..03f75691
--- /dev/null
+++ b/test/parse/expr/brif-named.txt
@@ -0,0 +1,4 @@
+(module
+ (func
+ (block $foo
+ (br_if $foo (i32.const 1)))))
diff --git a/test/parse/expr/brif.txt b/test/parse/expr/brif.txt
new file mode 100644
index 00000000..1537232b
--- /dev/null
+++ b/test/parse/expr/brif.txt
@@ -0,0 +1,4 @@
+(module
+ (func
+ (label $foo
+ (br_if 0 (i32.const 1)))))
diff --git a/test/parse/expr/call-defined-later.txt b/test/parse/expr/call-defined-later.txt
new file mode 100644
index 00000000..7d2286d7
--- /dev/null
+++ b/test/parse/expr/call-defined-later.txt
@@ -0,0 +1,5 @@
+(module
+ (func $foo
+ (call $bar (i32.const 0) (i32.const 1)))
+ (func $bar (param i32 i32) (result i32)
+ (i32.const 0)))
diff --git a/test/parse/expr/call-empty.txt b/test/parse/expr/call-empty.txt
new file mode 100644
index 00000000..1f35ac84
--- /dev/null
+++ b/test/parse/expr/call-empty.txt
@@ -0,0 +1 @@
+(module (func (call 0)))
diff --git a/test/parse/expr/call-name-prefix.txt b/test/parse/expr/call-name-prefix.txt
new file mode 100644
index 00000000..c87a3fcb
--- /dev/null
+++ b/test/parse/expr/call-name-prefix.txt
@@ -0,0 +1,5 @@
+(module
+ (func $foomore
+ (call $foo (i32.const 0)))
+ (func $foo (param i32)
+ (nop)))
diff --git a/test/parse/expr/call-named.txt b/test/parse/expr/call-named.txt
new file mode 100644
index 00000000..b95c276d
--- /dev/null
+++ b/test/parse/expr/call-named.txt
@@ -0,0 +1,3 @@
+(module
+ (func $foo (param f32)
+ (call $foo (f32.const 0.0))))
diff --git a/test/parse/expr/call.txt b/test/parse/expr/call.txt
new file mode 100644
index 00000000..3eea0a25
--- /dev/null
+++ b/test/parse/expr/call.txt
@@ -0,0 +1,2 @@
+(module (func (param i32)
+ (call 0 (i32.const 1))))
diff --git a/test/parse/expr/callimport-defined-later.txt b/test/parse/expr/callimport-defined-later.txt
new file mode 100644
index 00000000..956a0070
--- /dev/null
+++ b/test/parse/expr/callimport-defined-later.txt
@@ -0,0 +1,4 @@
+(module
+ (func
+ (call_import 0 (f32.const 0)))
+ (import "foo" "bar" (param f32)))
diff --git a/test/parse/expr/callimport-named.txt b/test/parse/expr/callimport-named.txt
new file mode 100644
index 00000000..0cd1f02d
--- /dev/null
+++ b/test/parse/expr/callimport-named.txt
@@ -0,0 +1,4 @@
+(module
+ (import $bar "foo" "bar" (param f32))
+ (func
+ (call_import $bar (f32.const 0))))
diff --git a/test/parse/expr/callimport-type.txt b/test/parse/expr/callimport-type.txt
new file mode 100644
index 00000000..a6fdd420
--- /dev/null
+++ b/test/parse/expr/callimport-type.txt
@@ -0,0 +1,5 @@
+(module
+ (type (func (param i32) (result i32)))
+ (import "foo" "bar" (type 0))
+ (func (param i32) (result i32)
+ (call_import 0 (i32.const 0))))
diff --git a/test/parse/expr/callimport.txt b/test/parse/expr/callimport.txt
new file mode 100644
index 00000000..854aac81
--- /dev/null
+++ b/test/parse/expr/callimport.txt
@@ -0,0 +1,4 @@
+(module
+ (import "foo" "bar" (param i32) (result i32))
+ (func (param i32) (result i32)
+ (call_import 0 (i32.const 0))))
diff --git a/test/parse/expr/callindirect-named.txt b/test/parse/expr/callindirect-named.txt
new file mode 100644
index 00000000..b2b62ccc
--- /dev/null
+++ b/test/parse/expr/callindirect-named.txt
@@ -0,0 +1,3 @@
+(module
+ (type $t (func (param i32)))
+ (func $g (call_indirect $t (i32.const 0) (i32.const 0))))
diff --git a/test/parse/expr/callindirect.txt b/test/parse/expr/callindirect.txt
new file mode 100644
index 00000000..04da1800
--- /dev/null
+++ b/test/parse/expr/callindirect.txt
@@ -0,0 +1,3 @@
+(module
+ (type (func (param i32)))
+ (func (call_indirect 0 (i32.const 0) (i32.const 0))))
diff --git a/test/parse/expr/cast.txt b/test/parse/expr/cast.txt
new file mode 100644
index 00000000..5a6a207a
--- /dev/null
+++ b/test/parse/expr/cast.txt
@@ -0,0 +1,7 @@
+;; int->float reinterpret unsupported currently
+(module
+ (func
+ (f32.reinterpret/i32 (i32.const 0))
+ (i32.reinterpret/f32 (f32.const 0))
+ (f64.reinterpret/i64 (i64.const 0))
+ (i64.reinterpret/f64 (f64.const 0))))
diff --git a/test/parse/expr/compare.txt b/test/parse/expr/compare.txt
new file mode 100644
index 00000000..9df5bae3
--- /dev/null
+++ b/test/parse/expr/compare.txt
@@ -0,0 +1,34 @@
+(module
+ (func
+ (i32.eq (i32.const 0) (i32.const 0))
+ (i64.eq (i64.const 0) (i64.const 0))
+ (f32.eq (f32.const 0) (f32.const 0))
+ (f64.eq (f64.const 0) (f64.const 0))
+ (i32.ne (i32.const 0) (i32.const 0))
+ (i64.ne (i64.const 0) (i64.const 0))
+ (f32.ne (f32.const 0) (f32.const 0))
+ (f64.ne (f64.const 0) (f64.const 0))
+ (i32.lt_s (i32.const 0) (i32.const 0))
+ (i64.lt_s (i64.const 0) (i64.const 0))
+ (i32.lt_u (i32.const 0) (i32.const 0))
+ (i64.lt_u (i64.const 0) (i64.const 0))
+ (f32.lt (f32.const 0) (f32.const 0))
+ (f64.lt (f64.const 0) (f64.const 0))
+ (i32.le_s (i32.const 0) (i32.const 0))
+ (i64.le_s (i64.const 0) (i64.const 0))
+ (i32.le_u (i32.const 0) (i32.const 0))
+ (i64.le_u (i64.const 0) (i64.const 0))
+ (f32.le (f32.const 0) (f32.const 0))
+ (f64.le (f64.const 0) (f64.const 0))
+ (i32.gt_s (i32.const 0) (i32.const 0))
+ (i64.gt_s (i64.const 0) (i64.const 0))
+ (i32.gt_u (i32.const 0) (i32.const 0))
+ (i64.gt_u (i64.const 0) (i64.const 0))
+ (f32.gt (f32.const 0) (f32.const 0))
+ (f64.gt (f64.const 0) (f64.const 0))
+ (i32.ge_s (i32.const 0) (i32.const 0))
+ (i64.ge_s (i64.const 0) (i64.const 0))
+ (i32.ge_u (i32.const 0) (i32.const 0))
+ (i64.ge_u (i64.const 0) (i64.const 0))
+ (f32.ge (f32.const 0) (f32.const 0))
+ (f64.ge (f64.const 0) (f64.const 0))))
diff --git a/test/parse/expr/const.txt b/test/parse/expr/const.txt
new file mode 100644
index 00000000..16f8bc63
--- /dev/null
+++ b/test/parse/expr/const.txt
@@ -0,0 +1,43 @@
+(module
+ (func
+ (i32.const 0)
+ (i32.const -2147483648)
+ (i32.const 4294967295)
+ (i32.const -0x80000000)
+ (i32.const 0xffffffff)
+
+ (i64.const 0)
+ (i64.const -9223372036854775808)
+ (i64.const 18446744073709551615)
+ (i64.const -0x8000000000000000)
+ (i64.const 0xffffffffffffffff)
+
+ (f32.const 0.0)
+ (f32.const 1e23)
+ (f32.const 1.234567e-5)
+ (f32.const nan)
+ (f32.const -nan)
+ (f32.const +nan)
+ (f32.const nan:0xabc)
+ (f32.const -nan:0xabc)
+ (f32.const +nan:0xabc)
+ (f32.const infinity)
+ (f32.const -infinity)
+ (f32.const +infinity)
+ (f32.const -0x1p-1)
+ (f32.const 0x1.921fb6p+2)
+
+ (f64.const 0.0)
+ (f64.const -0.987654321)
+ (f64.const 6.283185307179586)
+ (f64.const nan)
+ (f64.const -nan)
+ (f64.const +nan)
+ (f64.const nan:0xabc)
+ (f64.const -nan:0xabc)
+ (f64.const +nan:0xabc)
+ (f64.const infinity)
+ (f64.const -infinity)
+ (f64.const +infinity)
+ (f64.const -0x1p-1)
+ (f64.const 0x1.921fb54442d18p+2)))
diff --git a/test/parse/expr/convert.txt b/test/parse/expr/convert.txt
new file mode 100644
index 00000000..e529ee7c
--- /dev/null
+++ b/test/parse/expr/convert.txt
@@ -0,0 +1,23 @@
+(module
+ (func
+ (i32.wrap/i64 (i64.const 0))
+ (i64.extend_u/i32 (i32.const 0))
+ (i64.extend_s/i32 (i32.const 0))
+ (i32.trunc_s/f32 (f32.const 0))
+ (i32.trunc_u/f32 (f32.const 0))
+ (i32.trunc_s/f64 (f64.const 0))
+ (i32.trunc_u/f64 (f64.const 0))
+ (i64.trunc_s/f32 (f32.const 0))
+ (i64.trunc_u/f32 (f32.const 0))
+ (i64.trunc_s/f64 (f64.const 0))
+ (i64.trunc_u/f64 (f64.const 0))
+ (f32.convert_s/i32 (i32.const 0))
+ (f32.convert_u/i32 (i32.const 0))
+ (f32.convert_s/i64 (i64.const 0))
+ (f32.convert_u/i64 (i64.const 0))
+ (f64.convert_s/i32 (i32.const 0))
+ (f64.convert_u/i32 (i32.const 0))
+ (f64.convert_s/i64 (i64.const 0))
+ (f64.convert_u/i64 (i64.const 0))
+ (f32.demote/f64 (f64.const 0))
+ (f64.promote/f32 (f32.const 0))))
diff --git a/test/parse/expr/expr-break.txt b/test/parse/expr/expr-break.txt
new file mode 100644
index 00000000..fdd18ef0
--- /dev/null
+++ b/test/parse/expr/expr-break.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (label
+ (break (i32.const 0)))
+ (label
+ (break 0 (i32.const 0)))))
diff --git a/test/parse/expr/getlocal-index-after-param.txt b/test/parse/expr/getlocal-index-after-param.txt
new file mode 100644
index 00000000..858ab979
--- /dev/null
+++ b/test/parse/expr/getlocal-index-after-param.txt
@@ -0,0 +1 @@
+(module (func (param i32) (local i32) (get_local 1)))
diff --git a/test/parse/expr/getlocal-index-mixed-named-unnamed.txt b/test/parse/expr/getlocal-index-mixed-named-unnamed.txt
new file mode 100644
index 00000000..da6fd4b4
--- /dev/null
+++ b/test/parse/expr/getlocal-index-mixed-named-unnamed.txt
@@ -0,0 +1,11 @@
+(module
+ (func (param i32) (param $n f32)
+ (local i32 i64)
+ (local $m f64)
+ (get_local 0)
+ (get_local 1)
+ (get_local $n) ;; 1
+ (get_local 2)
+ (get_local 3)
+ (get_local $m) ;; 4
+ (get_local 4)))
diff --git a/test/parse/expr/getlocal-named.txt b/test/parse/expr/getlocal-named.txt
new file mode 100644
index 00000000..f6e7a2a5
--- /dev/null
+++ b/test/parse/expr/getlocal-named.txt
@@ -0,0 +1 @@
+(module (func (local $foo i32) (get_local $foo)))
diff --git a/test/parse/expr/getlocal-param-named.txt b/test/parse/expr/getlocal-param-named.txt
new file mode 100644
index 00000000..4cca059e
--- /dev/null
+++ b/test/parse/expr/getlocal-param-named.txt
@@ -0,0 +1 @@
+(module (func (param $n i32) (get_local $n)))
diff --git a/test/parse/expr/getlocal-param.txt b/test/parse/expr/getlocal-param.txt
new file mode 100644
index 00000000..9bcd0f68
--- /dev/null
+++ b/test/parse/expr/getlocal-param.txt
@@ -0,0 +1 @@
+(module (func (param i32) (get_local 0)))
diff --git a/test/parse/expr/getlocal.txt b/test/parse/expr/getlocal.txt
new file mode 100644
index 00000000..5d6f03d8
--- /dev/null
+++ b/test/parse/expr/getlocal.txt
@@ -0,0 +1 @@
+(module (func (local i32) (get_local 0)))
diff --git a/test/parse/expr/if-return.txt b/test/parse/expr/if-return.txt
new file mode 100644
index 00000000..a78eda2b
--- /dev/null
+++ b/test/parse/expr/if-return.txt
@@ -0,0 +1,5 @@
+(module
+ (func (result i32)
+ (if_else (i32.const 1)
+ (return (i32.const 2))
+ (return (i32.const 3)))))
diff --git a/test/parse/expr/if-then-else.txt b/test/parse/expr/if-then-else.txt
new file mode 100644
index 00000000..66e6e36b
--- /dev/null
+++ b/test/parse/expr/if-then-else.txt
@@ -0,0 +1 @@
+(module (func (if_else (i32.const 0) (nop) (nop))))
diff --git a/test/parse/expr/if.txt b/test/parse/expr/if.txt
new file mode 100644
index 00000000..6adf02bb
--- /dev/null
+++ b/test/parse/expr/if.txt
@@ -0,0 +1 @@
+(module (func (if (i32.const 1) (nop))))
diff --git a/test/parse/expr/label-name.txt b/test/parse/expr/label-name.txt
new file mode 100644
index 00000000..333e5f53
--- /dev/null
+++ b/test/parse/expr/label-name.txt
@@ -0,0 +1 @@
+(module (func (label $foo (nop))))
diff --git a/test/parse/expr/label.txt b/test/parse/expr/label.txt
new file mode 100644
index 00000000..283bb2fe
--- /dev/null
+++ b/test/parse/expr/label.txt
@@ -0,0 +1,2 @@
+(module (func
+ (label (nop))))
diff --git a/test/parse/expr/load-aligned.txt b/test/parse/expr/load-aligned.txt
new file mode 100644
index 00000000..f8a2a943
--- /dev/null
+++ b/test/parse/expr/load-aligned.txt
@@ -0,0 +1,16 @@
+(module
+ (func
+ (i32.load align=4 (i32.const 0))
+ (i64.load align=4 (i32.const 0))
+ (i64.load8_s align=8 (i32.const 0))
+ (i64.load16_s align=1 (i32.const 0))
+ (i64.load32_s align=2 (i32.const 0))
+ (i64.load8_u align=4 (i32.const 0))
+ (i64.load16_u align=8 (i32.const 0))
+ (i64.load32_u align=1 (i32.const 0))
+ (i32.load8_s align=8 (i32.const 0))
+ (i32.load16_s align=1 (i32.const 0))
+ (i32.load8_u align=4 (i32.const 0))
+ (i32.load16_u align=8 (i32.const 0))
+ (f32.load align=2 (i32.const 0))
+ (f64.load align=8 (i32.const 0))))
diff --git a/test/parse/expr/load-offset.txt b/test/parse/expr/load-offset.txt
new file mode 100644
index 00000000..cf294750
--- /dev/null
+++ b/test/parse/expr/load-offset.txt
@@ -0,0 +1,31 @@
+(module
+ (func
+ (i32.load offset=0 (i32.const 0))
+ (i64.load offset=1 (i32.const 0))
+ (i64.load8_s offset=2 (i32.const 0))
+ (i64.load16_s offset=3 (i32.const 0))
+ (i64.load32_s offset=4 (i32.const 0))
+ (i64.load8_u offset=5 (i32.const 0))
+ (i64.load16_u offset=6 (i32.const 0))
+ (i64.load32_u offset=7 (i32.const 0))
+ (i32.load8_s offset=8 (i32.const 0))
+ (i32.load16_s offset=9 (i32.const 0))
+ (i32.load8_u offset=10 (i32.const 0))
+ (i32.load16_u offset=11 (i32.const 0))
+ (f32.load offset=12 (i32.const 0))
+ (f64.load offset=13 (i32.const 0))
+
+ (i32.load offset=0 align=1 (i32.const 0))
+ (i64.load offset=1 align=2 (i32.const 0))
+ (i64.load8_s offset=2 align=4 (i32.const 0))
+ (i64.load16_s offset=3 align=8 (i32.const 0))
+ (i64.load32_s offset=4 align=16 (i32.const 0))
+ (i64.load8_u offset=5 align=32 (i32.const 0))
+ (i64.load16_u offset=6 align=64 (i32.const 0))
+ (i64.load32_u offset=7 align=128 (i32.const 0))
+ (i32.load8_s offset=8 align=64 (i32.const 0))
+ (i32.load16_s offset=9 align=32 (i32.const 0))
+ (i32.load8_u offset=10 align=16 (i32.const 0))
+ (i32.load16_u offset=11 align=8 (i32.const 0))
+ (f32.load offset=12 align=4 (i32.const 0))
+ (f64.load offset=13 align=2 (i32.const 0))))
diff --git a/test/parse/expr/load.txt b/test/parse/expr/load.txt
new file mode 100644
index 00000000..fc7b3634
--- /dev/null
+++ b/test/parse/expr/load.txt
@@ -0,0 +1,16 @@
+(module
+ (func
+ (i32.load (i32.const 0))
+ (i32.load8_s (i32.const 0))
+ (i32.load16_s (i32.const 0))
+ (i32.load8_u (i32.const 0))
+ (i32.load16_u (i32.const 0))
+ (i64.load (i32.const 0))
+ (i64.load8_s (i32.const 0))
+ (i64.load16_s (i32.const 0))
+ (i64.load32_s (i32.const 0))
+ (i64.load8_u (i32.const 0))
+ (i64.load16_u (i32.const 0))
+ (i64.load32_u (i32.const 0))
+ (f32.load (i32.const 0))
+ (f64.load (i32.const 0))))
diff --git a/test/parse/expr/loadglobal-name.txt b/test/parse/expr/loadglobal-name.txt
new file mode 100644
index 00000000..f777fa79
--- /dev/null
+++ b/test/parse/expr/loadglobal-name.txt
@@ -0,0 +1,2 @@
+(module (global $n i32)
+ (func (load_global $n)))
diff --git a/test/parse/expr/loadglobal.txt b/test/parse/expr/loadglobal.txt
new file mode 100644
index 00000000..dec71a49
--- /dev/null
+++ b/test/parse/expr/loadglobal.txt
@@ -0,0 +1,2 @@
+(module (global i32)
+ (func (load_global 0)))
diff --git a/test/parse/expr/loop-empty.txt b/test/parse/expr/loop-empty.txt
new file mode 100644
index 00000000..95b68fed
--- /dev/null
+++ b/test/parse/expr/loop-empty.txt
@@ -0,0 +1 @@
+(module (func (loop)))
diff --git a/test/parse/expr/loop-named.txt b/test/parse/expr/loop-named.txt
new file mode 100644
index 00000000..e5b6f539
--- /dev/null
+++ b/test/parse/expr/loop-named.txt
@@ -0,0 +1,5 @@
+(module
+ (func
+ (loop (nop))
+ (loop $inner (nop))
+ (loop $inner $outer (nop))))
diff --git a/test/parse/expr/loop.txt b/test/parse/expr/loop.txt
new file mode 100644
index 00000000..45950ee3
--- /dev/null
+++ b/test/parse/expr/loop.txt
@@ -0,0 +1,3 @@
+(module
+ (func
+ (loop (nop) (nop))))
diff --git a/test/parse/expr/memory-size.txt b/test/parse/expr/memory-size.txt
new file mode 100644
index 00000000..d180cc96
--- /dev/null
+++ b/test/parse/expr/memory-size.txt
@@ -0,0 +1,3 @@
+(module
+ (func
+ (memory_size)))
diff --git a/test/parse/expr/nop.txt b/test/parse/expr/nop.txt
new file mode 100644
index 00000000..dbec68e4
--- /dev/null
+++ b/test/parse/expr/nop.txt
@@ -0,0 +1 @@
+(module (func (nop)))
diff --git a/test/parse/expr/resize-memory.txt b/test/parse/expr/resize-memory.txt
new file mode 100644
index 00000000..86795fee
--- /dev/null
+++ b/test/parse/expr/resize-memory.txt
@@ -0,0 +1,3 @@
+(module
+ (func
+ (grow_memory (i32.const 100))))
diff --git a/test/parse/expr/return-block.txt b/test/parse/expr/return-block.txt
new file mode 100644
index 00000000..14b5e864
--- /dev/null
+++ b/test/parse/expr/return-block.txt
@@ -0,0 +1,6 @@
+(module
+ (func (result i32)
+ (return
+ (block
+ (nop)
+ (i32.const 1)))))
diff --git a/test/parse/expr/return-empty.txt b/test/parse/expr/return-empty.txt
new file mode 100644
index 00000000..e8dea706
--- /dev/null
+++ b/test/parse/expr/return-empty.txt
@@ -0,0 +1,2 @@
+(module
+ (func (return)))
diff --git a/test/parse/expr/return-if.txt b/test/parse/expr/return-if.txt
new file mode 100644
index 00000000..3ce9cdcc
--- /dev/null
+++ b/test/parse/expr/return-if.txt
@@ -0,0 +1,6 @@
+(module
+ (func (result i32)
+ (return
+ (if_else (i32.const 1)
+ (i32.const 2)
+ (i32.const 3)))))
diff --git a/test/parse/expr/return-void.txt b/test/parse/expr/return-void.txt
new file mode 100644
index 00000000..76196f69
--- /dev/null
+++ b/test/parse/expr/return-void.txt
@@ -0,0 +1 @@
+(module (func (return)))
diff --git a/test/parse/expr/return.txt b/test/parse/expr/return.txt
new file mode 100644
index 00000000..8a49c2dd
--- /dev/null
+++ b/test/parse/expr/return.txt
@@ -0,0 +1,3 @@
+(module
+ (func (result i32)
+ (return (i32.const 42))))
diff --git a/test/parse/expr/select.txt b/test/parse/expr/select.txt
new file mode 100644
index 00000000..dc2b41f0
--- /dev/null
+++ b/test/parse/expr/select.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (i32.select (i32.const 1) (i32.const 2) (i32.const 3))
+ (i64.select (i32.const 1) (i64.const 2) (i64.const 3))
+ (f32.select (i32.const 1) (f32.const 2) (f32.const 3))
+ (f64.select (i32.const 1) (f64.const 2) (f64.const 3))))
diff --git a/test/parse/expr/setlocal-index-after-param.txt b/test/parse/expr/setlocal-index-after-param.txt
new file mode 100644
index 00000000..b21241de
--- /dev/null
+++ b/test/parse/expr/setlocal-index-after-param.txt
@@ -0,0 +1 @@
+(module (func (param i32) (local i32) (set_local 1 (i32.const 0))))
diff --git a/test/parse/expr/setlocal-index-mixed-named-unnamed.txt b/test/parse/expr/setlocal-index-mixed-named-unnamed.txt
new file mode 100644
index 00000000..398db637
--- /dev/null
+++ b/test/parse/expr/setlocal-index-mixed-named-unnamed.txt
@@ -0,0 +1,11 @@
+(module
+ (func (param i32) (param $n f32)
+ (local i32 i64)
+ (local $m f64)
+ (set_local 0 (i32.const 0))
+ (set_local 1 (f32.const 0))
+ (set_local $n (f32.const 0)) ;; 1
+ (set_local 2 (i32.const 0))
+ (set_local 3 (i64.const 0))
+ (set_local $m (f64.const 0)) ;; 4
+ (set_local 4 (f64.const 0))))
diff --git a/test/parse/expr/setlocal-named.txt b/test/parse/expr/setlocal-named.txt
new file mode 100644
index 00000000..304cebb4
--- /dev/null
+++ b/test/parse/expr/setlocal-named.txt
@@ -0,0 +1,3 @@
+(module (func
+ (local $n i32)
+ (set_local $n (i32.const 12))))
diff --git a/test/parse/expr/setlocal-param-named.txt b/test/parse/expr/setlocal-param-named.txt
new file mode 100644
index 00000000..4642accd
--- /dev/null
+++ b/test/parse/expr/setlocal-param-named.txt
@@ -0,0 +1 @@
+(module (func (param $n i32) (set_local $n (i32.const 0))))
diff --git a/test/parse/expr/setlocal-param.txt b/test/parse/expr/setlocal-param.txt
new file mode 100644
index 00000000..f80c2651
--- /dev/null
+++ b/test/parse/expr/setlocal-param.txt
@@ -0,0 +1 @@
+(module (func (param i32) (set_local 0 (i32.const 0))))
diff --git a/test/parse/expr/setlocal.txt b/test/parse/expr/setlocal.txt
new file mode 100644
index 00000000..01cbf799
--- /dev/null
+++ b/test/parse/expr/setlocal.txt
@@ -0,0 +1,2 @@
+(module (func (local i32)
+ (set_local 0 (i32.const 0))))
diff --git a/test/parse/expr/store-aligned.txt b/test/parse/expr/store-aligned.txt
new file mode 100644
index 00000000..07bfcd7c
--- /dev/null
+++ b/test/parse/expr/store-aligned.txt
@@ -0,0 +1,11 @@
+(module
+ (func
+ (i32.store8 align=1 (i32.const 0) (i32.const 0))
+ (i32.store16 align=2 (i32.const 0) (i32.const 0))
+ (i32.store align=4 (i32.const 0) (i32.const 0))
+ (i64.store align=8 (i32.const 0) (i64.const 0))
+ (i64.store8 align=1 (i32.const 0) (i64.const 0))
+ (i64.store16 align=2 (i32.const 0) (i64.const 0))
+ (i64.store32 align=4 (i32.const 0) (i64.const 0))
+ (f32.store align=4 (i32.const 0) (f32.const 0))
+ (f64.store align=8 (i32.const 0) (f64.const 0))))
diff --git a/test/parse/expr/store-offset.txt b/test/parse/expr/store-offset.txt
new file mode 100644
index 00000000..0c189c24
--- /dev/null
+++ b/test/parse/expr/store-offset.txt
@@ -0,0 +1,22 @@
+(module
+ (func
+ (i32.store8 offset=0 (i32.const 0) (i32.const 0))
+ (i32.store16 offset=1 (i32.const 0) (i32.const 0))
+ (i32.store offset=2 (i32.const 0) (i32.const 0))
+ (i64.store offset=3 (i32.const 0) (i64.const 0))
+ (i64.store8 offset=4 (i32.const 0) (i64.const 0))
+ (i64.store16 offset=5 (i32.const 0) (i64.const 0))
+ (i64.store32 offset=6 (i32.const 0) (i64.const 0))
+ (f32.store offset=7 (i32.const 0) (f32.const 0))
+ (f64.store offset=8 (i32.const 0) (f64.const 0))
+
+ ;; alignment must come after
+ (i32.store8 offset=0 align=1 (i32.const 0) (i32.const 0))
+ (i32.store16 offset=1 align=2 (i32.const 0) (i32.const 0))
+ (i32.store offset=2 align=4 (i32.const 0) (i32.const 0))
+ (i64.store offset=3 align=8 (i32.const 0) (i64.const 0))
+ (i64.store8 offset=4 align=16 (i32.const 0) (i64.const 0))
+ (i64.store16 offset=5 align=8 (i32.const 0) (i64.const 0))
+ (i64.store32 offset=6 align=4 (i32.const 0) (i64.const 0))
+ (f32.store offset=7 align=2 (i32.const 0) (f32.const 0))
+ (f64.store offset=8 align=1 (i32.const 0) (f64.const 0))))
diff --git a/test/parse/expr/store.txt b/test/parse/expr/store.txt
new file mode 100644
index 00000000..d6d9bf3c
--- /dev/null
+++ b/test/parse/expr/store.txt
@@ -0,0 +1,11 @@
+(module
+ (func
+ (i32.store8 (i32.const 0) (i32.const 0))
+ (i32.store16 (i32.const 0) (i32.const 0))
+ (i32.store (i32.const 0) (i32.const 0))
+ (i64.store (i32.const 0) (i64.const 0))
+ (i64.store8 (i32.const 0) (i64.const 0))
+ (i64.store16 (i32.const 0) (i64.const 0))
+ (i64.store32 (i32.const 0) (i64.const 0))
+ (f32.store (i32.const 0) (f32.const 0))
+ (f64.store (i32.const 0) (f64.const 0))))
diff --git a/test/parse/expr/storeglobal-name.txt b/test/parse/expr/storeglobal-name.txt
new file mode 100644
index 00000000..8c774588
--- /dev/null
+++ b/test/parse/expr/storeglobal-name.txt
@@ -0,0 +1,2 @@
+(module (global $n i32)
+ (func (store_global $n (i32.const 42))))
diff --git a/test/parse/expr/storeglobal.txt b/test/parse/expr/storeglobal.txt
new file mode 100644
index 00000000..a1526f66
--- /dev/null
+++ b/test/parse/expr/storeglobal.txt
@@ -0,0 +1,2 @@
+(module (global i32)
+ (func (store_global 0 (i32.const 12))))
diff --git a/test/parse/expr/tableswitch-default-br.txt b/test/parse/expr/tableswitch-default-br.txt
new file mode 100644
index 00000000..63425795
--- /dev/null
+++ b/test/parse/expr/tableswitch-default-br.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (label
+ (tableswitch (i32.const 0)
+ (table (case 0)) (br 0)
+ (case (nop))))))
diff --git a/test/parse/expr/tableswitch-empty-case.txt b/test/parse/expr/tableswitch-empty-case.txt
new file mode 100644
index 00000000..1e22e67b
--- /dev/null
+++ b/test/parse/expr/tableswitch-empty-case.txt
@@ -0,0 +1,7 @@
+(module
+ (func
+ (tableswitch (i32.const 0)
+ (table (case 0) (case 1)) (case 2)
+ (case)
+ (case)
+ (case (nop)))))
diff --git a/test/parse/expr/tableswitch-empty.txt b/test/parse/expr/tableswitch-empty.txt
new file mode 100644
index 00000000..f37ccc97
--- /dev/null
+++ b/test/parse/expr/tableswitch-empty.txt
@@ -0,0 +1,5 @@
+(module
+ (func
+ (label
+ (tableswitch (i32.const 0)
+ (table) (br 0)))))
diff --git a/test/parse/expr/tableswitch-multi.txt b/test/parse/expr/tableswitch-multi.txt
new file mode 100644
index 00000000..fec4481c
--- /dev/null
+++ b/test/parse/expr/tableswitch-multi.txt
@@ -0,0 +1,9 @@
+(module
+ (func
+ (tableswitch (i32.const 0)
+ (table (case 4) (case 3) (case 2) (case 1)) (case 0)
+ (case (nop))
+ (case (nop))
+ (case (nop))
+ (case (nop))
+ (case (nop)))))
diff --git a/test/parse/expr/tableswitch-named.txt b/test/parse/expr/tableswitch-named.txt
new file mode 100644
index 00000000..20d0a471
--- /dev/null
+++ b/test/parse/expr/tableswitch-named.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (tableswitch $exit (i32.const 0)
+ (table (case $0) (case $1)) (br $exit)
+ (case $0 (nop))
+ (case $1 (nop)))))
diff --git a/test/parse/expr/tableswitch-table-br.txt b/test/parse/expr/tableswitch-table-br.txt
new file mode 100644
index 00000000..b996aa7f
--- /dev/null
+++ b/test/parse/expr/tableswitch-table-br.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (label
+ (tableswitch (i32.const 0)
+ (table (br 0)) (case 0)
+ (case (nop))))))
diff --git a/test/parse/expr/tableswitch-unreferenced.txt b/test/parse/expr/tableswitch-unreferenced.txt
new file mode 100644
index 00000000..a60f3ed0
--- /dev/null
+++ b/test/parse/expr/tableswitch-unreferenced.txt
@@ -0,0 +1,7 @@
+(module
+ (func
+ (tableswitch (i32.const 0)
+ (table (case 0)) (case 1)
+ (case (nop))
+ (case (nop))
+ (case (nop)))))
diff --git a/test/parse/expr/tableswitch.txt b/test/parse/expr/tableswitch.txt
new file mode 100644
index 00000000..aa04a4c6
--- /dev/null
+++ b/test/parse/expr/tableswitch.txt
@@ -0,0 +1,6 @@
+(module
+ (func
+ (tableswitch (i32.const 0)
+ (table (case 0)) (case 1)
+ (case (nop))
+ (case (nop)))))
diff --git a/test/parse/expr/unary.txt b/test/parse/expr/unary.txt
new file mode 100644
index 00000000..64d5a610
--- /dev/null
+++ b/test/parse/expr/unary.txt
@@ -0,0 +1,23 @@
+(module
+ (func
+ (f32.neg (f32.const 0))
+ (f64.neg (f64.const 0))
+ (f32.abs (f32.const 0))
+ (f64.abs (f64.const 0))
+ (f32.sqrt (f32.const 0))
+ (f64.sqrt (f64.const 0))
+ (i32.not (i32.const 0))
+ (i32.clz (i32.const 0))
+ (i64.clz (i64.const 0))
+ (i32.ctz (i32.const 0))
+ (i64.ctz (i64.const 0))
+ (i32.popcnt (i32.const 0))
+ (i64.popcnt (i64.const 0))
+ (f32.ceil (f32.const 0))
+ (f64.ceil (f64.const 0))
+ (f32.floor (f32.const 0))
+ (f64.floor (f64.const 0))
+ (f32.trunc (f32.const 0))
+ (f64.trunc (f64.const 0))
+ (f32.nearest (f32.const 0))
+ (f64.nearest (f64.const 0))))
diff --git a/test/parse/expr/unreachable.txt b/test/parse/expr/unreachable.txt
new file mode 100644
index 00000000..e72ae48c
--- /dev/null
+++ b/test/parse/expr/unreachable.txt
@@ -0,0 +1 @@
+(module (func (unreachable)))
diff --git a/test/parse/func/bad-func-name.txt b/test/parse/func/bad-func-name.txt
new file mode 100644
index 00000000..94e66244
--- /dev/null
+++ b/test/parse/func/bad-func-name.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module
+ (func foo))
+(;; STDERR ;;;
+parse/func/bad-func-name.txt:3:9: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-local-binding-no-type.txt b/test/parse/func/bad-local-binding-no-type.txt
new file mode 100644
index 00000000..84e92047
--- /dev/null
+++ b/test/parse/func/bad-local-binding-no-type.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local $n)))
+(;; STDERR ;;;
+parse/func/bad-local-binding-no-type.txt:2:24: syntax error, unexpected ), expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-local-binding.txt b/test/parse/func/bad-local-binding.txt
new file mode 100644
index 00000000..d2617ef6
--- /dev/null
+++ b/test/parse/func/bad-local-binding.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local $foo $bar)))
+(;; STDERR ;;;
+parse/func/bad-local-binding.txt:2:27: syntax error, unexpected VAR, expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-local-name.txt b/test/parse/func/bad-local-name.txt
new file mode 100644
index 00000000..470e28f0
--- /dev/null
+++ b/test/parse/func/bad-local-name.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local 0 i32)))
+(;; STDERR ;;;
+parse/func/bad-local-name.txt:2:22: syntax error, unexpected INT, expecting ) or VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-local-type-list.txt b/test/parse/func/bad-local-type-list.txt
new file mode 100644
index 00000000..bb597741
--- /dev/null
+++ b/test/parse/func/bad-local-type-list.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local i32 i64 foo f32)))
+(;; STDERR ;;;
+parse/func/bad-local-type-list.txt:2:30: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-local-type.txt b/test/parse/func/bad-local-type.txt
new file mode 100644
index 00000000..4f901b78
--- /dev/null
+++ b/test/parse/func/bad-local-type.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local foo)))
+(;; STDERR ;;;
+parse/func/bad-local-type.txt:2:22: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param-after-local.txt b/test/parse/func/bad-param-after-local.txt
new file mode 100644
index 00000000..b7b71754
--- /dev/null
+++ b/test/parse/func/bad-param-after-local.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (local i32) (param i32)))
+(;; STDERR ;;;
+parse/func/bad-param-after-local.txt:2:28: syntax error, unexpected PARAM
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param-binding.txt b/test/parse/func/bad-param-binding.txt
new file mode 100644
index 00000000..aeeca691
--- /dev/null
+++ b/test/parse/func/bad-param-binding.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (param $bar $baz)))
+(;; STDERR ;;;
+parse/func/bad-param-binding.txt:2:27: syntax error, unexpected VAR, expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param-name.txt b/test/parse/func/bad-param-name.txt
new file mode 100644
index 00000000..ddd4e273
--- /dev/null
+++ b/test/parse/func/bad-param-name.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (param 0 i32)))
+(;; STDERR ;;;
+parse/func/bad-param-name.txt:2:22: syntax error, unexpected INT, expecting ) or VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param-redefinition.txt b/test/parse/func/bad-param-redefinition.txt
new file mode 100644
index 00000000..4a57f312
--- /dev/null
+++ b/test/parse/func/bad-param-redefinition.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (param $n i32) (param $n f32)))
+(;; STDERR ;;;
+parse/func/bad-param-redefinition.txt:2:31: redefinition of parameter "$n"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param-type-list.txt b/test/parse/func/bad-param-type-list.txt
new file mode 100644
index 00000000..f2c6d625
--- /dev/null
+++ b/test/parse/func/bad-param-type-list.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (param i32 i64 foo f32)))
+(;; STDERR ;;;
+parse/func/bad-param-type-list.txt:2:30: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-param.txt b/test/parse/func/bad-param.txt
new file mode 100644
index 00000000..2f6b6928
--- /dev/null
+++ b/test/parse/func/bad-param.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (param foo)))
+(;; STDERR ;;;
+parse/func/bad-param.txt:2:22: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-result-empty.txt b/test/parse/func/bad-result-empty.txt
new file mode 100644
index 00000000..793cda5b
--- /dev/null
+++ b/test/parse/func/bad-result-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (result)))
+(;; STDERR ;;;
+parse/func/bad-result-empty.txt:2:22: syntax error, unexpected ), expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-result-multi.txt b/test/parse/func/bad-result-multi.txt
new file mode 100644
index 00000000..f44a7914
--- /dev/null
+++ b/test/parse/func/bad-result-multi.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (result i32 i64)))
+(;; STDERR ;;;
+parse/func/bad-result-multi.txt:2:27: syntax error, unexpected VALUE_TYPE, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-result-type.txt b/test/parse/func/bad-result-type.txt
new file mode 100644
index 00000000..271e0509
--- /dev/null
+++ b/test/parse/func/bad-result-type.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (func (result foo)))
+(;; STDERR ;;;
+parse/func/bad-result-type.txt:2:23: unexpected token "foo"
+parse/func/bad-result-type.txt:2:26: syntax error, unexpected ), expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-param-type-mismatch.txt b/test/parse/func/bad-sig-param-type-mismatch.txt
new file mode 100644
index 00000000..80dc7b42
--- /dev/null
+++ b/test/parse/func/bad-sig-param-type-mismatch.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32 f32)))
+ (func (type $t) (param f32 f32)))
+(;; STDERR ;;;
+parse/func/bad-sig-param-type-mismatch.txt:4:4: type mismatch for argument 0 of function. got f32, expected i32
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-params-empty.txt b/test/parse/func/bad-sig-params-empty.txt
new file mode 100644
index 00000000..c15bcf74
--- /dev/null
+++ b/test/parse/func/bad-sig-params-empty.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func))
+ (func (type $t) (param i32)))
+(;; STDERR ;;;
+parse/func/bad-sig-params-empty.txt:4:4: expected 0 parameters, got 1
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-result-type-mistmatch.txt b/test/parse/func/bad-sig-result-type-mistmatch.txt
new file mode 100644
index 00000000..8f76d62e
--- /dev/null
+++ b/test/parse/func/bad-sig-result-type-mistmatch.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32) (result f32)))
+ (func (type $t) (param i32) (result i64)))
+(;; STDERR ;;;
+parse/func/bad-sig-result-type-mistmatch.txt:4:4: type mismatch. got i64, expected f32
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-result-type-not-void.txt b/test/parse/func/bad-sig-result-type-not-void.txt
new file mode 100644
index 00000000..505fb621
--- /dev/null
+++ b/test/parse/func/bad-sig-result-type-not-void.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32)))
+ (func (type $t) (param i32) (result f32)))
+(;; STDERR ;;;
+parse/func/bad-sig-result-type-not-void.txt:4:4: type mismatch. got f32, expected void
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-result-type-void.txt b/test/parse/func/bad-sig-result-type-void.txt
new file mode 100644
index 00000000..a99c0d8e
--- /dev/null
+++ b/test/parse/func/bad-sig-result-type-void.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32) (result f32)))
+ (func (type $t) (param i32)))
+(;; STDERR ;;;
+parse/func/bad-sig-result-type-void.txt:4:4: type mismatch. got void, expected f32
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-too-few-params.txt b/test/parse/func/bad-sig-too-few-params.txt
new file mode 100644
index 00000000..f588ab95
--- /dev/null
+++ b/test/parse/func/bad-sig-too-few-params.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32 f32)))
+ (func (type $t) (param i32)))
+(;; STDERR ;;;
+parse/func/bad-sig-too-few-params.txt:4:4: expected 2 parameters, got 1
+;;; STDERR ;;)
diff --git a/test/parse/func/bad-sig-too-many-params.txt b/test/parse/func/bad-sig-too-many-params.txt
new file mode 100644
index 00000000..027f91d7
--- /dev/null
+++ b/test/parse/func/bad-sig-too-many-params.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (type $t (func (param i32)))
+ (func (type $t) (param i32 i32)))
+(;; STDERR ;;;
+parse/func/bad-sig-too-many-params.txt:4:4: expected 1 parameters, got 2
+;;; STDERR ;;)
diff --git a/test/parse/func/func-named.txt b/test/parse/func/func-named.txt
new file mode 100644
index 00000000..f744db34
--- /dev/null
+++ b/test/parse/func/func-named.txt
@@ -0,0 +1 @@
+(module (func $foo))
diff --git a/test/parse/func/local-empty.txt b/test/parse/func/local-empty.txt
new file mode 100644
index 00000000..0c9c3d8f
--- /dev/null
+++ b/test/parse/func/local-empty.txt
@@ -0,0 +1 @@
+(module (func (local)))
diff --git a/test/parse/func/local-multi.txt b/test/parse/func/local-multi.txt
new file mode 100644
index 00000000..bb5813d2
--- /dev/null
+++ b/test/parse/func/local-multi.txt
@@ -0,0 +1 @@
+(module (func (local i32) (local $n i64)))
diff --git a/test/parse/func/local.txt b/test/parse/func/local.txt
new file mode 100644
index 00000000..c5b0149f
--- /dev/null
+++ b/test/parse/func/local.txt
@@ -0,0 +1 @@
+(module (func (local i32)))
diff --git a/test/parse/func/no-space.txt b/test/parse/func/no-space.txt
new file mode 100644
index 00000000..db3827e3
--- /dev/null
+++ b/test/parse/func/no-space.txt
@@ -0,0 +1,4 @@
+(module
+ (func $foomore(call $foo (i32.const 0x0)))
+ (func $foo (param i32)(nop))
+)
diff --git a/test/parse/func/param-binding.txt b/test/parse/func/param-binding.txt
new file mode 100644
index 00000000..0d79fef5
--- /dev/null
+++ b/test/parse/func/param-binding.txt
@@ -0,0 +1 @@
+(module (func (param $foo i32)))
diff --git a/test/parse/func/param-multi.txt b/test/parse/func/param-multi.txt
new file mode 100644
index 00000000..9ab0a662
--- /dev/null
+++ b/test/parse/func/param-multi.txt
@@ -0,0 +1 @@
+(module (func (param i32) (param $n f64)))
diff --git a/test/parse/func/param-type-1.txt b/test/parse/func/param-type-1.txt
new file mode 100644
index 00000000..a1aa01b5
--- /dev/null
+++ b/test/parse/func/param-type-1.txt
@@ -0,0 +1 @@
+(module (func (param i32)))
diff --git a/test/parse/func/param-type-2.txt b/test/parse/func/param-type-2.txt
new file mode 100644
index 00000000..19e0dc3a
--- /dev/null
+++ b/test/parse/func/param-type-2.txt
@@ -0,0 +1 @@
+(module (func (param i32 f32)))
diff --git a/test/parse/func/result.txt b/test/parse/func/result.txt
new file mode 100644
index 00000000..aa622c78
--- /dev/null
+++ b/test/parse/func/result.txt
@@ -0,0 +1 @@
+(module (func (result i32) (i32.const 0)))
diff --git a/test/parse/func/sig-match.txt b/test/parse/func/sig-match.txt
new file mode 100644
index 00000000..0042a9f5
--- /dev/null
+++ b/test/parse/func/sig-match.txt
@@ -0,0 +1,12 @@
+(module
+ (type $empty (func))
+ (type $i_v (func (param i32)))
+ (type $f_i (func (param f32) (result i32)))
+ (type $ii_i (func (param i32 i32) (result i32)))
+ (type $v_f (func (result f32)))
+
+ (func (type $empty))
+ (func (type $i_v) (param i32))
+ (func (type $f_i) (param f32) (result i32) (i32.const 0))
+ (func (type $ii_i) (param i32 i32) (result i32) (i32.const 0))
+ (func (type $v_f) (result f32) (f32.const 0)))
diff --git a/test/parse/func/sig.txt b/test/parse/func/sig.txt
new file mode 100644
index 00000000..649c66c5
--- /dev/null
+++ b/test/parse/func/sig.txt
@@ -0,0 +1,3 @@
+(module
+ (type $t (func (param i32) (result i32)))
+ (func (type $t) (i32.const 0)))
diff --git a/test/parse/line-comment.txt b/test/parse/line-comment.txt
new file mode 100644
index 00000000..d6d9f737
--- /dev/null
+++ b/test/parse/line-comment.txt
@@ -0,0 +1,3 @@
+;; here is a comment
+(module)
+;; here is another
diff --git a/test/parse/module/bad-export-empty.txt b/test/parse/module/bad-export-empty.txt
new file mode 100644
index 00000000..24df1083
--- /dev/null
+++ b/test/parse/module/bad-export-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (export))
+(;; STDERR ;;;
+parse/module/bad-export-empty.txt:2:16: syntax error, unexpected ), expecting TEXT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-export-name-undefined.txt b/test/parse/module/bad-export-name-undefined.txt
new file mode 100644
index 00000000..a7e3633f
--- /dev/null
+++ b/test/parse/module/bad-export-name-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (export "foo" $foo))
+(;; STDERR ;;;
+parse/module/bad-export-name-undefined.txt:2:23: undefined function variable "$foo"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-export-name.txt b/test/parse/module/bad-export-name.txt
new file mode 100644
index 00000000..31614976
--- /dev/null
+++ b/test/parse/module/bad-export-name.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (export "foo" foo))
+(;; STDERR ;;;
+parse/module/bad-export-name.txt:2:23: unexpected token "foo"
+parse/module/bad-export-name.txt:2:26: syntax error, unexpected ), expecting INT or VAR
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-export-no-string.txt b/test/parse/module/bad-export-no-string.txt
new file mode 100644
index 00000000..a80f15d2
--- /dev/null
+++ b/test/parse/module/bad-export-no-string.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (nop)) (export nop nop))
+(;; STDERR ;;;
+parse/module/bad-export-no-string.txt:2:30: syntax error, unexpected NOP, expecting TEXT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-export-too-many.txt b/test/parse/module/bad-export-too-many.txt
new file mode 100644
index 00000000..a7eb7cf6
--- /dev/null
+++ b/test/parse/module/bad-export-too-many.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (func (nop)) (export "nop" 0 foo))
+(;; STDERR ;;;
+parse/module/bad-export-too-many.txt:2:38: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-export-undefined.txt b/test/parse/module/bad-export-undefined.txt
new file mode 100644
index 00000000..a94b77f9
--- /dev/null
+++ b/test/parse/module/bad-export-undefined.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (export "foo" 0))
+(;; STDERR ;;;
+parse/module/bad-export-undefined.txt:2:23: function variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-func-redefinition.txt b/test/parse/module/bad-func-redefinition.txt
new file mode 100644
index 00000000..a05fd93e
--- /dev/null
+++ b/test/parse/module/bad-func-redefinition.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (func $n (nop))
+ (func $n (nop)))
+(;; STDERR ;;;
+parse/module/bad-func-redefinition.txt:4:3: redefinition of function "$n"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-global-binding.txt b/test/parse/module/bad-global-binding.txt
new file mode 100644
index 00000000..9e959b4d
--- /dev/null
+++ b/test/parse/module/bad-global-binding.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (global $n $foo))
+(;; STDERR ;;;
+parse/module/bad-global-binding.txt:2:20: syntax error, unexpected VAR, expecting VALUE_TYPE
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-global-redefinition.txt b/test/parse/module/bad-global-redefinition.txt
new file mode 100644
index 00000000..c38205d9
--- /dev/null
+++ b/test/parse/module/bad-global-redefinition.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (global $n i32) (global $n f32))
+(;; STDERR ;;;
+parse/module/bad-global-redefinition.txt:2:26: redefinition of global "$n"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-global-too-many.txt b/test/parse/module/bad-global-too-many.txt
new file mode 100644
index 00000000..fe7f2a58
--- /dev/null
+++ b/test/parse/module/bad-global-too-many.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (global $n i32 i32))
+(;; STDERR ;;;
+parse/module/bad-global-too-many.txt:2:24: syntax error, unexpected VALUE_TYPE, expecting )
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-global-type-list.txt b/test/parse/module/bad-global-type-list.txt
new file mode 100644
index 00000000..6288dc50
--- /dev/null
+++ b/test/parse/module/bad-global-type-list.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (global i32 i32 foo))
+(;; STDERR ;;;
+parse/module/bad-global-type-list.txt:2:25: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-import-not-param.txt b/test/parse/module/bad-import-not-param.txt
new file mode 100644
index 00000000..034c3ddc
--- /dev/null
+++ b/test/parse/module/bad-import-not-param.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (import "foo" "bar" (parump i32)))
+(;; STDERR ;;;
+parse/module/bad-import-not-param.txt:2:30: unexpected token "parump"
+parse/module/bad-import-not-param.txt:2:37: syntax error, unexpected VALUE_TYPE, expecting TYPE or PARAM or RESULT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-import-not-result.txt b/test/parse/module/bad-import-not-result.txt
new file mode 100644
index 00000000..85350405
--- /dev/null
+++ b/test/parse/module/bad-import-not-result.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (import "foo" "bar" (param i32) (resalt i32)))
+(;; STDERR ;;;
+parse/module/bad-import-not-result.txt:2:42: unexpected token "resalt"
+parse/module/bad-import-not-result.txt:2:49: syntax error, unexpected VALUE_TYPE, expecting RESULT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-import-one-string.txt b/test/parse/module/bad-import-one-string.txt
new file mode 100644
index 00000000..99b87938
--- /dev/null
+++ b/test/parse/module/bad-import-one-string.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (import "foo" (param i32)))
+(;; STDERR ;;;
+parse/module/bad-import-one-string.txt:2:23: syntax error, unexpected (, expecting TEXT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-import-redefinition.txt b/test/parse/module/bad-import-redefinition.txt
new file mode 100644
index 00000000..49a9f7d8
--- /dev/null
+++ b/test/parse/module/bad-import-redefinition.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (import $foo "bar" "baz" (param i32))
+ (import $foo "quux" "blorf" (param f32)))
+(;; STDERR ;;;
+parse/module/bad-import-redefinition.txt:4:3: redefinition of import "$foo"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-empty.txt b/test/parse/module/bad-memory-empty.txt
new file mode 100644
index 00000000..211468ae
--- /dev/null
+++ b/test/parse/module/bad-memory-empty.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory))
+(;; STDERR ;;;
+parse/module/bad-memory-empty.txt:2:16: syntax error, unexpected ), expecting INT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-init-size-negative.txt b/test/parse/module/bad-memory-init-size-negative.txt
new file mode 100644
index 00000000..2e352fa3
--- /dev/null
+++ b/test/parse/module/bad-memory-init-size-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory -100))
+(;; STDERR ;;;
+parse/module/bad-memory-init-size-negative.txt:2:17: invalid initial memory size "-100"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-init-size.txt b/test/parse/module/bad-memory-init-size.txt
new file mode 100644
index 00000000..b7d935e3
--- /dev/null
+++ b/test/parse/module/bad-memory-init-size.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (memory foo))
+(;; STDERR ;;;
+parse/module/bad-memory-init-size.txt:2:17: unexpected token "foo"
+parse/module/bad-memory-init-size.txt:2:20: syntax error, unexpected ), expecting INT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-max-less-than-init.txt b/test/parse/module/bad-memory-max-less-than-init.txt
new file mode 100644
index 00000000..0acc7503
--- /dev/null
+++ b/test/parse/module/bad-memory-max-less-than-init.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 50))
+(;; STDERR ;;;
+parse/module/bad-memory-max-less-than-init.txt:2:10: max size (50) must be greater than or equal to initial size (100)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-max-size-negative.txt b/test/parse/module/bad-memory-max-size-negative.txt
new file mode 100644
index 00000000..f1421b1d
--- /dev/null
+++ b/test/parse/module/bad-memory-max-size-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 -5))
+(;; STDERR ;;;
+parse/module/bad-memory-max-size-negative.txt:2:21: invalid max memory size "-5"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-max-size.txt b/test/parse/module/bad-memory-max-size.txt
new file mode 100644
index 00000000..d26f2c86
--- /dev/null
+++ b/test/parse/module/bad-memory-max-size.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 foo))
+(;; STDERR ;;;
+parse/module/bad-memory-max-size.txt:2:21: unexpected token "foo"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-segment-address-negative.txt b/test/parse/module/bad-memory-segment-address-negative.txt
new file mode 100644
index 00000000..989300e7
--- /dev/null
+++ b/test/parse/module/bad-memory-segment-address-negative.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 (segment -1 "foo")))
+(;; STDERR ;;;
+parse/module/bad-memory-segment-address-negative.txt:2:30: invalid memory segment address "-1"
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-segment-address-oob.txt b/test/parse/module/bad-memory-segment-address-oob.txt
new file mode 100644
index 00000000..d35841a5
--- /dev/null
+++ b/test/parse/module/bad-memory-segment-address-oob.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 (segment 200 "hi")))
+(;; STDERR ;;;
+parse/module/bad-memory-segment-address-oob.txt:2:22: address (200) greater than initial memory size (100)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-segment-address.txt b/test/parse/module/bad-memory-segment-address.txt
new file mode 100644
index 00000000..8023e329
--- /dev/null
+++ b/test/parse/module/bad-memory-segment-address.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module (memory 100 (segment foo)))
+(;; STDERR ;;;
+parse/module/bad-memory-segment-address.txt:2:30: unexpected token "foo"
+parse/module/bad-memory-segment-address.txt:2:33: syntax error, unexpected ), expecting INT
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-segment-end-oob.txt b/test/parse/module/bad-memory-segment-end-oob.txt
new file mode 100644
index 00000000..16594a69
--- /dev/null
+++ b/test/parse/module/bad-memory-segment-end-oob.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 10 (segment 5 "56789a")))
+(;; STDERR ;;;
+parse/module/bad-memory-segment-end-oob.txt:2:21: segment ends past the end of initial memory size (10)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-segment-overlap.txt b/test/parse/module/bad-memory-segment-overlap.txt
new file mode 100644
index 00000000..fbd211e9
--- /dev/null
+++ b/test/parse/module/bad-memory-segment-overlap.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module (memory 100 (segment 0 "hello") (segment 3 "hi")))
+(;; STDERR ;;;
+parse/module/bad-memory-segment-overlap.txt:2:42: address (3) less than end of previous segment (5)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-memory-too-many.txt b/test/parse/module/bad-memory-too-many.txt
new file mode 100644
index 00000000..07c62fb3
--- /dev/null
+++ b/test/parse/module/bad-memory-too-many.txt
@@ -0,0 +1,7 @@
+;;; ERROR: 1
+(module
+ (memory 100)
+ (memory 1000))
+(;; STDERR ;;;
+parse/module/bad-memory-too-many.txt:4:3: only one memory block allowed
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-module-no-close.txt b/test/parse/module/bad-module-no-close.txt
new file mode 100644
index 00000000..31cec0fb
--- /dev/null
+++ b/test/parse/module/bad-module-no-close.txt
@@ -0,0 +1,5 @@
+;;; ERROR: 1
+(module
+(;; STDERR ;;;
+parse/module/bad-module-no-close.txt:3:8: syntax error, unexpected EOF, expecting ( or )
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-table-invalid.txt b/test/parse/module/bad-table-invalid.txt
new file mode 100644
index 00000000..b3c34c96
--- /dev/null
+++ b/test/parse/module/bad-table-invalid.txt
@@ -0,0 +1,6 @@
+;;; ERROR: 1
+(module
+ (table 0))
+(;; STDERR ;;;
+parse/module/bad-table-invalid.txt:3:10: function variable out of range (max 0)
+;;; STDERR ;;)
diff --git a/test/parse/module/bad-table-too-many.txt b/test/parse/module/bad-table-too-many.txt
new file mode 100644
index 00000000..f32bf240
--- /dev/null
+++ b/test/parse/module/bad-table-too-many.txt
@@ -0,0 +1,8 @@
+;;; ERROR: 1
+(module
+ (func (param i32))
+ (table 0)
+ (table 0))
+(;; STDERR ;;;
+parse/module/bad-table-too-many.txt:5:3: only one table allowed
+;;; STDERR ;;)
diff --git a/test/parse/module/export-multi.txt b/test/parse/module/export-multi.txt
new file mode 100644
index 00000000..a356fc4b
--- /dev/null
+++ b/test/parse/module/export-multi.txt
@@ -0,0 +1,4 @@
+(module
+ (func (nop))
+ (export "a" 0)
+ (export "b" 0))
diff --git a/test/parse/module/export-named.txt b/test/parse/module/export-named.txt
new file mode 100644
index 00000000..9f0e7c73
--- /dev/null
+++ b/test/parse/module/export-named.txt
@@ -0,0 +1,3 @@
+(module
+ (func $n (result i32) (i32.const 0))
+ (export "n" $n))
diff --git a/test/parse/module/export.txt b/test/parse/module/export.txt
new file mode 100644
index 00000000..6ffe9f31
--- /dev/null
+++ b/test/parse/module/export.txt
@@ -0,0 +1,3 @@
+(module
+ (func (nop))
+ (export "nop" 0))
diff --git a/test/parse/module/global-empty.txt b/test/parse/module/global-empty.txt
new file mode 100644
index 00000000..255dff6a
--- /dev/null
+++ b/test/parse/module/global-empty.txt
@@ -0,0 +1 @@
+(module (global))
diff --git a/test/parse/module/global-many.txt b/test/parse/module/global-many.txt
new file mode 100644
index 00000000..46d40c03
--- /dev/null
+++ b/test/parse/module/global-many.txt
@@ -0,0 +1 @@
+(module (global i32 f32 i32))
diff --git a/test/parse/module/global-named.txt b/test/parse/module/global-named.txt
new file mode 100644
index 00000000..e7909ff6
--- /dev/null
+++ b/test/parse/module/global-named.txt
@@ -0,0 +1 @@
+(module (global $n i32))
diff --git a/test/parse/module/global.txt b/test/parse/module/global.txt
new file mode 100644
index 00000000..29abea09
--- /dev/null
+++ b/test/parse/module/global.txt
@@ -0,0 +1 @@
+(module (global i32))
diff --git a/test/parse/module/import-no-param.txt b/test/parse/module/import-no-param.txt
new file mode 100644
index 00000000..6c1c2fae
--- /dev/null
+++ b/test/parse/module/import-no-param.txt
@@ -0,0 +1 @@
+(module (import "foo" "bar"))
diff --git a/test/parse/module/import-type.txt b/test/parse/module/import-type.txt
new file mode 100644
index 00000000..b50c080e
--- /dev/null
+++ b/test/parse/module/import-type.txt
@@ -0,0 +1,3 @@
+(module
+ (type (func (param i32 i64 f32 f64) (result i32)))
+ (import "foo" "bar" (type 0)))
diff --git a/test/parse/module/import.txt b/test/parse/module/import.txt
new file mode 100644
index 00000000..6786fbc1
--- /dev/null
+++ b/test/parse/module/import.txt
@@ -0,0 +1,10 @@
+(module
+ ;; unnamed
+ (import "foo" "bar" (param i32) (result i64))
+
+ ;; named
+ (import $print_i32 "stdio" "print" (param i32))
+ (import $add_i32 "math" "add" (param i32 i32) (result i32))
+ (import $f32 "test" "f32" (param f32) (result f32))
+ (import $f64 "test" "f64" (param f64) (result f64))
+ (import $i64 "test" "i64" (param i64) (result i64)))
diff --git a/test/parse/module/memory-init-max-size.txt b/test/parse/module/memory-init-max-size.txt
new file mode 100644
index 00000000..ecefc97c
--- /dev/null
+++ b/test/parse/module/memory-init-max-size.txt
@@ -0,0 +1 @@
+(module (memory 100 200))
diff --git a/test/parse/module/memory-init-size.txt b/test/parse/module/memory-init-size.txt
new file mode 100644
index 00000000..ee26fe96
--- /dev/null
+++ b/test/parse/module/memory-init-size.txt
@@ -0,0 +1 @@
+(module (memory 100))
diff --git a/test/parse/module/memory-segment-1.txt b/test/parse/module/memory-segment-1.txt
new file mode 100644
index 00000000..062a5942
--- /dev/null
+++ b/test/parse/module/memory-segment-1.txt
@@ -0,0 +1 @@
+(module (memory 100 (segment 0 "hello, world!")))
diff --git a/test/parse/module/memory-segment-many.txt b/test/parse/module/memory-segment-many.txt
new file mode 100644
index 00000000..5a0075e1
--- /dev/null
+++ b/test/parse/module/memory-segment-many.txt
@@ -0,0 +1,6 @@
+(module
+ (memory 100
+ (segment 0 "hi")
+ (segment 4 "hello")
+ (segment 10 "goodbye")
+ (segment 20 "adios")))
diff --git a/test/parse/module/module-empty.txt b/test/parse/module/module-empty.txt
new file mode 100644
index 00000000..3af8f254
--- /dev/null
+++ b/test/parse/module/module-empty.txt
@@ -0,0 +1 @@
+(module)
diff --git a/test/parse/module/table-named.txt b/test/parse/module/table-named.txt
new file mode 100644
index 00000000..d769a079
--- /dev/null
+++ b/test/parse/module/table-named.txt
@@ -0,0 +1,5 @@
+(module
+ (func $f (param i32))
+ (func $g (param i32 i64))
+ (func $h (result i64) (i64.const 0))
+ (table $f $f $g $h))
diff --git a/test/parse/module/table.txt b/test/parse/module/table.txt
new file mode 100644
index 00000000..730a934b
--- /dev/null
+++ b/test/parse/module/table.txt
@@ -0,0 +1,5 @@
+(module
+ (func (param i32))
+ (func (param i32 i64))
+ (func (result i64) (i64.const 0))
+ (table 0 0 1 2))
diff --git a/test/parse/module/type-empty-param.txt b/test/parse/module/type-empty-param.txt
new file mode 100644
index 00000000..69a7cf42
--- /dev/null
+++ b/test/parse/module/type-empty-param.txt
@@ -0,0 +1 @@
+(module (type (func (param))))
diff --git a/test/parse/module/type-empty.txt b/test/parse/module/type-empty.txt
new file mode 100644
index 00000000..d75fc4cf
--- /dev/null
+++ b/test/parse/module/type-empty.txt
@@ -0,0 +1 @@
+(module (type (func)))
diff --git a/test/parse/module/type-multi-param.txt b/test/parse/module/type-multi-param.txt
new file mode 100644
index 00000000..a6176872
--- /dev/null
+++ b/test/parse/module/type-multi-param.txt
@@ -0,0 +1 @@
+(module (type (func (param i32 f32 f64) (result f32))))
diff --git a/test/parse/module/type-no-param.txt b/test/parse/module/type-no-param.txt
new file mode 100644
index 00000000..b3fc19e3
--- /dev/null
+++ b/test/parse/module/type-no-param.txt
@@ -0,0 +1 @@
+(module (type (func (result i32))))
diff --git a/test/parse/module/type.txt b/test/parse/module/type.txt
new file mode 100644
index 00000000..6d915a83
--- /dev/null
+++ b/test/parse/module/type.txt
@@ -0,0 +1 @@
+(module (type (func (param i32) (result i32))))
diff --git a/test/parse/nested-comments.txt b/test/parse/nested-comments.txt
new file mode 100644
index 00000000..89250f84
--- /dev/null
+++ b/test/parse/nested-comments.txt
@@ -0,0 +1,6 @@
+(module
+ (; foo bar
+ (; baz
+ ;)
+ ;)
+)
diff --git a/test/parse/string-escape.txt b/test/parse/string-escape.txt
new file mode 100644
index 00000000..29b4ea38
--- /dev/null
+++ b/test/parse/string-escape.txt
@@ -0,0 +1 @@
+(module (func) (export "tab:\t newline:\n slash:\\ quote:\' double:\"" 0))
diff --git a/test/parse/string-hex.txt b/test/parse/string-hex.txt
new file mode 100644
index 00000000..7c64fe4e
--- /dev/null
+++ b/test/parse/string-hex.txt
@@ -0,0 +1 @@
+(module (func) (export "foo\ba\dc\0d\ee" 0))