Advertisement
Hinski2

Untitled

May 26th, 2024
13
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 4.03 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 (*zmiana ident na pattern*)
  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 add_pattern env v p =
  54. match match_pattern env v p with
  55. | Some env -> env
  56. | None -> failwith "match failure"
  57.  
  58. let rec eval_env (env : env) (e : expr) : value =
  59. match e with
  60. | Unit -> VUnit
  61. | Int n -> VInt n
  62. | Bool b -> VBool b
  63. | Ctor(c, e) -> VCtor(c, eval_env env e)
  64. | If (p, t, e) ->
  65. (match eval_env env p with
  66. | VBool true -> eval_env env t
  67. | VBool false -> eval_env env e
  68. | _ -> raise Type_error)
  69. | Binop (And, e1, e2) ->
  70. (match eval_env env e1 with
  71. | VBool true -> eval_env env e2
  72. | VBool false -> VBool false
  73. | _ -> raise Type_error)
  74. | Binop (Or, e1, e2) ->
  75. (match eval_env env e1 with
  76. | VBool false -> eval_env env e2
  77. | VBool true -> VBool true
  78. | _ -> raise Type_error)
  79. | Binop (op, e1, e2) -> eval_op op (eval_env env e1) (eval_env env e2)
  80. | Let (pat, e1, e2) ->
  81. let r = eval_env env e1 in
  82. let new_env = add_pattern env r pat in (*tutaj chyba trzeba będzie dodać funcje do dodawania patternu do env*)
  83. eval_env new_env e2
  84. | Var x ->
  85. (match M.find_opt x env with
  86. | Some v -> v
  87. | None -> raise (Unbound_var x))
  88. | Fun (pat, e) -> VClosure (pat, e, env)
  89. | App (e1, e2) ->
  90. (match eval_env env e1, eval_env env e2 with
  91. | VClosure (pat, body, clo_env), v -> eval_env (add_pattern clo_env v pat) body (*tutaj teżtrzeba dodać tą funkcje*)
  92. | _, _ -> raise Type_error)
  93. | Pair(e1, e2) ->
  94. VPair(eval_env env e1, eval_env env e2)
  95. | Fst e ->
  96. (match eval_env env e with
  97. | VPair(v1, _) -> v1
  98. | _ -> raise Type_error)
  99. | Snd e ->
  100. (match eval_env env e with
  101. | VPair(_, v2) -> v2
  102. | _ -> raise Type_error)
  103. | Raise -> raise MyExn
  104. | Try(e1, e2) ->
  105. (try eval_env env e1 with
  106. | MyExn -> eval_env env e2)
  107. | Match(e, cs) ->
  108. match_clauses env (eval_env env e) cs
  109.  
  110. and match_clauses env v cs =
  111. match cs with
  112. | [] -> failwith "match failure"
  113. | (p, e) :: cs ->
  114. match match_pattern env v p with
  115. | Some env -> eval_env env e
  116. | None -> match_clauses env v cs
  117.  
  118. let eval_prog = eval_env M.empty
  119.  
  120. let rec string_of_value v =
  121. match v with
  122. | VUnit -> "()"
  123. | VInt n -> string_of_int n
  124. | VBool true -> "true"
  125. | VBool false -> "false"
  126. | VClosure _ -> "<fun>"
  127. | VPair(v1, v2) ->
  128. "(" ^ string_of_value v1 ^ ", " ^ string_of_value v2 ^ ")"
  129. | VCtor(c, v) -> c ^ "(" ^ string_of_value v ^ ")"
  130.  
  131. let print_value v =
  132. print_endline (string_of_value v)
  133.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement