1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-07-05 09:28:54 +00:00

Fixed allocating allocating local variables twice

This commit is contained in:
Karol Stasiak 2018-04-15 01:29:47 +02:00
parent 7eab7c439e
commit cdfbbf61b8
2 changed files with 20 additions and 10 deletions

View File

@ -79,6 +79,15 @@ class Environment(val parent: Option[Environment], val prefix: String) {
}.toList
}
private def isLocalVariableName(name: String): Boolean = name.contains('$') && !name.endsWith("$") && {
val fname = name.substring(0, name.indexOf('$'))
things.get(fname) -> parent.flatMap(_.things.get(fname)) match {
case (Some(_: NormalFunction), _) => true
case (_, Some(_: NormalFunction)) => true
case _ => false
}
}
def allocateVariables(nf: Option[NormalFunction], mem: CompiledMemory, callGraph: CallGraph, allocators: Map[String, VariableAllocator], options: CompilationOptions, onEachVariable: (String, Int) => Unit): Unit = {
val b = get[Type]("byte")
val p = get[Type]("pointer")
@ -91,7 +100,7 @@ class Environment(val parent: Option[Environment], val prefix: String) {
}
}.toSet
val toAdd = things.values.flatMap {
case m: UninitializedMemory =>
case m: UninitializedMemory if nf.isDefined == isLocalVariableName(m.name) =>
val vertex = if (options.flag(CompilationFlag.VariableOverlap)) {
nf.fold[VariableVertex](GlobalVertex) { f =>
if (m.alloc == VariableAllocationMethod.Static) {

View File

@ -4,6 +4,7 @@ import millfork.error.ErrorReporting
import millfork.node.{CallGraph, VariableVertex}
import millfork.{CompilationFlag, CompilationOptions}
import scala.annotation.tailrec
import scala.collection.mutable
/**
@ -49,10 +50,10 @@ class AfterCodeByteAllocator(val endBefore: Int) extends ByteAllocator {
def notifyAboutEndOfCode(org: Int): Unit = startAt = org
}
class VariableAllocator(private var pointers: List[Int], private val bytes: ByteAllocator) {
class VariableAllocator(private val pointers: List[Int], private val bytes: ByteAllocator) {
private var pointerMap = mutable.Map[Int, Set[VariableVertex]]()
private var variableMap = mutable.Map[Int, mutable.Map[Int, Set[VariableVertex]]]()
private val pointerMap = mutable.Map[Int, Set[VariableVertex]]()
private val variableMap = mutable.Map[Int, mutable.Map[Int, Set[VariableVertex]]]()
def allocatePointer(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex): Int = {
// TODO: search for free zeropage locations
@ -62,16 +63,16 @@ class VariableAllocator(private var pointers: List[Int], private val bytes: Byte
return addr
}
}
def pickFreePointer(): Int =
pointers match {
@tailrec
def pickFreePointer(ps: List[Int]): Int =
ps match {
case Nil =>
ErrorReporting.trace(pointerMap.mkString(", "))
ErrorReporting.fatal("Out of zero-page memory")
case next :: rest =>
if (mem.occupied(next) || mem.occupied(next + 1)) {
pointers = rest
pickFreePointer()
pickFreePointer(rest)
} else {
pointers = rest
mem.readable(next) = true
mem.readable(next + 1) = true
mem.occupied(next) = true
@ -82,7 +83,7 @@ class VariableAllocator(private var pointers: List[Int], private val bytes: Byte
next
}
}
pickFreePointer()
pickFreePointer(pointers)
}
def allocateBytes(mem: MemoryBank, callGraph: CallGraph, p: VariableVertex, options: CompilationOptions, count: Int, initialized: Boolean, writeable: Boolean): Int = {