Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- exception EmptyEnv;;
- exception WrongType;;
- exception NonFunctional;;
- type ide = string
- and exp =
- | True
- | False
- | Cst of int
- | Let of ide * exp * exp
- | Var of ide
- | Add of exp * exp
- | Min of exp * exp
- | Mul of exp * exp
- | Eq of exp * exp
- | NEq of exp * exp
- | And of exp * exp
- | Or of exp * exp
- | Not of exp
- | If of exp * exp * exp
- | Func of ide * ide * exp * exp
- | Apply of ide * exp
- and evT =
- | Unbound
- | CstT of int
- | BoolT of bool
- | Closure of ide * ide * exp * env
- and env = (ide -> evT);;
- let emptyenv = fun (x : ide) -> Unbound;;
- let bind (x : ide) (e : evT) r = fun (n : ide) -> if n = x then e else r n;;
- let applyenv (x : ide) ( r : ide -> evT) = r x;;
- let rec eval (e : exp) (r : ide -> evT ) =
- match e with
- | True -> BoolT(true)
- | False -> BoolT(false)
- | Cst ( i ) -> CstT (i)
- | Let ( i, e1, e2 ) -> let v1 = eval e1 r in
- eval e2 (bind i v1 r)
- | Var ( i ) -> applyenv i r
- | Add ( e1, e2) -> ( let v1 = eval e1 r in
- let v2 = eval e2 r in
- match v1, v2 with
- | CstT(a), CstT( b) -> CstT(a + b)
- | _ -> raise WrongType)
- | Min ( e1, e2) -> ( let v1 = eval e1 r in
- let v2 = eval e2 r in
- match v1, v2 with
- | CstT(a), CstT( b) -> CstT(a - b)
- | _ -> raise WrongType)
- | Mul ( e1, e2) -> ( let v1 = eval e1 r in
- let v2 = eval e2 r in
- match v1, v2 with
- | CstT(a), CstT( b) -> CstT(a * b)
- | _ -> raise WrongType)
- | Eq (e1, e2) -> (let v1 = eval e1 r in
- let v2 = eval e2 r in
- match v1, v2 with
- | BoolT(a), BoolT(b) -> if a = b then BoolT(true) else BoolT(false)
- | CstT(a), CstT(b) -> if a = b then BoolT(true) else BoolT(false)
- | _,_ -> raise WrongType )
- | NEq (e1, e2) -> (let v1 = eval e1 r in
- let v2 = eval e2 r in
- match v1, v2 with
- | BoolT(a), BoolT(b) -> if a <> b then BoolT(true) else BoolT(false)
- | CstT(a), CstT(b) -> if a <> b then BoolT(true) else BoolT(false)
- | _,_ -> raise WrongType )
- | And (e1, e2) -> ( match eval e1 r with
- | BoolT(true) -> eval e2 r
- | BoolT(false) -> BoolT (false)
- | _ -> raise WrongType)
- | Or (e1, e2) -> ( match eval e1 r with
- | BoolT(true) -> BoolT( true )
- | BoolT(false) -> eval e2 r
- | _ -> raise WrongType)
- | Not (e1) -> (match eval e1 r with
- | BoolT(true) -> BoolT(false)
- | BoolT(false) -> BoolT(true)
- | _ -> raise WrongType)
- | If (e, e1, e2) -> (match eval e r with
- | BoolT(t) -> if t = true then eval e1 r else eval e2 r
- | _ -> raise WrongType )
- | Func (i, p, e, e2) -> let c = Closure ( i, p, e, r) in
- eval e2 (bind i c r)
- | Apply(i, e) -> (match applyenv i r with
- | Closure (funName, funParam, funBody, funEnv) ->
- let paramVal = eval e r in
- eval funBody (bind funParam paramVal r)
- | _ -> raise NonFunctional)
- (*let x = 2;;
- let y = 3;;
- if x = y then x + y else x - y
- *)
- let testexp = Let("x", Cst(2), (
- Let("y", Cst(3), (
- If( Eq ( Var("x"), Var("y") ),
- Add( Var("x"), Var("y") ),
- Min( Var("x"), Var("y") )
- )
- ) )
- ) );;
- let funct = Func("const5", "x", Var("x"),
- Apply("const5", Cst(123)))
- let factorial = Func("fact", "x",
- If( NEq(Var("x"), Cst(1)),
- Mul(Var("x"), Apply("fact", Min(Var("x"), Cst(1) ) )),
- Cst(1)),
- Apply("fact", Cst(6)))
- let evalt = eval factorial emptyenv;;
- match evalt with
- | CstT(i) -> print_string (string_of_int i)
- | _ -> failwith "DUDE WHAT THE FUCK"
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement