Skip to content

Commit

Permalink
tests & bugfixes
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszcz authored and paulcadman committed Feb 6, 2024
1 parent c219941 commit 09fee21
Show file tree
Hide file tree
Showing 5 changed files with 53 additions and 36 deletions.
2 changes: 1 addition & 1 deletion src/Juvix/Compiler/Asm/Extra/Type.hs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Juvix.Compiler.Tree.Error
import Juvix.Compiler.Tree.Extra.Type

unifyTypes'' :: forall t e r. (Member (Error AsmError) r) => Maybe Location -> InfoTable' t e -> Type -> Type -> Sem r Type
unifyTypes'' loc tab ty1 ty2 = mapError toAsmError $ unifyTypes'' loc tab ty1 ty2
unifyTypes'' loc tab ty1 ty2 = mapError toAsmError $ unifyTypes' loc tab ty1 ty2
where
toAsmError :: TreeError -> AsmError
toAsmError TreeError {..} =
Expand Down
39 changes: 26 additions & 13 deletions src/Juvix/Compiler/Tree/Transformation/Validate.hs
Original file line number Diff line number Diff line change
Expand Up @@ -143,16 +143,22 @@ inferType tab funInfo = goInfer mempty
goExtendClosure bl NodeExtendClosure {..} = do
ty <- goInfer bl _nodeExtendClosureFun
let tys = typeArgs ty
m = length tys
n = length _nodeExtendClosureArgs
when (length tys <= n && typeTarget ty /= TyDynamic) $
throw $
TreeError
{ _treeErrorLoc = _nodeExtendClosureInfo ^. nodeInfoLocation,
_treeErrorMsg = "Too many arguments"
}
let tys' = take n tys ++ replicate (length tys - n) TyDynamic
forM_ (zipExact (toList _nodeExtendClosureArgs) tys') (uncurry (checkType bl))
return $ mkTypeFun (drop n tys) (typeTarget ty)
if
| n < m -> do
forM_ (zipExact (toList _nodeExtendClosureArgs) (take n tys)) (uncurry (checkType bl))
return $ mkTypeFun (drop n tys) (typeTarget ty)
| typeTarget ty == TyDynamic -> do
let tys' = tys ++ replicate (n - m) TyDynamic
forM_ (zipExact (toList _nodeExtendClosureArgs) tys') (uncurry (checkType bl))
return $ typeTarget ty
| otherwise ->
throw $
TreeError
{ _treeErrorLoc = _nodeExtendClosureInfo ^. nodeInfoLocation,
_treeErrorMsg = "Too many arguments"
}

goCall :: BinderList Type -> NodeCall -> Sem r Type
goCall bl NodeCall {..} = case _nodeCallType of
Expand All @@ -175,13 +181,19 @@ inferType tab funInfo = goInfer mempty
ty <- goInfer bl cl
let tys = typeArgs ty
n = length _nodeCallArgs
when (length tys /= n && typeTarget ty /= TyDynamic) $
when (length tys > n) $
throw $
TreeError
{ _treeErrorLoc = _nodeCallInfo ^. nodeInfoLocation,
_treeErrorMsg = "Wrong number of arguments"
_treeErrorMsg = "Too few arguments"
}
when (length tys < n && typeTarget ty /= TyDynamic) $
throw $
TreeError
{ _treeErrorLoc = _nodeCallInfo ^. nodeInfoLocation,
_treeErrorMsg = "Too many arguments"
}
let tys' = take n tys ++ replicate (length tys - n) TyDynamic
let tys' = tys ++ replicate (n - length tys) TyDynamic
forM_ (zipExact _nodeCallArgs tys') (uncurry (checkType bl))
return $ typeTarget ty

Expand Down Expand Up @@ -247,7 +259,8 @@ inferType tab funInfo = goInfer mempty
validateFunction :: (Member (Error TreeError) r) => InfoTable -> FunctionInfo -> Sem r FunctionInfo
validateFunction tab funInfo = do
ty <- inferType tab funInfo (funInfo ^. functionCode)
_ <- unifyTypes' (funInfo ^. functionLocation) tab ty (typeTarget (funInfo ^. functionType))
let ty' = if funInfo ^. functionArgsNum == 0 then funInfo ^. functionType else typeTarget (funInfo ^. functionType)
_ <- unifyTypes' (funInfo ^. functionLocation) tab ty ty'
return funInfo

validate :: (Member (Error TreeError) r) => InfoTable -> Sem r InfoTable
Expand Down
44 changes: 24 additions & 20 deletions test/Tree/Eval/Base.hs
Original file line number Diff line number Diff line change
Expand Up @@ -35,27 +35,31 @@ treeEvalAssertionParam evalParam mainFile expectedFile trans testTrans step = do
case runParser (toFilePath mainFile) s of
Left err -> assertFailure (show (pretty err))
Right tab0 -> do
unless (null trans) $
step "Transform"
case run $ runError @JuvixError $ applyTransformations trans tab0 of
step "Validate"
case run $ runError @JuvixError $ applyTransformations [Validate] tab0 of
Left err -> assertFailure (show (pretty (fromJuvixError @GenericError err)))
Right tab -> do
testTrans tab
case tab ^. infoMainFunction of
Just sym -> do
withTempDir'
( \dirPath -> do
let outputFile = dirPath <//> $(mkRelFile "out.out")
hout <- openFile (toFilePath outputFile) WriteMode
step "Evaluate"
evalParam hout sym tab
hClose hout
actualOutput <- readFile (toFilePath outputFile)
step "Compare expected and actual program output"
expected <- readFile (toFilePath expectedFile)
assertEqDiffText ("Check: RUN output = " <> toFilePath expectedFile) actualOutput expected
)
Nothing -> assertFailure "no 'main' function"
Right tab1 -> do
unless (null trans) $
step "Transform"
case run $ runError @JuvixError $ applyTransformations trans tab1 of
Left err -> assertFailure (show (pretty (fromJuvixError @GenericError err)))
Right tab -> do
testTrans tab
case tab ^. infoMainFunction of
Just sym -> do
withTempDir'
( \dirPath -> do
let outputFile = dirPath <//> $(mkRelFile "out.out")
hout <- openFile (toFilePath outputFile) WriteMode
step "Evaluate"
evalParam hout sym tab
hClose hout
actualOutput <- readFile (toFilePath outputFile)
step "Compare expected and actual program output"
expected <- readFile (toFilePath expectedFile)
assertEqDiffText ("Check: RUN output = " <> toFilePath expectedFile) actualOutput expected
)
Nothing -> assertFailure "no 'main' function"

evalAssertion :: Handle -> Symbol -> InfoTable -> IO ()
evalAssertion hout sym tab = do
Expand Down
2 changes: 1 addition & 1 deletion tests/Asm/positive/test032.jva
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ function uncurry(*, * -> *, *) {
tccall 2;
}

function pred_step(Pair) : (* -> *, *) -> * {
function pred_step(Pair) : Pair {
push arg[0].pair[1];
call isZero;
br {
Expand Down
2 changes: 1 addition & 1 deletion tests/Tree/positive/test032.jvt
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function uncurry(*, * → *, *) : * {
ccall(arg[0], arg[1], arg[2])
}

function pred_step(Pair) : (* → *, *) → * {
function pred_step(Pair) : Pair {
br(call[isZero](arg[0].pair[1])) {
true: alloc[pair](arg[0].pair[0], calloc[uncurry](calloc[succ](arg[0].pair[1])))
false: alloc[pair](calloc[uncurry](calloc[succ](arg[0].pair[0])), calloc[uncurry](calloc[succ](arg[0].pair[1])))
Expand Down

0 comments on commit 09fee21

Please sign in to comment.