-------------------------                                                 -- 001
-- Arithmetic Expressions                                                 -- 002
-------------------------                                                 -- 003
                                                                          -- 004
                                                                          -- 005
-- values are always integers (for now)                                   -- 006
type Value = Integer                                                      -- 007
                                                                          -- 008
--------------------------------------------------------------------      -- 009
-- Abstract Syntax Tree for Expressions                                   -- 010
data Exp = ExpN String           -- constants                             -- 011
         | ExpAdd Exp Exp        -- e1 + e2                               -- 012
         | ExpSub Exp Exp        -- e1 - e2                               -- 013
         | ExpMul Exp Exp        -- e1 * e2                               -- 014
         | ExpDiv Exp Exp        -- e1 / e2                               -- 015
         | ExpNeg Exp            -- -e                                    -- 016
                                                                          -- 017
-- Evaluates an expression                                                -- 018
evalExp :: Exp -> Value                                                   -- 019
                                                                          -- 020
evalExp (ExpN num) = val num 0                                            -- 021
  where val [] acc = acc                                                  -- 022
        val (x:xs) acc = val xs (acc * 10 + dig x)                        -- 023
        dig x = toInteger (fromEnum x - fromEnum '0')                     -- 024
evalExp (ExpAdd e1 e2) = (evalExp e1) + (evalExp e2)                      -- 025
evalExp (ExpSub e1 e2) = (evalExp e1) - (evalExp e2)                      -- 026
evalExp (ExpMul e1 e2) = (evalExp e1) * (evalExp e2)                      -- 027
evalExp (ExpDiv e1 e2) = (evalExp e1)  `div` (evalExp e2)                 -- 028
evalExp (ExpNeg e) = -(evalExp e)                                         -- 029
                                                                          -- 030
                                                                          -- 031
-------------------------------------------------------------------       -- 032
-------------------------------------------------------------------       -- 033
-- an example                                                             -- 034
                                                                          -- 035
-- 34 + 52 * 3                                                            -- 036
exp1 = ExpAdd (ExpN "34") (ExpMul (ExpN "52") (ExpN "3"))                 -- 037
                                                                          -- 038
                                                                          -- 039
-- code to show the value of an expression                                -- 040
main :: IO ()                                                             -- 041
main = print (evalExp exp1)                                               -- 042
                                                                          -- 043