diff --git a/codeAst/src/prog8/code/SymbolTable.kt b/codeAst/src/prog8/code/SymbolTable.kt index b2a06713f..238496c0d 100644 --- a/codeAst/src/prog8/code/SymbolTable.kt +++ b/codeAst/src/prog8/code/SymbolTable.kt @@ -1,10 +1,6 @@ package prog8.code - -import prog8.code.core.DataType -import prog8.code.core.Encoding -import prog8.code.core.Position -import prog8.code.core.ZeropageWish +import prog8.code.core.* /** @@ -51,6 +47,7 @@ enum class StNodeType { // MODULE, // not used with current scoping rules BLOCK, SUBROUTINE, + ROMSUB, LABEL, STATICVAR, MEMVAR, @@ -131,6 +128,7 @@ open class StNode(val name: String, StNodeType.MEMVAR -> print("(M) ") StNodeType.CONSTANT -> print("(C) ") StNodeType.BUILTINFUNC -> print("(F) ") + StNodeType.ROMSUB -> print("(R) ") } printProperties() println() @@ -153,7 +151,7 @@ class StStaticVariable(name: String, val initialStringValue: StString?, val initialArrayValue: StArray?, val arraysize: Int?, - val zpw: ZeropageWish, + val zpwish: ZeropageWish, position: Position) : StNode(name, StNodeType.STATICVAR, position) { init { @@ -164,7 +162,7 @@ class StStaticVariable(name: String, } override fun printProperties() { - print("$name dt=$dt zpw=$zpw") + print("$name dt=$dt zpw=$zpwish") } } @@ -177,14 +175,20 @@ class StConstant(name: String, val dt: DataType, val value: Double, position: Po } class StMemVar(name: String, val dt: DataType, val address: UInt, position: Position) : - StNode(name, StNodeType.MEMVAR, position -) { + StNode(name, StNodeType.MEMVAR, position) { override fun printProperties() { - print("$name dt=$dt address=${address.toString(16).padStart(4,'0')}") + print("$name dt=$dt address=${address.toHex()}") } } +class StRomSub(name: String, val address: UInt, position: Position) : + StNode(name, StNodeType.ROMSUB, position) { + override fun printProperties() { + print("$name address=${address.toHex()}") + } +} + class StArrayElement(val number: Double?, val addressOf: List?) typealias StString = Pair diff --git a/codeAst/src/prog8/code/ast/AstBase.kt b/codeAst/src/prog8/code/ast/AstBase.kt index 82af97b5c..06ed2d89d 100644 --- a/codeAst/src/prog8/code/ast/AstBase.kt +++ b/codeAst/src/prog8/code/ast/AstBase.kt @@ -51,16 +51,19 @@ abstract class PtNamedNode(val name: String, position: Position): PtNode(positio } +// TODO remove duplicates that are also in CompilationOptions (that is already passed into the AsmGen already) +// TODO make sure loadaddress is always set to a sensible value (not 0) see determineProgramLoadAddress() class ProgramOptions( val output: OutputType, val launcher: CbmPrgLauncherType, val zeropage: ZeropageType, val zpReserved: Collection, - val loadAddress: UInt?, + val loadAddress: UInt, val floatsEnabled: Boolean, val noSysInit: Boolean, val dontReinitGlobals: Boolean, - val optimize: Boolean + val optimize: Boolean, + val target: String ) diff --git a/codeAst/src/prog8/code/ast/AstStatements.kt b/codeAst/src/prog8/code/ast/AstStatements.kt index a92af9ea5..5116b5c55 100644 --- a/codeAst/src/prog8/code/ast/AstStatements.kt +++ b/codeAst/src/prog8/code/ast/AstStatements.kt @@ -156,14 +156,14 @@ class PtReturn(position: Position) : PtNode(position) { } -class PtVariable(name: String, val type: DataType, var value: PtExpression?, position: Position) : PtNamedNode(name, position) { +class PtVariable(name: String, val type: DataType, var value: PtExpression?, var arraySize: UInt?, position: Position) : PtNamedNode(name, position) { override fun printProperties() { print("$type $name") } } -class PtConstant(val name: String, val type: DataType, val value: Double, position: Position) : PtNode(position) { +class PtConstant(name: String, val type: DataType, val value: Double, position: Position) : PtNamedNode(name, position) { override fun printProperties() { print("$type $name = $value") } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt index b795bb9be..1419ed95b 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ProgramAndVarsGen.kt @@ -57,6 +57,7 @@ internal class ProgramAndVarsGen( CpuType.CPU65c02 -> "w65c02" else -> "unsupported" } + determineProgramLoadAddress(program, errors) asmgen.out("; $cpu assembly code for '${program.name}'") asmgen.out("; generated by $ourName on ${LocalDateTime.now().withNano(0)}") @@ -65,32 +66,6 @@ internal class ProgramAndVarsGen( asmgen.out("") asmgen.out(".cpu '$cpu'\n.enc 'none'\n") - program.actualLoadAddress = program.definedLoadAddress ?: 0u - if (program.actualLoadAddress == 0u) { - when(options.output) { - OutputType.RAW -> { - errors.err("load address must be specified with %address when using raw output type", program.toplevelModule.position) - return - } - OutputType.PRG -> { - when(options.launcher) { - CbmPrgLauncherType.BASIC -> { - program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS - } - CbmPrgLauncherType.NONE -> { - errors.err("load address must be specified with %address when not using basic launcher", program.toplevelModule.position) - return - } - } - } - OutputType.XEX -> { - if(options.launcher!=CbmPrgLauncherType.NONE) - throw AssemblyError("atari xex output can't contain BASIC launcher") - program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS - } - } - } - // the global prog8 variables needed val zp = zeropage asmgen.out("P8ZP_SCRATCH_B1 = ${zp.SCRATCH_B1}") @@ -161,6 +136,35 @@ internal class ProgramAndVarsGen( } } + // TODO do this in the compiler, not in the code generator. Maybe it needs to be part of ICompilationTarget? + private fun determineProgramLoadAddress(program: Program, errors: IErrorReporter) { + program.actualLoadAddress = program.definedLoadAddress ?: 0u + if (program.actualLoadAddress == 0u) { + when(options.output) { + OutputType.RAW -> { + errors.err("load address must be specified with %address when using raw output type", program.toplevelModule.position) + return + } + OutputType.PRG -> { + when(options.launcher) { + CbmPrgLauncherType.BASIC -> { + program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS + } + CbmPrgLauncherType.NONE -> { + errors.err("load address must be specified with %address when not using basic launcher", program.toplevelModule.position) + return + } + } + } + OutputType.XEX -> { + if(options.launcher!=CbmPrgLauncherType.NONE) + throw AssemblyError("atari xex output can't contain BASIC launcher") + program.actualLoadAddress = compTarget.machine.PROGRAM_LOAD_ADDRESS + } + } + } + } + private fun memorySlabs() { asmgen.out("; memory slabs") asmgen.out("prog8_slabs\t.block") diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/VariableAllocator.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/VariableAllocator.kt index 5290a076a..247289350 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/VariableAllocator.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/VariableAllocator.kt @@ -53,10 +53,10 @@ internal class VariableAllocator(private val symboltable: SymbolTable, val allVariables = collectAllVariables(symboltable) val numberOfAllocatableVariables = allVariables.size - val varsRequiringZp = allVariables.filter { it.zpw == ZeropageWish.REQUIRE_ZEROPAGE } - val varsPreferringZp = allVariables.filter { it.zpw == ZeropageWish.PREFER_ZEROPAGE } - val varsDontCare = allVariables.filter { it.zpw == ZeropageWish.DONTCARE } - val numberOfExplicitNonZpVariables = allVariables.count { it.zpw == ZeropageWish.NOT_IN_ZEROPAGE } + val varsRequiringZp = allVariables.filter { it.zpwish == ZeropageWish.REQUIRE_ZEROPAGE } + val varsPreferringZp = allVariables.filter { it.zpwish == ZeropageWish.PREFER_ZEROPAGE } + val varsDontCare = allVariables.filter { it.zpwish == ZeropageWish.DONTCARE } + val numberOfExplicitNonZpVariables = allVariables.count { it.zpwish == ZeropageWish.NOT_IN_ZEROPAGE } require(varsDontCare.size + varsRequiringZp.size + varsPreferringZp.size + numberOfExplicitNonZpVariables == numberOfAllocatableVariables) var numVariablesAllocatedInZP = 0 diff --git a/codeGenExperimental/src/prog8/codegen/experimental/AsmGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/AsmGen.kt index e8c7ebd02..820a5836c 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/AsmGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/AsmGen.kt @@ -1,6 +1,6 @@ package prog8.codegen.experimental -import prog8.code.SymbolTable +import prog8.code.* import prog8.code.ast.* import prog8.code.core.* import javax.xml.stream.XMLOutputFactory @@ -39,6 +39,7 @@ class AsmGen(internal val program: PtProgram, xml.startChildren() write(program.options) program.children.forEach { writeNode(it) } + writeSymboltable(symbolTable) xml.endElt() xml.endDoc() xml.close() @@ -46,13 +47,96 @@ class AsmGen(internal val program: PtProgram, return AssemblyProgram("dummy") } + private fun writeSymboltable(st: SymbolTable) { + xml.elt("symboltable") + xml.startChildren() + st.flat.forEach{ (name, entry) -> + xml.elt("entry") + xml.attr("name", name.joinToString(".")) + xml.attr("type", entry.type.name) + xml.startChildren() + writeStNode(entry) + xml.endElt() + } + xml.endElt() + } + + private fun writeStNode(node: StNode) { + when(node.type) { + StNodeType.GLOBAL, + StNodeType.LABEL, + StNodeType.BLOCK, + StNodeType.BUILTINFUNC, + StNodeType.SUBROUTINE -> {/* no additional info*/} + StNodeType.ROMSUB -> { + node as StRomSub + xml.elt("romsub") + xml.attr("address", node.address.toString()) + xml.endElt() + } + StNodeType.STATICVAR -> { + node as StStaticVariable + xml.elt("var") + xml.attr("type", node.dt.name) + xml.attr("zpwish", node.zpwish.name) + if(node.arraysize!=null) + xml.attr("arraysize", node.arraysize.toString()) + if(node.initialNumericValue!=null || node.initialArrayValue!=null || node.initialStringValue!=null) { + xml.startChildren() + if(node.initialNumericValue!=null) { + writeNumber(node.dt, node.initialNumericValue!!) + } + if(node.initialStringValue!=null) { + xml.writeTextNode( + "string", + listOf(Pair("encoding", node.initialStringValue!!.second.name)), + node.initialStringValue!!.first, + false + ) + } + if(node.initialArrayValue!=null) { + xml.elt("array") + xml.startChildren() + val eltDt = ArrayToElementTypes.getValue(node.dt) + node.initialArrayValue!!.forEach { + if(it.number!=null) { + writeNumber(eltDt, it.number!!) + } + if(it.addressOf!=null) { + xml.elt("addressof") + xml.attr("symbol", it.addressOf!!.joinToString(".")) + xml.endElt() + } + } + xml.endElt() + } + } + xml.endElt() + } + StNodeType.MEMVAR -> { + node as StMemVar + xml.writeTextNode("memvar", + listOf(Pair("type", node.dt.name)), + node.address.toString(), + false) + } + StNodeType.CONSTANT -> { + node as StConstant + xml.writeTextNode("const", + listOf(Pair("type", node.dt.name)), + intOrDouble(node.dt, node.value).toString(), + false) + } + } + } + private fun write(options: ProgramOptions) { xml.elt("options") + xml.attr("target", options.target) xml.attr("output", options.output.name) xml.attr("launcher", options.launcher.name) xml.attr("zeropage", options.zeropage.name) - if(options.loadAddress!=null) - xml.attr("loadaddress", options.loadAddress.toString()) + xml.attr("loadaddress", options.loadAddress.toString()) xml.attr("floatsenabled", options.floatsEnabled.toString()) xml.attr("nosysinit", options.noSysInit.toString()) xml.attr("dontreinitglobals", options.dontReinitGlobals.toString()) @@ -115,7 +199,6 @@ class AsmGen(internal val program: PtProgram, private fun write(breakPt: PtBreakpoint) { xml.elt("breakpoint") - xml.startChildren() xml.pos(breakPt.position) xml.endElt() } @@ -149,12 +232,12 @@ class AsmGen(internal val program: PtProgram, } private fun write(string: PtString) = - xml.writeTextNode("string", listOf(Pair("encoding", string.encoding.name)), string.value) + xml.writeTextNode("string", listOf(Pair("encoding", string.encoding.name)), string.value, false) private fun write(rept: PtRepeatLoop) { xml.elt("repeat") - xml.startChildren() xml.pos(rept.position) + xml.startChildren() xml.elt("count") xml.startChildren() writeNode(rept.count) @@ -168,8 +251,8 @@ class AsmGen(internal val program: PtProgram, private fun write(branch: PtConditionalBranch) { xml.elt("conditionalbranch") xml.attr("condition", branch.condition.name) - xml.startChildren() xml.pos(branch.position) + xml.startChildren() xml.elt("true") xml.startChildren() writeNode(branch.trueScope) @@ -219,9 +302,9 @@ class AsmGen(internal val program: PtProgram, private fun write(forLoop: PtForLoop) { xml.elt("for") - xml.attr("var", strTargetName(forLoop.variable)) - xml.startChildren() + xml.attr("loopvar", strTargetName(forLoop.variable)) xml.pos(forLoop.position) + xml.startChildren() xml.elt("iterable") xml.startChildren() writeNode(forLoop.iterable) @@ -246,8 +329,8 @@ class AsmGen(internal val program: PtProgram, private fun write(whenStmt: PtWhen) { xml.elt("when") - xml.startChildren() xml.pos(whenStmt.position) + xml.startChildren() xml.elt("value") xml.startChildren() writeNode(whenStmt.value) @@ -280,8 +363,8 @@ class AsmGen(internal val program: PtProgram, private fun write(inlineAsm: PtInlineAssembly) { xml.elt("assembly") - xml.startChildren() xml.pos(inlineAsm.position) + xml.startChildren() xml.writeTextNode("code", emptyList(), inlineAsm.assembly) xml.endElt() } @@ -293,7 +376,6 @@ class AsmGen(internal val program: PtProgram, xml.attr("offset", inlineBinary.offset!!.toString()) if(inlineBinary.length!=null) xml.attr("length", inlineBinary.length!!.toString()) - xml.startChildren() xml.pos(inlineBinary.position) xml.endElt() } @@ -338,9 +420,8 @@ class AsmGen(internal val program: PtProgram, } private fun write(addrof: PtAddressOf) { - xml.elt("addrof") - xml.startChildren() - write(addrof.identifier) + xml.elt("addressof") + xml.attr("symbol", strTargetName(addrof.identifier)) xml.endElt() } @@ -351,18 +432,16 @@ class AsmGen(internal val program: PtProgram, xml.attr("type", "VOID") else xml.attr("type", fcall.type.name) - xml.startChildren() xml.pos(fcall.position) + xml.startChildren() fcall.children.forEach { writeNode(it) } xml.endElt() } - private fun write(number: PtNumber) { - xml.elt("number") - xml.attr("type", number.type.name) - xml.attr("value", intOrDouble(number.type, number.number).toString()) - xml.endElt() - } + private fun write(number: PtNumber) = writeNumber(number.type, number.number) + + private fun writeNumber(type: DataType, number: Double) = + xml.writeTextNode("number", listOf(Pair("type", type.name)), intOrDouble(type, number).toString(), false) private fun write(symbol: PtIdentifier) { xml.elt("symbol") @@ -374,8 +453,8 @@ class AsmGen(internal val program: PtProgram, private fun write(assign: PtAssignment) { xml.elt("assign") xml.attr("aug", assign.augmentable.toString()) - xml.startChildren() xml.pos(assign.position) + xml.startChildren() write(assign.target) writeNode(assign.value) xml.endElt() @@ -383,21 +462,21 @@ class AsmGen(internal val program: PtProgram, private fun write(ifElse: PtIfElse) { xml.elt("ifelse") - xml.startChildren() xml.pos(ifElse.position) + xml.startChildren() xml.elt("condition") xml.startChildren() writeNode(ifElse.condition) xml.endElt() xml.elt("true") - xml.startChildren() xml.pos(ifElse.ifScope.position) + xml.startChildren() writeNode(ifElse.ifScope) xml.endElt() if(ifElse.elseScope.children.isNotEmpty()) { xml.elt("false") - xml.startChildren() xml.pos(ifElse.elseScope.position) + xml.startChildren() writeNode(ifElse.elseScope) xml.endElt() } @@ -422,30 +501,31 @@ class AsmGen(internal val program: PtProgram, private fun write(label: PtLabel) { xml.elt("label") - xml.attr("name", label.name) - xml.startChildren() + xml.attr("name", label.scopedName.joinToString(".")) xml.pos(label.position) xml.endElt() } private fun write(block: PtBlock) { xml.elt("block") - xml.attr("name", block.name) + xml.attr("name", block.scopedName.joinToString(".")) if(block.address!=null) xml.attr("address", block.address!!.toString()) xml.attr("library", block.library.toString()) - xml.startChildren() xml.pos(block.position) + xml.startChildren() block.children.forEach { writeNode(it) } xml.endElt() } private fun write(memMapped: PtMemMapped) { - xml.elt("memvar") - xml.attr("type", memMapped.type.name) - xml.attr("name", memMapped.name) - xml.attr("address", memMapped.address.toString()) - xml.endElt() + xml.writeTextNode("memvar", + listOf( + Pair("name", memMapped.scopedName.joinToString(".")), + Pair("type", memMapped.type.name) + ), + memMapped.address.toString(), + false) } private fun write(target: PtAssignTarget) { @@ -484,12 +564,12 @@ class AsmGen(internal val program: PtProgram, private fun write(sub: PtSub) { xml.elt("sub") - xml.attr("name", sub.name) + xml.attr("name", sub.scopedName.joinToString(".")) if(sub.inline) xml.attr("inline", "true") xml.attr("returntype", sub.returntype?.toString() ?: "VOID") - xml.startChildren() xml.pos(sub.position) + xml.startChildren() if(sub.parameters.isNotEmpty()) { xml.elt("parameters") xml.startChildren() @@ -519,22 +599,22 @@ class AsmGen(internal val program: PtProgram, private fun write(asmSub: PtAsmSub) { if(asmSub.address!=null) { xml.elt("romsub") - xml.attr("name", asmSub.name) + xml.attr("name", asmSub.scopedName.joinToString(".")) xml.attr("address", asmSub.address!!.toString()) if(asmSub.inline) xml.attr("inline", "true") - xml.startChildren() xml.pos(asmSub.position) + xml.startChildren() paramsEtcetera(asmSub) xml.endElt() } else { xml.elt("asmsub") - xml.attr("name", asmSub.name) + xml.attr("name", asmSub.scopedName.joinToString(".")) if(asmSub.inline) xml.attr("inline", "true") - xml.startChildren() xml.pos(asmSub.position) + xml.startChildren() paramsEtcetera(asmSub) xml.elt("code") xml.startChildren() @@ -572,18 +652,21 @@ class AsmGen(internal val program: PtProgram, } private fun write(constant: PtConstant) { - xml.elt("const") - xml.attr("name", constant.name) - xml.attr("type", constant.type.name) - xml.attr("value", intOrDouble(constant.type, constant.value).toString()) - xml.endElt() + xml.writeTextNode("const", + listOf( + Pair("name", constant.scopedName.joinToString(".")), + Pair("type", constant.type.name) + ), + intOrDouble(constant.type, constant.value).toString(), false) } private fun write(variable: PtVariable) { // TODO get this from the AST only? - xml.elt("var") - xml.attr("name", variable.name) + xml.elt("vardecl") + xml.attr("name", variable.scopedName.joinToString(".")) xml.attr("type", variable.type.name) + if(variable.arraySize!=null) + xml.attr("arraysize", variable.arraySize.toString()) if(variable.value!=null) { xml.startChildren() writeNode(variable.value!!) diff --git a/codeGenExperimental/src/prog8/codegen/experimental/IndentingXmlWriter.kt b/codeGenExperimental/src/prog8/codegen/experimental/IndentingXmlWriter.kt index 2406d7fd2..3f4623936 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/IndentingXmlWriter.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/IndentingXmlWriter.kt @@ -19,11 +19,7 @@ class IndentingXmlWriter(val xml: XMLStreamWriter): XMLStreamWriter by xml { content.push(true) } fun endElt(writeIndent: Boolean=true) = writeEndElement(writeIndent) - fun pos(pos: Position) { - elt("src") - attr("pos", pos.toString()) - endElt() - } + fun pos(pos: Position) = writeAttribute("src", pos.toString()) fun comment(text: String) { writeComment(text) writeCharacters("\n") @@ -79,11 +75,14 @@ class IndentingXmlWriter(val xml: XMLStreamWriter): XMLStreamWriter by xml { content.push(false) } - fun writeTextNode(name: String, attrs: List>, text: String) { + fun writeTextNode(name: String, attrs: List>, text: String, cdata: Boolean = true) { xml.writeCharacters(" ".repeat(indent)) xml.writeStartElement(name) attrs.forEach { (name, value) -> xml.writeAttribute(name, value) } - xml.writeCData(text) + if(cdata) + xml.writeCData(text) + else + xml.writeCharacters(text) xml.writeEndElement() xml.writeCharacters("\n") } diff --git a/compiler/src/prog8/compiler/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/IntermediateAstMaker.kt index 4e5567eb8..db4daf320 100644 --- a/compiler/src/prog8/compiler/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/IntermediateAstMaker.kt @@ -12,16 +12,18 @@ import kotlin.io.path.Path class IntermediateAstMaker(val program: Program, val comp: CompilationOptions) { fun transform(): PtProgram { + val loadAddress = program.actualLoadAddress val options = ProgramOptions( comp.output, comp.launcher, comp.zeropage, comp.zpReserved, - program.definedLoadAddress, + loadAddress, comp.floats, comp.noSysInit, comp.dontReinitGlobals, - comp.optimize + comp.optimize, + comp.compTarget.name ) val ptProgram = PtProgram( @@ -312,7 +314,7 @@ class IntermediateAstMaker(val program: Program, val comp: CompilationOptions) { return when(srcVar.type) { VarDeclType.VAR -> { val value = if(srcVar.value!=null) transformExpression(srcVar.value!!) else null - PtVariable(srcVar.name, srcVar.datatype, value, srcVar.position) + PtVariable(srcVar.name, srcVar.datatype, value, srcVar.arraysize?.constIndex()?.toUInt(), srcVar.position) } VarDeclType.CONST -> PtConstant(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number, srcVar.position) VarDeclType.MEMORY -> PtMemMapped(srcVar.name, srcVar.datatype, (srcVar.value as NumericLiteral).number.toUInt(), srcVar.position) @@ -359,7 +361,7 @@ class IntermediateAstMaker(val program: Program, val comp: CompilationOptions) { } private fun transform(srcArr: ArrayLiteral): PtArrayLiteral { - val arr = PtArrayLiteral(srcArr.type.getOrElse { throw FatalAstException("array must know its type") }, srcArr.position) + val arr = PtArrayLiteral(srcArr.inferType(program).getOrElse { throw FatalAstException("array must know its type") }, srcArr.position) for (elt in srcArr.value) arr.add(transformExpression(elt)) return arr diff --git a/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt b/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt index 437f1f97e..accd43300 100644 --- a/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt @@ -35,12 +35,18 @@ internal class SymbolTableMaker: IAstVisitor { } override fun visit(subroutine: Subroutine) { - val node = StNode(subroutine.name, StNodeType.SUBROUTINE, subroutine.position) - scopestack.peek().add(node) - scopestack.push(node) - super.visit(subroutine) - scopestack.pop() - // st.origAstLinks[subroutine] = node + if(subroutine.asmAddress!=null) { + val node = StRomSub(subroutine.name, subroutine.asmAddress!!, subroutine.position) + scopestack.peek().add(node) + // st.origAstLinks[subroutine] = node + } else { + val node = StNode(subroutine.name, StNodeType.SUBROUTINE, subroutine.position) + scopestack.peek().add(node) + scopestack.push(node) + super.visit(subroutine) + scopestack.pop() + // st.origAstLinks[subroutine] = node + } } override fun visit(decl: VarDecl) { diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c29ef3634..e3d46c6ad 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,6 +3,8 @@ TODO For next release ^^^^^^^^^^^^^^^^ +- ProgramOptions: remove duplicates that are also in CompilationOptions (that is already passed into the AsmGen already) +- ProgramOptions: make sure loadaddress is always set to a sensible value (not 0) see determineProgramLoadAddress() - unit test for PtProgram AST: should also test new things such as the Datatype in nodes. ... diff --git a/examples/test.p8 b/examples/test.p8 index 4fdf46c8d..8f79aaa6f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,7 +3,6 @@ %zeropage basicsafe %zpreserved 50,80 %zpreserved 150,155 -%address $4000 ; Note: this program is compatible with C64 and CX16. %option align_word