Parse defs and externs
authorLuke Lau <luke_lau@icloud.com>
Sat, 18 May 2019 16:54:06 +0000 (17:54 +0100)
committerLuke Lau <luke_lau@icloud.com>
Sat, 18 May 2019 22:36:09 +0000 (23:36 +0100)
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

diff --git a/AST.hs b/AST.hs
index c766afc1570140a77690e9f19259a68def0ac967..7dad3a19e91eab9f12657101bd224b5c81742d07 100644 (file)
--- 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