Untitled
unknown
plain_text
7 months ago
3.6 kB
13
Indexable
Never
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)))