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:
Neil Brown 2009-01-23 18:58:52 +00:00
parent 91f004a197
commit 1410e80fb1
4 changed files with 25 additions and 4 deletions

View File

@ -1538,6 +1538,16 @@ cgenAssign m [v] (A.ExpressionList _ [e])
tell ["="]
call genExpression e
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"
--}}}

View File

@ -302,6 +302,8 @@ data Expression =
data ExpressionList =
-- | A list of expressions resulting from a function call.
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.
| ExpressionList Meta [Expression]
deriving (Show, Eq, Typeable, Data)

View File

@ -73,6 +73,8 @@ resolveAmbiguities = occamOnlyPass "Resolve ambiguities"
-- FunctionCallList, since it can have multiple results.
doExpressionList (A.ExpressionList _ [A.FunctionCall 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
-- | Fold constant expressions.

View File

@ -374,16 +374,17 @@ checkFunctionCall m n es
return rs
-- | Check an intrinsic function call.
checkIntrinsicFunctionCall :: Meta -> String -> [A.Expression] -> PassM ()
checkIntrinsicFunctionCall m n es
checkIntrinsicFunctionCall :: Bool -> Meta -> String -> [A.Expression] -> PassM [A.Type]
checkIntrinsicFunctionCall usedInList m n es
= case lookup n intrinsicFunctions of
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"
let fs = [A.Formal A.ValAbbrev t (A.Name m s)
| (t, s) <- args]
checkActuals m (A.Name m n)
fs (map A.ActualExpression es)
return rs
Nothing -> dieP m $ n ++ " is not an intrinsic function"
-- | 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
sequence_ [checkType m et rt
| (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 ->
do when (length ets /= length es) $
dieP m $ "Wrong number of items in expression list; found "
@ -1149,7 +1156,7 @@ checkExpressions = checkDepthM doExpression
when (length rs /= 1) $
diePC m $ formatCode "Function % used in an expression returns more than one value" n
doExpression (A.IntrinsicFunctionCall m s es)
= checkIntrinsicFunctionCall m s es
= checkIntrinsicFunctionCall False m s es >> return ()
doExpression (A.SubscriptedExpr m s e)
= do t <- astTypeOf e
checkSubscript m s t