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 ["="]
|
||||
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"
|
||||
|
||||
--}}}
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue
Block a user