×
Samples Blogs Make Payment About Us Reviews 4.9/5 Order Now

Add Lambda Functions To Interpreters In Ocaml Assignment Solution

July 04, 2024
Priya Nair
Priya Nair
🇺🇸 United States
OCaml
Priya Nair, a graduate with an M.Sc. in Information Technology from the University of Melbourne, has 9 years of experience in software development and education. She has completed over 800 assignments involving OCaml, ensuring top-quality, customized solutions for students. Her ability to break down complex problems into manageable parts helps students understand and excel in their assignments.
Key Topics
  • Instructions
  • Requirements and Specifications
Tip of the day
Familiarize yourself with OCaml's pattern matching; it simplifies handling recursive data structures like lists and trees, making your code concise and easier to debug.
News
In 2024, Girls Who Code introduced a Data Science + AI track in their free summer programs for high school students, fostering skills in cybersecurity and creative coding​

Instructions

Objective
Write a program to add lambda functions to interpreters in Ocaml.

Requirements and Specifications

an imperative programming language
Screenshots of output
Add lambda functions to interpreter in Ocaml
Source Code
open Ast
exception TypeError
exception UndefinedVar
exception DivByZeroError
(* Remove shadowed bindings *)
let prune_env (env : environment) : environment =
  let binds = List.sort_uniq compare (List.map (fun (id, _) -> id) env) in
  List.map (fun e -> (e, List.assoc e env)) binds
(* Env print function to stdout *)
let print_env_std (env : environment): unit =
  List.fold_left (fun _ (var, value) ->
      match value with
        | Int_Val i -> Printf.printf "- %s => %s\n" var (string_of_int i)
        | Bool_Val b -> Printf.printf "- %s => %s\n" var (string_of_bool b)
        | Closure _ -> ()) () (prune_env env)
(* Env print function to string *)
let print_env_str (env : environment): string =
  List.fold_left (fun acc (var, value) ->
      match value with
        | Int_Val i -> acc ^ (Printf.sprintf "- %s => %s\n" var (string_of_int i))
        | Bool_Val b -> acc ^ (Printf.sprintf "- %s => %s\n" var (string_of_bool b))
        | Closure _ -> acc
      ) "" (prune_env env)
(***********************)
(****** Your Code ******)
(***********************)
(* evaluate an arithmetic expression in an environment *)
let rec eval_expr (e : exp) (env : environment) : value =
  match e with
  | Var n ->
    (match List.assoc_opt n env with
      | None -> raise UndefinedVar
      | Some v -> v)
  | Number n ->
    Int_Val n
  | Plus (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Int_Val (a + b)
      | _ -> raise TypeError)
  | Minus (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Int_Val (a - b)
      | _ -> raise TypeError)
  | Times (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Int_Val (a * b)
      | _ -> raise TypeError)
  | Div (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) ->
          if b != 0 then Int_Val (a / b)
          else raise DivByZeroError
      | _ -> raise TypeError)
  | Mod (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) ->
          if b != 0 then Int_Val (a mod b)
          else raise DivByZeroError
      | _ -> raise TypeError)
  | Eq (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Bool_Val (a = b)
      | (Bool_Val a, Bool_Val b) -> Bool_Val (a = b)
      | _ -> raise TypeError)
  | Leq (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Bool_Val (a <= b)
      | _ -> raise TypeError)
  | Lt (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Int_Val a, Int_Val b) -> Bool_Val (a < b)
      | _ -> raise TypeError)
  | Not e ->
    (match eval_expr e env with
      | Bool_Val a -> Bool_Val (not a)
      | _ -> raise TypeError)
  | And (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Bool_Val a, Bool_Val b) -> Bool_Val (a && b)
      | _ -> raise TypeError)
  | Or (e1, e2) ->
    (match (eval_expr e1 env, eval_expr e2 env) with
      | (Bool_Val a, Bool_Val b) -> Bool_Val (a || b)
      | _ -> raise TypeError)
  | True ->
    Bool_Val true
  | False ->
    Bool_Val false
  | App (e1, e2) ->
    (match eval_expr e1 env with
      | Closure (env', x, e') -> let v = eval_expr e2 env in
                                  eval_expr e' ((x, v)::env')
      | _ -> raise TypeError)
  | Fun (x, e) ->
    Closure (env, x, e)
(* evaluate a command in an environment *)
let rec eval_command (c : com) (env : environment) : environment =
    match c with
    | While (e, c1) ->
      let rec whilerec guard body env' =
        (match eval_expr guard env' with
        | Bool_Val b ->
            if b then whilerec guard body (eval_command body env')
            else env'
        | _ -> raise TypeError)
      in whilerec e c1 env
    | For (e, c1) ->
      let rec forrec n body env' =
        if n > 0 then forrec (n - 1) body (eval_command body env')
        else env'
      in
        (match eval_expr e env with
        | Int_Val i -> forrec i c1 env
        | _ -> raise TypeError)
    | Cond (e, c1, c2) ->
      (match eval_expr e env with
        | Bool_Val b ->
            if b then eval_command c1 env
            else eval_command c2 env
        | _ -> raise TypeError)
    | Comp (c1, c2) ->
      eval_command c2 (eval_command c1 env)
    | Assg (x, e) ->
      (match List.assoc_opt x env with
        | None -> raise UndefinedVar
        | Some v ->
          (match (v, eval_expr e env) with
          | (Int_Val _, Int_Val b) -> (x, Int_Val b)::env
          | (Bool_Val _, Bool_Val b) -> (x, Bool_Val b)::env
          | (Closure _, Closure (env',y,e')) ->
                    (x, Closure (env',y,e'))::env
          | _ -> raise TypeError))
    | Declare (Int_Type, x) ->
      (x, Int_Val 0) :: env
    | Declare (Bool_Type, x) ->
      (x, Bool_Val false) :: env
    | Declare (Lambda_Type, x) ->
      (x, Closure (env, "x", Var "x")) :: env
    | Skip ->
      env

Related Samples

Explore our Ocaml Assignments sample section designed to deepen your functional programming skills. Engage with topics like recursion, pattern matching, data structures, and functional programming paradigms. Each assignment offers clear solutions and insights to enhance your understanding and proficiency in Ocaml. Start mastering functional programming with our expertly curated assignments today.