1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-04 16:29:52 +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 = {
val name = stmt.name
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 && 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)
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 {
case SubbyteConstant(cc, _) => getAllCalledFunctions(cc)
case CompoundConstant(_, l, r) => getAllCalledFunctions(l) ++ getAllCalledFunctions(r)
case MemoryAddressConstant(th) => List(th.name.takeWhile(_ != '.'))
case MemoryAddressConstant(th) => List(extractThingName(th.name))
case _ => Nil
}
@ -106,7 +106,7 @@ object UnusedFunctions extends NodeOptimization {
case s: ReturnDispatchStatement =>
getAllCalledFunctions(s.getAllExpressions) ++ getAllCalledFunctions(s.branches.map(_.function))
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 HalfWordExpression(param, _) => getAllCalledFunctions(param :: Nil)
case SumExpression(xs, decimal) =>

View File

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