Advertisement
wandrake

Mylang

Apr 14th, 2011
232
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 4.27 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. type eval =
  49.     | Int of int
  50.     | Bool of bool
  51.     | Funval of efun
  52.     | Nameval of expr * eval Listenv.env
  53.     | Unbound
  54. and efun = expr * eval Listenv.env;;
  55.  
  56. let mult = function (x, y) ->
  57.     match (x, y) with
  58.         | (Int(a), Int(b)) -> Int(a * b)
  59.         | _ -> failwith ("wrong type");;
  60.  
  61. let sum = function (x, y) ->
  62.     match (x, y) with
  63.         | (Int(a), Int(b)) -> Int(a + b)
  64.         | _ -> failwith ("wrong type");;
  65.  
  66. let diff = function (x, y) ->
  67.     match (x, y) with
  68.         | (Int(a), Int(b)) -> Int(a - b)
  69.         | _ -> failwith ("wrong type");;
  70.  
  71. let div = function (x, y) ->
  72.     match (x, y) with
  73.         | (Int(a), Int(b)) -> Int(a / b)
  74.         | _ -> failwith ("wrong type");;
  75.  
  76. let band = function (x, y) ->
  77.     match (x, y) with
  78.         | (Bool(true), Bool(true)) -> Bool(true)
  79.         | (Bool(_), Bool(_)) -> Bool(false)
  80.         | _ -> failwith ("wrong type");;
  81.  
  82. let bor = function (x, y) ->
  83.     match (x, y) with
  84.         | (Bool(false), Bool(false)) -> Bool(false)
  85.         | (Bool(_), Bool(_)) -> Bool(true)
  86.         | _ -> failwith ("wrong type");;
  87.  
  88. let rec evaltostr e =
  89.     match e with
  90.         | Int(a) -> let s = Printf.sprintf "Int(%d) " a in s
  91.         | Bool(a) -> if a = true then "Bool(true) " else "Bool(false) "
  92.         | Funval(a, r) -> "Funzione :O "
  93.         | _ -> "Cazzo fai?!";;
  94.  
  95. let rec envtostr r =
  96.     match r with
  97.         | [] -> ""
  98.         | [(a, b)]::xs -> Printf.sprintf "%s%s%s" (a) (evaltostr(b)) (envtostr(xs));;
  99.  
  100. let rec sem (e, r) =
  101.     match e with
  102.         | Eint(x) -> Int(x)
  103.         | Ebool(x) -> Bool(x)
  104.         | Den(x) -> Listenv.applyenv(r, x)
  105.         | Sum(x, y) -> sum(sem(x, r), sem(y, r))
  106.         | Mult(x, y) -> mult(sem(x, r), sem(y, r))
  107.         | Diff(x, y) -> diff(sem(x, r), sem(y, r))
  108.         | Div(x, y) -> div(sem(x, r), sem(y, r))
  109.         | And(x, y) -> band(sem(x, r), sem(y, r))
  110.         | Or(x, y) -> bor(sem(x, r), sem(y, r))
  111.         | Equals(x, y) -> (match (sem(x, r), sem(y, r)) with
  112.             | Int(a), Int(b) -> if a = b then Bool(true) else Bool(false)
  113.             | _ -> failwith ("Wrong type"))
  114.         | Let(i, e1, e2) -> let r1 = Listenv.bind(r, i, sem(e1, r)) in sem(e2, r1)
  115.         | Fun(x, y) -> Funval(e, r)
  116.         | Apply(x, y) -> (match sem(x, r) with
  117.             | Funval(Fun(a, b), r) -> let r1 = Listenv.bind(r, a, sem(y, r)) in sem(b, r1)
  118.             | x -> Printf.printf "%s" (evaltostr(x)); failwith("Not a function!"))
  119.         | Name(x) -> Nameval(x, r)
  120.         | Nameden(x) -> (match sem(Den x, r) with
  121.             | Nameval(e1, r1) -> sem(e1, r1); Printf.printf "%s" (envtostr(r1));
  122.             | _ -> failwith ("Expected by-name parameter"))
  123.         | Ifthenelse(cond, x, y) -> match sem(cond, r) with
  124.             | Bool(true) -> sem(x, r)
  125.             | Bool(false) -> sem(y, r)
  126.             | _ -> failwith ("Ifthenelse: wrong condition!");;
  127.  
  128. let r = Listenv.bind(Listenv.emptyenv(Int 0), "q", Int 4) in Listenv.applyenv(r, "q");;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement