X-Git-Url: https://git.lukelau.me/?p=kaleidoscope-hs-old.git;a=blobdiff_plain;f=AST.hs;h=73523d6d4c8a37cef977d5614d355aaac13756af;hp=2bea0028cf47bb61f94c982f011ca24b72a612ac;hb=fd502ca628b539cffbc38c21755ebaa615b30b72;hpb=98897ccc44795260735bafc5124e0e14052247f2 diff --git a/AST.hs b/AST.hs index 2bea002..73523d6 100644 --- a/AST.hs +++ b/AST.hs @@ -4,6 +4,15 @@ import Data.Char import Text.Read import Text.ParserCombinators.ReadP hiding ((+++), choice) +newtype Program = Program [AST] + deriving Show + +instance Read Program where + readPrec = fmap Program $ lift $ sepBy1 (readS_to_P reads) $ do + skipSpaces + char ';' + skipSpaces + data AST = Function String [String] Expr | Eval Expr deriving Show @@ -11,8 +20,9 @@ data Expr = Num Float | BinOp BinOpType Expr Expr | Var String | Call String [Expr] + | If Expr Expr Expr deriving Show -data BinOpType = Add | Sub | Mul +data BinOpType = Add | Sub | Mul | Cmp Ordering deriving Show instance Read AST where @@ -25,20 +35,25 @@ instance Read AST where params <- between (char '(') (char ')') $ sepBy (munch1 isAlpha) skipSpaces skipSpaces - body <- between (char '{') (char '}') $ - readS_to_P reads - skipSpaces + body <- readS_to_P reads return (Function name params body) instance Read Expr where - readPrec = choice [ parseNum + readPrec = choice [ parseParens + , parseNum , parseVar , parseCall - , parseBinOp '+' Add - , parseBinOp '-' Sub - , parseBinOp '*' Mul + , parseIf + , parseBinOp "+" Add + , parseBinOp "-" Sub + , parseBinOp "*" Mul + , parseBinOp ">" (Cmp GT) + , parseBinOp "<" (Cmp LT) + , parseBinOp "==" (Cmp EQ) ] - where parseNum = Num <$> readPrec + where parseParens = step $ lift $ + between (char '(') (char ')') (readS_to_P reads) + parseNum = Num <$> readPrec parseVar = Var <$> lift (munch1 isAlpha) parseCall = do func <- lift (munch1 isAlpha) @@ -46,11 +61,27 @@ instance Read Expr where sepBy (readS_to_P reads) (skipSpaces >> char ',' >> skipSpaces) return (Call func params) - parseBinOp c typ = step $ do + parseBinOp s typ = step $ do a <- prec 11 readPrec lift $ do skipSpaces - char c + string s skipSpaces b <- readPrec return (BinOp typ a b) + parseIf = do + lift $ do + string "if" + skipSpaces + cond <- step readPrec + lift $ do + skipSpaces + string "then" + skipSpaces + thenE <- step readPrec + lift $ do + skipSpaces + string "else" + skipSpaces + elseE <- step readPrec + return (If cond thenE elseE)