COMP[39]161 Concepts of Programming Languages
Semester 2, 2018

Code (Week 6 Tuesday)

This code builds on the code from the Week 5 lecture.

module Week6 where

data Type = IntTy | BoolTy | FunTy Type Type deriving (Eq)
data Expr = Num Int | Lit Bool 
          | Plus Expr Expr 
          | LessEq Expr Expr 
          | If Expr Expr Expr 
          | Apply Expr Expr 
          | Recfun Type Type (Expr -> Expr -> Expr)

data Frame = PlusF1 Expr | PlusF2 Value 
           | LessEqF1 Expr | LessEqF2 Value 
           | IfF Expr Expr 
           | ApplyF1 Expr | ApplyF2 Value 

type Stack = [Frame]  
data State = Evaluate Stack Expr
           | Return   Stack Value 
data Value = IntV Int | BoolV Bool | FunV (Expr -> Expr -> Expr)

prettyValue :: Value -> String 
prettyValue v = prettyPrint 0 (uneval v)

evalC :: Expr -> Value 
evalC expr = go (Evaluate [] expr)
  where
    go (Return [] v) = v
    go s = go (oneStep s)

oneStep :: State -> State 
oneStep (Evaluate s (Num n)) = Return s (IntV n)
oneStep (Evaluate s (Lit b)) = Return s (BoolV b)
oneStep (Evaluate s (Plus e1 e2)) = Evaluate (PlusF1 e2:s) e1
oneStep (Return (PlusF1 e2:s) v1) = Evaluate (PlusF2 v1:s) e2
oneStep (Return (PlusF2 (IntV v1):s) (IntV v2)) = Return s (IntV (v1 + v2))
oneStep (Evaluate s (LessEq e1 e2)) = Evaluate (LessEqF1 e2:s) e1
oneStep (Return (LessEqF1 e2:s) v1) = Evaluate (LessEqF2 v1:s) e2
oneStep (Return (LessEqF2 (IntV v1):s) (IntV v2)) = Return s (BoolV (v1 <= v2))
oneStep (Evaluate s (If e1 e2 e3)) = Evaluate (IfF e2 e3:s) e1
oneStep (Return (IfF e2 e3:s) (BoolV v)) = if v then Evaluate s e2 
                                                else Evaluate s e3
oneStep (Evaluate s (Recfun _ _ abs)) = Return s (FunV abs)
oneStep (Evaluate s (Apply e1 e2)) = Evaluate (ApplyF1 e2 : s) e1
oneStep (Return (ApplyF1 e2 : s) v1) = Evaluate (ApplyF2 v1 : s) e2
oneStep (Return (ApplyF2 (FunV abs) : s) v1) 
  = Evaluate s (abs (uneval (FunV abs)) (uneval v1))

uneval :: Value -> Expr 
uneval (IntV n) = Num n
uneval (BoolV b) = Lit b 
uneval (FunV abs) = Recfun (error "Don't look at this") 
                           (error "Don't look at this") abs

2018-11-16 Fri 19:37

Announcements RSS