replace java Stack by kotlin ArrayDeque

This commit is contained in:
Irmen de Jong 2024-09-02 00:15:28 +02:00
parent 97c2dadd16
commit 2c2ae64194
8 changed files with 69 additions and 74 deletions

View File

@ -3,7 +3,8 @@ package prog8.code
import prog8.code.ast.*
import prog8.code.core.*
import prog8.code.target.VMTarget
import java.util.*
import kotlin.collections.ArrayDeque
class SymbolTableMaker(private val program: PtProgram, private val options: CompilationOptions) {
fun make(): SymbolTable {
@ -13,8 +14,8 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
st.add(StNode(it.key, StNodeType.BUILTINFUNC, PtIdentifier(it.key, it.value.returnType ?: DataType.UNDEFINED, Position.DUMMY)))
}
val scopestack = Stack<StNode>()
scopestack.push(st)
val scopestack = ArrayDeque<StNode>()
scopestack.add(st)
program.children.forEach {
addToSt(it, scopestack)
}
@ -35,7 +36,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
return st
}
private fun addToSt(node: PtNode, scope: Stack<StNode>) {
private fun addToSt(node: PtNode, scope: ArrayDeque<StNode>) {
val stNode = when(node) {
is PtAsmSub -> {
val parameters = node.parameters.map { StRomSubParameter(it.first, it.second.type) }
@ -104,7 +105,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
val size = (node.args[1] as PtNumber).number.toUInt()
val align = (node.args[2] as PtNumber).number.toUInt()
// don't add memory slabs in nested scope, just put them in the top level of the ST
scope.firstElement().add(StMemorySlab("prog8_memoryslab_$slabname", size, align, node))
scope.first().add(StMemorySlab("prog8_memoryslab_$slabname", size, align, node))
}
null
}
@ -112,14 +113,14 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
}
if(stNode!=null) {
scope.peek().add(stNode)
scope.push(stNode)
scope.last().add(stNode)
scope.add(stNode)
}
node.children.forEach {
addToSt(it, scope)
}
if(stNode!=null)
scope.pop()
scope.removeLast()
}
private fun makeInitialArray(value: PtArray): List<StArrayElement> {

View File

@ -1,7 +1,7 @@
package prog8.code.ast
import prog8.code.core.*
import java.util.*
import java.util.Objects
import kotlin.math.abs
import kotlin.math.truncate
@ -227,12 +227,6 @@ class PtMemoryByte(position: Position) : PtExpression(DataType.UBYTE, position)
class PtBool(val value: Boolean, position: Position) : PtExpression(DataType.BOOL, position) {
companion object {
fun fromNumber(number: Number, position: Position): PtBool =
PtBool(number != 0.0, position)
}
override fun hashCode(): Int = Objects.hash(type, value)
override fun equals(other: Any?): Boolean {

View File

@ -9,7 +9,7 @@ import prog8.code.ast.*
import prog8.code.core.*
import prog8.code.target.Cx16Target
import prog8.codegen.cpu6502.assignment.*
import java.util.*
import kotlin.collections.ArrayDeque
import kotlin.io.path.Path
import kotlin.io.path.writeLines
@ -772,7 +772,7 @@ class AsmGen6502Internal (
private fun translate(stmt: PtRepeatLoop) {
val endLabel = makeLabel("repeatend")
loopEndLabels.push(endLabel)
loopEndLabels.add(endLabel)
when (stmt.count) {
is PtNumber -> {
@ -816,7 +816,7 @@ class AsmGen6502Internal (
}
}
loopEndLabels.pop()
loopEndLabels.removeLast()
}
private fun repeatWordCount(iterations: Int, stmt: PtRepeatLoop) {

View File

@ -37,7 +37,7 @@ internal class ForLoopsAsmGen(
val endLabel = asmgen.makeLabel("for_end")
val modifiedLabel = asmgen.makeLabel("for_modified")
val modifiedLabel2 = asmgen.makeLabel("for_modifiedb")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val stepsize=range.step.asConstInteger()!!
if(stepsize < -1) {
@ -277,7 +277,7 @@ $endLabel""")
else -> throw AssemblyError("range expression can only be byte or word")
}
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun precheckFromToWord(iterableDt: DataType, stepsize: Int, fromVar: String, endLabel: String) {
@ -333,7 +333,7 @@ $endLabel""")
private fun translateForOverIterableVar(stmt: PtForLoop, iterableDt: DataType, ident: PtIdentifier) {
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val iterableName = asmgen.asmVariableName(ident)
val numElements = when(val symbol = asmgen.symbolTable.lookup(ident.name)) {
is StStaticVariable -> symbol.length!!
@ -477,7 +477,7 @@ $loopLabel sty $indexVar
}
else -> throw AssemblyError("can't iterate over $iterableDt")
}
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun translateForOverConstRange(stmt: PtForLoop, iterableDt: DataType, range: IntProgression) {
@ -495,7 +495,7 @@ $loopLabel sty $indexVar
// not one of the easy cases, generate more complex code...
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
when(iterableDt) {
DataType.ARRAY_B, DataType.ARRAY_UB -> {
// loop over byte range via loopvar, step >= 2 or <= -2
@ -601,13 +601,13 @@ $loopLabel""")
}
else -> throw AssemblyError("range expression can only be byte or word")
}
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun translateForSimpleByteRangeAsc(stmt: PtForLoop, range: IntProgression) {
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val varname = asmgen.asmVariableName(stmt.variable)
asmgen.out("""
lda #${range.first}
@ -627,13 +627,13 @@ $endLabel""")
bne $loopLabel
$endLabel""")
}
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun translateForSimpleByteRangeDesc(stmt: PtForLoop, range: IntProgression) {
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val varname = asmgen.asmVariableName(stmt.variable)
asmgen.out("""
lda #${range.first}
@ -664,13 +664,13 @@ $endLabel""")
$endLabel""")
}
}
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun translateForSimpleWordRangeAsc(stmt: PtForLoop, range: IntProgression) {
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val varname = asmgen.asmVariableName(stmt.variable)
asmgen.out("""
lda #<${range.first}
@ -691,13 +691,13 @@ $loopLabel""")
inc $varname+1""")
asmgen.jmp(loopLabel)
asmgen.out(endLabel)
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun translateForSimpleWordRangeDesc(stmt: PtForLoop, range: IntProgression) {
val loopLabel = asmgen.makeLabel("for_loop")
val endLabel = asmgen.makeLabel("for_end")
asmgen.loopEndLabels.push(endLabel)
asmgen.loopEndLabels.add(endLabel)
val varname = asmgen.asmVariableName(stmt.variable)
asmgen.out("""
lda #<${range.first}
@ -719,7 +719,7 @@ $loopLabel""")
+ dec $varname""")
asmgen.jmp(loopLabel)
asmgen.out(endLabel)
asmgen.loopEndLabels.pop()
asmgen.loopEndLabels.removeLast()
}
private fun assignLoopvarWord(stmt: PtForLoop, range: PtRange) =

View File

@ -11,9 +11,9 @@ import prog8.ast.statements.*
import prog8.code.ast.*
import prog8.code.core.*
import prog8.compiler.builtinFunctionReturnType
import java.io.File
import kotlin.io.path.Path
import kotlin.io.path.isRegularFile
import java.io.File
/**

View File

@ -12,7 +12,7 @@ import prog8.ast.walk.IAstVisitor
import prog8.code.core.*
import prog8.code.target.encodings.JapaneseCharacterConverter
import java.io.CharConversionException
import java.util.*
import java.util.Objects
import kotlin.math.abs
import kotlin.math.floor
import kotlin.math.truncate

View File

@ -1,7 +1,7 @@
package prog8.ast.expressions
import prog8.code.core.*
import java.util.*
import java.util.Objects
object InferredTypes {

View File

@ -6,7 +6,7 @@ import prog8.code.target.virtual.VirtualMachineDefinition
import prog8.intermediate.*
import java.awt.Color
import java.awt.Toolkit
import java.util.*
import kotlin.collections.ArrayDeque
import kotlin.math.*
import kotlin.random.Random
@ -39,8 +39,8 @@ class VirtualMachine(irProgram: IRProgram) {
val program: List<IRCodeChunk>
val artificialLabelAddresses: Map<Int, IRCodeChunk>
val registers = Registers()
val callStack = Stack<CallSiteContext>()
val valueStack = Stack<UByte>() // max 128 entries
val callStack = ArrayDeque<CallSiteContext>()
val valueStack = ArrayDeque<UByte>() // max 128 entries
var breakpointHandler: ((pcChunk: IRCodeChunk, pcIndex: Int) -> Unit)? = null // can set custom breakpoint handler
var pcChunk = IRCodeChunk(null, null)
var pcIndex = 0
@ -360,7 +360,7 @@ class VirtualMachine(irProgram: IRProgram) {
when(i.type!!) {
IRDataType.BYTE -> {
val value = registers.getUB(i.reg1!!)
valueStack.push(value)
valueStack.add(value)
}
IRDataType.WORD -> {
val value = registers.getUW(i.reg1!!)
@ -376,7 +376,7 @@ class VirtualMachine(irProgram: IRProgram) {
private fun InsPOP(i: IRInstruction) {
when(i.type!!) {
IRDataType.BYTE -> setResultReg(i.reg1!!, valueStack.pop().toInt(), i.type!!)
IRDataType.BYTE -> setResultReg(i.reg1!!, valueStack.removeLast().toInt(), i.type!!)
IRDataType.WORD -> setResultReg(i.reg1!!, valueStack.popw().toInt(), i.type!!)
IRDataType.FLOAT -> registers.setFloat(i.fpReg1!!, valueStack.popf())
}
@ -392,12 +392,12 @@ class VirtualMachine(irProgram: IRProgram) {
if(statusCarry)
status = status or 0b00000001u
// TODO overflow not yet supported
valueStack.push(status)
valueStack.add(status)
nextPc()
}
private fun InsPOPST() {
val status = valueStack.pop().toInt()
val status = valueStack.removeLast().toInt()
statusNegative = status and 0b10000000 != 0
statusZero = status and 0b00000010 != 0
statusCarry = status and 0b00000001 != 0
@ -411,7 +411,7 @@ class VirtualMachine(irProgram: IRProgram) {
if(value.dt==null)
break
when(value.dt!!) {
IRDataType.BYTE -> valueStack.push(value.value as UByte)
IRDataType.BYTE -> valueStack.add(value.value as UByte)
IRDataType.WORD -> valueStack.pushw(value.value as UShort)
IRDataType.FLOAT -> valueStack.pushf(value.value as Double)
}
@ -633,7 +633,7 @@ class VirtualMachine(irProgram: IRProgram) {
}
}
// store the call site and jump
callStack.push(CallSiteContext(pcChunk, pcIndex+1, i.fcallArgs!!))
callStack.add(CallSiteContext(pcChunk, pcIndex+1, i.fcallArgs!!))
branchTo(i)
}
@ -641,7 +641,7 @@ class VirtualMachine(irProgram: IRProgram) {
if(callStack.isEmpty())
exit(0)
else {
val context = callStack.pop()
val context = callStack.removeLast()
pcChunk = context.returnChunk
pcIndex = context.returnIndex
// ignore any return values.
@ -652,7 +652,7 @@ class VirtualMachine(irProgram: IRProgram) {
if(callStack.isEmpty())
exit(0)
else {
val context = callStack.pop()
val context = callStack.removeLast()
val returns = context.fcallSpec.returns
when (i.type!!) {
IRDataType.BYTE -> {
@ -1487,16 +1487,16 @@ class VirtualMachine(irProgram: IRProgram) {
val right = registers.getUB(reg2)
val division = if(right==0.toUByte()) 0xffu else left / right
val remainder = if(right==0.toUByte()) 0u else left % right
valueStack.push(division.toUByte())
valueStack.push(remainder.toUByte())
valueStack.add(division.toUByte())
valueStack.add(remainder.toUByte())
}
private fun divAndModConstUByte(reg1: Int, value: UByte) {
val left = registers.getUB(reg1)
val division = if(value==0.toUByte()) 0xffu else left / value
val remainder = if(value==0.toUByte()) 0u else left % value
valueStack.push(division.toUByte())
valueStack.push(remainder.toUByte())
valueStack.add(division.toUByte())
valueStack.add(remainder.toUByte())
}
private fun divAndModUWord(reg1: Int, reg2: Int) {
@ -2491,47 +2491,47 @@ class VirtualMachine(irProgram: IRProgram) {
}
}
internal fun Stack<UByte>.pushw(value: UShort) {
push((value and 255u).toUByte())
push((value.toInt() ushr 8).toUByte())
internal fun ArrayDeque<UByte>.pushw(value: UShort) {
add((value and 255u).toUByte())
add((value.toInt() ushr 8).toUByte())
}
internal fun Stack<UByte>.pushf(value: Double) {
internal fun ArrayDeque<UByte>.pushf(value: Double) {
// push float; lsb first, msb last
var bits = value.toBits()
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
bits = bits ushr 8
push(bits.toUByte())
add(bits.toUByte())
}
internal fun Stack<UByte>.popw(): UShort {
val msb = pop()
val lsb = pop()
internal fun ArrayDeque<UByte>.popw(): UShort {
val msb = removeLast()
val lsb = removeLast()
return ((msb.toInt() shl 8) + lsb.toInt()).toUShort()
}
internal fun Stack<UByte>.popf(): Double {
internal fun ArrayDeque<UByte>.popf(): Double {
// pop float; lsb is on bottom, msb on top
val b0 = pop().toLong()
val b1 = pop().toLong()
val b2 = pop().toLong()
val b3 = pop().toLong()
val b4 = pop().toLong()
val b5 = pop().toLong()
val b6 = pop().toLong()
val b7 = pop().toLong()
val b0 = removeLast().toLong()
val b1 = removeLast().toLong()
val b2 = removeLast().toLong()
val b3 = removeLast().toLong()
val b4 = removeLast().toLong()
val b5 = removeLast().toLong()
val b6 = removeLast().toLong()
val b7 = removeLast().toLong()
val bits = b7 +
(1L shl 8)*b6 +
(1L shl 16)*b5 +