1 module Interpreter(interp) where
    2 
    3 import Syntax    (Command(..), Expr(..), Name)
    4 import Behaviour (Trace(..), (+++))
    5 import Value     (Value(Bol, Wrong), uno, duo)
    6 
    7 type Env = [(Name,Value)]
    8 
    9 interp :: Command -> Trace Value
   10 interp p = fst (run p [])
   11 
   12 look :: Name -> Env -> Value
   13 look x s = maybe Wrong id (lookup x s)
   14 
   15 update :: Name -> Value -> Env -> Env
   16 update x a s = (x,a) : filter (\(y,_) -> y/=x) s
   17 
   18 run :: Command -> Env -> (Trace Value, Env)
   19 run Skip        s = (End, s)
   20 run (x := e)    s = (End, update x (eval e s) s)
   21 run (p :-> q)   s = let (outp, sp) = run p s
   22                         (outq, sq) = run q sp
   23                     in (outp +++ outq, sq)
   24 run (If e p q)  s = case eval e s of
   25                     Bol True  -> run p s
   26                     Bol False -> run q s
   27                     _         -> (Crash, s)
   28 run (While e p) s = case eval e s of
   29                     Bol True  -> let (outp,sp) = run p s
   30                                      (outw,sw) = run (While e p) sp
   31                                  in (outp +++ Step outw, sw)
   32                     Bol False -> (End, s)
   33                     _         -> (Crash, s)
   34 run (Print e)   s = (eval e s :> End, s)
   35 
   36 eval :: Expr -> Env -> Value
   37 eval (Var x)      s = look x s
   38 eval (Val v)      s = v
   39 eval (Uno op a)   s = uno op (eval a s)
   40 eval (Duo op a b) s = duo op (eval a s) (eval b s)