Added support for list literals to the Rain parser

This commit is contained in:
Neil Brown 2008-03-21 20:03:47 +00:00
parent f7141bda6f
commit 2189a6c28a
4 changed files with 44 additions and 0 deletions

View File

@ -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

View File

@ -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

View File

@ -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]

View File

@ -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)
{