mirror of
https://github.com/irmen/prog8.git
synced 2024-12-25 08:29:25 +00:00
Merge branch 'optimize-st'
# Conflicts: # examples/test.p8
This commit is contained in:
commit
eba0bde6f3
@ -1,6 +1,7 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import com.github.michaelbull.result.fold
|
||||
import prog8.code.StNode
|
||||
import prog8.code.StNodeType
|
||||
import prog8.code.SymbolTable
|
||||
import prog8.code.SymbolTableMaker
|
||||
@ -282,6 +283,18 @@ class AsmGen6502Internal (
|
||||
name
|
||||
}
|
||||
|
||||
fun asmVariableName(st: StNode, scope: PtSub?): String {
|
||||
val name = asmVariableName(st.scopedName)
|
||||
if(scope==null)
|
||||
return name
|
||||
// remove the whole prefix and just make the variable name locally scoped (64tass scopes it to the proper .proc block)
|
||||
val subName = scope.scopedName
|
||||
return if (name.length>subName.length && name.startsWith(subName) && name[subName.length] == '.')
|
||||
name.drop(subName.length+1)
|
||||
else
|
||||
name
|
||||
}
|
||||
|
||||
internal fun getTempVarName(dt: DataType): String {
|
||||
return when(dt) {
|
||||
DataType.UBYTE -> "cx16.r9L"
|
||||
|
@ -1,5 +1,6 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import prog8.code.StMemVar
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
@ -311,106 +312,97 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
}
|
||||
|
||||
private fun funcReverse(fcall: PtBuiltinFunctionCall) {
|
||||
val variable = fcall.args.single()
|
||||
if (variable is PtIdentifier) {
|
||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
||||
val decl = symbol!!.astNode as IPtVariable
|
||||
val numElements = when(decl) {
|
||||
is PtConstant -> throw AssemblyError("cannot reverse a constant")
|
||||
is PtMemMapped -> decl.arraySize
|
||||
is PtVariable -> decl.arraySize
|
||||
val variable = fcall.args.single() as PtIdentifier
|
||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
||||
val (dt, numElements) = when(symbol) {
|
||||
is StStaticVariable -> symbol.dt to symbol.length!!
|
||||
is StMemVar -> symbol.dt to symbol.length!!
|
||||
else -> DataType.UNDEFINED to 0
|
||||
}
|
||||
val varName = asmgen.asmVariableName(variable)
|
||||
when (dt) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr prog8_lib.func_reverse_b""")
|
||||
}
|
||||
val varName = asmgen.asmVariableName(variable)
|
||||
when (decl.type) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr prog8_lib.func_reverse_b""")
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr prog8_lib.func_reverse_w""")
|
||||
}
|
||||
DataType.STR -> {
|
||||
val stringLength = (symbol as StStaticVariable).length!!-1
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$stringLength
|
||||
jsr prog8_lib.func_reverse_b""")
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr floats.func_reverse_f""")
|
||||
}
|
||||
in SplitWordArrayTypes -> TODO("split word reverse")
|
||||
else -> throw AssemblyError("weird type")
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr prog8_lib.func_reverse_w""")
|
||||
}
|
||||
DataType.STR -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #${numElements-1}
|
||||
jsr prog8_lib.func_reverse_b""")
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements
|
||||
jsr floats.func_reverse_f""")
|
||||
}
|
||||
in SplitWordArrayTypes -> TODO("split word reverse")
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcSort(fcall: PtBuiltinFunctionCall) {
|
||||
val variable = fcall.args.single()
|
||||
if (variable is PtIdentifier) {
|
||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
||||
val decl = symbol!!.astNode as IPtVariable
|
||||
val varName = asmgen.asmVariableName(variable)
|
||||
val numElements = when(decl) {
|
||||
is PtConstant -> throw AssemblyError("cannot sort a constant")
|
||||
is PtMemMapped -> decl.arraySize
|
||||
is PtVariable -> decl.arraySize
|
||||
val variable = fcall.args.single() as PtIdentifier
|
||||
val symbol = asmgen.symbolTable.lookup(variable.name)
|
||||
val varName = asmgen.asmVariableName(variable)
|
||||
val (dt, numElements) = when(symbol) {
|
||||
is StStaticVariable -> symbol.dt to symbol.length!!
|
||||
is StMemVar -> symbol.dt to symbol.length!!
|
||||
else -> DataType.UNDEFINED to 0
|
||||
}
|
||||
when (dt) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements""")
|
||||
asmgen.out(if (dt == DataType.ARRAY_UB) " jsr prog8_lib.func_sort_ub" else " jsr prog8_lib.func_sort_b")
|
||||
}
|
||||
when (decl.type) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements""")
|
||||
asmgen.out(if (decl.type == DataType.ARRAY_UB) " jsr prog8_lib.func_sort_ub" else " jsr prog8_lib.func_sort_b")
|
||||
}
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements""")
|
||||
asmgen.out(if (decl.type == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w")
|
||||
}
|
||||
DataType.STR -> {
|
||||
val stringLength = (symbol as StStaticVariable).length!!-1
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$stringLength
|
||||
jsr prog8_lib.func_sort_ub""")
|
||||
}
|
||||
DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported")
|
||||
in SplitWordArrayTypes -> TODO("split word sort")
|
||||
else -> throw AssemblyError("weird type")
|
||||
DataType.ARRAY_UW, DataType.ARRAY_W -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #$numElements""")
|
||||
asmgen.out(if (dt == DataType.ARRAY_UW) " jsr prog8_lib.func_sort_uw" else " jsr prog8_lib.func_sort_w")
|
||||
}
|
||||
} else
|
||||
throw AssemblyError("weird type")
|
||||
DataType.STR -> {
|
||||
asmgen.out("""
|
||||
lda #<$varName
|
||||
ldy #>$varName
|
||||
sta P8ZP_SCRATCH_W1
|
||||
sty P8ZP_SCRATCH_W1+1
|
||||
lda #${numElements-1}
|
||||
jsr prog8_lib.func_sort_ub""")
|
||||
}
|
||||
DataType.ARRAY_F -> throw AssemblyError("sorting of floating point array is not supported")
|
||||
in SplitWordArrayTypes -> TODO("split word sort")
|
||||
else -> throw AssemblyError("weird type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun funcRor2(fcall: PtBuiltinFunctionCall) {
|
||||
@ -1245,12 +1237,11 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
|
||||
// address in P8ZP_SCRATCH_W1, number of elements in A
|
||||
arg as PtIdentifier
|
||||
val symbol = asmgen.symbolTable.lookup(arg.name)
|
||||
val arrayVar = symbol!!.astNode as IPtVariable
|
||||
val numElements = when(arrayVar) {
|
||||
is PtConstant -> null
|
||||
is PtMemMapped -> arrayVar.arraySize
|
||||
is PtVariable -> arrayVar.arraySize
|
||||
} ?: throw AssemblyError("length of non-array requested")
|
||||
val numElements = when(symbol) {
|
||||
is StStaticVariable -> symbol.length!!
|
||||
is StMemVar -> symbol.length!!
|
||||
else -> 0
|
||||
}
|
||||
val identifierName = asmgen.asmVariableName(arg)
|
||||
asmgen.out("""
|
||||
lda #<$identifierName
|
||||
|
@ -1,7 +1,11 @@
|
||||
package prog8.codegen.cpu6502
|
||||
|
||||
import com.github.michaelbull.result.fold
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.StMemVar
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.ast.PtForLoop
|
||||
import prog8.code.ast.PtIdentifier
|
||||
import prog8.code.ast.PtRange
|
||||
import prog8.code.core.*
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
@ -332,11 +336,10 @@ $endLabel""")
|
||||
asmgen.loopEndLabels.push(endLabel)
|
||||
val iterableName = asmgen.asmVariableName(ident)
|
||||
val symbol = asmgen.symbolTable.lookup(ident.name)
|
||||
val decl = symbol!!.astNode as IPtVariable
|
||||
val numElements = when(decl) {
|
||||
is PtConstant -> throw AssemblyError("length of non-array requested")
|
||||
is PtMemMapped -> decl.arraySize
|
||||
is PtVariable -> decl.arraySize
|
||||
val numElements = when(symbol) {
|
||||
is StStaticVariable -> symbol.length!!
|
||||
is StMemVar -> symbol.length!!
|
||||
else -> 0
|
||||
}
|
||||
when(iterableDt) {
|
||||
DataType.STR -> {
|
||||
@ -364,7 +367,7 @@ $loopLabel sty $indexVar
|
||||
lda $iterableName,y
|
||||
sta ${asmgen.asmVariableName(stmt.variable)}""")
|
||||
asmgen.translate(stmt.statements)
|
||||
if(numElements!!<=255u) {
|
||||
if(numElements<=255) {
|
||||
asmgen.out("""
|
||||
ldy $indexVar
|
||||
iny
|
||||
@ -379,7 +382,7 @@ $loopLabel sty $indexVar
|
||||
bne $loopLabel
|
||||
beq $endLabel""")
|
||||
}
|
||||
if(numElements>=16u) {
|
||||
if(numElements>=16) {
|
||||
// allocate index var on ZP if possible
|
||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||
result.fold(
|
||||
@ -392,7 +395,7 @@ $loopLabel sty $indexVar
|
||||
asmgen.out(endLabel)
|
||||
}
|
||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||
val length = numElements!! * 2u
|
||||
val length = numElements * 2
|
||||
val indexVar = asmgen.makeLabel("for_index")
|
||||
val loopvarName = asmgen.asmVariableName(stmt.variable)
|
||||
asmgen.out("""
|
||||
@ -403,7 +406,7 @@ $loopLabel sty $indexVar
|
||||
lda $iterableName+1,y
|
||||
sta $loopvarName+1""")
|
||||
asmgen.translate(stmt.statements)
|
||||
if(length<=127u) {
|
||||
if(length<=127) {
|
||||
asmgen.out("""
|
||||
ldy $indexVar
|
||||
iny
|
||||
@ -420,7 +423,7 @@ $loopLabel sty $indexVar
|
||||
bne $loopLabel
|
||||
beq $endLabel""")
|
||||
}
|
||||
if(length>=16u) {
|
||||
if(length>=16) {
|
||||
// allocate index var on ZP if possible
|
||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||
result.fold(
|
||||
@ -444,7 +447,7 @@ $loopLabel sty $indexVar
|
||||
lda ${iterableName}_msb,y
|
||||
sta $loopvarName+1""")
|
||||
asmgen.translate(stmt.statements)
|
||||
if(numElements<=255u) {
|
||||
if(numElements<=255) {
|
||||
asmgen.out("""
|
||||
ldy $indexVar
|
||||
iny
|
||||
@ -459,7 +462,7 @@ $loopLabel sty $indexVar
|
||||
bne $loopLabel
|
||||
beq $endLabel""")
|
||||
}
|
||||
if(numElements>=16u) {
|
||||
if(numElements>=16) {
|
||||
// allocate index var on ZP if possible
|
||||
val result = zeropage.allocate(indexVar, DataType.UBYTE, null, stmt.position, asmgen.errors)
|
||||
result.fold(
|
||||
|
@ -1,5 +1,7 @@
|
||||
package prog8.codegen.cpu6502.assignment
|
||||
|
||||
import prog8.code.StMemVar
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.ast.*
|
||||
import prog8.code.core.*
|
||||
import prog8.codegen.cpu6502.AsmGen6502Internal
|
||||
@ -1814,23 +1816,21 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
|
||||
private fun containmentCheckIntoA(containment: PtContainmentCheck) {
|
||||
val elementDt = containment.element.type
|
||||
val symbol = asmgen.symbolTable.lookup(containment.iterable.name)
|
||||
val variable = symbol!!.astNode as IPtVariable
|
||||
val varname = asmgen.asmVariableName(containment.iterable)
|
||||
val numElements = when(variable) {
|
||||
is PtConstant -> null
|
||||
is PtMemMapped -> variable.arraySize
|
||||
is PtVariable -> variable.arraySize
|
||||
val symbol = asmgen.symbolTable.lookup(containment.iterable.name)!!
|
||||
val symbolName = asmgen.asmVariableName(symbol, containment.definingSub())
|
||||
val (dt, numElements) = when(symbol) {
|
||||
is StStaticVariable -> symbol.dt to symbol.length!!
|
||||
is StMemVar -> symbol.dt to symbol.length!!
|
||||
else -> DataType.UNDEFINED to 0
|
||||
}
|
||||
when(variable.type) {
|
||||
when(dt) {
|
||||
DataType.STR -> {
|
||||
// use subroutine
|
||||
assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt == DataType.BYTE)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), symbol.astNode.position,"P8ZP_SCRATCH_W1"), varname, null, null)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position,"P8ZP_SCRATCH_W1"), symbolName, null, null)
|
||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||
val stringVal = (variable as PtVariable).value as PtString
|
||||
asmgen.out(" ldy #${stringVal.value.length}")
|
||||
asmgen.out(" ldy #${numElements-1}")
|
||||
asmgen.out(" jsr prog8_lib.containment_bytearray")
|
||||
return
|
||||
}
|
||||
@ -1840,7 +1840,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
DataType.ARRAY_B, DataType.ARRAY_UB -> {
|
||||
assignExpressionToRegister(containment.element, RegisterOrPair.A, elementDt == DataType.BYTE)
|
||||
asmgen.saveRegisterStack(CpuRegister.A, true)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), symbol.astNode.position, "P8ZP_SCRATCH_W1"), varname, null, null)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W1"), symbolName, null, null)
|
||||
asmgen.restoreRegisterStack(CpuRegister.A, false)
|
||||
asmgen.out(" ldy #$numElements")
|
||||
asmgen.out(" jsr prog8_lib.containment_bytearray")
|
||||
@ -1848,7 +1848,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
|
||||
}
|
||||
DataType.ARRAY_W, DataType.ARRAY_UW -> {
|
||||
assignExpressionToVariable(containment.element, "P8ZP_SCRATCH_W1", elementDt)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), symbol.astNode.position, "P8ZP_SCRATCH_W2"), varname, null, null)
|
||||
assignAddressOf(AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.UWORD, containment.definingISub(), containment.position, "P8ZP_SCRATCH_W2"), symbolName, null, null)
|
||||
asmgen.out(" ldy #$numElements")
|
||||
asmgen.out(" jsr prog8_lib.containment_wordarray")
|
||||
return
|
||||
|
@ -18,7 +18,6 @@ class IRCodeGen(
|
||||
private val expressionEval = ExpressionGen(this)
|
||||
private val builtinFuncGen = BuiltinFuncGen(this, expressionEval)
|
||||
private val assignmentGen = AssignmentGen(this, expressionEval)
|
||||
private var irSymbolTable: IRSymbolTable = IRSymbolTable(null)
|
||||
internal val registers = RegisterPool()
|
||||
|
||||
fun generate(): IRProgram {
|
||||
@ -26,7 +25,7 @@ class IRCodeGen(
|
||||
moveAllNestedSubroutinesToBlockScope()
|
||||
verifyNameScoping(program, symbolTable)
|
||||
|
||||
irSymbolTable = IRSymbolTable(symbolTable)
|
||||
val irSymbolTable = IRSymbolTable.fromStDuringCodegen(symbolTable)
|
||||
val irProg = IRProgram(program.name, irSymbolTable, options, program.encoding)
|
||||
|
||||
// collect global variables initializers
|
||||
|
@ -24,7 +24,7 @@ class TestIRPeepholeOpt: FunSpec({
|
||||
compTarget = target,
|
||||
loadAddress = target.machine.PROGRAM_LOAD_ADDRESS
|
||||
)
|
||||
val prog = IRProgram("test", IRSymbolTable(null), options, target)
|
||||
val prog = IRProgram("test", IRSymbolTable(), options, target)
|
||||
prog.addBlock(block)
|
||||
prog.linkChunks()
|
||||
prog.validate()
|
||||
|
@ -5,11 +5,11 @@ package prog8.buildversion
|
||||
*/
|
||||
const val MAVEN_GROUP = "prog8"
|
||||
const val MAVEN_NAME = "compiler"
|
||||
const val VERSION = "9.7"
|
||||
const val GIT_REVISION = 4286
|
||||
const val GIT_SHA = "cfc9c15f1e9fe96940e170fb14ad3a957109977c"
|
||||
const val GIT_DATE = "2023-12-10T15:22:00Z"
|
||||
const val GIT_BRANCH = "master"
|
||||
const val BUILD_DATE = "2023-12-10T15:44:19Z"
|
||||
const val BUILD_UNIX_TIME = 1702223059842L
|
||||
const val VERSION = "9.8-SNAPSHOT"
|
||||
const val GIT_REVISION = 4287
|
||||
const val GIT_SHA = "08a079a96e67c26298b81de2d35919be51a3dfd0"
|
||||
const val GIT_DATE = "2023-12-11T20:15:48Z"
|
||||
const val GIT_BRANCH = "no-vardecls"
|
||||
const val BUILD_DATE = "2023-12-11T21:48:14Z"
|
||||
const val BUILD_UNIX_TIME = 1702331294381L
|
||||
const val DIRTY = 1
|
||||
|
@ -56,7 +56,7 @@ class IRFileReader {
|
||||
val initGlobals = parseInitGlobals(reader)
|
||||
val blocks = parseBlocksUntilProgramEnd(reader)
|
||||
|
||||
val st = IRSymbolTable(null)
|
||||
val st = IRSymbolTable()
|
||||
asmsymbols.forEach { (name, value) -> st.addAsmSymbol(name, value)}
|
||||
varsWithoutInit.forEach { st.add(it) }
|
||||
variables.forEach { st.add(it) }
|
||||
|
@ -142,7 +142,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
if(irProgram.options.includeSourcelines) {
|
||||
if(code.sourceLinesPositions.any {it !== Position.DUMMY}) {
|
||||
xml.writeStartElement("P8SRC")
|
||||
var sourceTxt = StringBuilder("\n")
|
||||
val sourceTxt = StringBuilder("\n")
|
||||
code.sourceLinesPositions.forEach { pos ->
|
||||
val line = SourceLineCache.retrieveLine(pos)
|
||||
if(line!=null) {
|
||||
@ -210,8 +210,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb zp=${variable.zpwish}\n")
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_msb zp=${variable.zpwish}\n")
|
||||
} else {
|
||||
val typeStr = getTypeString(variable)
|
||||
xml.writeCharacters("$typeStr ${variable.name} zp=${variable.zpwish}\n")
|
||||
xml.writeCharacters("${variable.typeString} ${variable.name} zp=${variable.zpwish}\n")
|
||||
}
|
||||
}
|
||||
|
||||
@ -228,15 +227,15 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
lsbValue = ""
|
||||
msbValue = ""
|
||||
} else {
|
||||
lsbValue = variable.onetimeInitializationArrayValue!!.joinToString(",") {
|
||||
lsbValue = variable.onetimeInitializationArrayValue.joinToString(",") {
|
||||
if(it.number!=null)
|
||||
(it.number!!.toInt() and 255).toHex()
|
||||
(it.number.toInt() and 255).toHex()
|
||||
else
|
||||
"@<${it.addressOfSymbol}"
|
||||
}
|
||||
msbValue = variable.onetimeInitializationArrayValue!!.joinToString(",") {
|
||||
msbValue = variable.onetimeInitializationArrayValue.joinToString(",") {
|
||||
if(it.number!=null)
|
||||
(it.number!!.toInt() shr 8).toHex()
|
||||
(it.number.toInt() shr 8).toHex()
|
||||
else
|
||||
"@>${it.addressOfSymbol}"
|
||||
}
|
||||
@ -244,26 +243,25 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_lsb=$lsbValue zp=${variable.zpwish}\n")
|
||||
xml.writeCharacters("ubyte[${variable.length}] ${variable.name}_msb=$msbValue zp=${variable.zpwish}\n")
|
||||
} else {
|
||||
val typeStr = getTypeString(variable)
|
||||
val value: String = when(variable.dt) {
|
||||
DataType.FLOAT -> (variable.onetimeInitializationNumericValue ?: "").toString()
|
||||
in NumericDatatypes -> (variable.onetimeInitializationNumericValue?.toInt()?.toHex() ?: "").toString()
|
||||
DataType.STR -> {
|
||||
val encoded = irProgram.encoding.encodeString(variable.onetimeInitializationStringValue!!.first, variable.onetimeInitializationStringValue!!.second) + listOf(0u)
|
||||
val encoded = irProgram.encoding.encodeString(variable.onetimeInitializationStringValue!!.first, variable.onetimeInitializationStringValue.second) + listOf(0u)
|
||||
encoded.joinToString(",") { it.toInt().toString() }
|
||||
}
|
||||
DataType.ARRAY_F -> {
|
||||
if(variable.onetimeInitializationArrayValue!=null) {
|
||||
variable.onetimeInitializationArrayValue!!.joinToString(",") { it.number!!.toString() }
|
||||
variable.onetimeInitializationArrayValue.joinToString(",") { it.number!!.toString() }
|
||||
} else {
|
||||
"" // array will be zero'd out at program start
|
||||
}
|
||||
}
|
||||
in ArrayDatatypes -> {
|
||||
if(variable.onetimeInitializationArrayValue!==null) {
|
||||
variable.onetimeInitializationArrayValue!!.joinToString(",") {
|
||||
variable.onetimeInitializationArrayValue.joinToString(",") {
|
||||
if(it.number!=null)
|
||||
it.number!!.toInt().toHex()
|
||||
it.number.toInt().toHex()
|
||||
else
|
||||
"@${it.addressOfSymbol}"
|
||||
}
|
||||
@ -273,7 +271,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
}
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
xml.writeCharacters("$typeStr ${variable.name}=$value zp=${variable.zpwish}\n")
|
||||
xml.writeCharacters("${variable.typeString} ${variable.name}=$value zp=${variable.zpwish}\n")
|
||||
}
|
||||
}
|
||||
xml.writeEndElement()
|
||||
@ -282,8 +280,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
|
||||
xml.writeStartElement("MEMORYMAPPEDVARIABLES")
|
||||
xml.writeCharacters("\n")
|
||||
for (variable in irProgram.st.allMemMappedVariables()) {
|
||||
val typeStr = getTypeString(variable)
|
||||
xml.writeCharacters("@$typeStr ${variable.name}=${variable.address.toHex()}\n")
|
||||
xml.writeCharacters("@${variable.typeString} ${variable.name}=${variable.address.toHex()}\n")
|
||||
}
|
||||
xml.writeEndElement()
|
||||
xml.writeCharacters("\n")
|
||||
|
@ -1,88 +1,88 @@
|
||||
package prog8.intermediate
|
||||
|
||||
import prog8.code.*
|
||||
import prog8.code.ast.PtVariable
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.ZeropageWish
|
||||
import prog8.code.core.internedStringsModuleName
|
||||
import prog8.code.core.*
|
||||
|
||||
|
||||
// In the Intermediate Representation, all nesting has been removed.
|
||||
// So the symbol table is just a big flat mapping of (scoped)name to node.
|
||||
// We define a stripped down symbol table for use in the IR phase only, rather than reuse the codegen symboltable
|
||||
|
||||
class IRSymbolTable(sourceSt: SymbolTable?) {
|
||||
private val table = mutableMapOf<String, StNode>()
|
||||
class IRSymbolTable {
|
||||
private val table = mutableMapOf<String, IRStNode>()
|
||||
private val asmSymbols = mutableMapOf<String, String>()
|
||||
|
||||
init {
|
||||
if(sourceSt!=null) {
|
||||
sourceSt.allVariables.forEach {
|
||||
add(it)
|
||||
}
|
||||
sourceSt.allMemMappedVariables.forEach {
|
||||
add(it)
|
||||
}
|
||||
sourceSt.allMemorySlabs.forEach {
|
||||
add(it)
|
||||
}
|
||||
companion object {
|
||||
fun fromStDuringCodegen(sourceSt: SymbolTable?): IRSymbolTable {
|
||||
val st = IRSymbolTable()
|
||||
if (sourceSt != null) {
|
||||
sourceSt.allVariables.forEach {
|
||||
st.add(it)
|
||||
}
|
||||
sourceSt.allMemMappedVariables.forEach {
|
||||
st.add(it)
|
||||
}
|
||||
sourceSt.allMemorySlabs.forEach {
|
||||
st.add(it)
|
||||
}
|
||||
|
||||
require(table.all { it.key==it.value.name })
|
||||
require(st.table.all { it.key == it.value.name })
|
||||
|
||||
allVariables().forEach {variable ->
|
||||
variable.onetimeInitializationArrayValue?.let {
|
||||
it.forEach { arrayElt ->
|
||||
if(arrayElt.addressOfSymbol!=null) {
|
||||
require(arrayElt.addressOfSymbol!!.contains('.')) {
|
||||
"pointer var in array should be properly scoped: ${arrayElt.addressOfSymbol} in ${variable.name}"
|
||||
st.allVariables().forEach { variable ->
|
||||
variable.onetimeInitializationArrayValue?.let {
|
||||
it.forEach { arrayElt ->
|
||||
if (arrayElt.addressOfSymbol != null) {
|
||||
require(arrayElt.addressOfSymbol.contains('.')) {
|
||||
"pointer var in array should be properly scoped: ${arrayElt.addressOfSymbol} in ${variable.name}"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return st
|
||||
}
|
||||
}
|
||||
|
||||
fun allVariables(): Sequence<StStaticVariable> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<StStaticVariable>()
|
||||
fun allVariables(): Sequence<IRStStaticVariable> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<IRStStaticVariable>()
|
||||
|
||||
fun allMemMappedVariables(): Sequence<StMemVar> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<StMemVar>()
|
||||
fun allMemMappedVariables(): Sequence<IRStMemVar> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<IRStMemVar>()
|
||||
|
||||
fun allMemorySlabs(): Sequence<StMemorySlab> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<StMemorySlab>()
|
||||
fun allMemorySlabs(): Sequence<IRStMemorySlab> =
|
||||
table.asSequence().map { it.value }.filterIsInstance<IRStMemorySlab>()
|
||||
|
||||
fun lookup(name: String) = table[name]
|
||||
|
||||
fun add(variable: StStaticVariable) {
|
||||
val scopedName: String
|
||||
val varToadd: StStaticVariable
|
||||
val varToadd: IRStStaticVariable
|
||||
if('.' in variable.name) {
|
||||
scopedName = variable.name
|
||||
varToadd = variable
|
||||
varToadd = IRStStaticVariable.from(variable)
|
||||
} else {
|
||||
fun fixupAddressOfInArray(array: List<StArrayElement>?): List<StArrayElement>? {
|
||||
fun fixupAddressOfInArray(array: List<StArrayElement>?): List<IRStArrayElement>? {
|
||||
if(array==null)
|
||||
return null
|
||||
val newArray = mutableListOf<StArrayElement>()
|
||||
val newArray = mutableListOf<IRStArrayElement>()
|
||||
array.forEach {
|
||||
if(it.addressOfSymbol!=null) {
|
||||
val target = variable.lookup(it.addressOfSymbol!!)!!
|
||||
newArray.add(StArrayElement(null, target.scopedName))
|
||||
newArray.add(IRStArrayElement(null, target.scopedName))
|
||||
} else {
|
||||
newArray.add(it)
|
||||
newArray.add(IRStArrayElement.from(it))
|
||||
}
|
||||
}
|
||||
return newArray
|
||||
}
|
||||
scopedName = variable.scopedName
|
||||
val dummyNode = PtVariable(scopedName, variable.dt, variable.zpwish, null, null, variable.astNode.position)
|
||||
varToadd = StStaticVariable(scopedName, variable.dt,
|
||||
varToadd = IRStStaticVariable(scopedName, variable.dt,
|
||||
variable.onetimeInitializationNumericValue,
|
||||
variable.onetimeInitializationStringValue,
|
||||
fixupAddressOfInArray(variable.onetimeInitializationArrayValue),
|
||||
variable.length,
|
||||
variable.zpwish,
|
||||
dummyNode
|
||||
variable.zpwish
|
||||
)
|
||||
}
|
||||
table[scopedName] = varToadd
|
||||
@ -91,27 +91,26 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
||||
|
||||
fun add(variable: StMemVar) {
|
||||
val scopedName: String
|
||||
val varToadd: StMemVar
|
||||
val varToadd: IRStMemVar
|
||||
if('.' in variable.name) {
|
||||
scopedName = variable.name
|
||||
varToadd = variable
|
||||
varToadd = IRStMemVar.from(variable)
|
||||
} else {
|
||||
scopedName = try {
|
||||
variable.scopedName
|
||||
} catch (ux: UninitializedPropertyAccessException) {
|
||||
variable.name
|
||||
}
|
||||
varToadd = StMemVar(scopedName, variable.dt, variable.address, variable.length, variable.astNode)
|
||||
varToadd = IRStMemVar(scopedName, variable.dt, variable.address, variable.length)
|
||||
}
|
||||
table[scopedName] = varToadd
|
||||
}
|
||||
|
||||
fun add(variable: StMemorySlab) {
|
||||
val varToadd = if('.' in variable.name)
|
||||
variable
|
||||
IRStMemorySlab.from(variable)
|
||||
else {
|
||||
val dummyNode = PtVariable(variable.name, DataType.ARRAY_UB, ZeropageWish.NOT_IN_ZEROPAGE, null, null, variable.astNode.position)
|
||||
StMemorySlab("prog8_slabs.${variable.name}", variable.size, variable.align, dummyNode)
|
||||
IRStMemorySlab("prog8_slabs.${variable.name}", variable.size, variable.align)
|
||||
}
|
||||
table[varToadd.name] = varToadd
|
||||
}
|
||||
@ -133,3 +132,118 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
enum class IRStNodeType {
|
||||
STATICVAR,
|
||||
MEMVAR,
|
||||
MEMORYSLAB
|
||||
// the other StNodeType types aren't used here anymore.
|
||||
// this symbol table only contains variables.
|
||||
}
|
||||
|
||||
open class IRStNode(val name: String,
|
||||
val type: IRStNodeType,
|
||||
val children: MutableMap<String, StNode> = mutableMapOf()
|
||||
)
|
||||
|
||||
class IRStMemVar(name: String,
|
||||
val dt: DataType,
|
||||
val address: UInt,
|
||||
val length: Int? // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
|
||||
) : IRStNode(name, IRStNodeType.MEMVAR) {
|
||||
companion object {
|
||||
fun from(variable: StMemVar): IRStMemVar {
|
||||
return IRStMemVar(
|
||||
variable.name,
|
||||
variable.dt,
|
||||
variable.address,
|
||||
variable.length
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val typeString: String
|
||||
get() = when (dt) {
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[${length}]"
|
||||
DataType.ARRAY_B -> "byte[${length}]"
|
||||
DataType.ARRAY_UW -> "uword[${length}]"
|
||||
DataType.ARRAY_W -> "word[${length}]"
|
||||
DataType.ARRAY_F -> "float[${length}]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("@split can't be used on memory mapped arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
}
|
||||
|
||||
class IRStMemorySlab(
|
||||
name: String,
|
||||
val size: UInt,
|
||||
val align: UInt
|
||||
): IRStNode(name, IRStNodeType.MEMORYSLAB) {
|
||||
companion object {
|
||||
fun from(variable: StMemorySlab): IRStMemorySlab {
|
||||
return IRStMemorySlab(
|
||||
variable.name,
|
||||
variable.size,
|
||||
variable.align
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IRStStaticVariable(name: String,
|
||||
val dt: DataType,
|
||||
val onetimeInitializationNumericValue: Double?, // regular (every-run-time) initialization is done via regular assignments
|
||||
val onetimeInitializationStringValue: IRStString?,
|
||||
val onetimeInitializationArrayValue: IRStArray?,
|
||||
val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte
|
||||
val zpwish: ZeropageWish // used in the variable allocator
|
||||
) : IRStNode(name, IRStNodeType.STATICVAR) {
|
||||
companion object {
|
||||
fun from(variable: StStaticVariable): IRStStaticVariable {
|
||||
return IRStStaticVariable(variable.name,
|
||||
variable.dt,
|
||||
variable.onetimeInitializationNumericValue,
|
||||
variable.onetimeInitializationStringValue,
|
||||
variable.onetimeInitializationArrayValue?.map { IRStArrayElement.from(it) },
|
||||
variable.length,
|
||||
variable.zpwish)
|
||||
}
|
||||
}
|
||||
|
||||
val uninitialized = onetimeInitializationArrayValue==null && onetimeInitializationStringValue==null && onetimeInitializationNumericValue==null
|
||||
|
||||
val typeString: String
|
||||
get() = when (dt) {
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[${length}]"
|
||||
DataType.ARRAY_B -> "byte[${length}]"
|
||||
DataType.ARRAY_UW -> "uword[${length}]"
|
||||
DataType.ARRAY_W -> "word[${length}]"
|
||||
DataType.ARRAY_F -> "float[${length}]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
}
|
||||
|
||||
class IRStArrayElement(val number: Double?, val addressOfSymbol: String?) {
|
||||
companion object {
|
||||
fun from(elt: StArrayElement): IRStArrayElement {
|
||||
return IRStArrayElement(elt.number, elt.addressOfSymbol)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
typealias IRStArray = List<IRStArrayElement>
|
||||
typealias IRStString = Pair<String, Encoding>
|
||||
|
@ -1,7 +1,9 @@
|
||||
package prog8.intermediate
|
||||
|
||||
import prog8.code.*
|
||||
import prog8.code.Either
|
||||
import prog8.code.core.*
|
||||
import prog8.code.left
|
||||
import prog8.code.right
|
||||
|
||||
|
||||
fun getTypeString(dt : DataType): String = when(dt) {
|
||||
@ -20,38 +22,6 @@ fun getTypeString(dt : DataType): String = when(dt) {
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
|
||||
fun getTypeString(memvar: StMemVar): String = when(memvar.dt) {
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[${memvar.length}]"
|
||||
DataType.ARRAY_B -> "byte[${memvar.length}]"
|
||||
DataType.ARRAY_UW -> "uword[${memvar.length}]"
|
||||
DataType.ARRAY_W -> "word[${memvar.length}]"
|
||||
DataType.ARRAY_F -> "float[${memvar.length}]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("@split can't be used on memory mapped arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
|
||||
fun getTypeString(variable : StStaticVariable): String = when(variable.dt) {
|
||||
DataType.UBYTE -> "ubyte"
|
||||
DataType.BYTE -> "byte"
|
||||
DataType.UWORD -> "uword"
|
||||
DataType.WORD -> "word"
|
||||
DataType.FLOAT -> "float"
|
||||
DataType.BOOL, DataType.ARRAY_BOOL -> throw InternalCompilerException("bool should have been converted to ubyte")
|
||||
DataType.ARRAY_UB, DataType.STR -> "ubyte[${variable.length}]"
|
||||
DataType.ARRAY_B -> "byte[${variable.length}]"
|
||||
DataType.ARRAY_UW -> "uword[${variable.length}]"
|
||||
DataType.ARRAY_W -> "word[${variable.length}]"
|
||||
DataType.ARRAY_F -> "float[${variable.length}]"
|
||||
in SplitWordArrayTypes -> throw InternalCompilerException("split array should have been converted to 2 ubyte arrays")
|
||||
else -> throw InternalCompilerException("weird dt")
|
||||
}
|
||||
|
||||
fun convertIRType(typestr: String): IRDataType? {
|
||||
return when(typestr.lowercase()) {
|
||||
"" -> null
|
||||
|
@ -1,16 +1,12 @@
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.ints.shouldBeGreaterThan
|
||||
import io.kotest.matchers.shouldBe
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.core.CbmPrgLauncherType
|
||||
import prog8.code.core.CompilationOptions
|
||||
import prog8.code.core.OutputType
|
||||
import prog8.code.core.ZeropageType
|
||||
import prog8.code.target.Cx16Target
|
||||
import prog8.intermediate.IRFileReader
|
||||
import prog8.intermediate.IRFileWriter
|
||||
import prog8.intermediate.IRProgram
|
||||
import prog8.intermediate.IRSymbolTable
|
||||
import prog8.intermediate.*
|
||||
import kotlin.io.path.*
|
||||
|
||||
class TestIRFileInOut: FunSpec({
|
||||
@ -29,7 +25,7 @@ class TestIRFileInOut: FunSpec({
|
||||
loadAddress = target.machine.PROGRAM_LOAD_ADDRESS,
|
||||
outputDir = tempdir
|
||||
)
|
||||
val program = IRProgram("unittest-irwriter", IRSymbolTable(null), options, target)
|
||||
val program = IRProgram("unittest-irwriter", IRSymbolTable(), options, target)
|
||||
val writer = IRFileWriter(program, null)
|
||||
val generatedFile = writer.write()
|
||||
val lines = generatedFile.readLines()
|
||||
@ -107,9 +103,9 @@ return
|
||||
program.name shouldBe "test-ir-reader"
|
||||
program.blocks.size shouldBe 2
|
||||
program.st.allVariables().count() shouldBe 3
|
||||
val var1 = program.st.lookup("sys.wait.jiffies") as StStaticVariable
|
||||
val var2 = program.st.lookup("sys.bssvar") as StStaticVariable
|
||||
val var3 = program.st.lookup("sys.emptystring") as StStaticVariable
|
||||
val var1 = program.st.lookup("sys.wait.jiffies") as IRStStaticVariable
|
||||
val var2 = program.st.lookup("sys.bssvar") as IRStStaticVariable
|
||||
val var3 = program.st.lookup("sys.emptystring") as IRStStaticVariable
|
||||
var1.uninitialized shouldBe false
|
||||
var2.uninitialized shouldBe true
|
||||
var3.uninitialized shouldBe true
|
||||
|
@ -1,8 +1,5 @@
|
||||
package prog8.vm
|
||||
|
||||
import prog8.code.StArray
|
||||
import prog8.code.StArrayElement
|
||||
import prog8.code.StStaticVariable
|
||||
import prog8.code.core.ArrayDatatypes
|
||||
import prog8.code.core.AssemblyError
|
||||
import prog8.code.core.DataType
|
||||
@ -247,7 +244,7 @@ class VmProgramLoader {
|
||||
if(iElts.isEmpty() || iElts.size==1) {
|
||||
val iElt = if(iElts.isEmpty()) {
|
||||
require(variable.uninitialized)
|
||||
StArrayElement(0.0, null)
|
||||
IRStArrayElement(0.0, null)
|
||||
} else {
|
||||
require(!variable.uninitialized)
|
||||
iElts[0]
|
||||
@ -262,8 +259,8 @@ class VmProgramLoader {
|
||||
}
|
||||
|
||||
private fun initializeWithValues(
|
||||
variable: StStaticVariable,
|
||||
iElts: StArray,
|
||||
variable: IRStStaticVariable,
|
||||
iElts: IRStArray,
|
||||
startAddress: Int,
|
||||
symbolAddresses: MutableMap<String, Int>,
|
||||
memory: Memory,
|
||||
@ -325,8 +322,8 @@ class VmProgramLoader {
|
||||
}
|
||||
|
||||
private fun initializeWithOneValue(
|
||||
variable: StStaticVariable,
|
||||
iElt: StArrayElement,
|
||||
variable: IRStStaticVariable,
|
||||
iElt: IRStArrayElement,
|
||||
startAddress: Int,
|
||||
symbolAddresses: MutableMap<String, Int>,
|
||||
memory: Memory,
|
||||
@ -389,7 +386,7 @@ class VmProgramLoader {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getInitializerValue(arrayDt: DataType, elt: StArrayElement, symbolAddresses: MutableMap<String, Int>): Double {
|
||||
private fun getInitializerValue(arrayDt: DataType, elt: IRStArrayElement, symbolAddresses: MutableMap<String, Int>): Double {
|
||||
if(elt.addressOfSymbol!=null) {
|
||||
when(arrayDt) {
|
||||
DataType.ARRAY_UB, DataType.STR, DataType.ARRAY_B, DataType.ARRAY_BOOL -> {
|
||||
|
@ -29,7 +29,7 @@ class TestVm: FunSpec( {
|
||||
}
|
||||
|
||||
test("vm execution: empty program") {
|
||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||
val program = IRProgram("test", IRSymbolTable(), getTestOptions(), VMTarget())
|
||||
val vm = VirtualMachine(program)
|
||||
vm.callStack.shouldBeEmpty()
|
||||
vm.valueStack.shouldBeEmpty()
|
||||
@ -43,7 +43,7 @@ class TestVm: FunSpec( {
|
||||
}
|
||||
|
||||
test("vm execution: modify memory") {
|
||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||
val program = IRProgram("test", IRSymbolTable(), getTestOptions(), VMTarget())
|
||||
val block = IRBlock("testmain", null, false, false, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
||||
val startSub = IRSubroutine("testmain.testsub", emptyList(), null, Position.DUMMY)
|
||||
val code = IRCodeChunk(startSub.label, null)
|
||||
@ -72,7 +72,7 @@ class TestVm: FunSpec( {
|
||||
}
|
||||
|
||||
test("asmsub not supported in vm even with IR") {
|
||||
val program = IRProgram("test", IRSymbolTable(null), getTestOptions(), VMTarget())
|
||||
val program = IRProgram("test", IRSymbolTable(), getTestOptions(), VMTarget())
|
||||
val block = IRBlock("main", null, false, false, IRBlock.BlockAlignment.NONE, Position.DUMMY)
|
||||
val startSub = IRAsmSubroutine(
|
||||
"main.asmstart",
|
||||
|
Loading…
Reference in New Issue
Block a user