X-Git-Url: http://git.lukelau.me/?a=blobdiff_plain;f=AST.hs;h=e491b648a7d45f7bd3b419b0e3ff6a8c215cbd83;hb=2f3c8f5cb6c8b9e6f5be02b20910f8105a9011a6;hp=5b22ea6c662714d483f1dd1ec51755e5f4b7dc7a;hpb=d6cecbbf067560322e391363250fd3c5d45bfbec;p=kaleidoscope-hs.git diff --git a/AST.hs b/AST.hs index 5b22ea6..e491b64 100644 --- a/AST.hs +++ b/AST.hs @@ -1,9 +1,11 @@ module AST where +import Data.Char import Text.Read import Text.ParserCombinators.ReadP hiding ((+++), choice) data Expr = Num Float + | Var String | BinOp BinOp Expr Expr deriving Show @@ -11,16 +13,15 @@ data BinOp = Add | Sub | Mul | Cmp Ordering deriving Show instance Read Expr where - readPrec = choice [ parseNum + readPrec = parens $ choice [ parseNum + , parseVar , parseBinOp "<" 10 (Cmp LT) , parseBinOp "+" 20 Add , parseBinOp "-" 20 Sub , parseBinOp "*" 40 Mul ] where parseNum = Num <$> readPrec - -- use 'prec 1' and 'step' so that parsing 'a' - -- can only go one step deep, to prevent ininfite - -- recursion + parseVar = Var <$> lift (munch1 isAlpha) parseBinOp s prc op = prec prc $ do a <- step readPrec lift $ do @@ -30,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