diff --git a/common/TestUtils.hs b/common/TestUtils.hs index 9ff1abd..faeb8c2 100644 --- a/common/TestUtils.hs +++ b/common/TestUtils.hs @@ -274,6 +274,7 @@ data ExprHelper = | Lit A.Expression | EHTrue | Range A.Type ExprHelper ExprHelper + | Func String [ExprHelper] buildExprPattern :: ExprHelper -> Pattern buildExprPattern = (stopCaringPattern emptyMeta) . mkPattern . buildExpr @@ -288,6 +289,7 @@ buildExpr (Lit e) = e buildExpr EHTrue = A.True emptyMeta buildExpr (Range t begin end) = A.ExprConstr emptyMeta $ A.RangeConstr emptyMeta t (buildExpr begin) (buildExpr end) +buildExpr (Func f es) = A.FunctionCall emptyMeta (simpleName f) (map buildExpr es) -- | A simple definition of a variable simpleDef :: String -> A.SpecType -> A.NameDef diff --git a/frontends/ParseRain.hs b/frontends/ParseRain.hs index ebe6673..acfbea4 100644 --- a/frontends/ParseRain.hs +++ b/frontends/ParseRain.hs @@ -277,7 +277,12 @@ expression foldOps lhs (m,op,rhs) = A.Dyadic m op lhs rhs subExpr' :: RainParser A.Expression - subExpr' = do {id <- variable ; return $ A.ExprVariable (findMeta id) id} + subExpr' = try ( do funcName <- name + sLeftR + es <- sepBy expression sComma + sRightR + return $ A.FunctionCall (A.nameMeta funcName) funcName es) + <|> do {id <- variable ; return $ A.ExprVariable (findMeta id) id} <|> literal <|> range <|> do {(m,op) <- monadicArithOp ; rhs <- subExpr' ; return $ A.Monadic m op rhs} diff --git a/frontends/ParseRainTest.hs b/frontends/ParseRainTest.hs index 9dab13c..7e4cfce 100644 --- a/frontends/ParseRainTest.hs +++ b/frontends/ParseRainTest.hs @@ -191,6 +191,18 @@ testExprs = ,failE (":?c") ,passE ("(48 + (uint8: src % 10)) + r",300,Dy (Dy (Lit $ intLiteral 48) A.Plus (Cast A.Byte $ Dy (Var "src") A.Rem (Lit $ intLiteral 10))) A.Plus (Var "r")) + + -- Function calls: + ,passE ("foo()", 400, Func "foo" []) + ,passE ("foo(0)", 401, Func "foo" [Lit $ intLiteral 0]) + ,passE ("foo(0,1,2,3)", 402, Func "foo" $ map (Lit . intLiteral) [0,1,2,3]) + ,passE ("2 + foo()", 403, Dy (Lit $ intLiteral 2) A.Plus $ Func "foo" []) + ,failE ("foo(") + ,failE ("foo)") + ,failE ("foo + 2()") + ,failE ("[]()") + ,failE ("()()") + ] where passE :: (String,Int,ExprHelper) -> ParseTest A.Expression