X-Git-Url: https://git.lukelau.me/?p=kaleidoscope-hs-old.git;a=blobdiff_plain;f=AST.hs;h=1965ae6ba8378bc8277b2b46fe031ea04a64a5d5;hp=6528215422482fbfa3111faece64c3ff80205983;hb=808a6ae35fb1f2ff61a84991af1e7722298a4d62;hpb=a0b31174f4b7f6ac037dc4002c38cd61b09dabaa diff --git a/AST.hs b/AST.hs index 6528215..1965ae6 100644 --- a/AST.hs +++ b/AST.hs @@ -1,20 +1,63 @@ module AST where +import Data.Char import Text.Read -import Text.ParserCombinators.ReadP hiding ((+++)) +import Text.ParserCombinators.ReadP hiding ((+++), choice) +newtype Program = Program [AST] + deriving Show + +instance Read Program where + readPrec = fmap Program $ lift $ sepBy1 (readPrec_to_P readPrec 0) $ do + skipSpaces + char ';' + skipSpaces + +data AST = Function String [String] Expr + | Eval Expr + deriving Show data Expr = Num Float - | Add Expr Expr + | BinOp BinOpType Expr Expr + | Var String + | Call String [Expr] deriving Show +data BinOpType = Add | Sub | Mul + deriving Show + +instance Read AST where + readPrec = parseFunction +++ (Eval <$> readPrec) + where parseFunction = lift $ do + skipSpaces + string "def" + skipSpaces + name <- munch1 isAlpha + params <- between (char '(') (char ')') $ + sepBy (munch1 isAlpha) skipSpaces + skipSpaces + body <- readS_to_P reads + return (Function name params body) instance Read Expr where - readPrec = parseNum +++ parseAdd + readPrec = choice [ parseNum + , parseVar + , parseCall + , parseBinOp '+' Add + , parseBinOp '-' Sub + , parseBinOp '*' Mul + ] where parseNum = Num <$> readPrec - parseAdd = step $ do + parseVar = Var <$> lift (munch1 isAlpha) + parseCall = do + func <- lift (munch1 isAlpha) + params <- lift $ between (char '(') (char ')') $ + sepBy (readS_to_P reads) + (skipSpaces >> char ',' >> skipSpaces) + return (Call func params) + parseBinOp c typ = step $ do a <- prec 11 readPrec lift $ do skipSpaces - char '+' + char c skipSpaces b <- readPrec - return (Add a b) + return (BinOp typ a b)