×
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
When working on OCaml assignments, make use of pattern matching to simplify your code. It provides a clean and efficient way to handle different cases, especially for recursive functions and data structures like lists and trees. This can reduce complexity and improve readability.
News
Universities worldwide are seeing a surge in programming enrollment, as coding becomes an essential skill across disciplines. To meet growing academic pressures, more students are seeking online help for programming assignments and coursework.

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.