fix: fix merge breaks, add function names to scope before renaming bodies

This commit is contained in:
2025-02-05 20:41:49 +00:00
parent 6027bea95e
commit 0f18bca7fd
4 changed files with 35 additions and 34 deletions

View File

@@ -41,30 +41,34 @@ object renamer {
): Map[Ident, SemType] =
given globalNames: mutable.Map[Ident, SemType] = mutable.Map.empty
given globalNumbering: mutable.Map[String, Int] = mutable.Map.empty
rename(Scope(mutable.Map.empty, Map.empty))(prog)
val scope = Scope(mutable.Map.empty, Map.empty)
val Program(funcs, main) = prog
funcs
.map { case FuncDecl(retType, name, params, body) =>
val paramTypes = params.map { param =>
val paramType = SemType(param.paramType)
paramType
}
scope.add(KnownType.Func(SemType(retType), paramTypes), name, IdentType.Func)
(params zip paramTypes, body)
}
.foreach { case (params, body) =>
val functionScope = scope.subscope
params.foreach { case (param, paramType) =>
functionScope.add(paramType, param.name, IdentType.Var)
}
body.toList.foreach(rename(functionScope.subscope)) // body can shadow function params
}
main.toList.foreach(rename(scope))
globalNames.toMap
private def rename(scope: Scope)(
node: Program | FuncDecl | Ident | Stmt | LValue | RValue
node: Ident | Stmt | LValue | RValue
)(using
globalNames: mutable.Map[Ident, SemType],
globalNumbering: mutable.Map[String, Int],
errors: mutable.Builder[Error, List[Error]]
): Unit = node match {
case Program(funcs, main) => {
funcs.foreach(rename(scope))
main.toList.foreach(rename(scope))
}
case FuncDecl(retType, name, params, body) => {
val functionScope = scope.subscope
val paramTypes = params.map { param =>
val paramType = SemType(param.paramType)
functionScope.add(paramType, param.name, IdentType.Var)
paramType
}
scope.add(KnownType.Func(SemType(retType), paramTypes), name, IdentType.Func)
body.toList.foreach(rename(functionScope))
}
case VarDecl(synType, name, value) => {
// Order matters here. Variable isn't declared until after the value is evaluated.
rename(scope)(value)
@@ -112,7 +116,7 @@ object renamer {
}
// Default to variables. Only `call` uses IdentType.Func.
case id: Ident => renameIdent(scope, id, IdentType.Var)
case IntLiter(_) | BoolLiter(_) | CharLiter(_) | StrLiter(_) | PairLiter | Skip => ()
case IntLiter(_) | BoolLiter(_) | CharLiter(_) | StrLiter(_) | PairLiter() | Skip() => ()
}
private def renameIdent(scope: Scope, ident: Ident, identType: IdentType)(using