From: Siraaj Khandkar Date: Tue, 17 Apr 2018 22:29:26 +0000 (-0400) Subject: Rewrite purely functionally X-Git-Url: https://git.xandkar.net/?p=tiger.ml.git;a=commitdiff_plain;h=a437a796f4839dd29c610b1ef0c7a017e89cdc71 Rewrite purely functionally --- diff --git a/exercises/ch01/straight_line_program_interpreter.ml b/exercises/ch01/straight_line_program_interpreter.ml index de4b921..534965f 100644 --- a/exercises/ch01/straight_line_program_interpreter.ml +++ b/exercises/ch01/straight_line_program_interpreter.ml @@ -19,7 +19,8 @@ module Spl : sig | OpExp of exp * binop * exp | EseqExp of stm * exp - val maxargs : stm -> int + val maxargs : stm -> int option + (** Option because a program may not have any print statements at all. *) end = struct type id = string @@ -45,31 +46,40 @@ end = struct * is 2. *) let maxargs stm = - let max = ref 0 in - let rec check_stm = function + let opt_max_update opt n = + match opt with + | None -> Some n + | Some m -> Some (max m n) + in + let opt_max_merge a b = + match a, b with + | None , None -> None + | None , b -> b + | Some _, None -> a + | Some _, Some n -> opt_max_update a n + in + let rec check_stm max_opt stm = + match stm with | PrintStm exps -> - let exps_length = List.length exps in - if exps_length > !max then max := exps_length else (); - List.iter exps ~f:check_exp + List.fold_left exps + ~init:(opt_max_update max_opt (List.length exps)) + ~f:check_exp | AssignStm (_, e) -> - check_exp e + check_exp max_opt e | CompoundStm (s1, s2) -> - check_stm s1; - check_stm s2 - and check_exp = function - | IdExp _ | NumExp _ -> () + opt_max_merge (check_stm max_opt s1) (check_stm max_opt s2) + and check_exp max_opt exp = + match exp with + | IdExp _ | NumExp _ -> max_opt | OpExp (e1, _, e2) -> - check_exp e1; - check_exp e2 + opt_max_merge (check_exp max_opt e1) (check_exp max_opt e2) | EseqExp (s, e) -> - check_stm s; - check_exp e + opt_max_merge (check_stm max_opt s) (check_exp max_opt e) in - check_stm stm; - !max + check_stm None stm end -let spl_prog = +let spl_prog_orig = (* a := 5 + 3; * b := (print(a, a - 1), 10 * a); * print(b) @@ -91,5 +101,24 @@ let spl_prog = ) ) +let spl_prog_noprint = + (* a := 5 + 3; + * b := 10 * a + *) + Spl.CompoundStm + ( Spl.AssignStm + ("a", Spl.OpExp (Spl.NumExp 5, Spl.Plus, Spl.NumExp 3)) + , Spl.AssignStm + ("b", Spl.OpExp (Spl.NumExp 10, Spl.Times, Spl.IdExp "a")) + ) + let () = - Printf.printf "maxargs: %d\n" (Spl.maxargs spl_prog) + let string_of_maxargs int_opt = + match int_opt with + | Some n -> string_of_int n + | None -> "N/A" + in + 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))