Commit | Line | Data |
---|---|---|
3c647fbc SK |
1 | module List = ListLabels |
2 | ||
3 | module Spl : sig | |
4 | type id = string | |
5 | ||
6 | type binop = | |
7 | | Plus | |
8 | | Minus | |
9 | | Times | |
10 | | Div | |
11 | ||
12 | type stm = | |
13 | | CompoundStm of stm * stm | |
14 | | AssignStm of id * exp | |
15 | | PrintStm of exp list | |
16 | and exp = | |
17 | | IdExp of id | |
18 | | NumExp of int | |
19 | | OpExp of exp * binop * exp | |
20 | | EseqExp of stm * exp | |
21 | ||
22 | val maxargs : stm -> int | |
23 | end = struct | |
24 | type id = string | |
25 | ||
26 | type binop = | |
27 | | Plus | |
28 | | Minus | |
29 | | Times | |
30 | | Div | |
31 | ||
32 | type stm = | |
33 | | CompoundStm of stm * stm | |
34 | | AssignStm of id * exp | |
35 | | PrintStm of exp list | |
36 | and exp = | |
37 | | IdExp of id | |
38 | | NumExp of int | |
39 | | OpExp of exp * binop * exp | |
40 | | EseqExp of stm * exp | |
41 | ||
42 | (* 01.p.1: Write ML function (maxargs : stm -> int) that tells the | |
43 | * maximum number of arguments of any print statement within any | |
44 | * subexpression of a given statement. For example, maxargs(prog) | |
45 | * is 2. | |
46 | *) | |
47 | let maxargs stm = | |
48 | let max = ref 0 in | |
49 | let rec check_stm = function | |
50 | | PrintStm exps -> | |
51 | let exps_length = List.length exps in | |
52 | if exps_length > !max then max := exps_length else (); | |
53 | List.iter exps ~f:check_exp | |
54 | | AssignStm (_, e) -> | |
55 | check_exp e | |
56 | | CompoundStm (s1, s2) -> | |
57 | check_stm s1; | |
58 | check_stm s2 | |
59 | and check_exp = function | |
60 | | IdExp _ | NumExp _ -> () | |
61 | | OpExp (e1, _, e2) -> | |
62 | check_exp e1; | |
63 | check_exp e2 | |
64 | | EseqExp (s, e) -> | |
65 | check_stm s; | |
66 | check_exp e | |
67 | in | |
68 | check_stm stm; | |
69 | !max | |
70 | end | |
71 | ||
72 | let spl_prog = | |
73 | (* a := 5 + 3; | |
74 | * b := (print(a, a - 1), 10 * a); | |
75 | * print(b) | |
76 | *) | |
77 | Spl.CompoundStm | |
78 | ( Spl.AssignStm ("a", Spl.OpExp (Spl.NumExp 5, Spl.Plus, Spl.NumExp 3)) | |
79 | , Spl.CompoundStm | |
80 | ( Spl.AssignStm | |
81 | ( "b" | |
82 | , Spl.EseqExp | |
83 | ( Spl.PrintStm | |
84 | [ Spl.IdExp "a" | |
85 | ; Spl.OpExp (Spl.IdExp "a", Spl.Minus, Spl.NumExp 1) | |
86 | ] | |
87 | , Spl.OpExp (Spl.NumExp 10, Spl.Times, Spl.IdExp "a") | |
88 | ) | |
89 | ) | |
90 | , Spl.PrintStm [Spl.IdExp "b"] | |
91 | ) | |
92 | ) | |
93 | ||
94 | let () = | |
95 | Printf.printf "maxargs: %d\n" (Spl.maxargs spl_prog) |