Rain: added more type-checker tests and made them pass
This commit is contained in:
parent
eeacaf1de4
commit
15ce5fee06
|
@ -100,12 +100,14 @@ checkExpressionTypes = everywhereASTM checkExpression
|
||||||
= do tlhs <- typeOfExpression lhs
|
= do tlhs <- typeOfExpression lhs
|
||||||
trhs <- typeOfExpression rhs
|
trhs <- typeOfExpression rhs
|
||||||
if (tlhs == trhs)
|
if (tlhs == trhs)
|
||||||
then return e
|
then (if validOp op tlhs then return e else dieP m $ "Operator: \"" ++ show op ++ "\" is not valid on type: \"" ++ show tlhs)
|
||||||
else if (isIntegerType tlhs && isIntegerType trhs)
|
else if (isIntegerType tlhs && isIntegerType trhs)
|
||||||
then case (leastGeneralSharedTypeRain [tlhs,trhs]) of
|
then case (leastGeneralSharedTypeRain [tlhs,trhs]) of
|
||||||
Nothing -> dieP m $ "Cannot find a suitable type to convert expression to, types are: " ++ show tlhs ++ " and " ++ show trhs
|
Nothing -> dieP m $ "Cannot find a suitable type to convert expression to, types are: " ++ show tlhs ++ " and " ++ show trhs
|
||||||
Just t -> return $ A.Dyadic m op (convert t tlhs lhs) (convert t trhs rhs)
|
Just t -> if validOp op t then return $ A.Dyadic m op (convert t tlhs lhs) (convert t trhs rhs) else dieP m $
|
||||||
else return e --TODO
|
"Operator: \"" ++ show op ++ "\" is not valid on type: \"" ++ show tlhs
|
||||||
|
else --The operators are not equal, and are not integers. Therefore this must be an error:
|
||||||
|
dieP m $ "Mis-matched types; no operator applies to types: " ++ show tlhs ++ " and " ++ show trhs
|
||||||
checkExpression e@(A.Monadic m op rhs)
|
checkExpression e@(A.Monadic m op rhs)
|
||||||
= do trhs <- typeOfExpression rhs
|
= do trhs <- typeOfExpression rhs
|
||||||
if (op == A.MonadicMinus)
|
if (op == A.MonadicMinus)
|
||||||
|
@ -115,7 +117,12 @@ checkExpressionTypes = everywhereASTM checkExpression
|
||||||
A.UInt32 -> return $ A.Monadic m op $ convert A.Int64 trhs rhs
|
A.UInt32 -> return $ A.Monadic m op $ convert A.Int64 trhs rhs
|
||||||
A.UInt64 -> dieP m $ "Cannot apply unary minus to type: " ++ show trhs ++ " because there is no type large enough to safely contain the result"
|
A.UInt64 -> dieP m $ "Cannot apply unary minus to type: " ++ show trhs ++ " because there is no type large enough to safely contain the result"
|
||||||
_ -> if (isIntegerType trhs) then return e else dieP m $ "Trying to apply unary minus to non-integer type: " ++ show trhs
|
_ -> if (isIntegerType trhs) then return e else dieP m $ "Trying to apply unary minus to non-integer type: " ++ show trhs
|
||||||
else return e
|
else if (op == A.MonadicNot)
|
||||||
|
then
|
||||||
|
case trhs of
|
||||||
|
A.Bool -> return e
|
||||||
|
_ -> dieP m $ "Cannot apply unary not to non-boolean type: " ++ show trhs
|
||||||
|
else dieP m $ "Invalid Rain operator: \"" ++ show op ++ "\""
|
||||||
checkExpression e = return e
|
checkExpression e = return e
|
||||||
|
|
||||||
convert :: A.Type -> A.Type -> A.Expression -> A.Expression
|
convert :: A.Type -> A.Type -> A.Expression -> A.Expression
|
||||||
|
@ -123,4 +130,21 @@ checkExpressionTypes = everywhereASTM checkExpression
|
||||||
then e
|
then e
|
||||||
else A.Conversion (findMeta e) A.DefaultConversion dest e
|
else A.Conversion (findMeta e) A.DefaultConversion dest e
|
||||||
|
|
||||||
|
validOp :: A.DyadicOp -> A.Type -> Bool
|
||||||
|
validOp A.Plus t = isIntegerType t
|
||||||
|
validOp A.Minus t = isIntegerType t
|
||||||
|
validOp A.Times t = isIntegerType t
|
||||||
|
validOp A.Div t = isIntegerType t
|
||||||
|
validOp A.Rem t = isIntegerType t
|
||||||
|
validOp A.Eq _ = True
|
||||||
|
validOp A.NotEq _ = True
|
||||||
|
validOp A.Less t = haveOrder t
|
||||||
|
validOp A.LessEq t = haveOrder t
|
||||||
|
validOp A.More t = haveOrder t
|
||||||
|
validOp A.MoreEq t = haveOrder t
|
||||||
|
validOp A.And A.Bool = True
|
||||||
|
validOp A.Or A.Bool = True
|
||||||
|
validOp _ _ = False
|
||||||
|
|
||||||
|
haveOrder :: A.Type -> Bool
|
||||||
|
haveOrder = isIntegerType
|
||||||
|
|
|
@ -89,26 +89,52 @@ annotateIntTest = TestList
|
||||||
checkExpressionTest :: Test
|
checkExpressionTest :: Test
|
||||||
checkExpressionTest = TestList
|
checkExpressionTest = TestList
|
||||||
[
|
[
|
||||||
|
--Already same types:
|
||||||
passSame 0 A.Int64 $ Dy (Var "x") A.Plus (Var "x")
|
passSame 0 A.Int64 $ Dy (Var "x") A.Plus (Var "x")
|
||||||
,passSame 1 A.Byte $ Dy (Var "xu8") A.Plus (Var "xu8")
|
,passSame 1 A.Byte $ Dy (Var "xu8") A.Plus (Var "xu8")
|
||||||
|
|
||||||
|
--Upcasting:
|
||||||
,pass 100 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Var "xu8")) (Dy (Var "x") A.Plus (Var "xu8"))
|
,pass 100 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Var "xu8")) (Dy (Var "x") A.Plus (Var "xu8"))
|
||||||
,pass 101 A.Int32 (Dy (Cast A.Int32 $ Var "x16") A.Plus (Cast A.Int32 $ Var "xu16")) (Dy (Var "x16") A.Plus (Var "xu16"))
|
,pass 101 A.Int32 (Dy (Cast A.Int32 $ Var "x16") A.Plus (Cast A.Int32 $ Var "xu16")) (Dy (Var "x16") A.Plus (Var "xu16"))
|
||||||
|
|
||||||
|
--Upcasting a cast:
|
||||||
,pass 200 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Cast A.Int32 $ Var "xu8")) (Dy (Var "x") A.Plus (Cast A.Int32 $ Var "xu8"))
|
,pass 200 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Cast A.Int32 $ Var "xu8")) (Dy (Var "x") A.Plus (Cast A.Int32 $ Var "xu8"))
|
||||||
|
|
||||||
|
--Impossible conversions:
|
||||||
,fail 300 $ Dy (Var "x") A.Plus (Var "xu64")
|
,fail 300 $ Dy (Var "x") A.Plus (Var "xu64")
|
||||||
|
|
||||||
|
--Integer literals:
|
||||||
,pass 400 A.Int16 (Dy (Var "x16") A.Plus (Cast A.Int16 $ int A.Int8 100)) (Dy (Var "x16") A.Plus (int A.Int8 100))
|
,pass 400 A.Int16 (Dy (Var "x16") A.Plus (Cast A.Int16 $ int A.Int8 100)) (Dy (Var "x16") A.Plus (int A.Int8 100))
|
||||||
,pass 401 A.Int16 (Dy (Cast A.Int16 $ Var "x8") A.Plus (int A.Int16 200)) (Dy (Var "x8") A.Plus (int A.Int16 200))
|
,pass 401 A.Int16 (Dy (Cast A.Int16 $ Var "x8") A.Plus (int A.Int16 200)) (Dy (Var "x8") A.Plus (int A.Int16 200))
|
||||||
--This fails because you are trying to add a signed constant to an unsigned integer that cannot be expanded:
|
--This fails because you are trying to add a signed constant to an unsigned integer that cannot be expanded:
|
||||||
,fail 402 $ Dy (Var "xu64") A.Plus (int A.Int64 0)
|
,fail 402 $ Dy (Var "xu64") A.Plus (int A.Int64 0)
|
||||||
|
|
||||||
|
--Monadic integer operations:
|
||||||
,passSame 500 A.Int32 (Mon A.MonadicMinus (Var "x32"))
|
,passSame 500 A.Int32 (Mon A.MonadicMinus (Var "x32"))
|
||||||
,pass 501 A.Int32 (Mon A.MonadicMinus (Cast A.Int32 $ Var "xu16")) (Mon A.MonadicMinus (Var "xu16"))
|
,pass 501 A.Int32 (Mon A.MonadicMinus (Cast A.Int32 $ Var "xu16")) (Mon A.MonadicMinus (Var "xu16"))
|
||||||
,fail 502 $ Mon A.MonadicMinus (Var "xu64")
|
,fail 502 $ Mon A.MonadicMinus (Var "xu64")
|
||||||
,pass 503 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Mon A.MonadicMinus (Var "x32"))) (Dy (Var "x") A.Plus (Mon A.MonadicMinus (Var "x32")))
|
,pass 503 A.Int64 (Dy (Var "x") A.Plus (Cast A.Int64 $ Mon A.MonadicMinus (Var "x32"))) (Dy (Var "x") A.Plus (Mon A.MonadicMinus (Var "x32")))
|
||||||
|
|
||||||
|
--Mis-matched types (integer/boolean):
|
||||||
|
,fail 600 $ Dy (Var "b") A.Plus (Var "x")
|
||||||
|
,fail 601 $ Mon A.MonadicMinus (Var "b")
|
||||||
|
,fail 602 $ Dy (Var "x") A.Or (Var "x")
|
||||||
|
,fail 603 $ Dy (Var "x") A.Eq (Var "b")
|
||||||
|
,fail 604 $ Dy (Var "b") A.Plus (Var "b")
|
||||||
|
,fail 605 $ Dy (Var "b") A.Less (Var "b")
|
||||||
|
|
||||||
|
--Booleans (easy!)
|
||||||
|
,passSame 1000 A.Bool $ Mon A.MonadicNot (Var "b")
|
||||||
|
,passSame 1001 A.Bool $ Dy (Var "b") A.Or (Var "b")
|
||||||
|
,passSame 1002 A.Bool $ Dy (Var "b") A.And (Mon A.MonadicNot $ Var "b")
|
||||||
|
|
||||||
|
--Comparison (same types):
|
||||||
|
,passSame 1100 A.Bool $ Dy (Var "b") A.Eq (Var "b")
|
||||||
|
,passSame 1101 A.Bool $ Dy (Var "x") A.Eq (Var "x")
|
||||||
|
,passSame 1102 A.Bool $ Dy (Var "xu8") A.NotEq (Var "xu8")
|
||||||
|
,passSame 1103 A.Bool $ Dy (Var "x") A.Less (Var "x")
|
||||||
|
,passSame 1104 A.Bool $ Dy (Dy (Var "x") A.Eq (Var "x")) A.And (Dy (Var "xu8") A.NotEq (Var "xu8"))
|
||||||
|
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
passSame :: Int -> A.Type -> ExprHelper -> Test
|
passSame :: Int -> A.Type -> ExprHelper -> Test
|
||||||
|
|
Loading…
Reference in New Issue
Block a user