Rain: added support for parsing character literals
This commit is contained in:
parent
fa405e7e46
commit
d39e2693cd
12
RainParse.hs
12
RainParse.hs
|
@ -180,15 +180,16 @@ stringLiteral
|
|||
where
|
||||
testToken (L.TokStringLiteral str) = Just str
|
||||
testToken _ = Nothing
|
||||
replaceEscapes :: String -> String
|
||||
replaceEscapes [] = []
|
||||
replaceEscapes ('\\':(c:cs)) = if c == 'n' then ('\n':replaceEscapes cs) else (c:replaceEscapes cs)
|
||||
replaceEscapes (c:cs) = (c:replaceEscapes cs)
|
||||
|
||||
replaceEscapes :: String -> String
|
||||
replaceEscapes [] = []
|
||||
replaceEscapes ('\\':(c:cs)) = if c == 'n' then ('\n':replaceEscapes cs) else (c:replaceEscapes cs)
|
||||
replaceEscapes (c:cs) = (c:replaceEscapes cs)
|
||||
|
||||
literalCharacter :: RainParser A.LiteralRepr
|
||||
literalCharacter
|
||||
= do (m,c) <- getToken testToken
|
||||
return $ A.ByteLiteral m c
|
||||
return $ A.ByteLiteral m (replaceEscapes c)
|
||||
where
|
||||
testToken (L.TokCharLiteral c) = Just c
|
||||
testToken _ = Nothing
|
||||
|
@ -206,6 +207,7 @@ integerLiteral = do {i <- integer ; return $ A.Literal (findMeta i) A.Int i}
|
|||
|
||||
literal :: RainParser A.Expression
|
||||
literal = do {(lr, dim) <- stringLiteral ; return $ A.Literal (findMeta lr) (A.Array [dim] 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}
|
||||
|
|
|
@ -42,7 +42,7 @@ fail x = ExpFail x
|
|||
--Runs a parse test, given a tuple of: (source text, parser function, assert)
|
||||
testParsePass :: Show a => (String, RP.RainParser a , (a -> Assertion)) -> Assertion
|
||||
testParsePass (text,prod,test)
|
||||
= do lexOut <- (L.runLexer "<test>" text)
|
||||
= do lexOut <- (L.runLexer "<unknown-parse-test>" text)
|
||||
case lexOut of
|
||||
Left m -> assertFailure $ "Parse error in:\n" ++ text ++ "\n***at: " ++ (show m)
|
||||
Right toks -> case (runParser parser emptyState "<test>" toks) of
|
||||
|
@ -166,6 +166,8 @@ testExprs =
|
|||
Cast (A.Chan A.DirInput nonShared $ A.UserDataType $ typeName "c") $ Var "b")
|
||||
,failE ("?c:")
|
||||
,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"))
|
||||
]
|
||||
where
|
||||
passE :: (String,Int,ExprHelper) -> ParseTest A.Expression
|
||||
|
@ -214,6 +216,17 @@ testLiteral =
|
|||
,fail ("\"\"a",RP.literal)
|
||||
,fail ("\"\\\"",RP.literal)
|
||||
|
||||
--Characters:
|
||||
|
||||
,pass ("'0'", RP.literal, assertPatternMatch "testLiteral 300" $ makeLiteralCharPattern '0')
|
||||
,pass ("'\\''", RP.literal, assertPatternMatch "testLiteral 300" $ makeLiteralCharPattern '\'')
|
||||
,pass ("'\\n'", RP.literal, assertPatternMatch "testLiteral 300" $ makeLiteralCharPattern '\n')
|
||||
,pass ("'\\\\'", RP.literal, assertPatternMatch "testLiteral 300" $ makeLiteralCharPattern '\\')
|
||||
,fail ("''",RP.literal)
|
||||
,fail ("'",RP.literal)
|
||||
,fail ("'\\",RP.literal)
|
||||
,fail ("'ab'",RP.literal)
|
||||
,fail ("'\\n\\n'",RP.literal)
|
||||
]
|
||||
|
||||
testRange :: [ParseTest A.Expression]
|
||||
|
|
|
@ -167,6 +167,11 @@ makeLiteralString str = A.Literal emptyMeta (A.Array [A.Dimension (length str)]
|
|||
makeLiteralStringPattern :: String -> Pattern
|
||||
makeLiteralStringPattern = (stopCaringPattern emptyMeta) . mkPattern . makeLiteralString
|
||||
|
||||
-- | Creates a 'Pattern' to match an 'A.Expression' instance.
|
||||
-- All meta tags are ignored
|
||||
makeLiteralCharPattern :: Char -> Pattern
|
||||
makeLiteralCharPattern c = tag3 A.Literal DontCare A.Byte (tag2 A.ByteLiteral DontCare [c])
|
||||
|
||||
-- | Asserts a comparison using a custom comparison function.
|
||||
-- @'assertCompareCustom' msg (==) x y@ will function the same (except for slightly different messages on failure) as @'assertEqual' msg x y@.
|
||||
assertCompareCustom ::
|
||||
|
|
Loading…
Reference in New Issue
Block a user