diff --git a/backends/GenerateC.hs b/backends/GenerateC.hs index 06a33ff..e451a92 100644 --- a/backends/GenerateC.hs +++ b/backends/GenerateC.hs @@ -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" --}}} diff --git a/data/AST.hs b/data/AST.hs index 42111b5..92dab13 100644 --- a/data/AST.hs +++ b/data/AST.hs @@ -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) diff --git a/frontends/OccamPasses.hs b/frontends/OccamPasses.hs index ddd69c6..753f6ef 100644 --- a/frontends/OccamPasses.hs +++ b/frontends/OccamPasses.hs @@ -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. diff --git a/frontends/OccamTypes.hs b/frontends/OccamTypes.hs index 3055bf4..6399c27 100644 --- a/frontends/OccamTypes.hs +++ b/frontends/OccamTypes.hs @@ -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