diff --git a/LexRain.x b/LexRain.x index da870e3..54e44a0 100644 --- a/LexRain.x +++ b/LexRain.x @@ -37,6 +37,7 @@ $hexDigit = [0-9 a-f A-F] | "+" | "-" | "*" | "/" | "%" | ">=" | "<=" | "<" | ">" + | ".." | "process" | "pareach" | "seqeach" | "par" | "seq" | "run" | "if" | "while" | "else" diff --git a/RainParse.hs b/RainParse.hs index 693bf36..628762a 100644 --- a/RainParse.hs +++ b/RainParse.hs @@ -66,6 +66,7 @@ sColon = reserved ":" sComma = reserved "," sIn = reserved "?" sOut = reserved "!" +sDots = reserved ".." --}}} --{{{ Keywords @@ -198,13 +199,19 @@ integer testToken (L.TokDecimalLiteral d) = Just d testToken _ = Nothing +integerLiteral :: RainParser A.Expression +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 {i <- integer ; return $ A.Literal (findMeta i) A.Int i} + <|> integerLiteral <|> do {m <- reserved "true" ; return $ A.True m} <|> do {m <- reserved "false" ; return $ A.False m} "literal" +range :: RainParser A.Expression +range = try $ do {m <- sLeftQ ; begin <- integerLiteral; sDots ; end <- integerLiteral ; sRightQ ; return $ A.ExprConstr m $ A.RangeConstr m begin end} + expression :: RainParser A.Expression expression = try compExpression @@ -231,6 +238,7 @@ expression subExpr' :: RainParser A.Expression subExpr' = do {id <- variableId ; return $ A.ExprVariable (findMeta id) id} <|> literal + <|> range <|> do {(m,op) <- monadicArithOp ; rhs <- subExpr' ; return $ A.Monadic m op rhs} <|> do {sLeftR ; e <- expression ; sRightR ; return e} diff --git a/RainParseTest.hs b/RainParseTest.hs index d576593..7c17100 100644 --- a/RainParseTest.hs +++ b/RainParseTest.hs @@ -216,6 +216,16 @@ testLiteral = ] +testRange :: [ParseTest A.Expression] +testRange = + [ + pass("[0..1]", RP.expression, assertPatternMatch "testRange 0" $ tag2 A.ExprConstr DontCare $ tag3 A.RangeConstr DontCare (intLiteralPattern 0) (intLiteralPattern 1)) + ,pass("[0..10000]", RP.expression, assertPatternMatch "testRange 0" $ tag2 A.ExprConstr DontCare $ tag3 A.RangeConstr DontCare (intLiteralPattern 0) (intLiteralPattern 10000)) + ,pass("[-3..-1]", RP.expression, assertPatternMatch "testRange 0" $ tag2 A.ExprConstr DontCare $ tag3 A.RangeConstr DontCare (intLiteralPattern $ -3) (intLiteralPattern $ -1)) + --For now, at least, this should fail: + ,fail("[0..x]", RP.expression) + ] + --Helper function for ifs: makeIf :: [(A.Expression,A.Process)] -> A.Process makeIf list = A.If m $ A.Several m (map makeChoice list) @@ -518,6 +528,7 @@ tests = TestList [ parseTests testExprs, parseTests testLiteral, + parseTests testRange, parseTests testWhile, parseTests testSeq, parseTests testPar,