From 5b4118ef8c41e2e93b1257c4d62498cc44335cbd Mon Sep 17 00:00:00 2001 From: darkf Date: Fri, 18 Oct 2013 23:22:42 -0700 Subject: [PATCH] add initial parser --- parser.hs | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 parser.hs diff --git a/parser.hs b/parser.hs new file mode 100644 index 0000000..1548063 --- /dev/null +++ b/parser.hs @@ -0,0 +1,85 @@ +module Parser where + +import Text.Parsec +import Text.Parsec.String +import Text.Parsec.Expr +import qualified Text.Parsec.Token as T +import Text.Parsec.Language +import AST + +languageDef = emptyDef {T.commentStart="{-", + T.commentEnd="-}", + T.commentLine="--", + T.nestedComments=True, + T.identStart = letter <|> char '_', + T.identLetter = alphaNum <|> char '_', + T.reservedNames = ["do", "end", "(", ")", ";", "."], + T.reservedOpNames = ["+", "*"]} + +lexer = T.makeTokenParser languageDef +exprparser = buildExpressionParser ops term "expression" +ops = [ [Infix (reservedOp "*" >> return Mul) AssocLeft ] + , [Infix (reservedOp "+" >> return Add) AssocLeft] + ] + +identifier = T.identifier lexer -- parses an identifier +reserved = T.reserved lexer -- parses a reserved name +reservedOp = T.reservedOp lexer -- parses an operator +parens = T.parens lexer -- parses surrounding parenthesis +integer = T.integer lexer -- parses an integer +semi = T.semi lexer -- parses a semicolon +whiteSpace = T.whiteSpace lexer -- parses whitespace +symbol = T.symbol lexer + +statement = + do + e <- exprparser + -- char ';' + return e + +block = do + reserved "do" + lst <- seqStmt + reserved "end" + return $ Block lst + +funDef = do + name <- identifier + reserved "(" + reserved ")" + reserved "->" + lst <- exprparser + return $ rewriteFun (FunDef name (UnitP, lst)) + +-- curry FunDef to a definition of lambdas +rewriteFun (FunDef name (pattern, body)) = + Def name $ Lambda [(pattern, [body])] + +call = do + name <- identifier + whiteSpace + char '(' + char ')' + whiteSpace + return $ Call name [UnitConst] + +term = block + <|> try funDef + <|> try call + <|> parens exprparser + <|> fmap Var identifier + <|> fmap IntConst integer + +manyExpr = many1 exprparser + +seqStmt = do + lst <- sepBy1 statement semi + return lst + +program = + many1 $ do + e <- exprparser + reserved "." + return e + +parseProgram = parse program "program" \ No newline at end of file