(************************************************************************** * You can add new test cases by adding new elements to the following lists * Format is: * TESTARG(, , , , ..., ) * * is the number of argument that the function being tested takes. **************************************************************************) open Str;; let example_1 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [], [ ], Integer(0)) ]) ]);; let example_2 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b"))], [Assignment( Identifier("b"), MethodCall( NewId(Identifier("Foo")), Identifier("start"), [])) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [], [ Method( IntType, Identifier("start"), [], [], [], Integer(1)) ]) ]);; let example_3 = Program( [ Class( Identifier("Test"), Identifier(""), [StaticVar(IntType, Identifier("g"))], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(ArrayType(Boolean), Identifier("b"))], [Assignment( Identifier("b"), NewArray(Boolean, Integer(3))); ArrayAssignment( Identifier("b"), Integer(2), False); ArrayAssignment( Identifier("b"), Integer(1), Not(True)) ], Integer(0)); Method( IntType, Identifier("sub"), [], [Var(IntType, Identifier("a"))], [Block( [Assignment( Identifier("a"), Integer(0))]) ], Integer(0)) ]) ]);; let example_4 = Program( [ Class( Identifier("Test"), Identifier(""), [Var(IntType, Identifier("g")); Var(IntType, Identifier("h"))], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [], [While( True, If( False, Break, Continue)) ], Integer(0)) ]) ]);; let example_5 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(FloatType, Identifier("b")); Var(FloatType, Identifier("c"))], [Assignment( Identifier("b"), Float(3.4)) ], Integer(0)) ]) ]);; let example_6 = Program( [ Class( Identifier("Test"), Identifier(""), [Var(IdType(Identifier("Foo")), Identifier("g"))], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(StringType, Identifier("b")); Var(StringType, Identifier("c"))], [Assignment( Identifier("b"), String("Nice")) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [Var(IntType, Identifier("g")); StaticVar(IntType, Identifier("h"))], [ Method( IntType, Identifier("start"), [], [], [], Integer(1)) ]) ]);; let example_7 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), Operation(Integer(1), Plus, Integer(333)) ); Assignment( Identifier("c"), Operation(Integer(3), Multiplication, Integer(11)) ) ], Integer(0)) ]) ]);; let example_8 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), Operation(Integer(1), Minus, Integer(333)) ); Assignment( Identifier("c"), Operation(Integer(3), Division, Integer(11)) ) ], Integer(0)) ]) ]);; let example_9 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(Boolean, Identifier("b")); Var(Boolean, Identifier("c"))], [ Assignment( Identifier("b"), Not(Operation(Not(True), And, False)) ); Assignment( Identifier("c"), Operation(True, Or, Not(False)) ) ], Integer(0)) ]) ]);; let example_10 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b")); Var(StringType, Identifier("c"))], [ Assignment( Identifier("b"), Length(Id(Identifier("c"))) ) ], Integer(0)) ]); ]);; let example_11 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), MethodCall(NewId(Identifier("Foo")), Identifier("start"), [Integer(10)]) ) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [], [ Method( IntType, Identifier("start"), [(IntType, Identifier("a"))], [], [], Integer(1)) ]) ]);; let example_12 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(ArrayType(IntType), Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), NewArray(IntType, Integer(10)) ); Assignment( Identifier("c"), Array(Id(Identifier("b")), Integer(0)) ) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [], [ Method( IntType, Identifier("start"), [(IntType, Identifier("a"))], [], [], Integer(1)) ]); Class( Identifier("Bar"), Identifier("Foo"), [], [ Method( IntType, Identifier("stop"), [(IntType, Identifier("a"))], [], [], Integer(3)) ]) ]);; let example_13 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(IntType, Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), Operation( Operation(Integer(1), Minus, Integer(333)), Multiplication, Operation(Integer(534), Division, Integer(253)) ) ) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [], [ Method( IntType, Identifier("start"), [(IntType, Identifier("a"))], [], [], Integer(1)) ]); Class( Identifier("Bar"), Identifier("Foo"), [], [ Method( IntType, Identifier("stop"), [(IntType, Identifier("a"))], [], [], Integer(3)) ]) ]);; let example_14 = Program( [ Class( Identifier("Test"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [Var(ArrayType(IdType(Identifier("Foo"))), Identifier("b")); Var(IntType, Identifier("c"))], [ Assignment( Identifier("b"), NewArray(IdType(Identifier("Foo")), Operation(Integer(5), Plus, Integer(10))) ); Block([ ArrayAssignment( Identifier("b"), Operation(Integer(5), Minus, Integer(2)), NewId(Identifier("Foo"))); Assignment( Identifier("c"), MethodCall(Array(Id(Identifier("b")), Integer(3)), Identifier("start"), [Integer(10); Integer(15)]) ) ]) ], Integer(0)) ]); Class( Identifier("Foo"), Identifier(""), [Var(IntType, Identifier("x")); Var(StringType, Identifier("y"))], [ Method( IntType, Identifier("start"), [(IntType, Identifier("a")); (IntType, Identifier("b"))], [Var(IntType, Identifier("f")); Var(StringType, Identifier("w"))], [], Integer(1)) ]); Class( Identifier("Bar"), Identifier("Foo"), [StaticVar(IntType, Identifier("b")); StaticVar(IntType, Identifier("c"))], [ Method( IntType, Identifier("stop"), [(IntType, Identifier("a"))], [Var(IntType, Identifier("e")); Var(StringType, Identifier("d"))], [], Integer(3)) ]) ]);; let example_15 = Program( [ Class( Identifier("Factorial"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [], [Println(MethodCall( NewId(Identifier("Fac")), Identifier("ComputeFac"), [Integer(10)]))], Integer(0)) ]); Class( Identifier("Fac"), Identifier(""), [], [ Method( IntType, Identifier("ComputeFac"), [(IntType, Identifier("num"))], [Var(IntType, Identifier("num_aux"))], [ If( Operation( Id(Identifier("num")), GreaterThan, Integer(1)), Assignment( Identifier("num_aux"), Integer(1)), Assignment( Identifier("num_aux"), Operation( Id(Identifier("num")), Multiplication, MethodCall( This, Identifier("ComputeFac"), [(Operation( Id(Identifier("num")), Minus, Integer(1))) ])))) ], Id(Identifier("num_aux"))) ]) ]);; let example_1_extra = example_15;; let example_1_4hrs = Program( [ Class( Identifier("Test_4hrs"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [], [Println(MethodCall( NewId(Identifier("SubClass")), Identifier("dosomething"), [Integer(1);]))], Integer(0)) ]); Class( Identifier("SubClass"), Identifier(""), [], [ Method( IntType, Identifier("dosomething"), [(IntType, Identifier("i"))], [], [ Switch( Id(Identifier("i")), [(1,[Println(String("one"))]); (2,[Println(String("two"))]); (3,[Println(String("three"))])], [Println(Integer(0))]) ], Id(Identifier("v_3"))) ]) ]);; let example_2_1_extra = example_14;; let example_2_2_extra = Program( [ Class( Identifier("Example"), Identifier(""), [], [ Method( IntType, Identifier("main"), [(ArrayType(StringType), Identifier("a"))], [], [Println(MethodCall( NewId(Identifier("Class_1")), Identifier("Method_1"), [Integer(10); Integer(10)]))], Integer(0)) ]); Class( Identifier("Class_1"), Identifier(""), [Var(IntType, Identifier("v_1")); Var(IntType, Identifier("v_2"))], [ Method( IntType, Identifier("Method_1"), [(IntType, Identifier("v_3")); (IntType, Identifier("v_4"))], [Var(IntType, Identifier("v_5")); Var(Boolean, Identifier("v_6")); Var(ArrayType(IntType), Identifier("v_7"))], [ If( Operation( Id(Identifier("v_5")), GreaterThan, Integer(1)), Assignment( Identifier("v_6"), True), Assignment( Identifier("v_7"), NewArray(IntType, Integer(10)) )) ], Id(Identifier("v_3"))); Method( IntType, Identifier("Method_2"), [(IntType, Identifier("v_8"))], [Var(IntType, Identifier("v_9")); Var(Boolean, Identifier("v_10")); Var(ArrayType(IntType), Identifier("v_11"))], [ If( Operation( Id(Identifier("v_9")), GreaterThan, Integer(1)), Assignment( Identifier("v_10"), True), Assignment( Identifier("v_11"), NewArray(IntType, Integer(10)) )) ], Id(Identifier("v_9"))) ]); Class( Identifier("Class_2"), Identifier("Class_1"), [Var(IntType, Identifier("v_12"))], [ Method( IntType, Identifier("Method_3"), [(IntType, Identifier("v_13"))], [Var(IntType, Identifier("v_14")); Var(Boolean, Identifier("v_15"))], [ If( Operation( Id(Identifier("v_14")), GreaterThan, Integer(1)), Assignment( Identifier("v_15"), True), Assignment( Identifier("v_15"), False)) ], Id(Identifier("v_1"))) ]) ]);; (* -------------------------------------- *) let rec p1_canon str = (p1_canon_process (p1_canon_ws (p1_canon_gt str)) "") and p1_canon_gt str = (Str.global_replace (Str.regexp ">") "<" (str)) and p1_canon_ws str = (Str.global_replace (Str.regexp "\\(\n\\|\t\\| \\)+") "" (str)) (* It should be used after p1_canon_ws *) and p1_canon_process str ret = if str = "" then ret else ( let pos1 = try (Str.search_forward (Str.regexp "=") str 0) with _ -> 60000; and pos2 = try (Str.search_forward (Str.regexp "\\[") str 0) with _ -> 60000; and pos3 = try (Str.search_forward (Str.regexp "return") str 0) with _ -> 60000; and pos4 = try (Str.search_forward (Str.regexp "if(") str 0) with _ -> 60000; and pos5 = try (Str.search_forward (Str.regexp "while(") str 0) with _ -> 60000; and pos6 = try (Str.search_forward (Str.regexp "println(") str 0) with _ -> 60000; and pos7 = try (Str.search_forward (Str.regexp "switch(") str 0) with _ -> 60000; in let min_pos = min_list [pos1;pos2;pos3;pos4;pos5;pos6;pos7] 50000 in if (pos1 = min_pos) then p1_canon_process (Str.string_after str (Str.search_forward (Str.regexp ";") str (pos1 + 1))) (ret ^ (Str.string_before str (pos1 + 1)) ^ (p1_canon_exp (Str.string_after (Str.string_before str (Str.search_forward (Str.regexp ";") str (pos1 + 1))) (pos1 + 1)))) else if(pos2 = min_pos) then p1_canon_process (Str.string_after str (Str.search_forward (Str.regexp "\\]") str (pos2 + 1))) (ret ^ (Str.string_before str (pos2 + 1)) ^ (p1_canon_exp (Str.string_after (Str.string_before str (Str.search_forward (Str.regexp "\\]") str (pos2 + 1))) (pos2 + 1)))) else if(pos3 = min_pos) then p1_canon_process (Str.string_after str (Str.search_forward (Str.regexp ";") str (pos3 + 6))) (ret ^ (Str.string_before str (pos3 + 6)) ^ (p1_canon_exp (Str.string_after (Str.string_before str (Str.search_forward (Str.regexp ";") str (pos3 + 6))) (pos3 + 6)))) else if(pos4 = min_pos) then (let rest = (Str.string_after str (pos4 + 3)) and par_pos = p1_canon_par_pos (Str.string_after str (pos4 + 3)) 0 in if par_pos = (String.length rest) then ret ^ str else p1_canon_process (Str.string_after rest par_pos) (ret ^ (Str.string_before str (pos4 + 3)) ^ (p1_canon_exp (Str.string_before rest par_pos)))) else if(pos5 = min_pos) then (let rest = (Str.string_after str (pos5 + 6)) and par_pos = p1_canon_par_pos (Str.string_after str (pos5 + 6)) 0 in if par_pos = (String.length rest) then ret ^ str else p1_canon_process (Str.string_after rest par_pos) (ret ^ (Str.string_before str (pos5 + 6)) ^ (p1_canon_exp (Str.string_before rest par_pos)))) else if(pos6 = min_pos) then (let rest = (Str.string_after str (pos6 + 8)) and par_pos = p1_canon_par_pos (Str.string_after str (pos6 + 8)) 0 in if par_pos = (String.length rest) then ret ^ str else p1_canon_process (Str.string_after rest par_pos) (ret ^ (Str.string_before str (pos6 + 8)) ^ (p1_canon_exp (Str.string_before rest par_pos)))) else if(pos7 = min_pos) then let rest = (Str.string_after str (pos7 + 7)) and par_pos = (p1_canon_par_pos (Str.string_after str (pos7 + 7)) 0) in if par_pos = (String.length rest) then ret ^ str else p1_canon_process (Str.string_after rest par_pos) (ret ^ (Str.string_before str (pos7 + 7)) ^ (p1_canon_exp (Str.string_before rest par_pos))) else ret ^ str ) and min_list lst min = match lst with [] -> min | hd::rd -> if hd 0 then (1 + p1_canon_par_pos rest (n - 1)) else 0 else 1 + p1_canon_par_pos rest n ) and p1_canon_bra_pos str n = if str = "" then 0 else ( let fst = (Str.string_before str 1) and rest = (Str.string_after str 1) in if fst = "[" then (1 + p1_canon_bra_pos rest (n + 1)) else if fst = "]" then if n > 0 then (1 + p1_canon_bra_pos rest (n - 1)) else 0 else 1 + p1_canon_bra_pos rest n ) (* str doesn't need to be enclosed by () *) and p1_canon_exp str = if str ="" then "" else let fst = (Str.string_before str 1) and rest = (Str.string_after str 1) in if fst = "(" then (let pos = (p1_canon_par_pos rest 0) in if pos = (String.length rest) then str else if pos = ((String.length rest) - 1) then p1_canon_exp (Str.string_before rest ((String.length rest) - 1)) else "(" ^ (p1_canon_exp (Str.string_before rest pos)) ^ ")" ^ (p1_canon_exp2 (Str.string_after rest (pos + 1)))) else if fst = "[" then (let pos = (p1_canon_bra_pos rest 0) in "[" ^ (p1_canon_exp (Str.string_before rest pos)) ^ "]" ^ (p1_canon_exp2 (Str.string_after rest (pos + 1)))) else fst ^ (p1_canon_exp2 rest) (* str maybe need to be enclosed by () *) and p1_canon_exp2 str = if str ="" then "" else let fst = (Str.string_before str 1) and rest = (Str.string_after str 1) in if fst = "(" then (let pos = (p1_canon_par_pos rest 0) in "(" ^ (p1_canon_exp (Str.string_before rest pos)) ^ ")" ^ (p1_canon_exp2 (Str.string_after rest (pos + 1)))) else if fst = "[" then (let pos = (p1_canon_bra_pos rest 0) in "[" ^ (p1_canon_exp (Str.string_before rest pos)) ^ "]" ^ (p1_canon_exp2 (Str.string_after rest (pos + 1)))) else fst ^ (p1_canon_exp2 rest) let p1_canon2 str = p1_canon_process (Str.global_replace (Str.regexp "\\( \\)+") "" (Str.global_replace (Str.regexp "^\t\t\\( \\)") "\t\t\t" (Str.global_replace (Str.regexp "^\t\\( \\)") "\t\t" (Str.global_replace (Str.regexp "^\\( \\)") "\t" (Str.global_replace (Str.regexp "\t") " " (Str.global_replace (Str.regexp "\\(\n\\)+") "\n" (Str.global_replace (Str.regexp ">") "<" str))))))) "" (* Canonicalization function for problem 2 *) let rec p2_canon table = List.sort p2_canon_2 (List.map p2_canon_3 table) and p2_canon_2 (class_name, method_name, vl) (class_name2, method_name2, vl2) = p2_canon_5 class_name class_name2 (p2_canon_5 method_name method_name2 0) and p2_canon_3 (class_name, method_name, vl) = (class_name, method_name, (List.sort p2_canon_4 vl)) and p2_canon_4 variable_1 variable_2 = match (variable_1, variable_2) with (Field(class_name, _, str), Field(class_name2, _, str2)) -> p2_canon_5 class_name class_name2 (p2_canon_5 str str2 0) | (Field(_, _, _), Argument(_, _)) -> -1 | (Field(_, _, _), MethodVar(_, _)) -> -1 | (Argument(_, str), Argument(_,str2)) -> p2_canon_5 str str2 0 | (Argument(_, _), Field(_, _, _)) -> 1 | (Argument(_, _), MethodVar(_, _)) -> -1 | (MethodVar(_, str), MethodVar(_, str2)) -> p2_canon_5 str str2 0 | (MethodVar(_, _), Field(_, _, _)) -> 1 | (MethodVar(_, _), Argument(_, _)) -> 1 and p2_canon_5 str str2 mid = if str = str2 then mid else if str > str2 then 1 else -1 let p1_sol p = print_endline (p1_canon (Solution.pretty_print p)); (p1_canon (Solution.pretty_print p));; let p1_stu p = print_endline (p1_canon (Student.pretty_print p)); (p1_canon (Student.pretty_print p));; let p1b_sol p = print_endline (p1_canon2 (Solution.pretty_print p)); (p1_canon2 (Solution.pretty_print p));; let p1b_stu p = print_endline (p1_canon2 (Student.pretty_print p)); (p1_canon2 (Student.pretty_print p));; let p2_sol p = (p2_canon (Solution.symboltable p));; let p2_stu p = (p2_canon (Student.symboltable p));; let p2extra_sol p = (p2_canon (Solution.symboltable2 p));; let p2extra_stu p = (p2_canon (Student.symboltable2 p));; (* This list is for regular problems *) let rubric = [ TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_1); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_2); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_3); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_4); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_5); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_6); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_7); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_8); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_9); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_10); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_11); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_12); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_13); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_14); TEST1ARG_TWOFUN(1, p1_sol, p1_stu, example_15); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_1); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_2); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_3); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_4); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_5); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_6); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_7); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_8); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_9); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_10); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_11); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_12); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_13); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_14); TEST1ARG_TWOFUN(1, p2_sol, p2_stu, example_15) ] (* Note: the last entry should not be followed by a semicolon. *) (* This list is for extra credit problems *) let extra_rubric = [ (* TEST1ARG(5, pretty_print, example_1_extra); *) TEST1ARG_TWOFUN(5, p1b_sol, p1b_stu, example_1_extra); (* problem 1 for extra *) TEST1ARG_TWOFUN(0, p1_sol, p1_stu, example_1_4hrs); (* problem 1 for 4 hrs students *) TEST1ARG_TWOFUN(2, p2extra_sol, p2extra_stu, example_2_1_extra); (* problem 2 extra *) TEST1ARG_TWOFUN(3, p2extra_sol, p2extra_stu, example_2_2_extra) (* problem 2 extra *) ]