Check assignments.
This commit is contained in:
parent
b3e3308b3e
commit
d7e829b4c6
|
@ -152,12 +152,6 @@ checkExpressionBool m e = checkExpressionType m A.Bool e
|
||||||
checkVariableType :: Meta -> A.Type -> A.Variable -> PassM ()
|
checkVariableType :: Meta -> A.Type -> A.Variable -> PassM ()
|
||||||
checkVariableType m et v = typeOfVariable v >>= checkType m et
|
checkVariableType m et v = typeOfVariable v >>= checkType m et
|
||||||
|
|
||||||
-- | Check that two lists of types match (for example, for parallel
|
|
||||||
-- assignment).
|
|
||||||
checkTypeList :: Meta -> [A.Type] -> [A.Type] -> PassM ()
|
|
||||||
checkTypeList m ets rts
|
|
||||||
= sequence_ [checkType m et rt | (et, rt) <- zip ets rts]
|
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
--{{{ more complex checks
|
--{{{ more complex checks
|
||||||
|
|
||||||
|
@ -273,19 +267,18 @@ checkDyadicOp op l r
|
||||||
checkList lm lt >> checkList rm rt >> checkType rm lt rt
|
checkList lm lt >> checkList rm rt >> checkType rm lt rt
|
||||||
|
|
||||||
-- | Check a function call.
|
-- | Check a function call.
|
||||||
checkFunctionCall :: Meta -> A.Name -> [A.Expression] -> Bool -> PassM ()
|
checkFunctionCall :: Meta -> A.Name -> [A.Expression] -> PassM [A.Type]
|
||||||
checkFunctionCall m n es singleOnly
|
checkFunctionCall m n es
|
||||||
= do st <- specTypeOfName n
|
= do st <- specTypeOfName n
|
||||||
case st of
|
case st of
|
||||||
A.Function _ _ rs fs _ ->
|
A.Function _ _ rs fs _ ->
|
||||||
do when (singleOnly && length rs /= 1) $
|
do when (length es /= length fs) $
|
||||||
diePC m $ formatCode "Function % used in an expression returns more than one value" n
|
|
||||||
when (length es /= length fs) $
|
|
||||||
diePC m $ formatCode ("Function % called with wrong number of arguments; found " ++ (show $ length es) ++ ", expected " ++ (show $ length fs)) n
|
diePC m $ formatCode ("Function % called with wrong number of arguments; found " ++ (show $ length es) ++ ", expected " ++ (show $ length fs)) n
|
||||||
sequence_ [do rt <- typeOfExpression e
|
sequence_ [do rt <- typeOfExpression e
|
||||||
checkType (findMeta e) et rt
|
checkType (findMeta e) et rt
|
||||||
| (e, A.Formal _ et _) <- zip es fs]
|
| (e, A.Formal _ et _) <- zip es fs]
|
||||||
_ -> diePC m $ formatCode ("% is not a function; it's a " ++ show st) n
|
return rs
|
||||||
|
_ -> diePC m $ formatCode "% is not a function" n
|
||||||
|
|
||||||
-- | Check an intrinsic function call.
|
-- | Check an intrinsic function call.
|
||||||
checkIntrinsicFunctionCall :: Meta -> String -> [A.Expression] -> Bool
|
checkIntrinsicFunctionCall :: Meta -> String -> [A.Expression] -> Bool
|
||||||
|
@ -401,6 +394,24 @@ checkProtocol m t tag items doItem
|
||||||
sequence_ [doItem it item
|
sequence_ [doItem it item
|
||||||
| (it, item) <- zip its items]
|
| (it, item) <- zip its items]
|
||||||
|
|
||||||
|
checkExpressionList :: [A.Type] -> A.ExpressionList -> PassM ()
|
||||||
|
checkExpressionList ets el
|
||||||
|
= case el of
|
||||||
|
A.FunctionCallList m n es ->
|
||||||
|
do rs <- checkFunctionCall m n es
|
||||||
|
when (length ets /= length rs) $
|
||||||
|
diePC m $ formatCode ("Function % has wrong number of return values; found " ++ (show $ length rs) ++ ", expected " ++ (show $ length ets)) n
|
||||||
|
sequence_ [checkType m et rt
|
||||||
|
| (et, rt) <- zip ets rs]
|
||||||
|
A.ExpressionList m es ->
|
||||||
|
do when (length ets /= length es) $
|
||||||
|
dieP m $ "Wrong number of items in expression list; found "
|
||||||
|
++ (show $ length es) ++ ", expected "
|
||||||
|
++ (show $ length ets)
|
||||||
|
sequence_ [do rt <- typeOfExpression e
|
||||||
|
checkType (findMeta e) et rt
|
||||||
|
| (e, et) <- zip es ets]
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
||||||
-- | Check the AST for type consistency.
|
-- | Check the AST for type consistency.
|
||||||
|
@ -466,7 +477,9 @@ checkExpressions = checkDepthM doExpression
|
||||||
checkScalar m t >> checkScalar (findMeta e) et
|
checkScalar m t >> checkScalar (findMeta e) et
|
||||||
doExpression (A.Literal m t lr) = doLiteralRepr t lr
|
doExpression (A.Literal m t lr) = doLiteralRepr t lr
|
||||||
doExpression (A.FunctionCall m n es)
|
doExpression (A.FunctionCall m n es)
|
||||||
= checkFunctionCall m n es True
|
= do rs <- checkFunctionCall m n es
|
||||||
|
when (length rs /= 1) $
|
||||||
|
diePC m $ formatCode "Function % used in an expression returns more than one value" n
|
||||||
doExpression (A.IntrinsicFunctionCall m s es)
|
doExpression (A.IntrinsicFunctionCall m s es)
|
||||||
= checkIntrinsicFunctionCall m s es True
|
= checkIntrinsicFunctionCall m s es True
|
||||||
doExpression (A.SubscriptedExpr m s e)
|
doExpression (A.SubscriptedExpr m s e)
|
||||||
|
@ -503,7 +516,10 @@ checkProcesses :: Data t => t -> PassM t
|
||||||
checkProcesses = checkDepthM doProcess
|
checkProcesses = checkDepthM doProcess
|
||||||
where
|
where
|
||||||
doProcess :: A.Process -> PassM ()
|
doProcess :: A.Process -> PassM ()
|
||||||
-- Assign
|
doProcess (A.Assign m vs el)
|
||||||
|
= do vts <- mapM (typeOfVariable) vs
|
||||||
|
mapM_ checkWritable vs
|
||||||
|
checkExpressionList vts el
|
||||||
doProcess (A.Input _ v im) = doInput v im
|
doProcess (A.Input _ v im) = doInput v im
|
||||||
doProcess (A.Output m v ois) = doOutput m v ois
|
doProcess (A.Output m v ois) = doOutput m v ois
|
||||||
doProcess (A.OutputCase m v tag ois) = doOutputCase m v tag ois
|
doProcess (A.OutputCase m v tag ois) = doOutputCase m v tag ois
|
||||||
|
|
|
@ -279,6 +279,25 @@ testOccamTypes = TestList
|
||||||
-- Choices
|
-- Choices
|
||||||
, testOK 1300 $ testChoice $ A.Choice m boolE skip
|
, testOK 1300 $ testChoice $ A.Choice m boolE skip
|
||||||
, testFail 1301 $ testChoice $ A.Choice m intE skip
|
, testFail 1301 $ testChoice $ A.Choice m intE skip
|
||||||
|
|
||||||
|
-- Assignment
|
||||||
|
, testOK 1400 $ A.Assign m [intV] $ A.ExpressionList m [intE]
|
||||||
|
, testOK 1401 $ A.Assign m [intV, intV] $ A.ExpressionList m [intE, intE]
|
||||||
|
, testFail 1402 $ A.Assign m [intV] $ A.ExpressionList m [realE]
|
||||||
|
, testFail 1403 $ A.Assign m [intV, intV] $ A.ExpressionList m [intE]
|
||||||
|
, testFail 1404 $ A.Assign m [intV] $ A.ExpressionList m [intE, intE]
|
||||||
|
, testOK 1410 $ A.Assign m [intV, intV]
|
||||||
|
$ A.FunctionCallList m function22 [intE, intE]
|
||||||
|
, testFail 1411 $ A.Assign m [intV]
|
||||||
|
$ A.FunctionCallList m function22 [intE, intE]
|
||||||
|
, testFail 1412 $ A.Assign m [intV, intV, intV]
|
||||||
|
$ A.FunctionCallList m function22 [intE, intE]
|
||||||
|
, testFail 1413 $ A.Assign m [intV, realV]
|
||||||
|
$ A.FunctionCallList m function22 [intE, intE]
|
||||||
|
, testFail 1414 $ A.Assign m [intV, realV]
|
||||||
|
$ A.FunctionCallList m function22 [intE, realE]
|
||||||
|
, testFail 1415 $ A.Assign m [intV, realV]
|
||||||
|
$ A.FunctionCallList m function22 [realE]
|
||||||
--}}}
|
--}}}
|
||||||
]
|
]
|
||||||
where
|
where
|
||||||
|
|
Loading…
Reference in New Issue
Block a user