mirror of
https://github.com/irmen/prog8.git
synced 2024-10-07 00:55:33 +00:00
optimizing scoped names more and fix scoping of identifier names in arrays (pointers) in SymbolTable
This commit is contained in:
parent
e0913a39ab
commit
8e730ef93d
@ -18,7 +18,7 @@ class SymbolTable : StNode("", StNodeType.GLOBAL, Position.DUMMY) {
|
|||||||
val flat: Map<List<String>, StNode> by lazy {
|
val flat: Map<List<String>, StNode> by lazy {
|
||||||
val result = mutableMapOf<List<String>, StNode>()
|
val result = mutableMapOf<List<String>, StNode>()
|
||||||
fun flatten(node: StNode) {
|
fun flatten(node: StNode) {
|
||||||
result[node.scopedName] = node
|
result[node.scopedName.split('.')] = node
|
||||||
node.children.values.forEach { flatten(it) }
|
node.children.values.forEach { flatten(it) }
|
||||||
}
|
}
|
||||||
children.values.forEach { flatten(it) }
|
children.values.forEach { flatten(it) }
|
||||||
@ -57,7 +57,7 @@ class SymbolTable : StNode("", StNodeType.GLOBAL, Position.DUMMY) {
|
|||||||
children.mapNotNull { if (it.value.type == StNodeType.MEMORYSLAB) it.value as StMemorySlab else null }
|
children.mapNotNull { if (it.value.type == StNodeType.MEMORYSLAB) it.value as StMemorySlab else null }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun lookup(scopedName: List<String>) = flat[scopedName]
|
override fun lookup(scopedName: String) = flat[scopedName.split('.')] // TODO dotted string as keys
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -84,23 +84,27 @@ open class StNode(val name: String,
|
|||||||
|
|
||||||
lateinit var parent: StNode
|
lateinit var parent: StNode
|
||||||
|
|
||||||
val scopedName: List<String> by lazy {
|
val scopedName: String by lazy {
|
||||||
if(type== StNodeType.GLOBAL)
|
scopedNameList.joinToString(".")
|
||||||
emptyList()
|
|
||||||
else
|
|
||||||
parent.scopedName + name
|
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun lookup(scopedName: List<String>) =
|
open fun lookup(scopedName: String) =
|
||||||
if(scopedName.size>1) lookupQualified(scopedName) else lookupUnqualified(scopedName[0])
|
lookup(scopedName.split('.'))
|
||||||
|
|
||||||
fun lookupUnqualifiedOrElse(name: String, default: () -> StNode) =
|
fun lookupUnqualifiedOrElse(name: String, default: () -> StNode) =
|
||||||
lookupUnqualified(name) ?: default()
|
lookupUnqualified(name) ?: default()
|
||||||
|
|
||||||
fun lookupUnqualifiedOrElse(scopedName: List<String>, default: () -> StNode) =
|
fun lookupQualifiedOrElse(scopedName: List<String>, default: () -> StNode) =
|
||||||
lookup(scopedName) ?: default()
|
lookup(scopedName) ?: default()
|
||||||
|
|
||||||
private fun lookupQualified(scopedName: List<String>): StNode? {
|
private val scopedNameList: List<String> by lazy {
|
||||||
|
if(type== StNodeType.GLOBAL)
|
||||||
|
emptyList()
|
||||||
|
else
|
||||||
|
parent.scopedNameList + name
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun lookup(scopedName: List<String>): StNode? {
|
||||||
// a scoped name refers to a name in another namespace, and always stars from the root.
|
// a scoped name refers to a name in another namespace, and always stars from the root.
|
||||||
var node = this
|
var node = this
|
||||||
while(node.type!= StNodeType.GLOBAL)
|
while(node.type!= StNodeType.GLOBAL)
|
||||||
@ -218,7 +222,11 @@ class StRomSub(name: String,
|
|||||||
|
|
||||||
class StSubroutineParameter(val name: String, val type: DataType)
|
class StSubroutineParameter(val name: String, val type: DataType)
|
||||||
class StRomSubParameter(val register: RegisterOrStatusflag, val type: DataType)
|
class StRomSubParameter(val register: RegisterOrStatusflag, val type: DataType)
|
||||||
class StArrayElement(val number: Double?, val addressOfSymbol: String?)
|
class StArrayElement(val number: Double?, val addressOfSymbol: String?) {
|
||||||
|
init {
|
||||||
|
require(addressOfSymbol==null || addressOfSymbol.contains('.'))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typealias StString = Pair<String, Encoding>
|
typealias StString = Pair<String, Encoding>
|
||||||
typealias StArray = List<StArrayElement>
|
typealias StArray = List<StArrayElement>
|
||||||
|
@ -286,7 +286,7 @@ internal class ProgramAndVarsGen(
|
|||||||
// regular subroutine
|
// regular subroutine
|
||||||
asmgen.out("${sub.name}\t$asmStartScope")
|
asmgen.out("${sub.name}\t$asmStartScope")
|
||||||
|
|
||||||
val scope = symboltable.lookupUnqualifiedOrElse(sub.scopedName) { throw AssemblyError("lookup") }
|
val scope = symboltable.lookupQualifiedOrElse(sub.scopedName) { throw AssemblyError("lookup") }
|
||||||
require(scope.type==StNodeType.SUBROUTINE)
|
require(scope.type==StNodeType.SUBROUTINE)
|
||||||
val varsInSubroutine = getVars(scope)
|
val varsInSubroutine = getVars(scope)
|
||||||
|
|
||||||
@ -461,8 +461,9 @@ internal class ProgramAndVarsGen(
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun zeropagevars2asm(varNames: Set<List<String>>) {
|
private fun zeropagevars2asm(varNames2: Set<String>) {
|
||||||
val zpVariables = allocator.zeropageVars.filter { it.key in varNames }
|
val varNamesAsList = varNames2.map { it.split('.') } // TODO use dotted string
|
||||||
|
val zpVariables = allocator.zeropageVars.filter { it.key in varNamesAsList }
|
||||||
for ((scopedName, zpvar) in zpVariables) {
|
for ((scopedName, zpvar) in zpVariables) {
|
||||||
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
|
if (scopedName.size == 2 && scopedName[0] == "cx16" && scopedName[1][0] == 'r' && scopedName[1][1].isDigit())
|
||||||
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
|
continue // The 16 virtual registers of the cx16 are not actual variables in zp, they're memory mapped
|
||||||
|
@ -22,7 +22,8 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
allocateZeropageVariables()
|
allocateZeropageVariables()
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables
|
internal fun isZpVar(scopedName: List<String>) = scopedName in zeropage.allocatedVariables // TODO remove, use dotted string
|
||||||
|
internal fun isZpVar(scopedName: String) = scopedName.split('.') in zeropage.allocatedVariables
|
||||||
|
|
||||||
internal fun getFloatAsmConst(number: Double): String {
|
internal fun getFloatAsmConst(number: Double): String {
|
||||||
val asmName = globalFloatConsts[number]
|
val asmName = globalFloatConsts[number]
|
||||||
@ -56,7 +57,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
|
|
||||||
varsRequiringZp.forEach { variable ->
|
varsRequiringZp.forEach { variable ->
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'), // TODO use dotted name
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
@ -75,7 +76,7 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
varsPreferringZp.forEach { variable ->
|
varsPreferringZp.forEach { variable ->
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'), // TODO use dotted name
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
@ -88,13 +89,13 @@ internal class VariableAllocator(private val symboltable: SymbolTable,
|
|||||||
// try to allocate any other interger variables into the zeropage until it is full.
|
// try to allocate any other interger variables into the zeropage until it is full.
|
||||||
// TODO some form of intelligent priorization? most often used variables first? loopcounter vars first? ...?
|
// TODO some form of intelligent priorization? most often used variables first? loopcounter vars first? ...?
|
||||||
if(errors.noErrors()) {
|
if(errors.noErrors()) {
|
||||||
for (variable in varsDontCare.sortedBy { it.scopedName.size }) {
|
for (variable in varsDontCare.sortedBy { it.scopedName.length }) {
|
||||||
if(variable.dt in IntegerDatatypes) {
|
if(variable.dt in IntegerDatatypes) {
|
||||||
if(zeropage.free.isEmpty()) {
|
if(zeropage.free.isEmpty()) {
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
val result = zeropage.allocate(
|
val result = zeropage.allocate(
|
||||||
variable.scopedName,
|
variable.scopedName.split('.'), // TODO use dotted name,
|
||||||
variable.dt,
|
variable.dt,
|
||||||
variable.length,
|
variable.length,
|
||||||
variable.position,
|
variable.position,
|
||||||
|
@ -454,7 +454,7 @@ class IRCodeGen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(forLoop: PtForLoop): IRCodeChunks {
|
private fun translate(forLoop: PtForLoop): IRCodeChunks {
|
||||||
val loopvar = symbolTable.lookup(forLoop.variable.name.split('.'))!!
|
val loopvar = symbolTable.lookup(forLoop.variable.name)!!
|
||||||
val iterable = forLoop.iterable
|
val iterable = forLoop.iterable
|
||||||
val result = mutableListOf<IRCodeChunkBase>()
|
val result = mutableListOf<IRCodeChunkBase>()
|
||||||
when(iterable) {
|
when(iterable) {
|
||||||
@ -465,8 +465,8 @@ class IRCodeGen(
|
|||||||
result += translateForInNonConstantRange(forLoop, loopvar)
|
result += translateForInNonConstantRange(forLoop, loopvar)
|
||||||
}
|
}
|
||||||
is PtIdentifier -> {
|
is PtIdentifier -> {
|
||||||
val iterableVar = symbolTable.lookup(iterable.name.split('.')) as StStaticVariable
|
val iterableVar = symbolTable.lookup(iterable.name) as StStaticVariable
|
||||||
val loopvarSymbol = loopvar.scopedName.joinToString(".")
|
val loopvarSymbol = loopvar.scopedName
|
||||||
val indexReg = registers.nextFree()
|
val indexReg = registers.nextFree()
|
||||||
val tmpReg = registers.nextFree()
|
val tmpReg = registers.nextFree()
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
@ -529,7 +529,7 @@ class IRCodeGen(
|
|||||||
throw AssemblyError("step 0")
|
throw AssemblyError("step 0")
|
||||||
val indexReg = registers.nextFree()
|
val indexReg = registers.nextFree()
|
||||||
val endvalueReg = registers.nextFree()
|
val endvalueReg = registers.nextFree()
|
||||||
val loopvarSymbol = loopvar.scopedName.joinToString(".")
|
val loopvarSymbol = loopvar.scopedName
|
||||||
val loopvarDt = when(loopvar) {
|
val loopvarDt = when(loopvar) {
|
||||||
is StMemVar -> loopvar.dt
|
is StMemVar -> loopvar.dt
|
||||||
is StStaticVariable -> loopvar.dt
|
is StStaticVariable -> loopvar.dt
|
||||||
@ -560,7 +560,7 @@ class IRCodeGen(
|
|||||||
|
|
||||||
private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StNode): IRCodeChunks {
|
private fun translateForInConstantRange(forLoop: PtForLoop, loopvar: StNode): IRCodeChunks {
|
||||||
val loopLabel = createLabelName()
|
val loopLabel = createLabelName()
|
||||||
val loopvarSymbol = loopvar.scopedName.joinToString(".")
|
val loopvarSymbol = loopvar.scopedName
|
||||||
val indexReg = registers.nextFree()
|
val indexReg = registers.nextFree()
|
||||||
val loopvarDt = when(loopvar) {
|
val loopvarDt = when(loopvar) {
|
||||||
is StMemVar -> loopvar.dt
|
is StMemVar -> loopvar.dt
|
||||||
|
@ -392,7 +392,7 @@ private fun createAssemblyAndAssemble(program: Program,
|
|||||||
compilerOptions.compTarget.machine.initializeMemoryAreas(compilerOptions)
|
compilerOptions.compTarget.machine.initializeMemoryAreas(compilerOptions)
|
||||||
program.processAstBeforeAsmGeneration(compilerOptions, errors)
|
program.processAstBeforeAsmGeneration(compilerOptions, errors)
|
||||||
errors.report()
|
errors.report()
|
||||||
val symbolTable = SymbolTableMaker().makeFrom(program, compilerOptions)
|
val symbolTable = SymbolTableMaker(program, compilerOptions).make()
|
||||||
|
|
||||||
// TODO make removing all VarDecls work, but this needs inferType to be able to get its information from somewhere else as the VarDecl nodes in the Ast,
|
// TODO make removing all VarDecls work, but this needs inferType to be able to get its information from somewhere else as the VarDecl nodes in the Ast,
|
||||||
// or don't use inferType at all anymore and "bake the type information" into the Ast somehow.
|
// or don't use inferType at all anymore and "bake the type information" into the Ast somehow.
|
||||||
|
@ -111,18 +111,8 @@ class IntermediateAstMaker(private val program: Program, private val symbolTable
|
|||||||
return target
|
return target
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun targetOf(identifier: IdentifierReference): Pair<String, DataType> {
|
|
||||||
val target=identifier.targetStatement(program)!! as INamedStatement
|
|
||||||
val targetname: String = if(target.name in program.builtinFunctions.names)
|
|
||||||
"<builtin>.${target.name}"
|
|
||||||
else
|
|
||||||
target.scopedName.joinToString(".")
|
|
||||||
val type = identifier.inferType(program).getOr(DataType.UNDEFINED)
|
|
||||||
return Pair(targetname, type)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun transform(identifier: IdentifierReference): PtIdentifier {
|
private fun transform(identifier: IdentifierReference): PtIdentifier {
|
||||||
val (target, type) = targetOf(identifier)
|
val (target, type) = identifier.targetNameAndType(program)
|
||||||
return PtIdentifier(target, type, identifier.position)
|
return PtIdentifier(target, type, identifier.position)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -220,7 +210,7 @@ class IntermediateAstMaker(private val program: Program, private val symbolTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun transform(srcCall: FunctionCallStatement): PtFunctionCall {
|
private fun transform(srcCall: FunctionCallStatement): PtFunctionCall {
|
||||||
val (target, type) = targetOf(srcCall.target)
|
val (target, type) = srcCall.target.targetNameAndType(program)
|
||||||
val call = PtFunctionCall(target,true, type, srcCall.position)
|
val call = PtFunctionCall(target,true, type, srcCall.position)
|
||||||
for (arg in srcCall.args)
|
for (arg in srcCall.args)
|
||||||
call.add(transformExpression(arg))
|
call.add(transformExpression(arg))
|
||||||
@ -228,7 +218,7 @@ class IntermediateAstMaker(private val program: Program, private val symbolTable
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun transform(srcCall: FunctionCallExpression): PtFunctionCall {
|
private fun transform(srcCall: FunctionCallExpression): PtFunctionCall {
|
||||||
val (target, _) = targetOf(srcCall.target)
|
val (target, _) = srcCall.target.targetNameAndType(program)
|
||||||
val type = srcCall.inferType(program).getOrElse {
|
val type = srcCall.inferType(program).getOrElse {
|
||||||
throw FatalAstException("unknown dt $srcCall")
|
throw FatalAstException("unknown dt $srcCall")
|
||||||
}
|
}
|
||||||
|
@ -12,13 +12,13 @@ import prog8.code.core.DataType
|
|||||||
import prog8.code.core.Position
|
import prog8.code.core.Position
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal class SymbolTableMaker: IAstVisitor {
|
internal class SymbolTableMaker(private val program: Program, private val options: CompilationOptions): IAstVisitor {
|
||||||
|
|
||||||
private val st = SymbolTable()
|
private val st = SymbolTable()
|
||||||
private val scopestack = Stack<StNode>()
|
private val scopestack = Stack<StNode>()
|
||||||
private var dontReinitGlobals = false
|
private var dontReinitGlobals = false
|
||||||
|
|
||||||
fun makeFrom(program: Program, options: CompilationOptions): SymbolTable {
|
fun make(): SymbolTable {
|
||||||
scopestack.clear()
|
scopestack.clear()
|
||||||
st.children.clear()
|
st.children.clear()
|
||||||
dontReinitGlobals = options.dontReinitGlobals
|
dontReinitGlobals = options.dontReinitGlobals
|
||||||
@ -104,8 +104,14 @@ internal class SymbolTableMaker: IAstVisitor {
|
|||||||
return null
|
return null
|
||||||
return arrayLit.value.map {
|
return arrayLit.value.map {
|
||||||
when(it){
|
when(it){
|
||||||
is AddressOf -> StArrayElement(null, it.identifier.nameInSource.joinToString("."))
|
is AddressOf -> {
|
||||||
is IdentifierReference -> StArrayElement(null, it.nameInSource.joinToString("."))
|
val scopedName = it.identifier.targetNameAndType(program).first
|
||||||
|
StArrayElement(null, scopedName)
|
||||||
|
}
|
||||||
|
is IdentifierReference -> {
|
||||||
|
val scopedName = it.targetNameAndType(program).first
|
||||||
|
StArrayElement(null, scopedName)
|
||||||
|
}
|
||||||
is NumericLiteral -> StArrayElement(it.number, null)
|
is NumericLiteral -> StArrayElement(it.number, null)
|
||||||
else -> throw FatalAstException("weird element dt in array literal")
|
else -> throw FatalAstException("weird element dt in array literal")
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import prog8.code.core.ZeropageWish
|
|||||||
class TestSymbolTable: FunSpec({
|
class TestSymbolTable: FunSpec({
|
||||||
test("empty symboltable") {
|
test("empty symboltable") {
|
||||||
val st = SymbolTable()
|
val st = SymbolTable()
|
||||||
st.scopedName shouldBe emptyList()
|
st.scopedName shouldBe ""
|
||||||
st.name shouldBe ""
|
st.name shouldBe ""
|
||||||
st.type shouldBe StNodeType.GLOBAL
|
st.type shouldBe StNodeType.GLOBAL
|
||||||
st.children shouldBe mutableMapOf()
|
st.children shouldBe mutableMapOf()
|
||||||
@ -31,25 +31,25 @@ class TestSymbolTable: FunSpec({
|
|||||||
test("symboltable global lookups") {
|
test("symboltable global lookups") {
|
||||||
val st = makeSt()
|
val st = makeSt()
|
||||||
st.lookupUnqualified("undefined") shouldBe null
|
st.lookupUnqualified("undefined") shouldBe null
|
||||||
st.lookup(listOf("undefined")) shouldBe null
|
st.lookup("undefined") shouldBe null
|
||||||
var default = st.lookupUnqualifiedOrElse("undefined") { StNode("default", StNodeType.LABEL, Position.DUMMY) }
|
var default = st.lookupUnqualifiedOrElse("undefined") { StNode("default", StNodeType.LABEL, Position.DUMMY) }
|
||||||
default.name shouldBe "default"
|
default.name shouldBe "default"
|
||||||
default = st.lookupUnqualifiedOrElse(listOf("undefined")) { StNode("default", StNodeType.LABEL, Position.DUMMY) }
|
default = st.lookupUnqualifiedOrElse("undefined") { StNode("default", StNodeType.LABEL, Position.DUMMY) }
|
||||||
default.name shouldBe "default"
|
default.name shouldBe "default"
|
||||||
|
|
||||||
val msbFunc = st.lookupUnqualifiedOrElse("msb") { fail("msb must be found") }
|
val msbFunc = st.lookupUnqualifiedOrElse("msb") { fail("msb must be found") }
|
||||||
msbFunc.type shouldBe StNodeType.BUILTINFUNC
|
msbFunc.type shouldBe StNodeType.BUILTINFUNC
|
||||||
|
|
||||||
val variable = st.lookupUnqualifiedOrElse(listOf("block1", "sub2", "v2")) { fail("v2 must be found") }
|
val variable = st.lookupQualifiedOrElse(listOf("block1", "sub2", "v2")) { fail("v2 must be found") }
|
||||||
variable.type shouldBe StNodeType.STATICVAR
|
variable.type shouldBe StNodeType.STATICVAR
|
||||||
}
|
}
|
||||||
|
|
||||||
test("symboltable nested lookups") {
|
test("symboltable nested lookups") {
|
||||||
val st = makeSt()
|
val st = makeSt()
|
||||||
|
|
||||||
val sub1 = st.lookupUnqualifiedOrElse(listOf("block1", "sub1")) { fail("should find sub1") }
|
val sub1 = st.lookupQualifiedOrElse(listOf("block1", "sub1")) { fail("should find sub1") }
|
||||||
sub1.name shouldBe "sub1"
|
sub1.name shouldBe "sub1"
|
||||||
sub1.scopedName shouldBe listOf("block1", "sub1")
|
sub1.scopedName shouldBe "block1.sub1"
|
||||||
sub1.type shouldBe StNodeType.SUBROUTINE
|
sub1.type shouldBe StNodeType.SUBROUTINE
|
||||||
sub1.children.size shouldBe 2
|
sub1.children.size shouldBe 2
|
||||||
|
|
||||||
@ -62,7 +62,7 @@ class TestSymbolTable: FunSpec({
|
|||||||
blockc.type shouldBe StNodeType.CONSTANT
|
blockc.type shouldBe StNodeType.CONSTANT
|
||||||
blockc.value shouldBe 999.0
|
blockc.value shouldBe 999.0
|
||||||
|
|
||||||
val subsub = st.lookupUnqualifiedOrElse(listOf("block2", "sub2", "subsub")) { fail("should find subsub") }
|
val subsub = st.lookupQualifiedOrElse(listOf("block2", "sub2", "subsub")) { fail("should find subsub") }
|
||||||
subsub.lookupUnqualified("blockc") shouldBe null
|
subsub.lookupUnqualified("blockc") shouldBe null
|
||||||
subsub.lookupUnqualified("label") shouldNotBe null
|
subsub.lookupUnqualified("label") shouldNotBe null
|
||||||
}
|
}
|
||||||
|
@ -38,7 +38,7 @@ class TestIntermediateAst: FunSpec({
|
|||||||
loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
|
loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
|
||||||
)
|
)
|
||||||
val result = compileText(target, false, text, writeAssembly = false)!!
|
val result = compileText(target, false, text, writeAssembly = false)!!
|
||||||
val st = SymbolTableMaker().makeFrom(result.program, options)
|
val st = SymbolTableMaker(result.program, options).make()
|
||||||
val ast = IntermediateAstMaker(result.program, st, options).transform()
|
val ast = IntermediateAstMaker(result.program, st, options).transform()
|
||||||
ast.name shouldBe result.program.name
|
ast.name shouldBe result.program.name
|
||||||
ast.allBlocks().any() shouldBe true
|
ast.allBlocks().any() shouldBe true
|
||||||
|
@ -72,7 +72,7 @@ class TestAsmGenSymbols: StringSpec({
|
|||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
|
val options = CompilationOptions(OutputType.RAW, CbmPrgLauncherType.NONE, ZeropageType.FULL, emptyList(), false, true, C64Target(), 999u)
|
||||||
options.compTarget.machine.zeropage = C64Zeropage(options)
|
options.compTarget.machine.zeropage = C64Zeropage(options)
|
||||||
val st = SymbolTableMaker().makeFrom(program, options)
|
val st = SymbolTableMaker(program, options).make()
|
||||||
return AsmGen(program, st, options, errors)
|
return AsmGen(program, st, options, errors)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -914,6 +914,16 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
|||||||
fun targetVarDecl(program: Program): VarDecl? = targetStatement(program) as? VarDecl
|
fun targetVarDecl(program: Program): VarDecl? = targetStatement(program) as? VarDecl
|
||||||
fun targetSubroutine(program: Program): Subroutine? = targetStatement(program) as? Subroutine
|
fun targetSubroutine(program: Program): Subroutine? = targetStatement(program) as? Subroutine
|
||||||
|
|
||||||
|
fun targetNameAndType(program: Program): Pair<String, DataType> {
|
||||||
|
val target=targetStatement(program)!! as INamedStatement
|
||||||
|
val targetname: String = if(target.name in program.builtinFunctions.names)
|
||||||
|
"<builtin>.${target.name}"
|
||||||
|
else
|
||||||
|
target.scopedName.joinToString(".")
|
||||||
|
val type = inferType(program).getOr(DataType.UNDEFINED)
|
||||||
|
return Pair(targetname, type)
|
||||||
|
}
|
||||||
|
|
||||||
override fun linkParents(parent: Node) {
|
override fun linkParents(parent: Node) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- optimize scoped symbols: .split('.') / .joinToString(".")
|
- optimize scoped symbols: .split('.') / .joinToString(".") / 'dotted string' comments
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
@ -62,15 +62,15 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
|||||||
val newArray = mutableListOf<StArrayElement>()
|
val newArray = mutableListOf<StArrayElement>()
|
||||||
array.forEach {
|
array.forEach {
|
||||||
if(it.addressOfSymbol!=null) {
|
if(it.addressOfSymbol!=null) {
|
||||||
val target = variable.lookup(it.addressOfSymbol!!.split('.'))!!
|
val target = variable.lookup(it.addressOfSymbol!!)!!
|
||||||
newArray.add(StArrayElement(null, target.scopedName.joinToString(".")))
|
newArray.add(StArrayElement(null, target.scopedName))
|
||||||
} else {
|
} else {
|
||||||
newArray.add(it)
|
newArray.add(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newArray
|
return newArray
|
||||||
}
|
}
|
||||||
scopedName = variable.scopedName.joinToString(".")
|
scopedName = variable.scopedName
|
||||||
varToadd = StStaticVariable(scopedName, variable.dt, variable.bss,
|
varToadd = StStaticVariable(scopedName, variable.dt, variable.bss,
|
||||||
variable.onetimeInitializationNumericValue,
|
variable.onetimeInitializationNumericValue,
|
||||||
variable.onetimeInitializationStringValue,
|
variable.onetimeInitializationStringValue,
|
||||||
@ -91,7 +91,7 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
|||||||
scopedName = variable.name
|
scopedName = variable.name
|
||||||
varToadd = variable
|
varToadd = variable
|
||||||
} else {
|
} else {
|
||||||
scopedName = variable.scopedName.joinToString(".")
|
scopedName = variable.scopedName
|
||||||
varToadd = StMemVar(scopedName, variable.dt, variable.address, variable.length, variable.position)
|
varToadd = StMemVar(scopedName, variable.dt, variable.address, variable.length, variable.position)
|
||||||
}
|
}
|
||||||
table[scopedName] = varToadd
|
table[scopedName] = varToadd
|
||||||
|
Loading…
Reference in New Issue
Block a user