Added support for intrinsic functions with multiple return values
Previously, such a function was an IntrinsicFunctionCall inside one expression of an ExpressionList, which the type-checker rejected. I've had to add a new constructor to ExpressionList, and I've quickly hacked together the line in the C backend to make it work -- but it does seem to work.
This commit is contained in:
parent
91f004a197
commit
1410e80fb1
|
@ -1538,6 +1538,16 @@ cgenAssign m [v] (A.ExpressionList _ [e])
|
||||||
tell ["="]
|
tell ["="]
|
||||||
call genExpression e
|
call genExpression e
|
||||||
tell [";"]
|
tell [";"]
|
||||||
|
cgenAssign m (v:vs) (A.IntrinsicFunctionCallList _ n es)
|
||||||
|
= do call genVariable v
|
||||||
|
tell ["=occam_",n,"("]
|
||||||
|
seqComma $ map (call genExpression) es
|
||||||
|
mapM (\v -> tell [","] >> call genActual (A.Formal A.Abbrev A.Int (A.Name
|
||||||
|
emptyMeta "dummy_intrinsic_param")) (A.ActualVariable v)) vs
|
||||||
|
tell [","]
|
||||||
|
genMeta m
|
||||||
|
tell [");"]
|
||||||
|
|
||||||
cgenAssign m _ _ = call genMissing "Cannot perform assignment with multiple destinations or multiple sources"
|
cgenAssign m _ _ = call genMissing "Cannot perform assignment with multiple destinations or multiple sources"
|
||||||
|
|
||||||
--}}}
|
--}}}
|
||||||
|
|
|
@ -302,6 +302,8 @@ data Expression =
|
||||||
data ExpressionList =
|
data ExpressionList =
|
||||||
-- | A list of expressions resulting from a function call.
|
-- | A list of expressions resulting from a function call.
|
||||||
FunctionCallList Meta Name [Expression]
|
FunctionCallList Meta Name [Expression]
|
||||||
|
-- | A list of expressions resulting from an intrinsic function call.
|
||||||
|
| IntrinsicFunctionCallList Meta String [Expression]
|
||||||
-- | A list of expressions resulting from, well, a list of expressions.
|
-- | A list of expressions resulting from, well, a list of expressions.
|
||||||
| ExpressionList Meta [Expression]
|
| ExpressionList Meta [Expression]
|
||||||
deriving (Show, Eq, Typeable, Data)
|
deriving (Show, Eq, Typeable, Data)
|
||||||
|
|
|
@ -73,6 +73,8 @@ resolveAmbiguities = occamOnlyPass "Resolve ambiguities"
|
||||||
-- FunctionCallList, since it can have multiple results.
|
-- FunctionCallList, since it can have multiple results.
|
||||||
doExpressionList (A.ExpressionList _ [A.FunctionCall m n es])
|
doExpressionList (A.ExpressionList _ [A.FunctionCall m n es])
|
||||||
= return $ A.FunctionCallList m n es
|
= return $ A.FunctionCallList m n es
|
||||||
|
doExpressionList (A.ExpressionList _ [A.IntrinsicFunctionCall m n es])
|
||||||
|
= return $ A.IntrinsicFunctionCallList m n es
|
||||||
doExpressionList e = return e
|
doExpressionList e = return e
|
||||||
|
|
||||||
-- | Fold constant expressions.
|
-- | Fold constant expressions.
|
||||||
|
|
|
@ -374,16 +374,17 @@ checkFunctionCall m n es
|
||||||
return rs
|
return rs
|
||||||
|
|
||||||
-- | Check an intrinsic function call.
|
-- | Check an intrinsic function call.
|
||||||
checkIntrinsicFunctionCall :: Meta -> String -> [A.Expression] -> PassM ()
|
checkIntrinsicFunctionCall :: Bool -> Meta -> String -> [A.Expression] -> PassM [A.Type]
|
||||||
checkIntrinsicFunctionCall m n es
|
checkIntrinsicFunctionCall usedInList m n es
|
||||||
= case lookup n intrinsicFunctions of
|
= case lookup n intrinsicFunctions of
|
||||||
Just (rs, args) ->
|
Just (rs, args) ->
|
||||||
do when (length rs /= 1) $
|
do when (not usedInList && length rs /= 1) $
|
||||||
dieP m $ "Function " ++ n ++ " used in an expression returns more than one value"
|
dieP m $ "Function " ++ n ++ " used in an expression returns more than one value"
|
||||||
let fs = [A.Formal A.ValAbbrev t (A.Name m s)
|
let fs = [A.Formal A.ValAbbrev t (A.Name m s)
|
||||||
| (t, s) <- args]
|
| (t, s) <- args]
|
||||||
checkActuals m (A.Name m n)
|
checkActuals m (A.Name m n)
|
||||||
fs (map A.ActualExpression es)
|
fs (map A.ActualExpression es)
|
||||||
|
return rs
|
||||||
Nothing -> dieP m $ n ++ " is not an intrinsic function"
|
Nothing -> dieP m $ n ++ " is not an intrinsic function"
|
||||||
|
|
||||||
-- | Check a mobile allocation.
|
-- | Check a mobile allocation.
|
||||||
|
@ -499,6 +500,12 @@ checkExpressionList ets el
|
||||||
diePC m $ formatCode ("Function % has wrong number of return values; found " ++ (show $ length rs) ++ ", expected " ++ (show $ length ets)) n
|
diePC m $ formatCode ("Function % has wrong number of return values; found " ++ (show $ length rs) ++ ", expected " ++ (show $ length ets)) n
|
||||||
sequence_ [checkType m et rt
|
sequence_ [checkType m et rt
|
||||||
| (et, rt) <- zip ets rs]
|
| (et, rt) <- zip ets rs]
|
||||||
|
A.IntrinsicFunctionCallList m n es ->
|
||||||
|
do rs <- checkIntrinsicFunctionCall True m n es
|
||||||
|
when (length ets /= length rs) $
|
||||||
|
dieP m $ "Intrinsic function " ++ n ++ " has wrong number of return values; found " ++ (show $ length rs) ++ ", expected " ++ (show $ length ets)
|
||||||
|
sequence_ [checkType m et rt
|
||||||
|
| (et, rt) <- zip ets rs]
|
||||||
A.ExpressionList m es ->
|
A.ExpressionList m es ->
|
||||||
do when (length ets /= length es) $
|
do when (length ets /= length es) $
|
||||||
dieP m $ "Wrong number of items in expression list; found "
|
dieP m $ "Wrong number of items in expression list; found "
|
||||||
|
@ -1149,7 +1156,7 @@ checkExpressions = checkDepthM doExpression
|
||||||
when (length rs /= 1) $
|
when (length rs /= 1) $
|
||||||
diePC m $ formatCode "Function % used in an expression returns more than one value" n
|
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
|
= checkIntrinsicFunctionCall False m s es >> return ()
|
||||||
doExpression (A.SubscriptedExpr m s e)
|
doExpression (A.SubscriptedExpr m s e)
|
||||||
= do t <- astTypeOf e
|
= do t <- astTypeOf e
|
||||||
checkSubscript m s t
|
checkSubscript m s t
|
||||||
|
|
Loading…
Reference in New Issue
Block a user