pass more tests

This commit is contained in:
Ilya Rezvov
2018-02-24 21:08:18 -08:00
parent 254bfca5f8
commit 55215f56de
3 changed files with 21 additions and 10 deletions
+10 -3
View File
@@ -790,12 +790,19 @@ signature_locals_body1 :: { Function }
| 'param' ident valtype ')' signature_locals_body { | 'param' ident valtype ')' signature_locals_body {
prependFuncParams [ParamType (Just $2) $3] $5 prependFuncParams [ParamType (Just $2) $3] $5
} }
| 'result' list(valtype) ')' locals_body { | result_locals_body1 { $1 }
prependFuncResults $2 $ emptyFunction { locals = fst $4, body = snd $4 }
result_locals_body :: { Function }
: ')' { emptyFunction }
| '(' result_locals_body1 { $2 }
result_locals_body1 :: { Function }
: 'result' list(valtype) ')' result_locals_body {
prependFuncResults $2 $4
} }
| locals_body1 { | locals_body1 {
emptyFunction { locals = fst $1, body = snd $1 } emptyFunction { locals = fst $1, body = snd $1 }
} }
locals_body :: { ([LocalType], [Instruction]) } locals_body :: { ([LocalType], [Instruction]) }
: ')' { ([], []) } : ')' { ([], []) }
+9 -6
View File
@@ -20,6 +20,8 @@ import Control.Monad.State.Lazy (StateT, evalStateT, get, put)
import Control.Monad.Reader (ReaderT, runReaderT, withReaderT, ask) import Control.Monad.Reader (ReaderT, runReaderT, withReaderT, ask)
import Control.Monad.Except (Except, runExcept, throwError) import Control.Monad.Except (Except, runExcept, throwError)
import Debug.Trace as Debug
data ValidationResult = data ValidationResult =
DuplicatedExportNames [String] DuplicatedExportNames [String]
| InvalidTableType | InvalidTableType
@@ -328,13 +330,13 @@ replace x y (v:r) = (if x == v then y else v) : replace x y r
unify :: Arrow -> Arrow -> Checker Arrow unify :: Arrow -> Arrow -> Checker Arrow
unify (f `Arrow` []) (f' `Arrow` t') = unify (f `Arrow` []) (f' `Arrow` t') =
return $ (f ++ f') `Arrow` t' return $ (reverse f' ++ f) `Arrow` t'
unify (f `Arrow` t) ([] `Arrow` t') = unify (f `Arrow` t) ([] `Arrow` t') =
return $ f `Arrow` (t' ++ t) return $ f `Arrow` (t' ++ t)
unify (f `Arrow` (Val v':t)) ((Val v:f') `Arrow` t') = unify (f `Arrow` (Val v':t)) ((Val v:f') `Arrow` t') =
if v == v' if v == v'
then unify (f `Arrow` t) (f' `Arrow` t') then unify (f `Arrow` t) (f' `Arrow` t')
else throwError TypeMismatch else Debug.trace ("type err " ++ show v' ++ " - " ++ show v) $ throwError TypeMismatch
unify (f `Arrow` (Var r:t)) ((Val v:f') `Arrow` t') = unify (f `Arrow` (Var r:t)) ((Val v:f') `Arrow` t') =
let subst = replace (Var r) (Val v) in let subst = replace (Var r) (Val v) in
unify (subst f `Arrow` subst t) (f' `Arrow` t') unify (subst f `Arrow` subst t) (f' `Arrow` t')
@@ -344,11 +346,12 @@ unify (f `Arrow` (Val v:t)) ((Var r:f') `Arrow` t') =
unify (f `Arrow` (Var r:t)) ((Var r':f') `Arrow` t') = unify (f `Arrow` (Var r:t)) ((Var r':f') `Arrow` t') =
let subst = replace (Var r') (Var r) in let subst = replace (Var r') (Var r) in
unify (f `Arrow` t) (subst f' `Arrow` subst t') unify (f `Arrow` t) (subst f' `Arrow` subst t')
unify (f `Arrow` (Any:t)) (f' `Arrow` t') = unify (f `Arrow` (Any:_)) (_ `Arrow` t') =
return $ f `Arrow` t' return $ f `Arrow` t'
unify (f `Arrow` t) ((Any:f') `Arrow` t') = unify (f `Arrow` _) ((Any:_) `Arrow` t') =
return $ f `Arrow` t' return $ f `Arrow` t'
unify' :: Arrow -> Arrow -> Checker Arrow
unify' (f `Arrow` t) (f' `Arrow` t') = unify (reverse f `Arrow` reverse t) (reverse f' `Arrow` reverse t') unify' (f `Arrow` t) (f' `Arrow` t') = unify (reverse f `Arrow` reverse t) (reverse f' `Arrow` reverse t')
getExpressionType :: [Instruction] -> Checker Arrow getExpressionType :: [Instruction] -> Checker Arrow
@@ -381,12 +384,12 @@ ctxFromModule locals labels returns Module {types, functions, tables, mems, glob
isFunctionValid :: Function -> Validator isFunctionValid :: Function -> Validator
isFunctionValid Function {funcType, locals, body} mod@Module {types} = isFunctionValid Function {funcType, locals, body} mod@Module {types} =
let ft@(FuncType params results) = types !! fromIntegral funcType in let FuncType params results = types !! fromIntegral funcType in
let r = safeHead results in let r = safeHead results in
let ctx = ctxFromModule (params ++ locals) [r] r mod in let ctx = ctxFromModule (params ++ locals) [r] r mod in
case runChecker ctx $ getExpressionType body of case runChecker ctx $ getExpressionType body of
Left err -> err Left err -> err
Right arr -> if arr == asArrow ft then Valid else TypeMismatch Right arr -> if arr == (empty ==> results) then Valid else TypeMismatch
functionsShouldBeValid :: Validator functionsShouldBeValid :: Validator
functionsShouldBeValid mod@Module {functions} = functionsShouldBeValid mod@Module {functions} =
+2 -1
View File
@@ -31,7 +31,8 @@ compile file = do
main :: IO () main :: IO ()
main = do main = do
files <- Directory.listDirectory "tests/samples" files <- Directory.listDirectory "tests/samples"
compile "fact.wast" -- let files = ["endianess.wast"]
-- compile "fact.wast"
syntaxTestCases <- (`mapM` files) $ \file -> do syntaxTestCases <- (`mapM` files) $ \file -> do
content <- LBS.readFile $ "tests/samples/" ++ file content <- LBS.readFile $ "tests/samples/" ++ file
let result = Parser.parseModule <$> Lexer.scanner content let result = Parser.parseModule <$> Lexer.scanner content