Advertisement
Guest User

Project

a guest
Feb 6th, 2017
436
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 5.12 KB | None | 0 0
  1. type ide = string
  2. type exp =
  3.     | Eint of int
  4.     | Ebool of bool
  5.     | Den of ide
  6.     | Sum of exp * exp
  7.     | Diff of exp * exp
  8.     | Prod of exp * exp
  9.     | Eq of exp * exp
  10.     | Minus of exp
  11.     | Iszero of exp
  12.     | Or of exp * exp
  13.     | And of exp * exp
  14.     | Not of exp
  15.     | Ifthenelse of exp * exp * exp
  16.     | Let of ide * exp * exp
  17.     | Fun of ide * exp
  18.     | Apply of exp * exp  
  19.     | Letrec of ide * ide * exp * exp
  20.     | Etup of tuple (*Tupla come espressione*)
  21.     | Pipe of tuple (*Concatenazione di funzioni*)
  22.     | ManyTimes of int * exp (*Esecuzione iterata di una funzione*)
  23. and tuple =
  24.     | Nil (*Tupla vuota*)
  25.     | Seq of exp * tuple (*Tupla di espressioni*)
  26. ;;
  27.  
  28. type 't env = (string * 't) list
  29.     exception WrongBindlist
  30.     let emptyenv(x) = [("", x)]
  31.     let rec applyenv(x, y) = match x with
  32.       | [(_, e)] -> e
  33.       | (i1, e1) :: x1 -> if y = i1 then e1
  34.           else applyenv(x1, y)
  35.       | [] -> failwith("wrong env")  
  36.     let bind(r, l, e) = (l, e) :: r
  37.     let rec bindlist(r, il, el) = match (il, el) with
  38.       | ([], []) -> r
  39.       | (i::il1, e::el1) -> bindlist(bind(r, i, e), il1, el1)
  40.       | _ -> raise WrongBindlist
  41. ;;
  42.  
  43. type eval=
  44.     | Int of int
  45.     | Bool of bool
  46.     | Unbound
  47.     | RecFunVal of ide * ide * exp * eval env
  48.     | Funval of efun
  49.     | ValTup of etuple
  50. and efun = ide * exp * eval env
  51. and etuple =
  52.     | Nil
  53.     | Seq of eval * etuple
  54. ;;
  55.  
  56. let typecheck(x, y) = match x with
  57.   | "int" ->  
  58.       (match y with
  59.         | Int(u) -> true
  60.         | _ -> false)
  61.   | "bool" ->
  62.       (match y with
  63.         |Bool(b) -> true
  64.         |_->false)
  65.   |_->failwith("error");;
  66.  
  67.   let plus(x, y) = if typecheck("int", x) && typecheck("int", y) then  
  68.     (match (x, y) with
  69.       |(Int(u), Int(w)) -> Int(u + w))
  70.   else failwith ("error");;
  71.  
  72.  
  73. let diff(x,y)=if typecheck("int",x) && typecheck("int", y) then
  74.     (match (x, y) with
  75.       |(Int(u), Int(w)) -> Int(u - w)
  76.       |_->failwith("error"))
  77.   else failwith ("type error");;
  78.  
  79.  
  80. let prod(x,y)=if typecheck("int",x) && typecheck("int", y) then
  81.     (match (x, y) with
  82.       |(Int(u), Int(w)) -> Int(u * w)
  83.       |_->failwith("error"))
  84.   else failwith ("type error");;
  85.  
  86.  
  87. let iszero(x)=if typecheck("int",x) then
  88.     (match x with
  89.       |Int(u)->if u=0 then Bool(true) else Bool(false)
  90.       |_->failwith("error"))
  91.   else failwith("type error");;
  92.  
  93.  
  94. let equ(x,y)=if typecheck("int",x) && typecheck("int", y) then
  95.     (match (x, y) with
  96.       |(Int(u), Int(w)) -> if u=w then Bool(true) else Bool(false)
  97.       |_->failwith("error"))
  98.   else failwith ("type error");;
  99.  
  100.  
  101. let minus(x)=if typecheck("int",x) then
  102.     (match x with
  103.       |Int(u)->Int(-u)
  104.       |_->failwith("error"))
  105.   else failwith("type error");;
  106.  
  107.  
  108. let e(x,y)=if typecheck("bool",x) && typecheck("bool", y) then
  109.     (match (x, y) with
  110.       |(Bool(u), Bool(w)) -> Bool(u && w)
  111.       |_->failwith("error"))
  112.   else failwith ("type error");;
  113.  
  114.  
  115. let o(x,y)=if typecheck("bool",x) && typecheck("bool", y) then
  116.     (match (x, y) with
  117.       |(Bool(u), Bool(w)) -> Bool(u || w)
  118.       |_->failwith("error"))
  119.   else failwith ("type error");;
  120.  
  121.  
  122. let non(x)=if typecheck("bool",x) then
  123.     (match x with
  124.       |Bool(u) -> Bool(not(u))
  125.       |_->failwith("error"))
  126.   else failwith ("type error");;
  127.  
  128. let rec sem ((ex: exp), (r: eval env)) = match ex with
  129.     | Eint(n) -> Int(n)
  130.     | Ebool(b) -> Bool(b)
  131.     | Den(i) -> applyenv(r, i)
  132.     | Sum(a,b) ->  plus(sem(a, r), sem(b, r))
  133.     | Diff(a,b)  ->  diff(sem(a, r), sem(b, r))
  134.     | Prod(a,b)->prod(sem(a,r), sem(b,r))
  135.     | Iszero(a) -> iszero(sem(a, r))
  136.     | Eq(a,b) -> equ(sem(a, r),sem(b, r))
  137.     | Minus(a) ->  minus(sem(a, r))
  138.     | And(a,b) ->  e(sem(a, r), sem(b, r))
  139.     | Or(a,b) ->  o(sem(a, r), sem(b, r))
  140.     | Not(a) -> non(sem(a, r))
  141.     | Ifthenelse(a,b,c) -> let g = sem(a, r) in
  142.           if typecheck("bool", g) then
  143.             (if g = Bool(true) then sem(b, r) else sem(c, r))
  144.           else failwith ("nonboolean guard")
  145.     | Let(i, e1, e2) -> sem(e2, bind (r, i, sem(e1, r)))
  146.     | Fun(i,a) -> Funval(i,a,r)
  147.     | Letrec(f, i, fBody, letBody) ->
  148.         let benv = bind(r, f, (RecFunVal(f, i, fBody, r)))
  149.         in sem(letBody, benv)  
  150.     | Etup(tup) -> (match tup with
  151.         | Seq(ex1, tupla) ->
  152.             let evex1 = sem(ex1, r) in
  153.             let ValTup(etupl) = sem(Etup(tupla), r) in
  154.                 ValTup(Seq(evex1, etupl))
  155.         | Nil -> ValTup(Nil))
  156.     | Apply(Den f, arg1) ->
  157.         (let fclosure= sem(Den f, r) in
  158.            match fclosure with
  159.              | Funval(arg, fbody, fDecEnv) ->
  160.                  sem(fbody, bind(fDecEnv, arg, sem(arg1, r)))
  161.              | RecFunVal(f, arg, fbody, fDecEnv) ->
  162.                  let aVal= sem(arg1, r) in
  163.                  let rEnv= bind(fDecEnv, f, fclosure) in
  164.                  let aEnv= bind(rEnv, arg, aVal) in
  165.                    sem(fbody, aEnv)
  166.              | _ -> failwith("non functional value"))
  167.     | Apply(Pipe tup, arg) -> applyPipe tup arg r
  168.     | Apply(_,_) -> failwith("not function")
  169.  
  170. and applyPipe tup argo r = (match tup with
  171.     | Seq(Den f, tupla) ->
  172.         let appf = Apply(Den f,argo) in
  173.             applyPipe tupla appf r
  174.     | Nil -> sem(argo,r)
  175.     | _ -> failwith("Not a valid Pipe"))
  176. ;;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement