From 2189a6c28a72cf615b7febbe056f5227735813cd Mon Sep 17 00:00:00 2001 From: Neil Brown Date: Fri, 21 Mar 2008 20:03:47 +0000 Subject: [PATCH] Added support for list literals to the Rain parser --- common/TestUtils.hs | 4 ++++ frontends/ParseRain.hs | 21 +++++++++++++++++++++ frontends/ParseRainTest.hs | 17 +++++++++++++++++ testcases/lists.rain | 2 ++ 4 files changed, 44 insertions(+) diff --git a/common/TestUtils.hs b/common/TestUtils.hs index 42e416d..e8c08cb 100644 --- a/common/TestUtils.hs +++ b/common/TestUtils.hs @@ -52,6 +52,7 @@ import Metadata (emptyMeta) import Pass import Pattern import PrettyShow +import TagAST import TestFramework import TreeUtils import Types @@ -257,6 +258,9 @@ makeLiteralStringRainPattern = (stopCaringPattern emptyMeta) . mkPattern . makeL makeLiteralCharPattern :: Char -> Pattern makeLiteralCharPattern c = tag3 A.Literal DontCare A.Byte (tag2 A.ByteLiteral DontCare [c]) +makeListLiteralPattern :: [Pattern] -> Pattern +makeListLiteralPattern items = mLiteral (A.List A.Any) (mListLiteral items) + data ExprHelper = Dy ExprHelper A.DyadicOp ExprHelper | Mon A.MonadicOp ExprHelper diff --git a/frontends/ParseRain.hs b/frontends/ParseRain.hs index 2defbbf..b99a888 100644 --- a/frontends/ParseRain.hs +++ b/frontends/ParseRain.hs @@ -204,12 +204,33 @@ integer integerLiteral :: RainParser A.Expression integerLiteral = do {i <- integer ; return $ A.Literal (findMeta i) A.Int i} +listLiteral :: RainParser A.Expression +listLiteral + = try $ do m <- sLeftQ + (do try sRightQ + return $ A.Literal m (A.List A.Any) $ A.ListLiteral m [] + <|> do e0 <- try expression + (do try sRightQ + return $ A.Literal m (A.List A.Any) $ + A.ListLiteral m [e0] + -- Up until the first comma, this may be a type declaration + -- in a cast expression, so we "try" all the way + -- up until that comma + <|> do try sComma + es <- sepBy1 expression sComma + sRightQ + return $ A.Literal m (A.List A.Any) $ + A.ListLiteral m (e0 : es) + ) + ) + literal :: RainParser A.Expression literal = do {lr <- stringLiteral ; return $ A.Literal (findMeta lr) (A.List A.Byte) lr } <|> do {c <- literalCharacter ; return $ A.Literal (findMeta c) A.Byte c} <|> integerLiteral <|> do {m <- reserved "true" ; return $ A.True m} <|> do {m <- reserved "false" ; return $ A.False m} + <|> listLiteral "literal" range :: RainParser A.Expression diff --git a/frontends/ParseRainTest.hs b/frontends/ParseRainTest.hs index e140da3..17ea95a 100644 --- a/frontends/ParseRainTest.hs +++ b/frontends/ParseRainTest.hs @@ -249,6 +249,23 @@ testLiteral = ,fail ("'\\",RP.literal) ,fail ("'ab'",RP.literal) ,fail ("'\\n\\n'",RP.literal) + + -- Lists: + ,pass ("[0]", RP.literal, assertPatternMatch "testLiteral 400" $ + makeListLiteralPattern [intLiteralPattern 0]) + ,pass ("[]", RP.literal, assertPatternMatch "testLiteral 401" $ + makeListLiteralPattern []) + ,pass ("[0,1,2]", RP.literal, assertPatternMatch "testLiteral 400" $ + makeListLiteralPattern $ map intLiteralPattern [0,1,2]) + ,pass ("['0']", RP.literal, assertPatternMatch "testLiteral 400" $ + makeListLiteralPattern [makeLiteralCharPattern '0']) + + ,fail ("[", RP.literal) + ,fail ("]", RP.literal) + ,fail ("[,]", RP.literal) + ,fail ("[0,]", RP.literal) + ,fail ("[,0]", RP.literal) + ,fail ("[0,,1]", RP.literal) ] testRange :: [ParseTest A.Expression] diff --git a/testcases/lists.rain b/testcases/lists.rain index e56540a..68367d9 100644 --- a/testcases/lists.rain +++ b/testcases/lists.rain @@ -5,6 +5,8 @@ process main (?uint8: in, !uint8: out, !uint8: err) alphabet = ['a' .. 'z']; alphabet += ['A' .. 'Z']; + + alphabet += ['0','1','2'] + ['3','4','5'] + "6789"; seqeach (c : alphabet) {