fix symbol lookup in new ast and minor codegen errors

This commit is contained in:
Irmen de Jong 2023-01-30 23:13:36 +01:00
parent e31e5b2477
commit 5b6534bb28
8 changed files with 44 additions and 25 deletions

View File

@ -23,4 +23,8 @@ class CompilationOptions(val output: OutputType,
var evalStackBaseAddress: UInt? = null,
var outputDir: Path = Path(""),
var symbolDefs: Map<String, String> = emptyMap()
)
) {
init {
compTarget.machine.initializeMemoryAreas(this)
}
}

View File

@ -3,7 +3,6 @@ package prog8.codegen.cpu6502
import prog8.code.StConstant
import prog8.code.StMemVar
import prog8.code.SymbolTable
import prog8.code.core.AssemblyError
import prog8.code.core.IMachineDefinition
@ -448,6 +447,7 @@ private fun optimizeStoreLoadSame(
private val identifierRegex = Regex("""^([a-zA-Z_$][a-zA-Z\d_\.$]*)""")
private fun getAddressArg(line: String, symbolTable: SymbolTable): UInt? {
// try to get the constant value address, could return null if it's a symbol instead
val loadArg = line.trimStart().substring(3).trim()
return when {
loadArg.startsWith('$') -> loadArg.substring(1).toUIntOrNull(16)
@ -461,8 +461,7 @@ private fun getAddressArg(line: String, symbolTable: SymbolTable): UInt? {
when (val symbol = symbolTable.flat[identifier]) {
is StConstant -> symbol.value.toUInt()
is StMemVar -> symbol.address
null -> null
else -> throw AssemblyError("expected constant or memvar for address $line")
else -> null
}
} else null
}

View File

@ -66,29 +66,46 @@ internal fun PtIdentifier.targetStatement(program: PtProgram): PtNode {
}
internal fun PtProgram.lookup(name: String): PtNode {
val remainder = name.split('.').toMutableList() // TODO optimize split to not use memory allocations
fun recurse(node: PtNode): PtNode {
fun searchLocalSymbol(node: PtNode, namePart: String): PtNode? {
when(node) {
is PtProgram -> {
val blockName = remainder.removeFirst()
return recurse(allBlocks().single { it.name==blockName })
return node.allBlocks().single { it.name==namePart }
}
is PtAsmSub -> {
require(remainder.isEmpty())
return node
}
is PtBlock, is PtSub, is PtNamedNode -> {
if(remainder.isEmpty())
is PtNamedNode -> {
if(node.name==namePart)
return node
val childName = remainder.removeFirst()
return recurse(node.children.filterIsInstance<PtNamedNode>().single { it.name==childName})
}
else -> throw IllegalArgumentException("invalid name $name in parent $node")
is PtNodeGroup -> {
node.children.forEach {
val found = searchLocalSymbol(it, namePart)
if(found!=null)
return found
}
}
is PtIdentifier -> {
if(node.name==namePart)
return node
}
is PtSubroutineParameter -> {
if(node.name==namePart)
return node
}
else -> {
// NOTE: when other nodes containing scopes are introduced,
// these should be added here as well to look into!
}
}
node.children.forEach {
val found = searchLocalSymbol(it, namePart)
if(found!=null)
return found
}
return null
}
return recurse(this)
val remainder = name.splitToSequence('.')
return remainder.fold(this as PtNode) { acc, namePart -> searchLocalSymbol(acc, namePart)!! }
}
internal fun PtIdentifier.targetVarDecl(program: PtProgram): PtVariable? =

View File

@ -142,7 +142,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
if(!isArgumentTypeCompatible(value.type, parameter.type))
throw AssemblyError("argument type incompatible")
val varName = asmgen.asmVariableName(sub.scopedName + parameter.name)
val varName = asmgen.asmVariableName(sub.scopedName + "." + parameter.name)
asmgen.assignExpressionToVariable(value, varName, parameter.type, sub)
}

View File

@ -202,7 +202,7 @@ internal class AsmAssignment(val source: AsmAssignSource,
if(target.register !in arrayOf(RegisterOrPair.XY, RegisterOrPair.AX, RegisterOrPair.AY))
require(source.datatype != DataType.UNDEFINED) { "must not be placeholder/undefined datatype at $position" }
require(memsizer.memorySize(source.datatype) <= memsizer.memorySize(target.datatype)) {
"source dt size must be less or equal to target dt size at $position"
"source dt size must be less or equal to target dt size at $position srcdt=${source.datatype} targetdt=${target.datatype}"
}
}
}

View File

@ -1100,6 +1100,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
private fun assignCastViaLsbFunc(value: PtExpression, target: AsmAssignTarget) {
val lsb = PtBuiltinFunctionCall("lsb", false, true, DataType.UBYTE, value.position)
lsb.parent = value.parent
lsb.add(value)
val src = AsmAssignSource(SourceStorageKind.EXPRESSION, program, asmgen, DataType.UBYTE, expression = lsb)
val assign = AsmAssignment(src, target, false, program.memsizer, value.position)

View File

@ -15,7 +15,6 @@ import prog8.code.ast.PtIdentifier
import prog8.code.core.*
import prog8.code.target.C64Target
import prog8.code.target.VMTarget
import prog8.code.target.c64.C64Zeropage
import prog8.codegen.cpu6502.AsmGen
import prog8.compiler.astprocessing.IntermediateAstMaker
import prog8.compiler.astprocessing.SymbolTableMaker
@ -75,7 +74,6 @@ class TestAsmGenSymbols: StringSpec({
fun createTestAsmGen(program: Program): AsmGen {
val errors = ErrorReporterForTests()
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
options.compTarget.machine.zeropage = C64Zeropage(options)
val st = SymbolTableMaker(program, options).make()
val ptProgram = IntermediateAstMaker(program, st, options).transform()
return AsmGen(ptProgram, st, options, errors)

View File

@ -5,6 +5,7 @@ import prog8.ast.expressions.Expression
import prog8.ast.expressions.InferredTypes
import prog8.ast.expressions.NumericLiteral
import prog8.code.core.*
import prog8.code.target.virtual.VirtualMachineDefinition
internal object DummyFunctions : IBuiltinFunctions {
@ -44,8 +45,7 @@ internal object AsciiStringEncoder : IStringEncoding {
internal object DummyCompilationTarget : ICompilationTarget {
override val name: String = "dummy"
override val machine: IMachineDefinition
get() = throw NotImplementedError("dummy")
override val machine: IMachineDefinition = VirtualMachineDefinition() // not really true but I don't want to implement a full dummy machinedef
override val supportedEncodings = setOf(Encoding.PETSCII, Encoding.SCREENCODES, Encoding.ISO)
override val defaultEncoding = Encoding.PETSCII