From b0f5b6925dd016cefba819b6a2edc7cca03f990c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 3 Feb 2024 01:57:17 +0100 Subject: [PATCH] getting rid of pointer[idx] in ast, instead always use @(ptr+idx) --- codeCore/src/prog8/code/ast/AstExpressions.kt | 8 +- .../codegen/cpu6502/BuiltinFunctionsAsmGen.kt | 4 +- .../codegen/cpu6502/PostIncrDecrAsmGen.kt | 34 +-- .../cpu6502/assignment/AssignmentAsmGen.kt | 199 +++--------------- .../assignment/AugmentableAssignmentAsmGen.kt | 2 +- .../codegen/intermediate/AssignmentGen.kt | 19 -- .../codegen/intermediate/BuiltinFuncGen.kt | 1 - .../codegen/intermediate/ExpressionGen.kt | 29 +-- .../prog8/codegen/intermediate/IRCodeGen.kt | 27 +-- .../compiler/astprocessing/CodeDesugarer.kt | 35 ++- .../astprocessing/IntermediateAstMaker.kt | 6 +- compiler/test/vm/TestCompilerVirtual.kt | 3 - docs/source/todo.rst | 3 + examples/test.p8 | 76 ++----- 14 files changed, 81 insertions(+), 365 deletions(-) diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index a0a1ba4e6..a7dce7dbf 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -138,16 +138,16 @@ class PtAddressOf(position: Position) : PtExpression(DataType.UWORD, position) { class PtArrayIndexer(elementType: DataType, position: Position): PtExpression(elementType, position) { val variable: PtIdentifier - get() = children[0] as PtIdentifier + get() { + require((children[0] as? PtIdentifier)?.type in ArrayDatatypes+DataType.STR) // TODO remove + return children[0] as PtIdentifier + } val index: PtExpression get() = children[1] as PtExpression val splitWords: Boolean get() = variable.type in SplitWordArrayTypes - val usesPointerVariable: Boolean - get() = variable.type==DataType.UWORD - init { require(elementType in NumericDatatypes) } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 26a56983c..7fcded35b 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -677,7 +677,6 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, } is PtArrayIndexer -> { val indexer = fcall.args[0] as PtArrayIndexer - require(!indexer.usesPointerVariable) val elementSize: Int val msbAdd: Int if(indexer.splitWords) { @@ -846,8 +845,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, } else -> { val tempvar = asmgen.getTempVarName(DataType.FLOAT) - asmgen.assignExpressionTo(fcall.args[1], - AsmAssignTarget(TargetStorageKind.VARIABLE, asmgen, DataType.FLOAT, fcall.definingISub(), fcall.position, tempvar, null, null, null, null)) + asmgen.assignExpressionToVariable(fcall.args[1], tempvar, DataType.FLOAT) asmgen.assignExpressionToRegister(fcall.args[0], RegisterOrPair.AY) asmgen.out(""" pha diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt index 61359ecde..91ad85934 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/PostIncrDecrAsmGen.kt @@ -91,22 +91,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as val indexValue = constIndex * program.memsizer.memorySize(elementDt) when(elementDt) { in ByteDatatypes -> { - if(targetArrayIdx.usesPointerVariable) { - asmgen.out(""" - lda $asmArrayvarname - clc - adc #$indexValue - sta (+) +1 - lda $asmArrayvarname+1 - adc #0 - sta (+) +2""") - if(incr) - asmgen.out("+\tinc ${'$'}ffff\t; modified") - else - asmgen.out("+\tdec ${'$'}ffff\t; modified") - } else { - asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue") - } + asmgen.out(if (incr) " inc $asmArrayvarname+$indexValue" else " dec $asmArrayvarname+$indexValue") } in WordDatatypes -> { if(incr) @@ -130,22 +115,7 @@ internal class PostIncrDecrAsmGen(private val program: PtProgram, private val as asmgen.loadScaledArrayIndexIntoRegister(targetArrayIdx, CpuRegister.X) when(elementDt) { in ByteDatatypes -> { - if(targetArrayIdx.usesPointerVariable) { - asmgen.out(""" - txa - clc - adc $asmArrayvarname - sta (+) +1 - lda $asmArrayvarname+1 - adc #0 - sta (+) +2""") - if(incr) - asmgen.out("+\tinc ${'$'}ffff\t; modified") - else - asmgen.out("+\tdec ${'$'}ffff\t; modified") - } else { - asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x") - } + asmgen.out(if (incr) " inc $asmArrayvarname,x" else " dec $asmArrayvarname,x") } in WordDatatypes -> { if(incr) diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index e3610bcb2..07a79bc5c 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -64,32 +64,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, val value = assign.source.array!! val elementDt = assign.source.datatype val arrayVarName = asmgen.asmVariableName(value.variable) - - if(value.usesPointerVariable) { - if(elementDt !in ByteDatatypes) - throw AssemblyError("non-array var indexing requires bytes dt") - if(value.type != DataType.UBYTE) - throw AssemblyError("non-array var indexing requires bytes index") - if(asmgen.isTargetCpu(CpuType.CPU65c02) && (value.index as? PtNumber)?.number==0.0) { - if (asmgen.isZpVar(value.variable)) { - asmgen.out(" lda ($arrayVarName)") - } else { - asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1") - asmgen.out(" lda (P8ZP_SCRATCH_W1)") - } - } else { - asmgen.loadScaledArrayIndexIntoRegister(value, CpuRegister.Y) - if (asmgen.isZpVar(value.variable)) { - asmgen.out(" lda ($arrayVarName),y") - } else { - asmgen.out(" lda $arrayVarName | sta P8ZP_SCRATCH_W1 | lda $arrayVarName+1 | sta P8ZP_SCRATCH_W1+1") - asmgen.out(" lda (P8ZP_SCRATCH_W1),y") - } - } - assignRegisterByte(assign.target, CpuRegister.A, elementDt in SignedDatatypes, false) - return - } - val constIndex = value.index.asConstInteger() if(value.splitWords) { @@ -805,26 +779,11 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pha") asmgen.assignExpressionToRegister(rightArrayIndexer.index, RegisterOrPair.Y, false) if(!rightArrayIndexer.index.isSimple()) asmgen.out(" pla") - if(rightArrayIndexer.usesPointerVariable && !asmgen.isZpVar(rightArrayIndexer.variable)) { - asmgen.out(""" - ldx ${rightArrayIndexer.variable.name} - stx P8ZP_SCRATCH_W1 - ldx ${rightArrayIndexer.variable.name}+1 - stx P8ZP_SCRATCH_W1+1""") - if (expr.operator == "+") - asmgen.out(" clc | adc (P8ZP_SCRATCH_W1),y") - else - asmgen.out(" sec | sbc (P8ZP_SCRATCH_W1),y") - } else { - val arrayvarname = if (rightArrayIndexer.usesPointerVariable) - "(${rightArrayIndexer.variable.name})" - else - asmgen.asmSymbolName(rightArrayIndexer.variable) - if (expr.operator == "+") - asmgen.out(" clc | adc $arrayvarname,y") - else - asmgen.out(" sec | sbc $arrayvarname,y") - } + val arrayvarname = asmgen.asmSymbolName(rightArrayIndexer.variable) + if (expr.operator == "+") + asmgen.out(" clc | adc $arrayvarname,y") + else + asmgen.out(" sec | sbc $arrayvarname,y") assignRegisterByte(target, CpuRegister.A, dt in SignedDatatypes, true) } else { assignExpressionToRegister(left, RegisterOrPair.A, left.type==DataType.BYTE) @@ -2836,21 +2795,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, storeRegisterAInMemoryAddress(target.memory!!) } TargetStorageKind.ARRAY -> { - if(assignsIndexedPointerVar(target)) { - if (target.constArrayIndexValue==0u) { - asmgen.out(" lda $sourceName") - asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable) - } else { - asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y) - if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" lda $sourceName | sta (${target.asmVarname}),y") - } else { - asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1") - asmgen.out(" lda $sourceName | sta (P8ZP_SCRATCH_W2),y") - } - } - return - } if(target.array!!.splitWords) TODO("assign into split words ${target.position}") if (target.constArrayIndexValue!=null) { @@ -3256,87 +3200,29 @@ internal class AssignmentAsmGen(private val program: PtProgram, if(target.array!!.splitWords) throw AssemblyError("cannot assign byte to split word array here ${target.position}") - if(assignsIndexedPointerVar(target)) { - // assign byte to a byte array via an uword pointervariable instead of a regular array variable - if (target.constArrayIndexValue!=null) { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") - } - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" ldy #${target.constArrayIndexValue} | sta (${target.asmVarname}),y") - } else { - asmgen.out(""" - ldy ${target.asmVarname} - sty P8ZP_SCRATCH_W1 - ldy ${target.asmVarname}+1 - sty P8ZP_SCRATCH_W1+1 - ldy #${target.constArrayIndexValue} - sta (P8ZP_SCRATCH_W1),y""") - } + // assign regular array indexing + if (target.constArrayIndexValue!=null) { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") } - else { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") - } - val indexVar = target.array.index as? PtIdentifier - if(indexVar!=null) { - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta (${target.asmVarname}),y") - } else { - asmgen.out(""" - ldy ${target.asmVarname} - sty P8ZP_SCRATCH_W1 - ldy ${target.asmVarname}+1 - sty P8ZP_SCRATCH_W1+1 - ldy ${asmgen.asmVariableName(indexVar)} - sta (P8ZP_SCRATCH_W1),y""") - } - } else { - asmgen.saveRegisterStack(register, false) - asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false) - asmgen.out(" pla") - if(asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" sta (${target.asmVarname}),y") - } else { - asmgen.out(""" - ldx ${target.asmVarname} - stx P8ZP_SCRATCH_W1 - ldx ${target.asmVarname}+1 - stx P8ZP_SCRATCH_W1+1 - sta (P8ZP_SCRATCH_W1),y""") - } - } + asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}") + } + else { + when (register) { + CpuRegister.A -> {} + CpuRegister.X -> asmgen.out(" txa") + CpuRegister.Y -> asmgen.out(" tya") } - return - } else { - // assign regular array indexing - if (target.constArrayIndexValue!=null) { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") - } - asmgen.out(" sta ${target.asmVarname}+${target.constArrayIndexValue}") - } - else { - when (register) { - CpuRegister.A -> {} - CpuRegister.X -> asmgen.out(" txa") - CpuRegister.Y -> asmgen.out(" tya") - } - val indexVar = target.array.index as? PtIdentifier - if(indexVar!=null) { - asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y") - } else { - require(target.array.index.type in ByteDatatypes) - asmgen.saveRegisterStack(register, false) - asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false) - asmgen.out(" pla | sta ${target.asmVarname},y") - } + val indexVar = target.array.index as? PtIdentifier + if(indexVar!=null) { + asmgen.out(" ldy ${asmgen.asmVariableName(indexVar)} | sta ${target.asmVarname},y") + } else { + require(target.array.index.type in ByteDatatypes) + asmgen.saveRegisterStack(register, false) + asmgen.assignExpressionToRegister(target.array.index, RegisterOrPair.Y, false) + asmgen.out(" pla | sta ${target.asmVarname},y") } } } @@ -3632,21 +3518,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, storeRegisterAInMemoryAddress(target.memory!!) } TargetStorageKind.ARRAY -> { - if(assignsIndexedPointerVar(target)) { - if (target.constArrayIndexValue==0u) { - asmgen.out(" lda #0") - asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable) - } else { - asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y) - if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" lda #0 | sta (${target.asmVarname}),y") - } else { - asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1") - asmgen.out(" lda #0 | sta (P8ZP_SCRATCH_W2),y") - } - } - return - } if(target.array!!.splitWords) throw AssemblyError("cannot assign byte to split word array here ${target.position}") if (target.constArrayIndexValue!=null) { @@ -3686,21 +3557,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, storeRegisterAInMemoryAddress(target.memory!!) } TargetStorageKind.ARRAY -> { - if(assignsIndexedPointerVar(target)) { - if (target.constArrayIndexValue==0u) { - asmgen.out(" lda #${byte.toHex()}") - asmgen.storeAIntoPointerVar(target.origAstTarget!!.array!!.variable) - } else { - asmgen.loadScaledArrayIndexIntoRegister(target.array!!, CpuRegister.Y) - if (asmgen.isZpVar(target.origAstTarget!!.array!!.variable)) { - asmgen.out(" lda #${byte.toHex()} | sta (${target.asmVarname}),y") - } else { - asmgen.out(" lda ${target.asmVarname} | sta P8ZP_SCRATCH_W2 | lda ${target.asmVarname}+1 | sta P8ZP_SCRATCH_W2+1") - asmgen.out(" lda #${byte.toHex()} | sta (P8ZP_SCRATCH_W2),y") - } - } - return - } if(target.array!!.splitWords) TODO("assign into split words ${target.position}") if (target.constArrayIndexValue!=null) { @@ -3732,9 +3588,6 @@ internal class AssignmentAsmGen(private val program: PtProgram, } } - private fun assignsIndexedPointerVar(target: AsmAssignTarget): Boolean = - target.origAstTarget?.array?.variable?.type==DataType.UWORD - internal fun assignConstantFloat(target: AsmAssignTarget, float: Double) { if (float == 0.0) { // optimized case for float zero diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt index d8f178a58..636579afd 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AugmentableAssignmentAsmGen.kt @@ -163,7 +163,7 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram, } } else -> { - asmgen.assignExpressionTo(memory.address, AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UWORD, memory.definingISub(), target.position, register = RegisterOrPair.AY)) + asmgen.assignExpressionToRegister(memory.address, RegisterOrPair.AY, false) asmgen.saveRegisterStack(CpuRegister.A, true) asmgen.saveRegisterStack(CpuRegister.Y, true) asmgen.out(" jsr prog8_lib.read_byte_from_address_in_AY_into_A") diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index 43927c87b..f33726136 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -302,25 +302,6 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val variable = targetArray.variable.name val itemsize = codeGen.program.memsizer.memorySize(targetArray.type) - if(targetArray.usesPointerVariable) { - if(itemsize!=1) - throw AssemblyError("non-array var indexing requires bytes dt") - if(targetArray.index.type!=DataType.UBYTE) - throw AssemblyError("non-array var indexing requires bytes index") - val tr = expressionEval.translateExpression(targetArray.index) - val idxReg = tr.resultReg - addToResult(result, tr, tr.resultReg, -1) - val code = IRCodeChunk(null, null) - if(zero) { - // there's no STOREZIX instruction - valueRegister = codeGen.registers.nextFree() - code += IRInstruction(Opcode.LOAD, targetDt, reg1=valueRegister, immediate = 0) - } - code += IRInstruction(Opcode.STOREIX, targetDt, reg1=valueRegister, reg2=idxReg, labelSymbol = variable) - result += code - return result - } - val fixedIndex = constIntValue(targetArray.index) val arrayLength = codeGen.symbolTable.getLength(targetArray.variable.name) if(zero) { diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt index 3fb6ddbea..6dd8167d8 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/BuiltinFuncGen.kt @@ -705,7 +705,6 @@ internal class BuiltinFuncGen(private val codeGen: IRCodeGen, private val exprGe } } is PtArrayIndexer -> { - require(!target.usesPointerVariable) if(target.splitWords) { // lsb/msb in split arrays, element index 'size' is always 1 val constIndex = target.index.asConstInteger() diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index e89115647..c4678b476 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -180,19 +180,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val vmDt = irType(arrayIx.type) val result = mutableListOf() val arrayVarSymbol = arrayIx.variable.name - - if(arrayIx.usesPointerVariable) { - if(eltSize!=1) - throw AssemblyError("non-array var indexing requires bytes dt") - if(arrayIx.index.type !in ByteDatatypes) - throw AssemblyError("non-array var indexing requires bytes index") - val tr = translateExpression(arrayIx.index) - addToResult(result, tr, tr.resultReg, -1) - val resultReg = codeGen.registers.nextFree() - addInstr(result, IRInstruction(Opcode.LOADIX, vmDt, reg1=resultReg, reg2=tr.resultReg, labelSymbol = arrayVarSymbol), null) - return ExpressionCodeResult(result, vmDt, resultReg, -1) - } - var resultRegister = -1 if(arrayIx.splitWords) { @@ -1253,20 +1240,17 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val result = mutableListOf() if(array.splitWords) return operatorMinusInplaceSplitArray(array, operand) - if(array.usesPointerVariable) { - TODO("inplace - for pointer variable") - } - val vmDt = irType(array.type) + val eltDt = irType(array.type) val constIndex = array.index.asConstInteger() val constValue = operand.asConstInteger() if(constIndex!=null && constValue!=null) { if(constValue==1) { - addInstr(result, IRInstruction(Opcode.DECM, vmDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null) + addInstr(result, IRInstruction(Opcode.DECM, eltDt, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize), null) } else { val valueReg=codeGen.registers.nextFree() result += IRCodeChunk(null, null).also { - it += IRInstruction(Opcode.LOAD, vmDt, reg1=valueReg, immediate = constValue) - it += IRInstruction(Opcode.SUBM, vmDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize) + it += IRInstruction(Opcode.LOAD, eltDt, reg1=valueReg, immediate = constValue) + it += IRInstruction(Opcode.SUBM, eltDt, reg1=valueReg, labelSymbol = array.variable.name, symbolOffset = constIndex*eltSize) } } return Ok(result) @@ -1344,9 +1328,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val result = mutableListOf() if(array.splitWords) return operatorPlusInplaceSplitArray(array, operand) - if(array.usesPointerVariable) { - TODO("inplace + for pointer variable") - } val eltSize = codeGen.program.memsizer.memorySize(array.type) val elementDt = irType(array.type) val constIndex = array.index.asConstInteger() @@ -1806,8 +1787,6 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { val result = mutableListOf() if(array.splitWords) TODO("inplace compare for split word array") - if(array.usesPointerVariable) - TODO("inplace compare for pointer variable") val vmDt = irType(array.type) val constIndex = array.index.asConstInteger() val constValue = value.asConstInteger() diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index f29d8766b..26989bc40 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -1534,20 +1534,7 @@ class IRCodeGen( val itemsize = program.memsizer.memorySize(array.type) val fixedIndex = constIntValue(array.index) if(fixedIndex!=null) { - val offset = fixedIndex*itemsize - val indexReg = registers.nextFree() - val dataReg = registers.nextFree() - if(array.usesPointerVariable) { - // we don't have an indirect dec/inc so do it via an intermediate register - result += IRCodeChunk(null,null).also { - it += IRInstruction(Opcode.LOAD, IRDataType.BYTE, reg1 = indexReg, immediate = offset) - it += IRInstruction(Opcode.LOADIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable) - it += IRInstruction(operationRegister, irDt, reg1=dataReg) - it += IRInstruction(Opcode.STOREIX, irDt, reg1 = dataReg, reg2 = indexReg, labelSymbol = variable) - } - } else { - addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = offset), null) - } + addInstr(result, IRInstruction(operationMem, irDt, labelSymbol = variable, symbolOffset = fixedIndex*itemsize), null) } else { val indexTr = expressionEval.translateExpression(array.index) addToResult(result, indexTr, indexTr.resultReg, -1) @@ -1555,15 +1542,9 @@ class IRCodeGen( result += multiplyByConst(IRDataType.BYTE, indexTr.resultReg, itemsize) result += IRCodeChunk(null, null).also { val incReg = registers.nextFree() - if(array.usesPointerVariable) { - it += IRInstruction(Opcode.LOADIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) - it += IRInstruction(operationRegister, irDt, reg1=incReg) - it += IRInstruction(Opcode.STOREIX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) - } else { - it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) - it += IRInstruction(operationRegister, irDt, reg1=incReg) - it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) - } + it += IRInstruction(Opcode.LOADX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) + it += IRInstruction(operationRegister, irDt, reg1=incReg) + it += IRInstruction(Opcode.STOREX, irDt, reg1=incReg, reg2=indexTr.resultReg, labelSymbol=variable) } } } else diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index 23bbd2385..8b8ed6d25 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -195,25 +195,22 @@ _after: // replace pointervar[word] by @(pointervar+word) to avoid the // "array indexing is limited to byte size 0..255" error for pointervariables. val indexExpr = arrayIndexedExpression.indexer.indexExpr - val indexerDt = indexExpr.inferType(program) - if(indexerDt.isWords) { - val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program) - if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) { - val add: Expression = - if(indexExpr.constValue(program)?.number==0.0) - arrayIndexedExpression.arrayvar.copy() - else - BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position) - return if(parent is AssignTarget) { - // assignment to array - val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) - val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) - } else { - // read from array - val memread = DirectMemoryRead(add, arrayIndexedExpression.position) - listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) - } + val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program) + if(arrayVar!=null && arrayVar.datatype==DataType.UWORD) { + val add: Expression = + if(indexExpr.constValue(program)?.number==0.0) + arrayIndexedExpression.arrayvar.copy() + else + BinaryExpression(arrayIndexedExpression.arrayvar.copy(), "+", indexExpr, arrayIndexedExpression.position) + return if(parent is AssignTarget) { + // assignment to array + val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) + val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) + } else { + // read from array + val memread = DirectMemoryRead(add, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) } } return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index d3436066a..948a10a4d 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -551,8 +551,10 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr } private fun transform(srcArr: ArrayIndexedExpression): PtArrayIndexer { - val arrayVarType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") } - val array = PtArrayIndexer(arrayVarType, srcArr.position) + if(srcArr.arrayvar.targetVarDecl(program)!!.datatype !in ArrayDatatypes + DataType.STR) + throw FatalAstException("array indexing can be used on array or string variables ${srcArr.position}") + val eltType = srcArr.inferType(program).getOrElse { throw FatalAstException("unknown dt") } + val array = PtArrayIndexer(eltType, srcArr.position) array.add(transform(srcArr.arrayvar)) array.add(transformExpression(srcArr.indexer.indexExpr)) return array diff --git a/compiler/test/vm/TestCompilerVirtual.kt b/compiler/test/vm/TestCompilerVirtual.kt index 4d8e68d3e..8f2d80190 100644 --- a/compiler/test/vm/TestCompilerVirtual.kt +++ b/compiler/test/vm/TestCompilerVirtual.kt @@ -288,9 +288,6 @@ mylabel: test("nesting with overlapping names is ok (doesn't work for 64tass)") { val src=""" -%import textio -%zeropage basicsafe - main { sub start() { main() diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 61b777273..4eda06138 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -1,6 +1,9 @@ TODO ==== +petaxian is now a lot larger since pointer[idx] is rewritten into @(ptr+idx). Missing some optimized code somewhere now? +VM textelite is now a lot larger too + (after merge in boolean): move all "OperatorXinplace" from expressionGen to AssignmentGen, see if we can get rid of the Result return type. ... diff --git a/examples/test.p8 b/examples/test.p8 index 4a60e7337..1f1aaa0d6 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,74 +1,30 @@ %import textio -;; %import test_stack +%import floats +%import math %zeropage basicsafe %option no_sysinit main { - uword[3] a - uword[3] b - ubyte @shared j - uword @shared aa = 1 - - sub derp() { - return aa=5 + sub derp(str arg) { + arg[4] = '?' } sub start() { - derp() - ;; test_stack.test() - j = 1 - a[j] = 1 - b[j] = 0 - b[j] += 5 * aa - b[j] += 5 * aa - b[j] += 5 * aa - b[j] += 5 * aa - txt.print_uw(b[j]) ; 20 + str msg = "hello" + derp(msg) + txt.chrout(msg[4]) ; ? txt.nl() - b[j] += 5 * a[1] - b[j] += 5 * a[1] - b[j] += 5 * a[1] - b[j] += 5 * a[1] - txt.print_uw(b[j]) ; 40 + uword @shared az = $4000 + @($4004) = 0 + az[4] |= $40 + txt.print_ub(@($4004)) ; 64 txt.nl() - b[j] += 5 * a[j] - b[j] += 5 * a[j] - b[j] += 5 * a[j] - b[j] += 5 * a[j] - txt.print_uw(b[j]) ; 60 + @(az+4) = 0 + @(az+4) |= $4f + txt.print_ub(@($4004)) ; 79 txt.nl() - ;; test_stack.test() - } -} -;%import textio -;%import floats -;%zeropage basicsafe -;%option no_sysinit -; -;main { -; sub start() { - -; uword @shared addr = 2000 -; @(2000) = 199 -; txt.print_ub(@(2000)) -; txt.nl() -; @(addr) = ~@(addr) -; txt.print_ub(@(2000)) -; txt.nl() -; -; word[3] @split @shared array = [1111,$10ff,3333] -; -; txt.print_w(array[1]) -; txt.nl() -; txt.print_w(-array[1]) -; txt.nl() -; array[1] = -array[1] -; txt.print_w(array[1]) -; txt.nl() -; txt.nl() -; ; ubyte @shared idx = 1 ; txt.print_w(array[idx]) ; txt.nl() @@ -151,5 +107,5 @@ main { ; bb = bb or barr[1] ; bb = bb xor barr[1] ; bb = not bb -; } -;} + } +}