1
0
mirror of https://github.com/KarolS/millfork.git synced 2025-01-03 19:31:02 +00:00

Fix some edge cases with large variables

This commit is contained in:
Karol Stasiak 2019-06-29 16:22:27 +02:00
parent 8af2cb6da2
commit 1e4b5acfba
5 changed files with 20 additions and 7 deletions

View File

@ -1472,6 +1472,9 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
def registerVariable(stmt: VariableDeclarationStatement, options: CompilationOptions, isPointy: Boolean): Unit = { def registerVariable(stmt: VariableDeclarationStatement, options: CompilationOptions, isPointy: Boolean): Unit = {
val name = stmt.name val name = stmt.name
val position = stmt.position val position = stmt.position
if (name == "" || name.contains(".") && !name.contains(".return")) {
log.warn(s"Invalid variable name: $name. Please report a bug.", position)
}
if (stmt.stack && parent.isEmpty) { if (stmt.stack && parent.isEmpty) {
if (stmt.stack && stmt.global) log.error(s"`$name` is static or global and cannot be on stack", position) if (stmt.stack && stmt.global) log.error(s"`$name` is static or global and cannot be on stack", position)
} }

View File

@ -24,4 +24,14 @@ trait NodeOptimization {
} while(lastSize != set.size) } while(lastSize != set.size)
result result
} }
def extractThingName(fullName: String): String = {
var result = fullName.takeWhile(_ != '.')
if (result.length == fullName.length) return result
val suffix = fullName.drop(result.length)
if (suffix == ".return" || suffix.startsWith(".return.")) {
result += ".return"
}
result
}
} }

View File

@ -93,7 +93,7 @@ object UnusedFunctions extends NodeOptimization {
def getAllCalledFunctions(c: Constant): List[String] = c match { def getAllCalledFunctions(c: Constant): List[String] = c match {
case SubbyteConstant(cc, _) => getAllCalledFunctions(cc) case SubbyteConstant(cc, _) => getAllCalledFunctions(cc)
case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r) case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r)
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.')) case MemoryAddressConstant(th) => List(extractThingName(th.name))
case _ => Nil case _ => Nil
} }
@ -106,7 +106,7 @@ object UnusedFunctions extends NodeOptimization {
case s: ReturnDispatchStatement => case s: ReturnDispatchStatement =>
getAllCalledFunctions(s.getAllExpressions) ++ getAllCalledFunctions(s.branches.map(_.function)) getAllCalledFunctions(s.getAllExpressions) ++ getAllCalledFunctions(s.branches.map(_.function))
case s: Statement => getAllCalledFunctions(s.getAllExpressions) case s: Statement => getAllCalledFunctions(s.getAllExpressions)
case s: VariableExpression => List(s.name.takeWhile(_ != '.')) case s: VariableExpression => List(extractThingName(s.name))
case s: LiteralExpression => Nil case s: LiteralExpression => Nil
case HalfWordExpression(param, _) => getAllCalledFunctions(param :: Nil) case HalfWordExpression(param, _) => getAllCalledFunctions(param :: Nil)
case SumExpression(xs, decimal) => case SumExpression(xs, decimal) =>

View File

@ -45,7 +45,7 @@ object UnusedGlobalVariables extends NodeOptimization {
def getAllReadVariables(c: Constant): List[String] = c match { def getAllReadVariables(c: Constant): List[String] = c match {
case SubbyteConstant(cc, _) => getAllReadVariables(cc) case SubbyteConstant(cc, _) => getAllReadVariables(cc)
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r) case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.')) case MemoryAddressConstant(th) => List(extractThingName(th.name))
case _ => Nil case _ => Nil
} }
@ -57,7 +57,7 @@ object UnusedGlobalVariables extends NodeOptimization {
case Assignment(VariableExpression(_), expr) => getAllReadVariables(expr :: Nil) case Assignment(VariableExpression(_), expr) => getAllReadVariables(expr :: Nil)
case ExpressionStatement(FunctionCallExpression(op, VariableExpression(_) :: params)) if op.endsWith("=") => getAllReadVariables(params) case ExpressionStatement(FunctionCallExpression(op, VariableExpression(_) :: params)) if op.endsWith("=") => getAllReadVariables(params)
case s: Statement => getAllReadVariables(s.getAllExpressions) case s: Statement => getAllReadVariables(s.getAllExpressions)
case s: VariableExpression => List(s.name.takeWhile(_ != '.')) case s: VariableExpression => List(extractThingName(s.name))
case s: LiteralExpression => Nil case s: LiteralExpression => Nil
case HalfWordExpression(param, _) => getAllReadVariables(param :: Nil) case HalfWordExpression(param, _) => getAllReadVariables(param :: Nil)
case SumExpression(xs, _) => getAllReadVariables(xs.map(_._2)) case SumExpression(xs, _) => getAllReadVariables(xs.map(_._2))

View File

@ -31,12 +31,12 @@ object UnusedLocalVariables extends NodeOptimization {
def getAllReadVariables(c: Constant): List[String] = c match { def getAllReadVariables(c: Constant): List[String] = c match {
case SubbyteConstant(cc, _) => getAllReadVariables(cc) case SubbyteConstant(cc, _) => getAllReadVariables(cc)
case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r) case CompoundConstant(_, l, r) => getAllReadVariables(l) ++ getAllReadVariables(r)
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.')) case MemoryAddressConstant(th) => List(extractThingName(th.name))
case _ => Nil case _ => Nil
} }
def getAllReadVariables(expressions: List[Node]): List[String] = expressions.flatMap { def getAllReadVariables(expressions: List[Node]): List[String] = expressions.flatMap {
case s: VariableExpression => List(s.name.takeWhile(_ != '.')) case s: VariableExpression => List(extractThingName(s.name))
case s: LiteralExpression => Nil case s: LiteralExpression => Nil
case HalfWordExpression(param, _) => getAllReadVariables(param :: Nil) case HalfWordExpression(param, _) => getAllReadVariables(param :: Nil)
case SumExpression(xs, _) => getAllReadVariables(xs.map(_._2)) case SumExpression(xs, _) => getAllReadVariables(xs.map(_._2))
@ -57,7 +57,7 @@ object UnusedLocalVariables extends NodeOptimization {
def optimizeVariables(log: Logger, statements: List[Statement]): List[Statement] = { def optimizeVariables(log: Logger, statements: List[Statement]): List[Statement] = {
val allLocals = getAllLocalVariables(statements) val allLocals = getAllLocalVariables(statements)
val allRead = statements.flatMap { val allRead = statements.flatMap {
case Assignment(VariableExpression(v), expression) => List(v.takeWhile(_ != '.') -> expression) case Assignment(VariableExpression(v), expression) => List(extractThingName(v) -> expression)
case ExpressionStatement(FunctionCallExpression(op, VariableExpression(_) :: params)) if op.endsWith("=") => params.map("```" -> _) case ExpressionStatement(FunctionCallExpression(op, VariableExpression(_) :: params)) if op.endsWith("=") => params.map("```" -> _)
case x => x.getAllExpressions.map("```" -> _) case x => x.getAllExpressions.map("```" -> _)
}.flatMap(getAllReadVariables(_)).toSet }.flatMap(getAllReadVariables(_)).toSet