Untitled

 avatar
unknown
plain_text
2 years ago
3.6 kB
14
Indexable
open Common;;

let const_to_val c = raise (Failure "Not implemented yet.")

let monOpApply op v = match op with 
  | HdOp -> (match v with | ListVal (hd::tl) -> hd | ListVal [] -> Exn 0)
  | TlOp -> (match v with | ListVal (hd::tl) -> ListVal tl | ListVal [] -> Exn 0)
  | FstOp -> (match v with | PairVal (x, y) -> x)
  | SndOp -> (match v with | PairVal (x, y) -> y)
  | IntNegOp -> (match v with | IntVal i -> IntVal (-i))
  | PrintOp -> (match v with | StringVal s -> print_string s; UnitVal)

let binOpApply binop (v1,v2) = match binop with 
  | IntPlusOp -> (match v1 with IntVal i1  -> (match v2 with IntVal i2 -> IntVal (i1 + i2)))
  | IntMinusOp -> (match v1 with IntVal i1 -> (match v2 with IntVal i2 -> IntVal (i1 - i2)))
  | IntTimesOp -> (match v1 with IntVal i1 -> (match v2 with IntVal i2 -> IntVal (i1 * i2)))
  | IntDivOp -> (match v1 with IntVal i1 -> (match v2 with IntVal i2 -> if i2 = 0 then Exn 0 else IntVal (i1 / i2)))
  | ModOp -> (match v1 with IntVal i1 -> (match v2 with IntVal i2 -> IntVal (i1 mod i2)))
  | FloatPlusOp -> (match v1 with FloatVal f1 -> (match v2 with FloatVal f2 -> FloatVal (f1 +. f2)))
  | FloatMinusOp -> (match v1 with FloatVal f1 -> (match v2 with FloatVal f2 -> FloatVal (f1 -. f2)))
  | FloatTimesOp -> (match v1 with FloatVal f1 -> (match v2 with FloatVal f2 -> FloatVal (f1 *. f2)))
  | ExpoOp -> (match v1 with FloatVal f1 -> (match v2 with FloatVal f2 -> FloatVal (f1 ** f2)))
  | FloatDivOp -> (match v1 with FloatVal f1 -> (match v2 with FloatVal f2 -> if f2 = 0.0 then Exn 0 else FloatVal (f1 /. f2)))
  | ConcatOp -> (match v1 with StringVal s1 -> (match v2 with StringVal s2 -> StringVal (s1 ^ s2)))
  | ConsOp -> (match v2 with ListVal l -> ListVal (v1 :: l))
  | CommaOp -> PairVal (v1, v2)
  | EqOp -> BoolVal (v1 = v2)
  | GreaterOp -> BoolVal (v1 > v2)



let const_to_val c = match c with 
  | IntConst c -> IntVal c 
  | FloatConst c -> FloatVal c
  | BoolConst c -> BoolVal c
  | StringConst c -> StringVal c 
  | UnitConst -> UnitVal
  | NilConst -> ListVal []

let rec eval_exp (exp, m) = match exp with 
  | ConstExp c -> const_to_val c 
  | VarExp x -> let v = lookup_mem m x in (match v with 
                | RecVarVal (g, y, e, m') -> Closure (y, e, ins_env m' g (RecVarVal (g, y, e, m')) )
                | _ -> v)
  | MonOpAppExp (mon, e) -> let v = eval_exp (e, m) in (match v with Exn i -> Exn i | _ -> monOpApply mon v)
  | BinOpAppExp (op, e1, e2) -> let v1 = (eval_exp (e1, m)) in (match v1 with Exn i -> Exn i | _ -> let v2 = (eval_exp (e2, m)) in (match v2 with Exn i -> Exn i | _ -> binOpApply op (v1, v2)))
  | IfExp (e1, e2, e3) -> let cond = eval_exp (e1, m) in (match cond with | Exn i -> Exn i | BoolVal b -> 
                          if b then eval_exp (e2, m) else eval_exp (e3, m))
  | LetInExp (x, e1, e2) -> let v1 = eval_exp (e1, m) in (match v1 with Exn i -> Exn i | _ -> eval_exp (e2, (ins_env m x v1)))
  | FunExp (x, e) -> Closure (x, e, m)
  | AppExp (e1, e2) -> let v1 = eval_exp (e1, m) in (match v1 with Exn i -> Exn i | Closure (x, e', m') -> 
                       let v' = eval_exp (e2, m) in (match v' with Exn i -> Exn i | _ -> eval_exp (e', (ins_env m' x v')) | Exn (i) -> Exn (i)))
  | LetRecInExp (f, x, e1, e2) -> eval_exp (e2, ins_env m f (RecVarVal (f, x, e1, m)))
  | RaiseExp e -> let v = eval_exp (e, m) in (match v with | IntVal n -> Exn n | Exn i -> Exn i)
  |



let eval_dec (dec, m) = match dec with 
  | Anon e -> ((None, eval_exp(e, m)), m)
  | Let (x, e) -> let v = eval_exp (e, m) in ((Some x, v), (ins_env m x v))
  | LetRec (f, x, e) -> ((Some f, RecVarVal (f, x, e, m)), ins_env m f (RecVarVal (f, x, e, m)))