20 enum KExp { |
20 enum KExp { |
21 case KReturn(v: KVal) |
21 case KReturn(v: KVal) |
22 case KLet(x: String, v: KVal, e: KExp) |
22 case KLet(x: String, v: KVal, e: KExp) |
23 } |
23 } |
24 import KExp._ |
24 import KExp._ |
|
25 |
|
26 def pexp(e: KExp): String = e match { |
|
27 case KReturn(v) => s"KReturn($v)" |
|
28 case KLet(x,e1,e2) => s"KLet($x = ${e1} \n in ${pexp(e2)})" |
|
29 } |
25 |
30 |
26 var cnt = -1 |
31 var cnt = -1 |
27 def Fresh(s: String) = { |
32 def Fresh(s: String) = { |
28 cnt = cnt + 1 |
33 cnt = cnt + 1 |
29 s"${s}_${cnt}" |
34 s"${s}_${cnt}" |
58 List(Call("bar", |
63 List(Call("bar", |
59 List(Aop("*", Num(4), Num(-7)))), |
64 List(Aop("*", Num(4), Num(-7)))), |
60 Num(3), |
65 Num(3), |
61 Call("id", List(Num(12)))))) |
66 Call("id", List(Num(12)))))) |
62 |
67 |
63 println(CPSi(etest)) |
68 println(pexp(CPSi(etest))) |
|
69 |
|
70 // Constant Folding |
|
71 def opt(v: KVal, env: Map[String, Int]) : KVal = v match { |
|
72 case KVar(s) => if (env.isDefinedAt(s)) KNum(env(s)) else KVar(s) |
|
73 case KNum(n) => KNum(n) |
|
74 case KAop(op, v1, v2) => (op, opt(v1, env), opt(v2, env)) match { |
|
75 case ("+", KNum(n1), KNum(n2)) => KNum(n1 + n2) |
|
76 case ("*", KNum(n1), KNum(n2)) => KNum(n1 * n2) |
|
77 case (_, v1o, v2o) => KAop(op, v1o, v2o) |
|
78 } |
|
79 case KCall(fname, args) => KCall(fname, args.map(opt(_, env))) |
|
80 } |
|
81 |
|
82 def Koptimise(ke: KExp, env: Map[String, Int] = Map()) : KExp = ke match { |
|
83 case KReturn(v) => KReturn(opt(v, env)) |
|
84 case KLet(x, v, e) => opt(v, env) match { |
|
85 case KNum(n) => Koptimise(e, env + (x -> n)) |
|
86 case vo => KLet(x, vo, Koptimise(e, env)) |
|
87 } |
|
88 } |
|
89 |
|
90 println("\n" ++ pexp(Koptimise(CPSi(etest)))) |