From 8a66ac4f81c3d1eab3b13a9e58cee0098573eff1 Mon Sep 17 00:00:00 2001 From: Luke Lau Date: Sat, 18 May 2019 17:54:06 +0100 Subject: [PATCH] Parse defs and externs They both share a common prototype so we can split that out into a separate definition. We also want to be able to parse top level expressions, so we add constructor for that in AST. Hopefully now you can see the beauty of monadic parsing: Function <$> readPrec <*> readPrec --- AST.hs | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-) diff --git a/AST.hs b/AST.hs index c766afc..7dad3a1 100644 --- a/AST.hs +++ b/AST.hs @@ -1,5 +1,6 @@ module AST where +import Data.Char import Text.Read import Text.ParserCombinators.ReadP hiding ((+++), choice) @@ -21,9 +22,6 @@ instance Read Expr where ] where parseNum = Num <$> readPrec parseVar = Var <$> lift (munch1 isAlpha) - -- use 'prec 1' and 'step' so that parsing 'a' - -- can only go one step deep, to prevent ininfite - -- recursion parseBinOp s prc op = prec prc $ do a <- step readPrec lift $ do @@ -33,3 +31,27 @@ instance Read Expr where b <- readPrec return (BinOp op a b) +data Prototype = Prototype String [String] + deriving Show + +instance Read Prototype where + readPrec = lift $ do + name <- munch1 isAlpha + params <- between (char '(') (char ')') $ + sepBy (munch1 isAlpha) skipSpaces + return (Prototype name params) + +data AST = Function Prototype Expr + | Extern Prototype + | TopLevelExpr Expr + deriving Show + +instance Read AST where + readPrec = parseFunction +++ parseExtern +++ parseTopLevel + where parseFunction = do + lift $ string "def" >> skipSpaces + Function <$> readPrec <*> readPrec + parseExtern = do + lift $ string "extern" >> skipSpaces + Extern <$> readPrec + parseTopLevel = TopLevelExpr <$> readPrec -- 2.30.2