Advertisement
wandrake

Untitled

Apr 14th, 2011
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.95 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)] -> failwith (Printf.sprintf "unbound value %s" i)
  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 typecheck (t, e) = match t with
  57.     | "eval" -> (match e with
  58.         | Int _ -> true
  59.         | Bool _ -> true
  60.         | Funval (_, _) -> true
  61.         | Nameval (_, _) -> true
  62.         | Unbound -> true
  63.         | _ -> false)
  64.     | _ -> failwith("you fucking dumb. HA-HA");;
  65.  
  66. let rec exprtostr e = (match e with
  67.     | Eint n -> Printf.sprintf "Eint %d" n
  68.     | Ebool b -> if b = true then "Bool true" else "Bool false"
  69.     | Sum(a, b) -> Printf.sprintf "Sum(%s, %s)" (exprtostr a) (exprtostr b)
  70.     | Den x -> Printf.sprintf "Den(%s)" x
  71.     | Mult(a, b) -> Printf.sprintf "Mult(%s, %s)" (exprtostr a) (exprtostr b)
  72.     | Diff(a, b) -> Printf.sprintf "Diff(%s, %s)" (exprtostr a) (exprtostr b)
  73.     | Div(a, b) -> Printf.sprintf "Div(%s, %s)" (exprtostr a) (exprtostr b)
  74.     | And(a, b) -> Printf.sprintf "And(%s, %s)" (exprtostr a) (exprtostr b)
  75.     | Or(a, b) -> Printf.sprintf "Or(%s, %s)" (exprtostr a) (exprtostr b)
  76.     | Equals(a, b) -> Printf.sprintf "Equals(%s, %s)" (exprtostr a) (exprtostr b)
  77.     | Let(i, e1, e2) -> Printf.sprintf "Let(%s, %s, %s)" i (exprtostr e1) (exprtostr e2)
  78.     | Fun(i, e) -> Printf.sprintf "Fun(%s, %s)" i (exprtostr e)
  79.     | Rec(i, e) -> Printf.sprintf "Rec(%s, %s)" i (exprtostr e)
  80.     | Apply(e1, e2) -> Printf.sprintf "Apply(%s, %s)" (exprtostr e1) (exprtostr e2)
  81.     | Nameden i -> Printf.sprintf "Nameden(%s)" i
  82.     | Name e -> Printf.sprintf "Name(%s)" (exprtostr e)
  83.     | Ifthenelse (cond, e1, e2) -> Printf.sprintf "Ifthenelse(%s, %s, %s)" (exprtostr cond) (exprtostr e1) (exprtostr e2))
  84. and envtostr r = (match r with
  85.     | [(_, e)] -> ""
  86.     | (i1, e1) :: rl -> if typecheck("eval", e1)
  87.                         then Printf.sprintf "%s %s -> %s " (i1) (evaltostr e1) (envtostr rl)
  88.                         else failwith("wrong type, you bastard.")
  89.     | _ -> failwith ("wrong env"))
  90. and evaltostr e = (match e with
  91.     | Int n -> Printf.sprintf "Int %d" n
  92.     | Bool b -> if b = true then "Bool true" else "Bool false"
  93.     | Funval(e, r) -> Printf.sprintf "Funval(%s, %s)" (exprtostr e) (envtostr r)
  94.     | Nameval(e, r) -> Printf.sprintf "Nameval(%s, %s)" (exprtostr e) (envtostr r)
  95.     | Unbound -> "Unbound");;
  96.  
  97. let mult = function (x, y) ->
  98.     match (x, y) with
  99.         | (Int(a), Int(b)) -> Int(a * b)
  100.         | _ -> failwith ("wrong type");;
  101.  
  102. let sum = function (x, y) ->
  103.     match (x, y) with
  104.         | (Int(a), Int(b)) -> Int(a + b)
  105.         | _ -> failwith ("wrong type");;
  106.  
  107. let diff = function (x, y) ->
  108.     match (x, y) with
  109.         | (Int(a), Int(b)) -> Int(a - b)
  110.         | _ -> failwith ("wrong type");;
  111.  
  112. let div = function (x, y) ->
  113.     match (x, y) with
  114.         | (Int(a), Int(b)) -> Int(a / b)
  115.         | _ -> failwith ("wrong type");;
  116.  
  117. let band = function (x, y) ->
  118.     match (x, y) with
  119.         | (Bool(true), Bool(true)) -> Bool(true)
  120.         | (Bool(_), Bool(_)) -> Bool(false)
  121.         | _ -> failwith ("wrong type");;
  122.  
  123. let bor = function (x, y) ->
  124.     match (x, y) with
  125.         | (Bool(false), Bool(false)) -> Bool(false)
  126.         | (Bool(_), Bool(_)) -> Bool(true)
  127.         | _ -> failwith ("wrong type");;
  128.  
  129. let rec sem (e, r) =
  130.     match e with
  131.         | Eint(x) -> Int(x)
  132.         | Ebool(x) -> Bool(x)
  133.         | Den(x) -> Listenv.applyenv(r, x)
  134.         | Sum(x, y) -> sum(sem(x, r), sem(y, r))
  135.         | Mult(x, y) -> mult(sem(x, r), sem(y, r))
  136.         | Diff(x, y) -> diff(sem(x, r), sem(y, r))
  137.         | Div(x, y) -> div(sem(x, r), sem(y, r))
  138.         | And(x, y) -> band(sem(x, r), sem(y, r))
  139.         | Or(x, y) -> bor(sem(x, r), sem(y, r))
  140.         | Equals(x, y) -> (match (sem(x, r), sem(y, r)) with
  141.             | Int(a), Int(b) -> if a = b then Bool(true) else Bool(false)
  142.             | _ -> failwith ("Wrong type"))
  143.         | Let(i, e1, e2) -> let r1 = Listenv.bind(r, i, sem(e1, r)) in sem(e2, r1)
  144.         | Fun(x, y) -> Funval(e, r)
  145.         | Apply(x, y) -> (match sem(x, r) with
  146.             | Funval(Fun(a, b), r) -> let r1 = Listenv.bind(r, a, sem(y, r)) in sem(b, r1)
  147.             | x -> Printf.printf "%s" (evaltostr x); failwith("Not a function!"))
  148.         | Name(x) -> Nameval(x, r)
  149.         | Nameden(x) -> (match sem(Den x, r) with
  150.             | Nameval(e1, r1) -> sem(e1, r1)
  151.             | _ -> failwith ("Expected by-name parameter"))
  152.         | Ifthenelse(cond, x, y) -> match sem(cond, r) with
  153.             | Bool(true) -> sem(x, r)
  154.             | Bool(false) -> sem(y, r)
  155.             | _ -> failwith ("Ifthenelse: wrong condition!");;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement