add Pass2
This commit is contained in:
parent
26305b7e0d
commit
c6a9928862
5 changed files with 214 additions and 28 deletions
100
misc/test.jl
Normal file
100
misc/test.jl
Normal file
|
@ -0,0 +1,100 @@
|
||||||
|
prog1 = ["prm", "+", [7, ["+", [5, 4]]]]
|
||||||
|
prog2 = ["prm","+", [["prm", "+", [5, 4]], ["prm","+", [7, 8]]]]
|
||||||
|
|
||||||
|
prog3 = ["prm","+", [["prm","+", [["cal", "foo", 999], 4]], 7]]
|
||||||
|
prog4 = ["prm","+", [1, 2]]
|
||||||
|
|
||||||
|
prog5 = 5
|
||||||
|
|
||||||
|
for i in prog4[2]
|
||||||
|
println(i)
|
||||||
|
end
|
||||||
|
|
||||||
|
struct SimpleExp
|
||||||
|
binds
|
||||||
|
body
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function rmComplex(exp)
|
||||||
|
return rmComplexAux1(exp, 0)
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
function rmComplexAux1(exp, varNo)
|
||||||
|
if exp[1] == "let"
|
||||||
|
res = splitLet([], exp, varNo)
|
||||||
|
println("RES=~=~", res)
|
||||||
|
tup = rmComplexAux2(SimpleExp(res[1], res[2]), res[3])
|
||||||
|
|
||||||
|
else
|
||||||
|
tup = rmComplexAux2(SimpleExp([], exp), varNo)
|
||||||
|
|
||||||
|
end
|
||||||
|
return tup
|
||||||
|
end
|
||||||
|
|
||||||
|
function rmComplexAux2(exp, varNo)
|
||||||
|
if isa(exp.body, Int) || isa(exp.body, String)
|
||||||
|
return (exp, varNo)
|
||||||
|
elseif isa(exp.body, Array) & (exp.body[1] == "prm" || exp.body[1] == "cal")
|
||||||
|
newResList = exp.binds
|
||||||
|
new_exp_body = Any[exp.body[1], exp.body[2]]
|
||||||
|
new_exp_args = []
|
||||||
|
println("exp_body", exp.body)
|
||||||
|
for i in exp.body[3]
|
||||||
|
res = rmComplexAux1(i, varNo)
|
||||||
|
println("res", res)
|
||||||
|
varNo = res[2]
|
||||||
|
newBind = res[1].binds
|
||||||
|
if newBind != []
|
||||||
|
println("new~~", newBind)
|
||||||
|
newResList = vcat(newResList, newBind)
|
||||||
|
push!(new_exp_args, last(newBind)[2])
|
||||||
|
else
|
||||||
|
push!(new_exp_args, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
push!(new_exp_body, new_exp_args)
|
||||||
|
|
||||||
|
println(newResList)
|
||||||
|
newBindVar = "tmp" * string(varNo)
|
||||||
|
varNo += 1
|
||||||
|
newBind = ["%let", newBindVar, new_exp_body]
|
||||||
|
push!(newResList, newBind)
|
||||||
|
return (SimpleExp(newResList, newBindVar), varNo)
|
||||||
|
else
|
||||||
|
return (exp, varNo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function splitLet(binds, exp, varNo)
|
||||||
|
if exp[1] == "let"
|
||||||
|
res = rmComplexAux1(exp[3], varNo)
|
||||||
|
binds = vcat(binds, res[1].binds)
|
||||||
|
new_exp = res[1].body
|
||||||
|
new_bind = ["%let", exp[2], new_exp]
|
||||||
|
push!(binds, new_bind)
|
||||||
|
|
||||||
|
|
||||||
|
varNo = res[2]
|
||||||
|
return splitLet(binds, exp[4], varNo)
|
||||||
|
else
|
||||||
|
return (binds, exp, varNo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
prog6 = ["let", "x", ["prm", "-", [10, 3]], ["let", "y", ["cal", "foo", [12]], ["prm", "+", [33, "x"]]]]
|
||||||
|
println("SPLITLET: ", splitLet([], prog6, 0))
|
||||||
|
|
||||||
|
println(rmComplex(prog1), "\n\n")
|
||||||
|
|
||||||
|
println(rmComplex(prog2), "\n\n")
|
||||||
|
println(rmComplex(prog3), "\n\n")
|
||||||
|
println(rmComplex(prog4), "\n\n")
|
||||||
|
println(rmComplex(prog5), "\n\n")
|
||||||
|
println(rmComplex(prog6), "\n\n")
|
13
passesInstrument.md
Normal file
13
passesInstrument.md
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
1. **OK**: uniquify deals with the shadowing of variables by renaming every variable to a
|
||||||
|
unique name.
|
||||||
|
2. **OK** remove_complex_operands ensures that each subexpression of a primitive operation or
|
||||||
|
function call is a variable or integer, that is, an atomic expression. We refer
|
||||||
|
to nonatomic expressions as complex. This pass introduces temporary variables
|
||||||
|
to hold the results of complex subexpressions.
|
||||||
|
3. **OK** explicate_control makes the execution order of the program explicit. It converts
|
||||||
|
the abstract syntax tree representation into a graph in which each node is a
|
||||||
|
labeled sequence of statements and the edges are goto statements.
|
||||||
|
4. select_instructions handles the difference between LVar operations and x86
|
||||||
|
instructions. This pass converts each LVar operation to a short sequence of
|
||||||
|
instructions that accomplishes the same task.
|
||||||
|
assign_homes
|
119
src/TComp.jl
119
src/TComp.jl
|
@ -3,6 +3,11 @@ include("./parser.jl")
|
||||||
using .Parser
|
using .Parser
|
||||||
using Match
|
using Match
|
||||||
|
|
||||||
|
# For pass 2
|
||||||
|
struct SimpleExp
|
||||||
|
binds
|
||||||
|
body
|
||||||
|
end
|
||||||
|
|
||||||
inp = ARGS
|
inp = ARGS
|
||||||
f = open(ARGS[1], "r")
|
f = open(ARGS[1], "r")
|
||||||
|
@ -15,8 +20,8 @@ tmp_var_no = 0
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Pass 1 duplicated varname unified
|
# Pass 1: Duplicated varname uniquified
|
||||||
function unifyVar(parsed, env)
|
function uniquifyVar(parsed, env)
|
||||||
@match parsed begin
|
@match parsed begin
|
||||||
# letrec is not considered
|
# letrec is not considered
|
||||||
#[("%let", "id"), [ty, var], val, [("%lambda", "id"), args, body]] => nothing
|
#[("%let", "id"), [ty, var], val, [("%lambda", "id"), args, body]] => nothing
|
||||||
|
@ -26,35 +31,28 @@ function unifyVar(parsed, env)
|
||||||
envNew = env
|
envNew = env
|
||||||
push!(envNew, var[1]) # push x of var = ("x", "id") in newEnv
|
push!(envNew, var[1]) # push x of var = ("x", "id") in newEnv
|
||||||
res = [("%let", "id"),
|
res = [("%let", "id"),
|
||||||
[ty, unifyVar(var, envNew)],
|
[ty, uniquifyVar(var, envNew)],
|
||||||
unifyVar(val, env),
|
uniquifyVar(val, env),
|
||||||
unifyVar(body, envNew)]
|
uniquifyVar(body, envNew)]
|
||||||
return res
|
return res
|
||||||
end
|
end
|
||||||
(var, "id") =>
|
(var, "id") =>
|
||||||
begin
|
begin
|
||||||
reversedEnv = reverse(env)
|
reversedEnv = reverse(env)
|
||||||
index = length(env) - findfirst(e -> e == var, reversedEnv) + 1
|
index = length(env) - findfirst(e -> e == var, reversedEnv) + 1
|
||||||
return (index, "id")
|
newVar = var * string(index)
|
||||||
|
return (newVar, "id")
|
||||||
end
|
end
|
||||||
[(plus, "plus"), lhs, rhs] =>
|
[("%prime", "id"), op, [lhs, rhs]] =>
|
||||||
begin
|
begin
|
||||||
lhs_new = unifyVar(lhs, env)
|
lhs_new = uniquifyVar(lhs, env)
|
||||||
rhs_new = unifyVar(rhs, env)
|
rhs_new = uniquifyVar(rhs, env)
|
||||||
return [(plus, "plus"), lhs_new, rhs_new]
|
return [("%prime", "id"), op, [lhs_new, rhs_new]]
|
||||||
|
|
||||||
end
|
|
||||||
[(minus, "minus"), lhs, rhs] =>
|
|
||||||
begin
|
|
||||||
lhs_new = unifyVar(lhs, env)
|
|
||||||
rhs_new = unifyVar(rhs, env)
|
|
||||||
return [(minus, "minus"), lhs_new, rhs_new]
|
|
||||||
|
|
||||||
end
|
end
|
||||||
[("%call", "id"), callee, args...] =>
|
[("%call", "id"), callee, args...] =>
|
||||||
begin
|
begin
|
||||||
unifiedCallee = unifyVar(callee, env)
|
unifiedCallee = uniquifyVar(callee, env)
|
||||||
unifiedArgs = map(x ->unifyVar(x, env), args[1])
|
unifiedArgs = map(x ->uniquifyVar(x, env), args[1])
|
||||||
|
|
||||||
return vcat([("%call", "id"), unifiedCallee], [unifiedArgs])
|
return vcat([("%call", "id"), unifiedCallee], [unifiedArgs])
|
||||||
end
|
end
|
||||||
|
@ -63,11 +61,86 @@ function unifyVar(parsed, env)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
emptyEnv = []
|
# PASS2 explicit Control and Remove Complex
|
||||||
res = unifyVar(parsed, emptyEnv)
|
function explicitControlRemoveComplex(prog)
|
||||||
print(res)
|
function rmComplex(exp)
|
||||||
|
return rmComplexAux1(exp, 0)
|
||||||
|
end
|
||||||
|
function rmComplexAux1(exp, varNo)
|
||||||
|
if exp[1] == ("%let", "id")
|
||||||
|
res = splitLet([], exp, varNo)
|
||||||
|
tup = rmComplexAux2(SimpleExp(res[1], res[2]), res[3])
|
||||||
|
else
|
||||||
|
tup = rmComplexAux2(SimpleExp([], exp), varNo)
|
||||||
|
end
|
||||||
|
return tup
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
function rmComplexAux2(exp, varNo)
|
||||||
|
|
||||||
|
return @match exp.body begin
|
||||||
|
(c, "int") => return (exp, varNo)
|
||||||
|
(v, "id") => return (exp, varNo)
|
||||||
|
[(id, "id"), caller, callee] where (id == "%prime" || id == "%call") =>
|
||||||
|
begin
|
||||||
|
newResList = exp.binds
|
||||||
|
new_exp_body = Any[(id, "id"), caller]
|
||||||
|
new_exp_args = []
|
||||||
|
|
||||||
|
for i in callee
|
||||||
|
res = rmComplexAux1(i, varNo)
|
||||||
|
varNo = res[2]
|
||||||
|
newBind = res[1].binds
|
||||||
|
if newBind != []
|
||||||
|
newResList = vcat(newResList, newBind)
|
||||||
|
push!(new_exp_args, last(newBind)[2])
|
||||||
|
else
|
||||||
|
push!(new_exp_args, i)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
push!(new_exp_body, new_exp_args)
|
||||||
|
|
||||||
|
println(newResList)
|
||||||
|
newBindVar = "tmp" * string(varNo)
|
||||||
|
varNo += 1
|
||||||
|
newBind = [("%let", "id"), newBindVar, new_exp_body]
|
||||||
|
push!(newResList, newBind)
|
||||||
|
return (SimpleExp(newResList, newBindVar), varNo)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
_ => "Error"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function splitLet(binds, exp, varNo)
|
||||||
|
if exp[1] == ("%let", "id")
|
||||||
|
res = rmComplexAux1(exp[3], varNo)
|
||||||
|
binds = vcat(binds, res[1].binds)
|
||||||
|
new_exp = res[1].body
|
||||||
|
new_bind = [("%let", "id"), exp[2], new_exp]
|
||||||
|
push!(binds, new_bind)
|
||||||
|
|
||||||
|
|
||||||
|
varNo = res[2]
|
||||||
|
return splitLet(binds, exp[4], varNo)
|
||||||
|
else
|
||||||
|
return (binds, exp, varNo)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return rmComplex(prog)[1]
|
||||||
|
end
|
||||||
|
|
||||||
|
emptyEnv = []
|
||||||
|
res = uniquifyVar(parsed, emptyEnv)
|
||||||
|
println("PASS1", res)
|
||||||
|
res2 = explicitControlRemoveComplex(res)
|
||||||
|
println("PASS2", Parser.prettyStringLisp(res2.binds), ", ", Parser.prettyStringLisp(res2.body))
|
||||||
|
|
||||||
close(f)
|
close(f)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -147,7 +147,7 @@ function prettyStringLisp(ele)
|
||||||
if isa(ele, String)
|
if isa(ele, String)
|
||||||
return ele
|
return ele
|
||||||
elseif isa(ele, Tuple)
|
elseif isa(ele, Tuple)
|
||||||
res = prettyStringLisp(ele[1])
|
res = string(prettyStringLisp(ele[1]))
|
||||||
return res
|
return res
|
||||||
elseif isa(ele, Array)
|
elseif isa(ele, Array)
|
||||||
mappedEle = map(prettyStringLisp, ele)
|
mappedEle = map(prettyStringLisp, ele)
|
||||||
|
@ -303,7 +303,7 @@ function longTermAux(input)
|
||||||
rawFunc = seq([factor, (typ("mul") | typ("div")), factor])
|
rawFunc = seq([factor, (typ("mul") | typ("div")), factor])
|
||||||
rawRes = rawFunc.fun(input)
|
rawRes = rawFunc.fun(input)
|
||||||
if rawRes != nothing
|
if rawRes != nothing
|
||||||
matched = [rawRes.matched[2], rawRes.matched[1], rawRes.matched[3]]
|
matched = [("%prime", "id"), rawRes.matched[2], [rawRes.matched[1], rawRes.matched[3]]]
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
|
@ -325,7 +325,7 @@ function longExpAux(input)
|
||||||
rawFunc = seq([term, (typ("plus") | typ("minus")), term])
|
rawFunc = seq([term, (typ("plus") | typ("minus")), term])
|
||||||
rawRes = rawFunc.fun(input)
|
rawRes = rawFunc.fun(input)
|
||||||
if rawRes != nothing
|
if rawRes != nothing
|
||||||
matched = [rawRes.matched[2], rawRes.matched[1], rawRes.matched[3]]
|
matched = [("%prime", "id"), rawRes.matched[2], [rawRes.matched[1], rawRes.matched[3]]]
|
||||||
res = ParserResult(matched, rawRes.remained)
|
res = ParserResult(matched, rawRes.remained)
|
||||||
return res
|
return res
|
||||||
else
|
else
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
int a = 12;
|
int a = 12;
|
||||||
int b = 12;
|
int b = (12 + (0 - a));
|
||||||
int a = 15;
|
int a = (15 + b);
|
||||||
int d = 20;
|
int d = 20;
|
||||||
a + d((0 - a), b)
|
a + d((0 - a), b)
|
Loading…
Reference in a new issue