Complete 1.01.p.2
authorSiraaj Khandkar <siraaj@khandkar.net>
Tue, 17 Apr 2018 23:48:01 +0000 (19:48 -0400)
committerSiraaj Khandkar <siraaj@khandkar.net>
Wed, 18 Apr 2018 00:26:38 +0000 (20:26 -0400)
straight line program interpreter - interp

README.md
exercises/ch01/straight_line_program_interpreter.ml

index 44193c3..f711a2e 100644 (file)
--- a/README.md
+++ b/README.md
@@ -13,9 +13,9 @@ Project Plan
 | [x]    | 1.01.1     | --- Modules and interfaces               | 001   | --       | --     | 2018-04-16 | ---------- |
 | [x]    | 1.01.2     | --- Tools and Software                   | 002   | --       | --     | 2018-04-16 | ---------- |
 | [x]    | 1.01.3     | --- Data structures for tree languages   | 003   | --       | --     | 2018-04-16 | ---------- |
-| [-]    | 1.01.p     | --- Program                              | 002   | --       | --     | 2018-04-16 | ---------- |
+| [x]    | 1.01.p     | --- Program                              | 002   | --       | --     | 2018-04-16 | ---------- |
 | [x]    | 1.01.p.1   | ---- interpreter: maxargs                | ---   | --       | --     | 2018-04-17 | 2018-04-17 |
-| [ ]    | 1.01.p.2   | ---- interpreter: interp                 | ---   | --       | --     | ---------- | ---------- |
+| [x]    | 1.01.p.2   | ---- interpreter: interp                 | ---   | --       | --     | 2018-04-17 | 2018-04-17 |
 | [ ]    | 1.01.e     | --- Exercises                            | 002   | --       | --     | ---------- | ---------- |
 | [ ]    | 1.01.e.1.a | ---- tree member                         | ---   | --       | --     | ---------- | ---------- |
 | [ ]    | 1.01.e.1.b | ---- tree key/val                        | ---   | --       | --     | ---------- | ---------- |
index 534965f..1f3edf8 100644 (file)
@@ -1,4 +1,5 @@
 module List = ListLabels
+module String = StringLabels
 
 module Spl : sig
   type id = string
@@ -19,9 +20,32 @@ module Spl : sig
     | OpExp of exp * binop * exp
     | EseqExp of stm * exp
 
+  exception Unknown_identifier of string
+
   val maxargs : stm -> int option
   (** Option because a program may not have any print statements at all. *)
+
+  val interp : stm -> unit
+  (** raises Unknown_identifier, if such is encountered *)
 end = struct
+  module Table : sig
+    type ('k, 'v) t
+    val empty : ('k, 'v) t
+    val set : ('k, 'v) t -> k:'k -> v:'v -> ('k, 'v) t
+    val get : ('k, 'v) t -> k:'k -> 'v option
+  end = struct
+    type ('k, 'v) t = ('k * 'v) list
+    let empty = []
+    let set t ~k ~v = (k, v) :: t
+    let get t ~k =
+      let rec search = function
+        | [] -> None
+        | (key, v) :: _ when key = k -> Some v
+        | (_, _) :: rest -> search rest
+      in
+      search t
+  end
+
   type id = string
 
   type binop =
@@ -40,6 +64,56 @@ end = struct
     | OpExp of exp * binop * exp
     | EseqExp of stm * exp
 
+  exception Unknown_identifier of string
+
+  let interp_binop op v1 v2 =
+    match op with
+    | Plus  -> v1 + v2
+    | Minus -> v1 - v2
+    | Times -> v1 * v2
+    | Div   -> v1 / v2
+
+  let rec interp_stm tbl_0 stm =
+    begin match stm with
+    | PrintStm exps ->
+        let (tbl_1, val_ints) =
+          List.fold_right exps
+            ~init:(tbl_0, [])
+            ~f:(fun e (tbl0, vs) ->
+                let (tbl1, v) = interp_exp tbl0 e in
+                (tbl1, v :: vs)
+            )
+        in
+        let val_strings = List.map val_ints ~f:string_of_int in
+        print_endline (String.concat val_strings ~sep:" ");
+        tbl_1
+    | AssignStm (id, e) ->
+        let (tbl_1, v) = interp_exp tbl_0 e in
+        Table.set tbl_1 ~k:id ~v
+    | CompoundStm (s1, s2) ->
+        let tbl_1 = interp_stm tbl_0 s1 in
+        interp_stm tbl_1 s2
+    end
+  and interp_exp tbl_0 exp =
+    ( match exp with
+    | IdExp id ->
+        ( match Table.get tbl_0 ~k:id with
+        | Some v -> (tbl_0, v)
+        | None   -> raise (Unknown_identifier id)
+        )
+    | NumExp n -> (tbl_0, n)
+    | OpExp (e1, op, e2) ->
+        let (tbl_1, v1) = interp_exp tbl_0 e1 in
+        let (tbl_2, v2) = interp_exp tbl_1 e2 in
+        (tbl_2, interp_binop op v1 v2)
+    | EseqExp (s, e) ->
+        let tbl_1 = interp_stm tbl_0 s in
+        interp_exp tbl_1 e
+    )
+
+  let interp stm : unit =
+    ignore (interp_stm (Table.empty) stm)
+
     (* 01.p.1: Write ML function (maxargs : stm -> int) that tells the
      * maximum number of arguments of any print statement within any
      * subexpression of a given statement. For example, maxargs(prog)
@@ -121,4 +195,7 @@ let () =
   Printf.printf "maxargs : spl_prog_orig -> %s\n"
     (string_of_maxargs (Spl.maxargs spl_prog_orig));
   Printf.printf "maxargs : spl_prog_noprint -> %s\n"
-    (string_of_maxargs (Spl.maxargs spl_prog_noprint))
+    (string_of_maxargs (Spl.maxargs spl_prog_noprint));
+  print_endline "BEGIN Spl.interp spl_prog_orig";
+  Spl.interp spl_prog_orig;
+  print_endline "END Spl.interp spl_prog_orig"
This page took 0.023763 seconds and 4 git commands to generate.