X-Git-Url: https://git.lukelau.me/?p=kaleidoscope-hs.git;a=blobdiff_plain;f=AST.hs;h=c766afc1570140a77690e9f19259a68def0ac967;hp=5628e7c7cd74c8d0f04d5b4e9c908e245e5696f6;hb=45afeea77cd017d2ac37cf330c595c22c90a7f87;hpb=ae80d076cba678169dbddac4a53edd2cb1e091fb diff --git a/AST.hs b/AST.hs index 5628e7c..c766afc 100644 --- a/AST.hs +++ b/AST.hs @@ -1,23 +1,35 @@ module AST where import Text.Read -import Text.ParserCombinators.ReadP hiding ((+++)) +import Text.ParserCombinators.ReadP hiding ((+++), choice) data Expr = Num Float - | Add Expr Expr + | Var String + | BinOp BinOp Expr Expr + deriving Show + +data BinOp = Add | Sub | Mul | Cmp Ordering deriving Show instance Read Expr where - readPrec = parseNum +++ parseAdd + readPrec = choice [ parseNum + , parseVar + , parseBinOp "<" 10 (Cmp LT) + , parseBinOp "+" 20 Add + , parseBinOp "-" 20 Sub + , parseBinOp "*" 40 Mul + ] 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 - parseAdd = prec 1 $ do + parseBinOp s prc op = prec prc $ do a <- step readPrec lift $ do skipSpaces - char '+' + string s skipSpaces b <- readPrec - return (Add a b) + return (BinOp op a b) +