Advertisement
Hinski2

zad5 eval

May 26th, 2024
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.45 KB | None | 0 0
  1. open Ast
  2.  
  3. module M = Map.Make(String)
  4.  
  5. exception Type_error
  6. exception Unbound_var of ident
  7.  
  8. exception MyExn
  9.  
  10. type env = value M.t
  11.  
  12. and value =
  13. | VUnit
  14. | VInt of int
  15. | VBool of bool
  16. | VClosure of pattern * expr * env
  17. | VPair of value * value
  18. | VCtor of cname * value
  19.  
  20. let eval_op (op : bop) (v1 : value) (v2 : value) : value =
  21. match op, v1, v2 with
  22. | Add, VInt i1, VInt i2 -> VInt (i1 + i2)
  23. | Sub, VInt i1, VInt i2 -> VInt (i1 - i2)
  24. | Mult, VInt i1, VInt i2 -> VInt (i1 * i2)
  25. | Div, VInt i1, VInt i2 -> VInt (i1 / i2)
  26. | Eq, VInt i1, VInt i2 -> VBool (i1 = i2)
  27. | Lt, VInt i1, VInt i2 -> VBool (i1 < i2)
  28. | Gt, VInt i1, VInt i2 -> VBool (i1 > i2)
  29. | Leq, VInt i1, VInt i2 -> VBool (i1 <= i2)
  30. | Geq, VInt i1, VInt i2 -> VBool (i1 >= i2)
  31. | Neq, VInt i1, VInt i2 -> VBool (i1 <> i2)
  32. | _ -> raise Type_error
  33.  
  34. let rec match_pattern env v p =
  35. match v, p with
  36. | _, PWildcard -> Some env
  37. | VUnit, PUnit -> Some env
  38. | _, PUnit -> None
  39. | VInt n, PInt m when n = m -> Some env
  40. | _, PInt _ -> None
  41. | VBool x, PBool y when x = y -> Some env
  42. | _, PBool _ -> None
  43. | _, PVar x -> Some (M.add x v env)
  44. | VCtor(c1, v), PCtor(c2, p) when c1 = c2 ->
  45. match_pattern env v p
  46. | _, PCtor _ -> None
  47. | VPair(v1, v2), PPair(p1, p2) ->
  48. (match match_pattern env v1 p1 with
  49. | None -> None
  50. | Some env -> match_pattern env v2 p2)
  51. | _, PPair _ -> None
  52.  
  53. let check_pattern p = (*dodanie funkcji która sprawdza czy pattern jest poprawny*)
  54. let rec aux p ids =
  55. match p with
  56. | PWildcard | PUnit | PInt _ | PBool _ -> ids
  57. | PVar id -> if List.mem id ids
  58. then failwith ("duplicate id " ^ id)
  59. else id::ids
  60. | PPair(p1, p2) ->
  61. let new_ids = aux p1 ids in
  62. aux p2 new_ids
  63. | PCtor(_, pat) -> aux pat ids
  64. in ignore(aux p [])
  65.  
  66. let add_pattern env v p =
  67. check_pattern p; (*sprawdzenie czy pattern który dodajemy jest poprawny*)
  68. match match_pattern env v p with
  69. | Some env -> env
  70. | None -> failwith "match failure"
  71.  
  72. let rec eval_env (env : env) (e : expr) : value =
  73. match e with
  74. | Unit -> VUnit
  75. | Int n -> VInt n
  76. | Bool b -> VBool b
  77. | Ctor(c, e) -> VCtor(c, eval_env env e)
  78. | If (p, t, e) ->
  79. (match eval_env env p with
  80. | VBool true -> eval_env env t
  81. | VBool false -> eval_env env e
  82. | _ -> raise Type_error)
  83. | Binop (And, e1, e2) ->
  84. (match eval_env env e1 with
  85. | VBool true -> eval_env env e2
  86. | VBool false -> VBool false
  87. | _ -> raise Type_error)
  88. | Binop (Or, e1, e2) ->
  89. (match eval_env env e1 with
  90. | VBool false -> eval_env env e2
  91. | VBool true -> VBool true
  92. | _ -> raise Type_error)
  93. | Binop (op, e1, e2) -> eval_op op (eval_env env e1) (eval_env env e2)
  94. | Let (pat, e1, e2) ->
  95. let r = eval_env env e1 in
  96. let new_env = add_pattern env r pat in
  97. eval_env new_env e2
  98. | Var x ->
  99. (match M.find_opt x env with
  100. | Some v -> v
  101. | None -> raise (Unbound_var x))
  102. | Fun (pat, e) -> VClosure (pat, e, env)
  103. | App (e1, e2) ->
  104. (match eval_env env e1, eval_env env e2 with
  105. | VClosure (pat, body, clo_env), v -> eval_env (add_pattern clo_env v pat) body
  106. | _, _ -> raise Type_error)
  107. | Pair(e1, e2) ->
  108. VPair(eval_env env e1, eval_env env e2)
  109. | Fst e ->
  110. (match eval_env env e with
  111. | VPair(v1, _) -> v1
  112. | _ -> raise Type_error)
  113. | Snd e ->
  114. (match eval_env env e with
  115. | VPair(_, v2) -> v2
  116. | _ -> raise Type_error)
  117. | Raise -> raise MyExn
  118. | Try(e1, e2) ->
  119. (try eval_env env e1 with
  120. | MyExn -> eval_env env e2)
  121. | Match(e, cs) ->
  122. match_clauses env (eval_env env e) cs
  123.  
  124. and match_clauses env v cs =
  125. match cs with
  126. | [] -> failwith "match failure"
  127. | (p, e) :: cs ->
  128. check_pattern p; (*tutaj robimy sprawdzenie patternu*)
  129. match match_pattern env v p with
  130. | Some env -> eval_env env e
  131. | None -> match_clauses env v cs
  132.  
  133. let eval_prog = eval_env M.empty
  134.  
  135. let rec string_of_value v =
  136. match v with
  137. | VUnit -> "()"
  138. | VInt n -> string_of_int n
  139. | VBool true -> "true"
  140. | VBool false -> "false"
  141. | VClosure _ -> "<fun>"
  142. | VPair(v1, v2) ->
  143. "(" ^ string_of_value v1 ^ ", " ^ string_of_value v2 ^ ")"
  144. | VCtor(c, v) -> c ^ "(" ^ string_of_value v ^ ")"
  145.  
  146. let print_value v =
  147. print_endline (string_of_value v)
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement