From 74f62ea933bf7fc6ae838318151a8b4056a38a8a Mon Sep 17 00:00:00 2001 From: Gleb Koval Date: Wed, 5 Feb 2025 20:41:49 +0000 Subject: [PATCH] fix: fix merge breaks, add function names to scope before renaming bodies --- src/main/wacc/Main.scala | 2 +- src/main/wacc/ast.scala | 19 ++++++++----------- src/main/wacc/renamer.scala | 38 ++++++++++++++++++++----------------- src/main/wacc/types.scala | 10 +++++----- 4 files changed, 35 insertions(+), 34 deletions(-) diff --git a/src/main/wacc/Main.scala b/src/main/wacc/Main.scala index dcc7e6d..a271c3c 100644 --- a/src/main/wacc/Main.scala +++ b/src/main/wacc/Main.scala @@ -34,7 +34,7 @@ def compile(contents: String): Int = { parser.parse(contents) match { case Success(ast) => given errors: mutable.Builder[Error, List[Error]] = List.newBuilder - val names = renamer.rename(ast) + renamer.rename(ast) // given ctx: types.TypeCheckerCtx[List[Error]] = // types.TypeCheckerCtx(names, errors) // types.check(ast) diff --git a/src/main/wacc/ast.scala b/src/main/wacc/ast.scala index 2457c8f..123adb5 100644 --- a/src/main/wacc/ast.scala +++ b/src/main/wacc/ast.scala @@ -27,10 +27,10 @@ object ast { case class StrLiter(v: String)(pos: Position) extends Expr6 object StrLiter extends ParserBridgePos1[String, StrLiter] case class PairLiter()(pos: Position) extends Expr6 - object PairLiter extends Expr6 with ParserBridgePos0[PairLiter] - case class Ident(v: String, var uid: Int = -1) extends Expr6 with LValue + object PairLiter extends ParserBridgePos0[PairLiter] + case class Ident(v: String, var uid: Int = -1)(pos: Position) extends Expr6 with LValue 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) extends Expr6 @@ -46,18 +46,15 @@ object ast { sealed trait UnaryOp extends Expr { val x: Expr } - sealed trait UnaryOp extends Expr { - val x: Expr - } - case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp with UnaryOp + case class Negate(x: Expr6)(pos: Position) extends Expr6 with UnaryOp 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] - 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] - 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] - 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] // Binary operators diff --git a/src/main/wacc/renamer.scala b/src/main/wacc/renamer.scala index e46d9dd..77e0bd6 100644 --- a/src/main/wacc/renamer.scala +++ b/src/main/wacc/renamer.scala @@ -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 diff --git a/src/main/wacc/types.scala b/src/main/wacc/types.scala index 388416f..e62f0db 100644 --- a/src/main/wacc/types.scala +++ b/src/main/wacc/types.scala @@ -17,14 +17,14 @@ object types { object SemType { def apply(synType: Type | PairElemType): KnownType = synType match { - case IntType => KnownType.Int - case BoolType => KnownType.Bool - case CharType => KnownType.Char - case StringType => KnownType.String + case IntType() => KnownType.Int + case BoolType() => KnownType.Bool + case CharType() => KnownType.Char + case StringType() => KnownType.String case ArrayType(elemType, dimension) => (0 until dimension).foldLeft(SemType(elemType))((acc, _) => KnownType.Array(acc)) case PairType(fst, snd) => KnownType.Pair(SemType(fst), SemType(snd)) - case UntypedPairType => KnownType.Pair(?, ?) + case UntypedPairType() => KnownType.Pair(?, ?) } } }