{- Elm Arithmetic Expression Evaluator CSci 450, Fall 2016 2016-11-26: H. Conrad Cunningham -} import Html exposing (..) -- Aritmetic expressions algebraic data type type Expr = Const Int | Var String | Neg Expr | Add Expr Expr | Sub Expr Expr | Mul Expr Expr | Div Expr Expr | Eq Expr Expr | Lt Expr Expr -- Environments mapping names to values type alias Env = List (String,Int) -- Function lookup looks up name in environment env and returns the -- value wrapped in a Maybe where Nothing means the value was not -- found in the environment. lookup : Env -> String -> Maybe Int lookup env name = let hasName t = Tuple.first t == name vals = List.filter hasName env in Maybe.map Tuple.second (List.head vals) -- Function asInt converts Bool value False to 0 and True to 1. asInt : Bool -> Int asInt b = case b of False -> 0 True -> 1 -- Function eval evaluates expression e in environment env and returns -- the resulting value. If a variable is undefined, then it evaluates -- to value 0. eval : Expr -> Env -> Int eval e env = case e of Const i -> i Var n -> Maybe.withDefault 0 (lookup env n) Neg e1 -> negate (eval e1 env) Add e1 e2 -> (eval e1 env) + (eval e2 env) Sub e1 e2 -> (eval e1 env) - (eval e2 env) Mul e1 e2 -> (eval e1 env) * (eval e2 env) Div e1 e2 -> (eval e1 env) // (eval e2 env) Eq e1 e2 -> asInt ((eval e1 env) == (eval e2 env)) Lt e1 e2 -> asInt ((eval e1 env) < (eval e2 env)) -- Simple Display Functions newline = br [] [] displayLines : List String -> List (Html msg) displayLines ss = case ss of [] -> [] x :: xs -> text x :: newline :: displayLines xs display : List String -> Html msg display ls = p [] (displayLines ls) -- Some testing env1 = [("x",2)] five = Const 5 three = Const 3 varx = Var "x" ex1 = Neg five ex2 = Add five ex1 ex3 = Sub five five ex4 = Mul five ex3 ex5 = Eq five five ex6 = Eq five three ex7 = Lt five three ex8 = Lt three five main = display [ "Start!" , toString five ++ " -> " ++ toString (eval five env1) , toString three ++ " -> " ++ toString (eval three env1) , toString varx ++ " -> " ++ toString (eval varx env1) , toString ex1 ++ " -> " ++ toString (eval ex1 env1) , toString ex2 ++ " -> " ++ toString (eval ex2 env1) , toString ex3 ++ " -> " ++ toString (eval ex3 env1) , toString ex4 ++ " -> " ++ toString (eval ex4 env1) , toString ex5 ++ " -> " ++ toString (eval ex5 env1) , toString ex6 ++ " -> " ++ toString (eval ex6 env1) , toString ex7 ++ " -> " ++ toString (eval ex7 env1) , toString ex8 ++ " -> " ++ toString (eval ex8 env1) , "Done!" ]