Advertisement
Guest User

Untitled

a guest
Apr 23rd, 2017
80
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.20 KB | None | 0 0
  1. module type ENV = sig
  2. type 't env
  3. val emptyenv : 't -> 't env
  4. val bind: 't env * string * 't->'t env
  5. val bindlist : 't env * (string list) * ('t list)
  6. -> 't env
  7. val applyenv : 't env * string -> 't
  8. exception WrongBindlist
  9. end
  10.  
  11. module Funenv:ENV = struct
  12. type 't env = string -> 't
  13. exception WrongBindlist
  14. let emptyenv(x) = function y -> x
  15. let applyenv(x,y) = x y
  16. let bind((r: 'a env) , (l:string), (e:'a)) =
  17. function lu -> if lu = l then e else applyenv(r,lu)
  18. let rec bindlist(r, il, el) = match (il,el) with
  19. | ([],[]) -> r
  20. | i::il1, e::el1 -> bindlist (bind(r, i, e), il1, el1)
  21. | _ -> raise WrongBindlist
  22. end
  23.  
  24.  
  25. module type STORE =
  26. sig
  27. type 't store
  28. type loc
  29. val emptystore : 't -> 't store
  30. val allocate : 't store * 't -> loc * 't store
  31. val update : 't store * loc * 't -> 't store
  32. val applystore : 't store * loc -> 't
  33. end
  34. module Funstore:STORE =
  35. struct
  36. type loc = int
  37. type 't store = loc -> 't
  38. let (newloc,initloc) = let count = ref(-1) in
  39. (fun () -> count := !count +1; !count),
  40. (fun () -> count := -1)
  41. let emptystore(x) = initloc(); function y -> x
  42. let applystore(x,y) = x y
  43. let allocate((r: 'a store) , (e:'a)) = let l = newloc() in
  44. (l, function lu -> if lu = l then e else applystore(r,lu))
  45. let update((r: 'a store) , (l:loc), (e:'a)) =
  46. function lu -> if lu = l then e else applystore(r,lu)
  47. end
  48.  
  49. type ide = string
  50.  
  51. type exp =
  52. | Eint of int
  53. | Ebool of bool
  54. | Den of ide
  55. | Prod of exp * exp
  56. | Sum of exp * exp
  57. | Diff of exp * exp
  58. | Eq of exp * exp
  59. | Minus of exp
  60. | Iszero of exp
  61. | Or of exp * exp
  62. | And of exp * exp
  63. | Not of exp
  64. | Ifthenelse of exp * exp * exp
  65. | Val of exp
  66. | Let of ide * exp * exp
  67. | Newloc of exp
  68. | Fun of ide list * exp
  69. | Appl of exp * exp list
  70. | Rec of ide * exp
  71. | Proc of ide list * decl * com list
  72.  
  73.  
  74. and decl = (ide * exp) list * (ide * exp) list
  75.  
  76. and com =
  77. | Assign of exp * exp
  78. | Cifthenelse of exp * com list * com list
  79. | While of exp * com list
  80. | Block of decl * com list
  81. | Call of exp * exp list
  82.  
  83. exception Nonstorable
  84. exception Nonexpressible
  85.  
  86. type eval =
  87. | Int of int
  88. | Bool of bool
  89. | Novalue
  90. | Funval of efun
  91.  
  92.  
  93. and dval =
  94. | Dint of int
  95. | Dbool of bool
  96. | Unbound
  97. | Dloc of Funstore.loc
  98. | Dfunval of efun
  99. | Dprocval of proc
  100.  
  101.  
  102. and mval =
  103. | Mint of int
  104. | Mbool of bool
  105. | Undefined
  106.  
  107. and efun = (dval list) * (mval Funstore.store) -> eval
  108. and proc = (dval list) * (mval Funstore.store) -> mval Funstore.store
  109.  
  110.  
  111. let evaltomval e =
  112. match e with
  113. | Int n -> Mint n
  114. | Bool n -> Mbool n
  115. | _ -> raise Nonstorable
  116.  
  117.  
  118. let mvaltoeval m =
  119. match m with
  120. | Mint n -> Int n
  121. | Mbool n -> Bool n
  122. | _ -> Novalue
  123.  
  124.  
  125. let evaltodval e =
  126. match e with
  127. | Int n -> Dint n
  128. | Bool n -> Dbool n
  129. | Novalue -> Unbound
  130. | Funval n -> Dfunval n
  131.  
  132.  
  133. let dvaltoeval e =
  134. match e with
  135. | Dint n -> Int n
  136. | Dbool n -> Bool n
  137. | Dloc n -> raise Nonexpressible
  138. | Dfunval n -> Funval n
  139. | Dprocval n -> raise Nonexpressible
  140. | Unbound -> Novalue
  141.  
  142. let typecheck (x, y) = match x with
  143. | "int" -> (match y with
  144. | Int(u) -> true
  145. | _ -> false)
  146. | "bool" -> (match y with
  147. | Bool(u) -> true
  148. | _ -> false)
  149. | _ -> failwith ("not a valid type")
  150.  
  151.  
  152. let minus x = if typecheck("int",x) then (match x with Int(y) -> Int(-y) )
  153. else failwith ("type error")
  154.  
  155. let iszero x = if typecheck("int",x) then (match x with Int(y) -> Bool(y=0) )
  156. else failwith ("type error")
  157.  
  158. let equ (x,y) = if typecheck("int",x) & typecheck("int",y)
  159. then (match (x,y) with (Int(u), Int(w)) -> Bool(u = w))
  160. else failwith ("type error")
  161.  
  162. let plus (x,y) = if typecheck("int",x) & typecheck("int",y)
  163. then (match (x,y) with (Int(u), Int(w)) -> Int(u+w))
  164. else failwith ("type error")
  165.  
  166. let diff (x,y) = if typecheck("int",x) & typecheck("int",y)
  167. then (match (x,y) with (Int(u), Int(w)) -> Int(u-w))
  168. else failwith ("type error")
  169.  
  170. let mult (x,y) = if typecheck("int",x) & typecheck("int",y)
  171. then (match (x,y) with (Int(u), Int(w)) -> Int(u*w))
  172. else failwith ("type error")
  173.  
  174. let et (x,y) = if typecheck("bool",x) & typecheck("bool",y)
  175. then (match (x,y) with (Bool(u), Bool(w)) -> Bool(u & w))
  176. else failwith ("type error")
  177.  
  178. let vel (x,y) = if typecheck("bool",x) & typecheck("bool",y)
  179. then (match (x,y) with (Bool(u), Bool(w)) -> Bool(u or w))
  180. else failwith ("type error")
  181.  
  182. let non x = if typecheck("bool",x)
  183. then (match x with Bool(y) -> Bool(not y) )
  184. else failwith ("type error")
  185.  
  186. open Funstore;;
  187. open Funenv;;
  188.  
  189.  
  190. let rec makefun ((a:exp),(x:dval env)) = match a with
  191. | Fun(ii,aa) -> Dfunval(function (d, s) -> sem aa (bindlist (x, ii, d)) s)
  192. | _ -> failwith ("Non-functional object")
  193.  
  194.  
  195. and makefunrec (i, Fun(ii, aa), r) =
  196. let functional ff (d, s1) =
  197. let r1 = bind(bindlist(r, ii, d), i, Dfunval(ff)) in sem aa r1 s1 in
  198. let rec fix = function x -> functional fix x in Funval(fix)
  199.  
  200.  
  201. and makeproc((a:exp),(x:dval env)) = match a with
  202. | Proc(ii,dl,cl) -> Dprocval(function (d, s) -> semb (dl,cl) (bindlist (x, ii, d)) s)
  203. | _ -> failwith ("Non-functional object")
  204.  
  205.  
  206. and applyfun ((ev1:dval),(ev2:dval list), s) = match ev1 with
  207. | Dfunval(x) -> x (ev2, s)
  208. | _ -> failwith ("attempt to apply a non-functional object")
  209.  
  210.  
  211. and applyproc ((ev1:dval),(ev2:dval list), s) = match ev1 with
  212. | Dprocval(x) -> x (ev2, s)
  213. | _ -> failwith ("attempt to apply a non-functional object")
  214.  
  215.  
  216. and sem (e:exp) (r:dval env) (s: mval store) =
  217. match e with
  218. | Eint(n) -> Int(n)
  219. | Ebool(b) -> Bool(b)
  220. | Den(i) -> dvaltoeval(applyenv(r,i))
  221. | Iszero(a) -> iszero((sem a r s) )
  222. | Eq(a,b) -> equ((sem a r s) ,(sem b r s) )
  223. | Prod(a,b) -> mult ( (sem a r s), (sem b r s))
  224. | Sum(a,b) -> plus ( (sem a r s), (sem b r s))
  225. | Diff(a,b) -> diff ( (sem a r s), (sem b r s))
  226. | Minus(a) -> minus( (sem a r s))
  227. | And(a,b) -> et ( (sem a r s), (sem b r s))
  228. | Or(a,b) -> vel ( (sem a r s), (sem b r s))
  229. | Not(a) -> non( (sem a r s))
  230. | Ifthenelse(a,b,c) ->
  231. let g = sem a r s in
  232. if typecheck("bool",g) then
  233. (if g = Bool(true)
  234. then sem b r s
  235. else sem c r s)
  236. else failwith ("nonboolean guard")
  237. | Val(e) -> let (v, s1) = semden e r s in (match v with
  238. | Dloc n -> mvaltoeval(applystore(s1, n))
  239. | _ -> failwith("not a variable"))
  240.  
  241. | Let(i,e1,e2) -> let (v, s1) = semden e1 r s in sem e2 (bind (r ,i, v)) s1
  242. | Fun(i,e1) -> dvaltoeval(makefun(e,r))
  243. | Rec(i,e1) -> makefunrec(i, e1, r)
  244. | Appl(a,b) -> let (v1, s1) = semlist b r s in applyfun(evaltodval(sem a r s), v1, s1)
  245. | _ -> failwith ("nonlegal expression for sem")
  246.  
  247. and semden (e:exp) (r:dval env) (s: mval store) = match e with
  248. | Den(i) -> (applyenv(r,i), s)
  249. | Fun(i, e1) -> (makefun(e, r), s)
  250. | Proc(i, dl,cl) -> (makeproc(e, r), s)
  251. | Newloc(e) -> let m = evaltomval(sem e r s) in let (l, s1) = allocate(s, m) in (Dloc l, s1)
  252. | _ -> (evaltodval(sem e r s), s)
  253.  
  254. and semlist el r s = match el with
  255. | [] -> ([], s)
  256. | e::el1 -> let (v1, s1) = semden e r s in let (v2, s2) = semlist el1 r s1 in (v1 :: v2, s2)
  257.  
  258.  
  259.  
  260. and semc (c: com) (r:dval env) (s: mval store) = match c with
  261. | Assign(e1, e2) -> let (v1, s1) = semden e1 r s in (match v1 with
  262. | Dloc(n) -> update(s1, n, evaltomval(sem e2 r s))
  263. | _ -> failwith ("wrong location in assignment"))
  264. | Cifthenelse(e, cl1, cl2) -> let g = sem e r s in
  265. if typecheck("bool",g) then
  266. (if g = Bool(true) then semcl cl1 r s else semcl cl2 r s)
  267. else failwith ("nonboolean guard")
  268. | While(e, cl) ->
  269. let functional ((fi: mval store -> mval store)) =
  270. function sigma ->
  271. let g = sem e r sigma in
  272. if typecheck("bool",g) then
  273. (if g = Bool(true) then fi(semcl cl r sigma) else sigma)
  274. else failwith ("nonboolean guard")
  275. in
  276. let rec ssfix = function x -> functional ssfix x in ssfix(s)
  277. | Call(e1, e2) -> let (p, s1) = semden e1 r s in let (v, s2) = semlist e2 r s1 in
  278. applyproc(p, v, s2)
  279. | Block(dl,cl) -> semb (dl,cl) r s
  280.  
  281.  
  282. and semcl cl r s =
  283. match cl with
  284. | [] -> s
  285. | c::cl1 -> semcl cl1 r (semc c r s)
  286.  
  287. and semb ((dl, rdl), cl) r s =
  288. let (r1, s1) = semdl (dl, rdl) r s in semcl cl r1 s1
  289.  
  290.  
  291. and semdl (dl, rl) r s = let (r1, s1) = semdv dl r s in
  292. semdr rl r1 s1
  293.  
  294. and semdv dl r s = match dl with
  295. | [] -> (r,s)
  296. | (i,e)::dl1 -> let (v, s1) = semden e r s in
  297. semdv dl1 (bind(r, i, v)) s1
  298.  
  299.  
  300. and semdr rl r s =
  301. let functional ((r1: dval env)) = (match rl with
  302. | [] -> r
  303. | (i,e) :: rl1 -> let (v, s2) = semden e r1 s in
  304. let (r2, s3) = semdr rl1 (bind(r, i, v)) s in r2) in
  305. let rec rfix = function x -> functional rfix x in (rfix, s)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement