in Ocaml, implement the next part of functionlet rec eval_ession env e = (**)up to the designated pointYou may use the included functions, the Stdlib module, the Str module, the List module, and the Re module. NO IMPERATIVES. NO REFERENCES. NO HASHMAPS. List of each kind of ession:type ession =| Int of int| Bool of bool| String of string| ID of var| Not of ession (*Continue from Here*) | Binop of op * ession * ession (* Stop here: rest of the function will be asked in followup questions *) | If of ession * ession * ession| App of ession * ession| Let of var * bool * ession * ession| Fun of var * ession| Closure of environment * var * ession| Record of (label * ession) list| Select of label * ession type op =| Add| Sub| Mult| Div| Concat| Greater| Less| GreaterEqual| LessEqual| Equal| NotEqual| Or| And FUNCTIONS SO FAR (* Exceptions *) exception TypeError of string exception DeclareError of string exception SelectError of string exception DivByZeroError (* Functions to manage environments *) let extend env x v = (x, ref v) :: env let rec lookup env x = match env with | [] -> raise (DeclareError ("Unbound variable " ^ x)) | (var, value) :: t -> if x = var then !value else lookup t x let extend_tmp env x = (x, ref (Int 0)) :: env let rec update env x v = match env with | [] -> raise (DeclareError ("Unbound variable " ^ x)) | (var, value) :: t -> if x = var then value := v else update t x v (* SO FAR *) let rec eval_ession env e = match e with | Int _ | Bool _ | String _ -> e (* Base cases: these evaluate to themselves *) | ID x -> lookup env x (* Lookup variable in the environment *) | Not e1 -> (match eval_ession env e1 with | Bool b -> Bool (not b) | _ -> raise (TypeError "Expected type bool")) (* CONTINUE FROM HERE *) BinopThere are five sorts of binary operator: Those carrying out integer arithmetic; those carrying out integer ordering comparisons; one carrying out string concatenation; and one carrying out equality (and inequality) comparisons; and those implementing boolean logic. Add, Sub, Mult, and DivArithmetic operators work on integers; if either argument evaluates to a non-Int, a TypeError should be raised. An attempt to divide by zero should raise a DivByZeroError exceptio.eval_ession [] (Binop (Add, (Int 1), (Int 2))) = Int 3eval_ession [] (Binop (Add, (Int 1), (Bool false))) (* TypeError "Expected type int" *)eval_ession [] (Binop (Div, (Int 1), (Int 0))) (* DivByZeroError *) Greater, Less, GreaterEqual, and LessEqualThese relational operators operate only on integers and produce a Bool containing the result of the operation. If either argument evaluates to a non-Int, a TypeError should be raised.eval_ession [] (Binop(Greater, (Int 1), (Int 2))) = Bool falseeval_ession [] (Binop(LessEqual, (Bool false), (Bool true))) (* TypeError "Expected type int" *) ConcatThis operation returns the result of concatenating two strings; if either argument evaluates to a non-String, a TypeError should be raised.eval_ession [] (Binop (Concat, (Int 1), (Int 2))) (* TypeError "Expected type string" *)eval_ession [] (Binop (Concat, (String "hello "), (String "ocaml"))) = String "hello ocaml" Equal and NotEqualThe equality operators require both arguments to be of the same type. The operators produce a Bool containing the result of the operation. If the two arguments to these operators do not evaluate to the same type (e.g., one boolean and one integer), a TypeError should be raised. Moreover, we cannot compare two closures for equality -- to do so risks an infinite loop because of the way recursive functions are implemented; trying to compare them also raises TypeError (OCaml does the same thing in its implementation, BTW).eval_ession [] (Binop(NotEqual, (Int 1), (Int 2))) = Bool trueeval_ession [] (Binop(Equal, (Bool false), (Bool true))) = Bool falseeval_ession [] (Binop(Equal, (String "hi"), (String "hi"))) = Bool trueeval_ession [] (Binop(NotEqual, (Int 1), (Bool false))) (* TypeError "Cannot compare types" *) Or and AndThese logical operations operate only on booleans and produce a Bool result. If either argument evaluates to a non-Bool, a TypeError should be raised.eval_ession [] (Binop(Or, (Int 1), (Int 2))) (* TypeError "Expected type bool" *)eval_ession [] (Binop(Or, (Bool false), (Bool true))) = Bool true
in Ocaml, implement the next part of function
let rec eval_ession env e = (**)
up to the designated point
You may use the included functions, the Stdlib module, the Str module, the List module, and the Re module. NO IMPERATIVES. NO REFERENCES. NO HASHMAPS.
List of each kind of ession:
type ession =
| Int of int
| Bool of bool
| String of string
| ID of var
| Not of ession
(*Continue from Here*)
| Binop of op * ession * ession
(* Stop here: rest of the function will be asked in followup questions *)
| If of ession * ession * ession
| App of ession * ession
| Let of var * bool * ession * ession
| Fun of var * ession
| Closure of environment * var * ession
| Record of (label * ession) list
| Select of label * ession
type op =
| Add
| Sub
| Mult
| Div
| Concat
| Greater
| Less
| GreaterEqual
| LessEqual
| Equal
| NotEqual
| Or
| And
FUNCTIONS SO FAR
(* Exceptions *)
exception TypeError of string
exception DeclareError of string
exception SelectError of string
exception DivByZeroError
(* Functions to manage environments *)
let extend env x v = (x, ref v) :: env
let rec lookup env x = match env with | [] -> raise (DeclareError ("Unbound variable " ^ x)) | (var, value) :: t -> if x = var then !value else lookup t x
let extend_tmp env x = (x, ref (Int 0)) :: env
let rec update env x v = match env with | [] -> raise (DeclareError ("Unbound variable " ^ x)) | (var, value) :: t -> if x = var then value := v else update t x v
(* SO FAR *)
let rec eval_ession env e =
match e with
| Int _ | Bool _ | String _ -> e (* Base cases: these evaluate to themselves *)
| ID x -> lookup env x (* Lookup variable in the environment *)
| Not e1 -> (match eval_ession env e1 with | Bool b -> Bool (not b) | _ -> raise (TypeError "Expected type bool"))
(* CONTINUE FROM HERE *)
Binop
There are five sorts of binary operator: Those carrying out integer arithmetic; those carrying out integer ordering comparisons; one carrying out string concatenation; and one carrying out equality (and inequality) comparisons; and those implementing boolean logic.
Add, Sub, Mult, and Div
Arithmetic operators work on integers; if either argument evaluates to a non-Int, a TypeError should be raised. An attempt to divide by zero should raise a DivByZeroError exceptio.
eval_ession [] (Binop (Add, (Int 1), (Int 2))) = Int 3
eval_ession [] (Binop (Add, (Int 1), (Bool false))) (* TypeError "Expected type int" *)
eval_ession [] (Binop (Div, (Int 1), (Int 0))) (* DivByZeroError *)
Greater, Less, GreaterEqual, and LessEqual
These relational operators operate only on integers and produce a Bool containing the result of the operation. If either argument evaluates to a non-Int, a TypeError should be raised.
eval_ession [] (Binop(Greater, (Int 1), (Int 2))) = Bool false
eval_ession [] (Binop(LessEqual, (Bool false), (Bool true))) (* TypeError "Expected type int" *)
Concat
This operation returns the result of concatenating two strings; if either argument evaluates to a non-String, a TypeError should be raised.
eval_ession [] (Binop (Concat, (Int 1), (Int 2))) (* TypeError "Expected type string" *)
eval_ession [] (Binop (Concat, (String "hello "), (String "ocaml"))) = String "hello ocaml"
Equal and NotEqual
The equality operators require both arguments to be of the same type. The operators produce a Bool containing the result of the operation. If the two arguments to these operators do not evaluate to the same type (e.g., one boolean and one integer), a TypeError should be raised. Moreover, we cannot compare two closures for equality -- to do so risks an infinite loop because of the way recursive functions are implemented; trying to compare them also raises TypeError (OCaml does the same thing in its implementation, BTW).
eval_ession [] (Binop(NotEqual, (Int 1), (Int 2))) = Bool true
eval_ession [] (Binop(Equal, (Bool false), (Bool true))) = Bool false
eval_ession [] (Binop(Equal, (String "hi"), (String "hi"))) = Bool true
eval_ession [] (Binop(NotEqual, (Int 1), (Bool false))) (* TypeError "Cannot compare types" *)
Or and And
These logical operations operate only on booleans and produce a Bool result. If either argument evaluates to a non-Bool, a TypeError should be raised.
eval_ession [] (Binop(Or, (Int 1), (Int 2))) (* TypeError "Expected type bool" *)
eval_ession [] (Binop(Or, (Bool false), (Bool true))) = Bool true
Step by step
Solved in 2 steps