diff --git a/hw1/bin/hellocaml.ml b/hw1/bin/hellocaml.ml index 1687cca..e1b3b74 100644 --- a/hw1/bin/hellocaml.ml +++ b/hw1/bin/hellocaml.ml @@ -846,7 +846,12 @@ let e3 : exp = Mult (Var "y", Mult (e2, Neg e2)) (* "y * ((x+1) * -(x+1))" *) Hint: you probably want to use the 'union' function you wrote for Problem 3-5. *) let rec vars_of (e : exp) : string list = - failwith "vars_of unimplemented" + match e with + | Var v -> [v] + | Const _ -> [] + | Add (a1, a2) -> union (vars_of a1) (vars_of a2) + | Mult (m1, m2) -> union (vars_of m1) (vars_of m2) + | Neg n1 -> vars_of n1 (* How should we _interpret_ (i.e. give meaning to) an expression? @@ -908,7 +913,11 @@ let ctxt2 : ctxt = [ ("x", 2L); ("y", 7L) ] (* maps "x" to 2L, "y" to 7L *) such value, it should raise the Not_found exception. *) let rec lookup (x : string) (c : ctxt) : int64 = - failwith "unimplemented" + match c with + | [] -> raise Not_found + | (n, v) :: t -> + if x = n then v + else lookup x t (* Problem 4-3 @@ -934,7 +943,20 @@ let rec lookup (x : string) (c : ctxt) : int64 = *) let rec interpret (c : ctxt) (e : exp) : int64 = - failwith "unimplemented" + match e with + | Var v -> lookup v c + | Const c -> c + | Add (e1, e2) -> + let a1 = interpret c e1 in + let a2 = interpret c e2 in + Int64.add a1 a2 + | Mult (e1, e2) -> + let m1 = interpret c e1 in + let m2 = interpret c e2 in + Int64.mul m1 m2 + | Neg e1 -> + let n1 = interpret c e1 in + Int64.neg n1 (* Problem 4-4 @@ -979,7 +1001,33 @@ let rec interpret (c : ctxt) (e : exp) : int64 = *) let rec optimize (e : exp) : exp = - failwith "optimize unimplemented" + match e with + | Var _ -> e + | Const _ -> e + | Neg n1 -> + let n1 = optimize n1 in + (match n1 with + | Neg n2 -> n2 + | Const c1 -> if c1 = 0L then Const 0L else Const (Int64.neg c1) + | _ -> Neg n1) + | Mult (e1, e2) -> + let e1 = optimize e1 in + let e2 = optimize e2 in + (match (e1, e2) with + | (Const c1, Const c2) -> Const (Int64.mul c1 c2) + | (Const 0L, _) -> Const 0L + | (_, Const 0L) -> Const 0L + | (Const 1L, _) -> e2 + | (_, Const 1L) -> e1 + | _ -> Mult (e1, e2)) + | Add (e1, e2) -> + let e1 = optimize e1 in + let e2 = optimize e2 in + match (e1, e2) with + | (Const c1, Const c2) -> Const (Int64.add c1 c2) + | (Const 0L, _) -> e2 + | (_, Const 0L) -> e1 + | _ -> Add (e1, e2) (******************************************************************************) (* *) @@ -1020,8 +1068,7 @@ type insn = | IPushV of string (* push (lookup string ctxt) onto the stack *) | IMul (* multiply the top two values on the stack *) | IAdd (* add the top two values on the stack *) - | INeg -(* negate the top value on the stack *) + | INeg (* negate the top value on the stack *) (* A stack program is just a list of instructions. *) type program = insn list @@ -1117,7 +1164,20 @@ let ans1 = run [] p1 - You should test the correctness of your compiler on several examples. *) let rec compile (e : exp) : program = - failwith "compile unimplemented" + match e with + | Const c -> [ IPushC c ] + | Var v -> [ IPushV v ] + | Add (e1, e2) -> + let p1 = compile e1 in + let p2 = compile e2 in + append p1 (append p2 [ IAdd ]) + | Mult (e1, e2) -> + let p1 = compile e1 in + let p2 = compile e2 in + append p1 (append p2 [ IMul ]) + | Neg e1 -> + let p1 = compile e1 in + append p1 [ INeg ] (************) (* Epilogue *) diff --git a/hw1/test/studenttests.ml b/hw1/test/studenttests.ml index cd3d6a6..571af0c 100644 --- a/hw1/test/studenttests.ml +++ b/hw1/test/studenttests.ml @@ -6,11 +6,33 @@ open Hellocaml (* You should also add additional test cases here to help you *) (* debug your program. *) +let e1 = Mult(Add(Const 1L, Const 2L), Add(Const 3L, Const 4L)) +let e2 = Add(Mult(Const 1L, Const 2L), Mult(Const 3L, Const 4L)) +let ctx3 = [("x", 10L); ("y", 20L)] +let e3 = Add(Mult(Const 1L, Var "x"), Mult(Var "y", Const 4L)) + let student_tests : suite = [ Test ("Student-Provided Tests For Problem 1-3", [ ("case1", assert_eqf (fun () -> prob3_ans) 42); ("case2", assert_eqf (fun () -> (prob3_case2 17)) 25); ("case3", assert_eqf (fun () -> prob3_case3) 64); ]); + + Test ("Student-Provided Tests for Problem 4-1", [ + ("vars_of1", assert_eqf (fun () -> vars_of (Mult(Mult( Var "z", Var "w" ), Mult (Var "y", Mult (Var "x", Const 1L))))) ["w"; "x"; "y"; "z"]); + ]); + + Test ("Student-Provided Tests for Problem 4-4", [ + ("optimize1", assert_eqf (fun () -> optimize (Neg(Neg(Const 0L)))) (Const 0L)); + ("optimize2", assert_eqf (fun () -> optimize (Neg(Neg(Neg(Const 0L))))) (Const 0L)); + ("optimize3", assert_eqf (fun () -> optimize (Neg(Neg(Neg(Const 1L))))) (Const (-1L))); + ("optimize4", assert_eqf (fun () -> optimize (Mult(Add(Const 5L, Const 5L), Neg(Neg(Const 1L))))) (Const (10L))); + ]); + + Test ("Student-Provided Tests for Problem 5", [ + ("compile1", assert_eqf (fun () -> interpret [] e1) (answer (execute [] [] (compile e1)))); + ("compile2", assert_eqf (fun () -> interpret [] e2) (answer (execute [] [] (compile e2)))); + ("compile3", assert_eqf (fun () -> interpret ctx3 e3) (answer (execute ctx3 [] (compile e3)))); + ]); ]