fix: fix merge breaks, add function names to scope before renaming bodies
This commit is contained in:
parent
ae9625b586
commit
74f62ea933
@ -34,7 +34,7 @@ def compile(contents: String): Int = {
|
|||||||
parser.parse(contents) match {
|
parser.parse(contents) match {
|
||||||
case Success(ast) =>
|
case Success(ast) =>
|
||||||
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
|
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
|
||||||
val names = renamer.rename(ast)
|
renamer.rename(ast)
|
||||||
// given ctx: types.TypeCheckerCtx[List[Error]] =
|
// given ctx: types.TypeCheckerCtx[List[Error]] =
|
||||||
// types.TypeCheckerCtx(names, errors)
|
// types.TypeCheckerCtx(names, errors)
|
||||||
// types.check(ast)
|
// types.check(ast)
|
||||||
|
@ -27,10 +27,10 @@ object ast {
|
|||||||
case class StrLiter(v: String)(pos: Position) extends Expr6
|
case class StrLiter(v: String)(pos: Position) extends Expr6
|
||||||
object StrLiter extends ParserBridgePos1[String, StrLiter]
|
object StrLiter extends ParserBridgePos1[String, StrLiter]
|
||||||
case class PairLiter()(pos: Position) extends Expr6
|
case class PairLiter()(pos: Position) extends Expr6
|
||||||
object PairLiter extends Expr6 with ParserBridgePos0[PairLiter]
|
object PairLiter extends ParserBridgePos0[PairLiter]
|
||||||
case class Ident(v: String, var uid: Int = -1) extends Expr6 with LValue
|
case class Ident(v: String, var uid: Int = -1)(pos: Position) extends Expr6 with LValue
|
||||||
object Ident extends ParserBridgePos1[String, Ident] {
|
object Ident extends ParserBridgePos1[String, Ident] {
|
||||||
def apply(x1: String): Ident = new Ident(x1)
|
def apply(v: String)(pos: Position): Ident = new Ident(v)(pos)
|
||||||
}
|
}
|
||||||
case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position)
|
case class ArrayElem(name: Ident, indices: NonEmptyList[Expr])(pos: Position)
|
||||||
extends Expr6
|
extends Expr6
|
||||||
@ -46,18 +46,15 @@ object ast {
|
|||||||
sealed trait UnaryOp extends Expr {
|
sealed trait UnaryOp extends Expr {
|
||||||
val x: Expr
|
val x: Expr
|
||||||
}
|
}
|
||||||
sealed trait UnaryOp extends Expr {
|
case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
|
||||||
val x: Expr
|
|
||||||
}
|
|
||||||
case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
|
|
||||||
object Negate extends ParserBridgePos1[Expr6, Negate]
|
object Negate extends ParserBridgePos1[Expr6, Negate]
|
||||||
case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
|
case class Not(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
|
||||||
object Not extends ParserBridgePos1[Expr6, Not]
|
object Not extends ParserBridgePos1[Expr6, Not]
|
||||||
case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
|
case class Len(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
|
||||||
object Len extends ParserBridgePos1[Expr6, Len]
|
object Len extends ParserBridgePos1[Expr6, Len]
|
||||||
case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
|
case class Ord(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
|
||||||
object Ord extends ParserBridgePos1[Expr6, Ord]
|
object Ord extends ParserBridgePos1[Expr6, Ord]
|
||||||
case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp
|
case class Chr(x: Expr6)(pos: Position) extends Expr6 with UnaryOp
|
||||||
object Chr extends ParserBridgePos1[Expr6, Chr]
|
object Chr extends ParserBridgePos1[Expr6, Chr]
|
||||||
|
|
||||||
// Binary operators
|
// Binary operators
|
||||||
|
@ -41,30 +41,34 @@ object renamer {
|
|||||||
): Map[Ident, SemType] =
|
): Map[Ident, SemType] =
|
||||||
given globalNames: mutable.Map[Ident, SemType] = mutable.Map.empty
|
given globalNames: mutable.Map[Ident, SemType] = mutable.Map.empty
|
||||||
given globalNumbering: mutable.Map[String, Int] = 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
|
globalNames.toMap
|
||||||
|
|
||||||
private def rename(scope: Scope)(
|
private def rename(scope: Scope)(
|
||||||
node: Program | FuncDecl | Ident | Stmt | LValue | RValue
|
node: Ident | Stmt | LValue | RValue
|
||||||
)(using
|
)(using
|
||||||
globalNames: mutable.Map[Ident, SemType],
|
globalNames: mutable.Map[Ident, SemType],
|
||||||
globalNumbering: mutable.Map[String, Int],
|
globalNumbering: mutable.Map[String, Int],
|
||||||
errors: mutable.Builder[Error, List[Error]]
|
errors: mutable.Builder[Error, List[Error]]
|
||||||
): Unit = node match {
|
): 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) => {
|
case VarDecl(synType, name, value) => {
|
||||||
// Order matters here. Variable isn't declared until after the value is evaluated.
|
// Order matters here. Variable isn't declared until after the value is evaluated.
|
||||||
rename(scope)(value)
|
rename(scope)(value)
|
||||||
@ -112,7 +116,7 @@ object renamer {
|
|||||||
}
|
}
|
||||||
// Default to variables. Only `call` uses IdentType.Func.
|
// Default to variables. Only `call` uses IdentType.Func.
|
||||||
case id: Ident => renameIdent(scope, id, IdentType.Var)
|
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
|
private def renameIdent(scope: Scope, ident: Ident, identType: IdentType)(using
|
||||||
|
@ -17,14 +17,14 @@ object types {
|
|||||||
|
|
||||||
object SemType {
|
object SemType {
|
||||||
def apply(synType: Type | PairElemType): KnownType = synType match {
|
def apply(synType: Type | PairElemType): KnownType = synType match {
|
||||||
case IntType => KnownType.Int
|
case IntType() => KnownType.Int
|
||||||
case BoolType => KnownType.Bool
|
case BoolType() => KnownType.Bool
|
||||||
case CharType => KnownType.Char
|
case CharType() => KnownType.Char
|
||||||
case StringType => KnownType.String
|
case StringType() => KnownType.String
|
||||||
case ArrayType(elemType, dimension) =>
|
case ArrayType(elemType, dimension) =>
|
||||||
(0 until dimension).foldLeft(SemType(elemType))((acc, _) => KnownType.Array(acc))
|
(0 until dimension).foldLeft(SemType(elemType))((acc, _) => KnownType.Array(acc))
|
||||||
case PairType(fst, snd) => KnownType.Pair(SemType(fst), SemType(snd))
|
case PairType(fst, snd) => KnownType.Pair(SemType(fst), SemType(snd))
|
||||||
case UntypedPairType => KnownType.Pair(?, ?)
|
case UntypedPairType() => KnownType.Pair(?, ?)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user