diff --git a/src/Language/Wasm/Parser.y b/src/Language/Wasm/Parser.y index c1380bb..78d3c48 100644 --- a/src/Language/Wasm/Parser.y +++ b/src/Language/Wasm/Parser.y @@ -555,9 +555,26 @@ foldedinst1 :: { [Instruction] } | 'call_indirect' folded_call_indirect { $2 } | 'block' opt(ident) opt(resulttype) list(instr) ')' { [BlockInstr $2 (fromMaybe [] $3) $4] } | 'loop' opt(ident) opt(resulttype) list(instr) ')' { [LoopInstr $2 (fromMaybe [] $3) $4] } - | 'if' opt(ident) opt(resulttype) list(foldedinstr) - '(' 'then' list(instr) ')' - '(' 'else' list(instr) opt(')') ')' { concat $4 ++ [IfInstr $2 (fromMaybe [] $3) $7 $11] } + | 'if' opt(ident) '(' folded_if_result { $4 $2 } + -- opt(resulttype) list(foldedinstr) + -- '(' 'then' list(instr) ')' + -- '(' 'else' list(instr) opt(')') ')' { concat $4 ++ [IfInstr $2 (fromMaybe [] $3) $7 $11] } + +folded_if_result :: { Maybe Ident -> [Instruction] } + : 'result' valtype ')' '(' folded_then_else { \ident -> [IfInstr ident [$2] (fst $5) (snd $5)] } + | 'result' valtype ')' '(' foldedinst1 '(' folded_then_else { \ident -> $5 ++ [IfInstr ident [$2] (fst $7) (snd $7)] } + | folded_if { $1 } + +folded_if :: { Maybe Ident -> [Instruction] } + : folded_then_else { \ident -> [IfInstr ident [] (fst $1) (snd $1)] } + | foldedinst1 '(' folded_then_else { \ident -> $1 ++ [IfInstr ident [] (fst $3) (snd $3)] } + +folded_then_else :: { ([Instruction], [Instruction]) } + : 'then' list(foldedinstr) ')' folded_else { (concat $2, $4)} + +folded_else :: { [Instruction] } + : ')' { [] } + | '(' 'else' list(foldedinstr) ')' ')' { concat $3 } folded_call_indirect :: { [Instruction] } : ')' { [PlainInstr $ CallIndirect $ AnonimousTypeUse $ FuncType [] []] } diff --git a/tests/Test.hs b/tests/Test.hs index 6e0d9d6..ca8a657 100644 --- a/tests/Test.hs +++ b/tests/Test.hs @@ -12,6 +12,6 @@ import qualified Language.Wasm.Parser as Parser main :: IO () main = do - file <- LBS.readFile "tests/samples/mod2.wast" + file <- LBS.readFile "tests/samples/if.wast" print $ Parser.parseModule <$> Lexer.scanner file defaultMain $ testGroup "Test Suite" [] diff --git a/tests/samples/mod2.wast b/tests/samples/mod2.wast deleted file mode 100644 index ebc0392..0000000 --- a/tests/samples/mod2.wast +++ /dev/null @@ -1,67 +0,0 @@ -(module - (type $func_i32 (func (param i32))) - (type $func_i64 (func (param i64))) - (type $func_f32 (func (param f32))) - (type $func_f64 (func (param f64))) - - (import "spectest" "print" (func (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (func (import "spectest" "print") (param i64)) - (import "spectest" "print" (func $print_i32 (param i32))) - ;; JavaScript can't handle i64 yet. - ;; (import "spectest" "print" (func $print_i64 (param i64))) - (import "spectest" "print" (func $print_f32 (param f32))) - (import "spectest" "print" (func $print_f64 (param f64))) - (import "spectest" "print" (func $print_i32_f32 (param i32 f32))) - (import "spectest" "print" (func $print_f64_f64 (param f64 f64))) - (func $print_i32-2 (import "spectest" "print") (param i32)) - (func $print_f64-2 (import "spectest" "print") (param f64)) - (import "test" "func-i64->i64" (func $i64->i64 (param i64) (result i64))) - - (func (export "p1") (import "spectest" "print") (param i32)) - (func $p (export "p2") (import "spectest" "print") (param i32)) - (func (export "p3") (export "p4") (import "spectest" "print") (param i32)) - (func (export "p5") (import "spectest" "print") (type 0)) - (func (export "p6") (import "spectest" "print") (type 0) (param i32) (result)) - - (import "spectest" "print" (func (type $forward))) - (func (import "spectest" "print") (type $forward)) - (type $forward (func (param i32))) - - (table anyfunc (elem $print_i32 $print_f64)) - (table (export "my-table") anyfunc (elem $print_i32 $print_f64)) - (table (export "my-table") (export "my-table2") anyfunc (elem $print_i32 $print_f64)) - (table (import "external-mod" "external-table") 0 anyfunc) - (table (export "my-table") (import "external-mod" "external-table") 0 anyfunc) - (table (export "my-table") (export "my-table2") (import "external-mod" "external-table") 0 anyfunc) - - (func (export "print32") (param $i i32) - (local $x f32) - (set_local $x (f32.convert_s/i32 (get_local $i))) - (call 0 (get_local $i)) - (call $print_i32_f32 - (i32.add (get_local $i) (i32.const 1)) - (f32.const 42) - ) - (call $print_i32 (get_local $i)) - (call $print_i32-2 (get_local $i)) - (call $print_f32 (get_local $x)) - (call_indirect (type $func_i32) (get_local $i) (i32.const 0)) - ) - - (func (export "print64") (param $i i64) - (local $x f64) - (set_local $x (f64.convert_s/i64 (call $i64->i64 (get_local $i)))) - ;; JavaScript can't handle i64 yet. - ;; (call 1 (get_local $i)) - (call $print_f64_f64 - (f64.add (get_local $x) (f64.const 1)) - (f64.const 53) - ) - ;; JavaScript can't handle i64 yet. - ;; (call $print_i64 (get_local $i)) - (call $print_f64 (get_local $x)) - (call $print_f64-2 (get_local $x)) - (call_indirect (type $func_f64) (get_local $x) (i32.const 1)) - ) -) \ No newline at end of file