module Expr where import SimpleLexer import Maybe pupd1 f (x,y) = (f x, y) data Op = MkOp String deriving Show data Expr = Var String | Num Integer | Bin Expr Op Expr deriving Show expr1 = Bin (Bin (Var "a") (MkOp "+") (Var "b") ) (MkOp "*") (Var "c") plus x y = Bin x (MkOp "+") y mult x y = Bin x (MkOp "*") y expr2 = (Var "a" `plus` Var "b") `mult` Var "c" showExpr :: Expr -> String showExpr (Var v) = v showExpr (Num n) = show n showExpr (Bin e1 op e2) = '(' : showExpr e1 ++ showOp op ++ showExpr e2 ++ ")" showOp :: Op -> String showOp (MkOp s) = s parseFactor :: [Token] -> Maybe (Expr, [Token]) parseFactor ((Ident v) : rest) = Just (Var v, rest) parseFactor ((Number n) : rest) = Just (Num n, rest) parseFactor ((Sep '(') : rest) = case parseExpr rest of Just (e, Sep ')' : rest1) -> Just (e, rest1) _ -> Nothing parseFactor _ = Nothing parseAddOp :: [Token] -> Maybe (Op, [Token]) parseAddOp ((Sep '+') : rest) = Just (MkOp "+", rest) parseAddOp ((Sep '-') : rest) = Just (MkOp "-", rest) parseAddOp _ = Nothing parseMultOp :: [Token] -> Maybe (Op, [Token]) parseMultOp ((Sep '*') : rest) = Just (MkOp "*", rest) parseMultOp ((Sep '/') : rest) = Just (MkOp "/", rest) parseMultOp _ = Nothing parseExpr1 :: [Token] -> Maybe (Expr, [Token]) parseExpr1 input = case parseTerm input of Nothing -> Nothing Just (e1, rest1) -> case parseAddOp rest1 of Nothing -> Just (e1, rest1) Just (op, rest2) -> case parseExpr1 rest2 of Nothing -> Nothing -- Syntax Error! Just (e2, rest3) -> Just ( Bin e1 op e2, rest3) parseExpr2 :: [Token] -> Maybe (Expr, [Token]) parseExpr2 input = case parseExpr2 input of Nothing -> parseTerm input Just (e1, rest1) -> case parseAddOp rest1 of Nothing -> Just (e1, rest1) Just (op, rest2) -> case parseTerm rest2 of Nothing -> parseTerm input Just (e2, rest3) -> Just ( Bin e1 op e2, rest3) parseExpr :: [Token] -> Maybe (Expr, [Token]) parseExpr = parseTerms id parseTerms :: (Expr -> Expr) -> [Token] -> Maybe (Expr, [Token]) parseTerms wrap input = case parseTerm input of Nothing -> Nothing Just (e1, rest1) -> case parseAddOp rest1 of Nothing -> Just (wrap e1, rest1) Just (op, rest2) -> parseTerms (Bin (wrap e1) op) rest2 parseTerm :: [Token] -> Maybe (Expr, [Token]) parseTerm = parseFactors id parseFactors :: (Expr -> Expr) -> [Token] -> Maybe (Expr, [Token]) parseFactors wrap input = case parseFactor input of Nothing -> Nothing Just (e1, rest1) -> case parseMultOp rest1 of Nothing -> Just (wrap e1, rest1) Just (op, rest2) -> parseFactors (Bin e1 op) rest2