Done with hw1

Signed-off-by: jmug <u.g.a.mariano@gmail.com>
This commit is contained in:
Mariano Uvalle 2025-01-27 15:45:32 -08:00
parent bd50dad69b
commit 3308388106
2 changed files with 89 additions and 7 deletions

View file

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