-- Sample implementation of classic OO patterns in FLP. -- It includes: Composite, Interpreter and Visitor. -- Sergio Antoy & Michael Hanus -- July 24, 2001 -- Updated Mon Apr 18 09:03:37 PDT 2011 import Expr import Store -- Composite-like representation of the abstract syntax of a -- small *while* language. The language's only type is integer. -- As typical, true is represented by 1, false by 0. data Statement = Assign String Expr | While Expr Statement | Compound [Statement] | Print Expr -- extend the abstract syntax as needed -- | IfThenElse Expr Statement Statement -- Interpret a statement. This function takes a statement and the -- environment, the state of the program. It returns a pair -- consisting of the updated environment and any output -- produced by the statement. interpret (Print expr) env = (env, [show (evaluate expr env)]) interpret (Assign var expr) env = (set var (evaluate expr env) env, []) interpret (While expr stat) env = if evaluate expr env == 0 then (env, []) -- else interpret (Compound [stat, While expr stat]) env else let (env1,out1) = interpret stat env (env2,out2) = interpret (While expr stat) env1 in (env2, out1++out2) interpret (Compound stats) env = aux stats env where aux [] env = (env, []) aux (s:ss) env = let (env1,out1) = interpret s env (env2,out2) = aux ss env1 in (env2, out1++out2) -- pretty print a program prettyPrint prog = [""] ++ pp 0 prog where indent i = if i<=0 then "" else " " ++ indent (i-1) pp i (Print expr) = [indent i ++ "print " ++ show expr] pp i (Assign var expr) = [indent i ++ var ++ " := " ++ show expr] pp i (While expr stat) = [indent i ++ "while " ++ show expr ++ " do"] ++ pp (i+1) stat pp i (Compound stats) = [indent i ++ "begin"] ++ ppc (i+1) stats ++ [indent i ++ "end"] where ppc _ [] = [] ppc i (s:ss) = pp i s ++ ppc i ss -- Run a program (statement) by interpreting it with the initially empty store -- and ignoring the modified store at the end: run :: Statement -> IO () run prog = (putStr . unlines . snd) (interpret prog init_store)