Advertisement
Hinski2

Untitled

Jun 2nd, 2024
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.31 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. | _, PAs(p, x) ->
  53. (match match_pattern env v p with
  54. | Some env -> Some (M.add x v env)
  55. | None -> None)
  56. | _, PWhen(p, e) -> (*dodanie PWhen*)
  57. (match match_pattern env v p with
  58. | Some env -> if ((eval_env env e = VBool(true))) (*sprawdzenie czy expr oblicza się do True w nowym środowisku*)
  59. then Some env
  60. else None
  61. | None -> None)
  62.  
  63.  
  64.  
  65. and check_pattern p =
  66. let rec aux p ids =
  67. match p with
  68. | PWildcard | PUnit | PInt _ | PBool _ -> ids
  69. | PVar id -> if List.mem id ids
  70. then failwith ("duplicate id " ^ id)
  71. else id::ids
  72. | PPair(p1, p2) ->
  73. let new_ids = aux p1 ids in
  74. aux p2 new_ids
  75. | PCtor(_, pat) -> aux pat ids
  76. | PAs(_, id) ->
  77. if List.mem id ids
  78. then failwith ("duplicate id " ^ id)
  79. else id::ids
  80. | PWhen(pat, _) -> aux pat ids (*dodanie PWhen*)
  81. in ignore(aux p [])
  82.  
  83. and add_pattern env v p =
  84. check_pattern p;
  85. match match_pattern env v p with
  86. | Some env -> env
  87. | None -> failwith "match failure"
  88.  
  89. and eval_env (env : env) (e : expr) : value =
  90. match e with
  91. | Unit -> VUnit
  92. | Int n -> VInt n
  93. | Bool b -> VBool b
  94. | Ctor(c, e) -> VCtor(c, eval_env env e)
  95. | If (p, t, e) ->
  96. (match eval_env env p with
  97. | VBool true -> eval_env env t
  98. | VBool false -> eval_env env e
  99. | _ -> raise Type_error)
  100. | Binop (And, e1, e2) ->
  101. (match eval_env env e1 with
  102. | VBool true -> eval_env env e2
  103. | VBool false -> VBool false
  104. | _ -> raise Type_error)
  105. | Binop (Or, e1, e2) ->
  106. (match eval_env env e1 with
  107. | VBool false -> eval_env env e2
  108. | VBool true -> VBool true
  109. | _ -> raise Type_error)
  110. | Binop (op, e1, e2) -> eval_op op (eval_env env e1) (eval_env env e2)
  111. | Let (pat, e1, e2) ->
  112. let r = eval_env env e1 in
  113. let new_env = add_pattern env r pat in
  114. eval_env new_env e2
  115. | Var x ->
  116. (match M.find_opt x env with
  117. | Some v -> v
  118. | None -> raise (Unbound_var x))
  119. | Fun (pat, e) -> VClosure (pat, e, env)
  120. | App (e1, e2) ->
  121. (match eval_env env e1, eval_env env e2 with
  122. | VClosure (pat, body, clo_env), v -> eval_env (add_pattern clo_env v pat) body
  123. | _, _ -> raise Type_error)
  124. | Pair(e1, e2) ->
  125. VPair(eval_env env e1, eval_env env e2)
  126. | Fst e ->
  127. (match eval_env env e with
  128. | VPair(v1, _) -> v1
  129. | _ -> raise Type_error)
  130. | Snd e ->
  131. (match eval_env env e with
  132. | VPair(_, v2) -> v2
  133. | _ -> raise Type_error)
  134. | Raise -> raise MyExn
  135. | Try(e1, e2) ->
  136. (try eval_env env e1 with
  137. | MyExn -> eval_env env e2)
  138. | Match(e, cs) ->
  139. match_clauses env (eval_env env e) cs
  140.  
  141. and match_clauses env v cs =
  142. match cs with
  143. | [] -> failwith "match failure"
  144. | (p, e) :: cs ->
  145. check_pattern p;
  146. match match_pattern env v p with
  147. | Some env -> eval_env env e
  148. | None -> match_clauses env v cs
  149.  
  150. let eval_prog = eval_env M.empty
  151.  
  152. let rec string_of_value v =
  153. match v with
  154. | VUnit -> "()"
  155. | VInt n -> string_of_int n
  156. | VBool true -> "true"
  157. | VBool false -> "false"
  158. | VClosure _ -> "<fun>"
  159. | VPair(v1, v2) -> print_VPair (v1, v2) true
  160. | VCtor(c, v) -> print_VCtor (c, v)
  161.  
  162. and print_VPair (v1, v2) add =
  163. if add then "(" ^ print_VPair (v1, v2) false ^ ")"
  164. else
  165. match v1 with
  166. | VPair(a, b) -> print_VPair (a, b) false ^ ", " ^ string_of_value v2
  167. | _ -> string_of_value v1 ^ ", " ^ string_of_value v2
  168.  
  169. and print_VCtor (c, v) =
  170. match v with
  171. | VInt n -> c ^ " " ^ string_of_int n
  172. | VBool true -> c ^ " true"
  173. | VBool false -> c ^ " false"
  174. | VClosure _ -> c ^ " <fun>"
  175. | VCtor(_, _) -> c ^ "(" ^ string_of_value v ^ ")"
  176. | _ -> c ^ string_of_value v
  177.  
  178. let print_value v =
  179. print_endline (string_of_value v)
  180.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement