Advertisement
Crax97

Factorial in token interpreter using OCaml

Dec 1st, 2018
387
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
OCaml 4.36 KB | None | 0 0
  1. exception EmptyEnv;;
  2. exception WrongType;;
  3. exception NonFunctional;;
  4.  
  5. type ide = string
  6. and exp =
  7.   | True
  8.   | False
  9.   | Cst of int
  10.   | Let of ide * exp * exp
  11.   | Var of ide
  12.   | Add of exp * exp
  13.   | Min of exp * exp
  14.   | Mul of exp * exp
  15.   | Eq of exp * exp
  16.   | NEq of exp * exp
  17.   | And of exp * exp
  18.   | Or of exp * exp
  19.   | Not of exp
  20.   | If of exp * exp * exp
  21.   | Func of ide * ide * exp * exp
  22.   | Apply of ide * exp
  23. and evT =
  24.   | Unbound
  25.   | CstT of int
  26.   | BoolT of bool
  27.   | Closure of ide * ide * exp * env
  28. and env = (ide -> evT);;
  29.  
  30. let emptyenv = fun (x : ide) -> Unbound;;
  31. let bind (x : ide) (e : evT) r = fun (n : ide) -> if n = x then e else r n;;
  32. let applyenv (x : ide) ( r : ide -> evT) = r x;;
  33.  
  34. let rec eval (e : exp) (r : ide -> evT ) =
  35.   match e with
  36.   | True -> BoolT(true)
  37.   | False -> BoolT(false)
  38.   | Cst ( i ) -> CstT (i)
  39.   | Let ( i, e1, e2 ) -> let v1 = eval e1 r in
  40.                           eval e2 (bind i v1 r)
  41.   | Var ( i ) -> applyenv i r
  42.   | Add ( e1, e2) ->  ( let v1 = eval e1 r in
  43.                       let v2 = eval e2 r in
  44.                       match v1, v2 with
  45.                       | CstT(a), CstT( b) -> CstT(a + b)
  46.                       | _ -> raise WrongType)
  47.   | Min ( e1, e2) ->  ( let v1 = eval e1 r in
  48.                       let v2 = eval e2 r in
  49.                       match v1, v2 with
  50.                       | CstT(a), CstT( b) -> CstT(a - b)
  51.                       | _ -> raise WrongType)
  52.   | Mul ( e1, e2) ->  ( let v1 = eval e1 r in
  53.                       let v2 = eval e2 r in
  54.                       match v1, v2 with
  55.                       | CstT(a), CstT( b) -> CstT(a * b)
  56.                       | _ -> raise WrongType)
  57.   | Eq (e1, e2) -> (let v1 = eval e1 r in
  58.                       let v2 = eval e2 r in
  59.                       match v1, v2 with
  60.                       | BoolT(a), BoolT(b) -> if a = b then BoolT(true) else BoolT(false)
  61.                       | CstT(a), CstT(b) -> if a = b then BoolT(true) else BoolT(false)
  62.                       | _,_ -> raise WrongType )
  63.   | NEq (e1, e2) -> (let v1 = eval e1 r in
  64.                       let v2 = eval e2 r in
  65.                       match v1, v2 with
  66.                       | BoolT(a), BoolT(b) -> if a <> b then BoolT(true) else BoolT(false)
  67.                       | CstT(a), CstT(b) -> if a <> b then BoolT(true) else BoolT(false)  
  68.                       | _,_ -> raise WrongType )
  69.   | And (e1, e2) ->   ( match eval e1 r with
  70.                         | BoolT(true) -> eval e2 r
  71.                         | BoolT(false) -> BoolT (false)
  72.                         | _ -> raise WrongType)
  73.   | Or (e1, e2) ->   ( match eval e1 r with
  74.                         | BoolT(true) -> BoolT( true )
  75.                         | BoolT(false) -> eval e2 r
  76.                         | _ -> raise WrongType)
  77.   | Not (e1) -> (match eval e1 r with
  78.                 | BoolT(true) -> BoolT(false)
  79.                 | BoolT(false) -> BoolT(true)
  80.                 | _ -> raise WrongType)
  81.   | If (e, e1, e2) -> (match eval e r with
  82.                       | BoolT(t) -> if t = true then eval e1 r else eval e2 r
  83.                       | _ -> raise WrongType )
  84.   | Func (i, p, e, e2) -> let c = Closure ( i, p, e, r) in
  85.                           eval e2 (bind i c r)
  86.  
  87.   | Apply(i, e) -> (match applyenv i r with
  88.                     | Closure (funName, funParam, funBody, funEnv) ->
  89.                       let paramVal = eval e r in
  90.                       eval funBody (bind funParam paramVal r)
  91.                     | _ -> raise NonFunctional)
  92.                    
  93. (*let x = 2;;
  94.   let y = 3;;
  95.   if x = y then x + y else x - y
  96. *)
  97. let testexp = Let("x", Cst(2), (
  98.                   Let("y", Cst(3), (
  99.                   If( Eq ( Var("x"), Var("y") ),
  100.                       Add( Var("x"), Var("y") ),
  101.                       Min( Var("x"), Var("y") )
  102.                     )
  103.                   ) )
  104.                 ) );;
  105.  
  106. let funct =   Func("const5", "x", Var("x"),
  107.               Apply("const5", Cst(123)))
  108. let factorial = Func("fact", "x",
  109.                 If( NEq(Var("x"), Cst(1)),
  110.                     Mul(Var("x"), Apply("fact", Min(Var("x"), Cst(1) ) )),
  111.                     Cst(1)),
  112.                 Apply("fact", Cst(6)))
  113. let evalt = eval factorial emptyenv;;
  114. match evalt with
  115. | CstT(i) -> print_string (string_of_int i)
  116. | _ -> failwith "DUDE WHAT THE FUCK"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement