| 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
* 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)
)
)
+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))