{- * Copyright (c): Uwe Schmidt, FH Wedel * * You may study, modify and distribute this source code * FOR NON-COMMERCIAL PURPOSES ONLY. * This copyright message has to remain unchanged. * * Note that this document is provided 'as is', * WITHOUT WARRANTY of any kind either expressed or implied. -} module Expr0 where import ShowTree data Expr = Const Int | Bin Op2 Expr Expr | Un Op1 Expr deriving (Show) data Op2 = Add | Sub | Mul | Div deriving (Show) data Op1 = Plus | Minus | Abs deriving (Show) eval :: Expr -> Int eval (Const n) = n eval (Bin op e1 e2) = apply2 op (eval e1) (eval e2) eval (Un op e1) = apply1 op (eval e1) apply2 :: Op2 -> (Int -> Int -> Int) apply2 Add = (+) apply2 Sub = (-) apply2 Mul = (*) apply2 Div = div apply1 :: Op1 -> (Int -> Int) apply1 Plus = id apply1 Minus = \ x -> 0 - x apply1 Abs = abs -- ---------------------------------------- -- -- example expr e1 :: Expr e1 = Bin Mul (Un Abs (Bin Sub (Const 1) (Const 8) ) ) (Bin Div (Const 13) (Const 2) ) v1 :: Int v1 = eval e1 -- ---------------------------------------- -- -- pretty printing expr prettyExpr :: Expr -> String prettyExpr (Const n) = show n prettyExpr (Bin op e1 e2) = "(" ++ prettyExpr e1 ++ " " ++ prettyOp2 op ++ " " ++ prettyExpr e2 ++ ")" prettyExpr (Un op e1) = "(" ++ prettyOp1 op ++ prettyExpr e1 ++ ")" prettyOp2 :: Op2 -> String prettyOp2 Add = "+" prettyOp2 Sub = "-" prettyOp2 Mul = "*" prettyOp2 Div = "`div`" prettyOp1 Plus = "+" prettyOp1 Minus = "-" prettyOp1 Abs = "abs " -- ---------------------------------------- -- -- pseudo graphical tree output for expr showExpr :: Expr -> String showExpr = formatStringNTree . toNTree where toNTree (Const n) = NTree (show n) [] toNTree (Bin op2 e1 e2) = NTree (show op2) [toNTree e1, toNTree e2] toNTree (Un op1 e1) = NTree (show op1) [toNTree e1] printExpr :: Expr -> IO () printExpr = putStrLn . showExpr -- ----------------------------------------