Untitled

mail@pastecode.io avatar
unknown
plain_text
2 years ago
2.7 kB
10
Indexable
(* File: one_step_exp_cps_eval.ml *)

open Common;;

let rec app_exn_handler env ex_k i = (match ex_k with 
  | ExnContVarCPS exi -> (match lookup_exn_cont env exi with 
    | None -> Failed 
    | Some (_k, _env) -> app_exn_handler _env _k i
  )
  | EmptyExnContCPS -> UncaughtException i
  | UpdateExnContCPS (l, _k) -> 
    let rec find_ex l i = (match l with 
      | [] -> app_exn_handler env _k i 
      | (None, v)::rem -> Intermediate (env, v) 
      | (n, v)::rem -> if n = Some i then Intermediate (env, v) else find_ex rem i 
    ) in find_ex l i 
)

let rec app_cont_to_value env k v = match k with 
  | External -> Final v
  | ContVarCPS (_k) -> (match lookup_cont env _k with 
    | None -> Failed 
    | Some (_k, _env) -> app_cont_to_value _env _k v)
  | FnContCPS (y, e) -> Intermediate((ValueBinding (y, v))::env, e)
  | ExnMatch ex_k -> (match v with 
    | IntVal i -> app_exn_handler env ex_k i 
    | _ -> Failed
  )


let rec one_step_exp_cps_eval env exp_cps = match exp_cps with 
  | ConstCPS (k, c) -> app_cont_to_value env k (const_to_val c)
  | VarCPS (k, x) -> (match lookup_value env x with | None -> Failed | Some v -> app_cont_to_value env k v)
  | MonOpAppCPS (k, op, x, e) -> (match lookup_value env x with 
    | None -> Failed 
    | Some v -> (match monOpApply op v with 
      | Exn n -> app_exn_handler env e n
      | Value v' -> app_cont_to_value env k v'
      ) 
    )
  | BinOpAppCPS (k, op, x, y, e) -> (match (lookup_value env x, lookup_value env y) with 
    | None, None | None, _ | _, None -> Failed 
    | Some v1, Some v2 -> (match binOpApply op v1 v2 with 
      | Exn n -> app_exn_handler env e n 
      | Value v -> app_cont_to_value env k v 
      )
    )
  | IfCPS (b, e1, e2) -> (match lookup_value env b with 
      | Some (BoolVal true) -> Intermediate (env, e1)
      | Some (BoolVal false) -> Intermediate (env, e2)
      | _ -> Failed
    )
  | FunCPS (k, x, ek, e, p) -> app_cont_to_value env k (CPSClosureVal (x, ek, e, p, env))
  | FixCPS (k, f, x, ek, e, p) -> app_cont_to_value env k (CPSRecClosureVal (f, x, ek, e, p, env))
  | AppCPS (k, f, x, eps) -> (match lookup_value env x with 
    | Some v -> (match lookup_value env f with 
      | None -> Failed 
      | Some CPSClosureVal (y, fk, ek, e, p') -> 
          Intermediate (ValueBinding(y, v)::ContBinding(fk, (k, env))::ExnContBinding(ek, (eps, env))::p', e)
      | Some CPSRecClosureVal (g, y, fk, ek, e, p') -> 
          Intermediate (ValueBinding(y, v)::ValueBinding(g, (CPSRecClosureVal (g, y, fk, ek, e, p')))::ContBinding(fk, (k, env))::ExnContBinding(ek, (eps, env))::p', e)
      | _ -> Failed
      )
    | _ -> Failed 
    )
  | _ -> Failed