69 lines
1.9 KiB
Text
69 lines
1.9 KiB
Text
data Exp where
|
|
-- Integer for the variable name to be able to use (==)
|
|
-- as we do not have type classes.
|
|
EVar : Int -> Exp
|
|
EInt : Int -> Exp
|
|
EAbs : Int -> Exp -> Exp
|
|
EApp : Exp -> Exp -> Exp
|
|
EAdd : Exp -> Exp -> Exp
|
|
|
|
data Pair a b where
|
|
Pair : a -> b -> Pair a b
|
|
|
|
data Env where
|
|
Env : List (Pair Int Val) -> Env
|
|
|
|
data Val where
|
|
VInt : Int -> Val
|
|
VClos : Env -> Int -> Exp -> Val
|
|
|
|
printExp : Exp -> Unit
|
|
printExp exp = case exp of
|
|
EInt _ => printStr "EInt\n"
|
|
EAdd _ _ => printStr "EAdd\n"
|
|
EAbs _ _ => printStr "EAbs\n"
|
|
EApp _ _ => printStr "EApp\n"
|
|
EVar _ => printStr "EVar\n"
|
|
|
|
const x y = x
|
|
|
|
-- interp : Env -> Exp -> Val
|
|
interp env exp = case const exp (printExp exp) of
|
|
EInt i => VInt i
|
|
EAdd e1 e2 => case interp env e1 of
|
|
VInt i => case interp env e2 of
|
|
VInt j => VInt (i + j)
|
|
EAbs ident expr => VClos env ident expr
|
|
EApp e1 e2 => case interp env e1 of
|
|
VClos closEnv ident exp => case interp env e2 of
|
|
v => interp (insert ident v closEnv) exp
|
|
-- Crash of incorrect program
|
|
EVar v => lookupVar v env
|
|
|
|
-- lookupVar : Int -> Env -> Val
|
|
lookupVar ident env = case env of
|
|
Env list => case list of
|
|
Cons a as => case a of
|
|
Pair identy val => case ident == identy of
|
|
True => val
|
|
False => lookupVar ident (Env as)
|
|
-- If the variable does not exist in
|
|
-- the context then we just crash the program
|
|
|
|
-- insert : Int -> Val -> Env -> Env
|
|
insert ident v env = case env of
|
|
Env list => Env (Cons (Pair ident v) list)
|
|
|
|
-- eval : Val -> Int
|
|
eval v = case v of
|
|
VInt i => i
|
|
-- Fail unless the final value is an integer
|
|
|
|
-- expression : Exp
|
|
expression = EApp (EAbs 0 (EAdd (EVar 0) (EInt 20))) (EInt 123)
|
|
|
|
-- context : Env
|
|
context = Env Nil
|
|
|
|
-- main : Int
|
|
main = eval (interp context expression)
|