2025-07-28 22:40:06 +08:00
|
|
|
module TComp
|
|
|
|
include("./parser.jl")
|
|
|
|
using .Parser
|
2025-08-19 23:57:14 +08:00
|
|
|
using Match
|
|
|
|
|
2025-08-21 00:00:59 +08:00
|
|
|
# For pass 2
|
|
|
|
struct SimpleExp
|
|
|
|
binds
|
|
|
|
body
|
|
|
|
end
|
2025-08-19 23:57:14 +08:00
|
|
|
|
|
|
|
inp = ARGS
|
|
|
|
f = open(ARGS[1], "r")
|
|
|
|
prog = read(f, String)
|
|
|
|
|
|
|
|
print(prog)
|
|
|
|
parsed = Parser.totalParse(prog)
|
|
|
|
print(parsed)
|
|
|
|
tmp_var_no = 0
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-08-21 00:00:59 +08:00
|
|
|
# Pass 1: Duplicated varname uniquified
|
|
|
|
function uniquifyVar(parsed, env)
|
2025-08-19 23:57:14 +08:00
|
|
|
@match parsed begin
|
|
|
|
# letrec is not considered
|
|
|
|
#[("%let", "id"), [ty, var], val, [("%lambda", "id"), args, body]] => nothing
|
|
|
|
|
|
|
|
[("%let", "id"), [ty, var], val, body] =>
|
|
|
|
begin
|
|
|
|
envNew = env
|
|
|
|
push!(envNew, var[1]) # push x of var = ("x", "id") in newEnv
|
|
|
|
res = [("%let", "id"),
|
2025-08-21 00:00:59 +08:00
|
|
|
[ty, uniquifyVar(var, envNew)],
|
|
|
|
uniquifyVar(val, env),
|
|
|
|
uniquifyVar(body, envNew)]
|
2025-08-19 23:57:14 +08:00
|
|
|
return res
|
|
|
|
end
|
|
|
|
(var, "id") =>
|
|
|
|
begin
|
|
|
|
reversedEnv = reverse(env)
|
|
|
|
index = length(env) - findfirst(e -> e == var, reversedEnv) + 1
|
2025-08-21 00:00:59 +08:00
|
|
|
newVar = var * string(index)
|
|
|
|
return (newVar, "id")
|
2025-08-19 23:57:14 +08:00
|
|
|
end
|
2025-08-21 00:00:59 +08:00
|
|
|
[("%prime", "id"), op, [lhs, rhs]] =>
|
2025-08-19 23:57:14 +08:00
|
|
|
begin
|
2025-08-21 00:00:59 +08:00
|
|
|
lhs_new = uniquifyVar(lhs, env)
|
|
|
|
rhs_new = uniquifyVar(rhs, env)
|
|
|
|
return [("%prime", "id"), op, [lhs_new, rhs_new]]
|
2025-08-19 23:57:14 +08:00
|
|
|
end
|
|
|
|
[("%call", "id"), callee, args...] =>
|
|
|
|
begin
|
2025-08-21 00:00:59 +08:00
|
|
|
unifiedCallee = uniquifyVar(callee, env)
|
|
|
|
unifiedArgs = map(x ->uniquifyVar(x, env), args[1])
|
2025-08-19 23:57:14 +08:00
|
|
|
|
|
|
|
return vcat([("%call", "id"), unifiedCallee], [unifiedArgs])
|
|
|
|
end
|
|
|
|
(c, "int") => return parsed
|
|
|
|
_ => "Error"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2025-08-21 00:00:59 +08:00
|
|
|
# PASS2 explicit Control and Remove Complex
|
|
|
|
function explicitControlRemoveComplex(prog)
|
|
|
|
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
|
|
|
|
|
2025-08-19 23:57:14 +08:00
|
|
|
|
2025-08-21 00:00:59 +08:00
|
|
|
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))
|
2025-08-19 23:57:14 +08:00
|
|
|
|
|
|
|
close(f)
|
|
|
|
|
2025-07-28 22:40:06 +08:00
|
|
|
|
|
|
|
|
|
|
|
end # module
|