Advertisement
wandrake

Untitled

Apr 25th, 2011
268
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.21 KB | None | 0 0
  1. type ide = string;;
  2.  
  3. type expr =
  4.     | Eint of int
  5.     | Ebool of bool
  6.     | Sum of expr * expr
  7.     | Den of ide
  8.     | Mult of expr * expr
  9.     | Diff of expr * expr
  10.     | Div of expr * expr
  11.     | And of expr * expr
  12.     | Or of expr * expr
  13.     | Equals of expr * expr
  14.     | Let of ide * expr * expr
  15.     | Fun of ide * expr
  16.     | Rec of ide * expr
  17.     | Apply of expr * expr
  18.     | Nameden of ide
  19.     | Name of expr
  20.     | Ifthenelse of expr * expr * expr;;
  21.  
  22. module type ENV =
  23.     sig
  24.         type 't env
  25.         exception WrongBindlist
  26.         val emptyenv : 't -> 't env
  27.         val applyenv : 't env * ide -> 't
  28.         val bind : 't env * ide * 't -> 't env
  29.         val bindlist : 't env * (ide list) * ('t list) -> 't env
  30.     end
  31.  
  32. module Listenv:ENV =
  33.     struct
  34.         type 't env = (ide * 't) list
  35.         exception WrongBindlist
  36.         let emptyenv(x) = [("", x)]
  37.         let rec applyenv(r, i) = match r with
  38.             | [(_, e)] -> e
  39.             | (i1, e) :: rl -> if i = i1 then e else applyenv(rl, i)
  40.             | _ -> failwith ("wrong env")
  41.         let bind(r, i, e) = (i, e) :: r
  42.         let rec bindlist(r, il, el) = match (il, el) with
  43.             | ([], []) -> r
  44.             | (i::il1, e::el1) -> let r1 = bind(r, i, e) in bindlist(r1, il1, el1)
  45.             | _ -> raise WrongBindlist
  46.     end
  47.  
  48. module Funenv:ENV =
  49.     struct
  50.         type 't env = ide -> 't
  51.         exception WrongBindlist
  52.         let emptyenv(x) = function y -> x
  53.         let applyenv(r, i) = r i
  54.         let bind(r, i, e) = function x -> if x = i then e else r i
  55.         let rec bindlist(r, il, el) = match (il, el) with
  56.             | ([], []) -> r
  57.             | (i::il1, e::el1) -> let r1 = bind(r, i, e) in bindlist(r1, il1, el1)
  58.             | _ -> raise WrongBindlist
  59.     end
  60.  
  61. type eval =
  62.     | Int of int
  63.     | Bool of bool
  64.     | Funval of efun
  65.     | Nameval of expr * eval Listenv.env
  66.     | Unbound
  67. and efun = expr * eval Listenv.env;;
  68.  
  69. let mult = function (x, y) ->
  70.     match (x, y) with
  71.         | (Int(a), Int(b)) -> Int(a * b)
  72.         | _ -> failwith ("wrong type");;
  73.  
  74. let sum = function (x, y) ->
  75.     match (x, y) with
  76.         | (Int(a), Int(b)) -> Int(a + b)
  77.         | _ -> failwith ("wrong type");;
  78.  
  79. let diff = function (x, y) ->
  80.     match (x, y) with
  81.         | (Int(a), Int(b)) -> Int(a - b)
  82.         | _ -> failwith ("wrong type");;
  83.  
  84. let div = function (x, y) ->
  85.     match (x, y) with
  86.         | (Int(a), Int(b)) -> Int(a / b)
  87.         | _ -> failwith ("wrong type");;
  88.  
  89. let band = function (x, y) ->
  90.     match (x, y) with
  91.         | (Bool(true), Bool(true)) -> Bool(true)
  92.         | (Bool(_), Bool(_)) -> Bool(false)
  93.         | _ -> failwith ("wrong type");;
  94.  
  95. let bor = function (x, y) ->
  96.     match (x, y) with
  97.         | (Bool(false), Bool(false)) -> Bool(false)
  98.         | (Bool(_), Bool(_)) -> Bool(true)
  99.         | _ -> failwith ("wrong type");;
  100.  
  101. let rec evaltostr e =
  102.     match e with
  103.         | Int(a) -> let s = Printf.sprintf "Int(%d) " a in s
  104.         | Bool(a) -> if a = true then "Bool(true) " else "Bool(false) "
  105.         | Funval(a, r) -> "Funzione :O "
  106.         | _ -> "Cazzo fai?!";;
  107.  
  108. let rec envtostr r =
  109.     match r with
  110.         | [] -> ""
  111.         | [(a, b)]::xs -> Printf.sprintf "%s%s%s" (a) (evaltostr(b)) (envtostr(xs));;
  112.  
  113. let rec sem (e, r) =
  114.     match e with
  115.         | Eint(x) -> Int(x)
  116.         | Ebool(x) -> Bool(x)
  117.         | Den(x) -> Listenv.applyenv(r, x)
  118.         | Sum(x, y) -> sum(sem(x, r), sem(y, r))
  119.         | Mult(x, y) -> mult(sem(x, r), sem(y, r))
  120.         | Diff(x, y) -> diff(sem(x, r), sem(y, r))
  121.         | Div(x, y) -> div(sem(x, r), sem(y, r))
  122.         | And(x, y) -> band(sem(x, r), sem(y, r))
  123.         | Or(x, y) -> bor(sem(x, r), sem(y, r))
  124.         | Equals(x, y) -> (match (sem(x, r), sem(y, r)) with
  125.             | Int(a), Int(b) -> if a = b then Bool(true) else Bool(false)
  126.             | _ -> failwith ("Wrong type"))
  127.         | Let(i, e1, e2) -> let r1 = Listenv.bind(r, i, sem(e1, r)) in sem(e2, r1)
  128.         | Fun(x, y) -> Funval(e, r)
  129. (*        | Rec(x, y) -> makefunrec(x, y, r)*)
  130.         | Apply(x, y) -> (match sem(x, r) with
  131.             | Funval(Fun(a, b), r2) -> let r1 = Listenv.bind(r2, a, sem(y, r)) in sem(b, r1)
  132.             | x -> Printf.printf "%s" (evaltostr x); failwith("Not a function!"))
  133.         | Name(x) -> Nameval(x, r)
  134.         | Nameden(x) -> (match sem(Den x, r) with
  135.             | Nameval(e1, r1) -> sem(e1, r1);
  136.             | _ -> failwith ("Expected by-name parameter"))
  137.         | Ifthenelse(cond, x, y) -> match sem(cond, r) with
  138.             | Bool(true) -> sem(x, r)
  139.             | Bool(false) -> sem(y, r)
  140.             | _ -> failwith ("Ifthenelse: wrong condition!");;
  141.  
  142. let r0 = Listenv.emptyenv(Int(0));;
  143.  
  144. let test1 = Sum(Eint(5), Eint(2));;
  145. let nameparam =
  146. Let(
  147.     "x",
  148.     Fun(
  149.         "a",
  150.         Sum(Nameden "a", Nameden "a")
  151.     ),
  152.     Let(
  153.         "q",
  154.         Eint(2),
  155.         Apply(
  156.             Den "x",
  157.             Name(Sum(Den "q", Den "q"))
  158.         )
  159.     )
  160. );;
  161.  
  162. let wrongnameparam =
  163. Let(
  164.     "x",
  165.     Fun(
  166.         "a",
  167.         Sum(Nameden "a", Nameden "a")
  168.     ),
  169.     Let(
  170.         "q",
  171.         Eint 2,
  172.         Apply(
  173.             Den "x",
  174.             Sum(Den "q", Den "q")
  175.         )
  176.     )
  177. );;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement