From cf9151f66953bd8a2a3f5cc26623a811c12fa430 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 24 Aug 2020 22:34:39 +0200 Subject: [PATCH] use AsmAssignment preferrably over creating new ast node for codegen --- .../compiler/target/c64/codegen/AsmGen.kt | 25 +++++++++++------- .../target/c64/codegen/ForLoopsAsmGen.kt | 26 ++++++++++--------- .../c64/codegen/assignment/AsmAssignment.kt | 6 ++--- examples/test.p8 | 8 ++++++ 4 files changed, 40 insertions(+), 25 deletions(-) diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt index 337e289e4..5e91847a4 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AsmGen.kt @@ -15,8 +15,11 @@ import prog8.compiler.target.c64.C64MachineDefinition import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX import prog8.compiler.target.c64.Petscii +import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource +import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget import prog8.compiler.target.c64.codegen.assignment.AsmAssignment import prog8.compiler.target.c64.codegen.assignment.AssignmentAsmGen +import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind import prog8.compiler.target.generatedLabelPrefix import prog8.functions.BuiltinFunctions import prog8.functions.FSignature @@ -184,11 +187,7 @@ internal class AsmGen(private val program: Program, blockLevelVarInits.getValue(block).forEach { decl -> val scopedFullName = decl.makeScopedName(decl.name).split('.') require(scopedFullName.first()==block.name) - // TODO use AsmAssignment - val target = AssignTarget(IdentifierReference(scopedFullName.drop(1), decl.position), null, null, decl.position) - val assign = Assignment(target, decl.value!!, decl.position) - assign.linkParents(decl.parent) - assignmentAsmGen.translate(assign) + assignInitialValueToVar(decl, scopedFullName.drop(1)) } out(" rts\n .pend") } @@ -196,6 +195,16 @@ internal class AsmGen(private val program: Program, out(if("force_output" in block.options()) "\n\t.bend\n" else "\n\t.pend\n") } + private fun assignInitialValueToVar(decl: VarDecl, variableName: List) { + val variable = IdentifierReference(variableName, decl.position) + variable.linkParents(decl.parent) + val asgn = AsmAssignment( + AsmAssignSource.fromAstSource(decl.value!!, program), + AsmAssignTarget(TargetStorageKind.VARIABLE, program, this, decl.datatype, variable = variable), + false, decl.position) + assignmentAsmGen.translateNormalAssignment(asgn) + } + private var generatedLabelSequenceNumber: Int = 0 internal fun makeLabel(postfix: String): String { @@ -1036,11 +1045,7 @@ $counterVar .byte 0""") } else { val next = (stmt.parent as INameScope).nextSibling(stmt) if (next !is ForLoop || next.loopVar.nameInSource.single() != stmt.name) { - // TODO use AsmAssignment - val target = AssignTarget(IdentifierReference(listOf(stmt.name), stmt.position), null, null, stmt.position) - val assign = Assignment(target, stmt.value!!, stmt.position) - assign.linkParents(stmt.parent) - translate(assign) + assignInitialValueToVar(stmt, listOf(stmt.name)) } } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt index 2dc5ccae6..2e6228fa9 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/ForLoopsAsmGen.kt @@ -11,6 +11,10 @@ import prog8.compiler.AssemblyError import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_HI_PLUS1_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_HEX import prog8.compiler.target.c64.C64MachineDefinition.ESTACK_LO_PLUS1_HEX +import prog8.compiler.target.c64.codegen.assignment.AsmAssignSource +import prog8.compiler.target.c64.codegen.assignment.AsmAssignTarget +import prog8.compiler.target.c64.codegen.assignment.AsmAssignment +import prog8.compiler.target.c64.codegen.assignment.TargetStorageKind import prog8.compiler.toHex import kotlin.math.absoluteValue @@ -115,11 +119,8 @@ $endLabel inx""") stepsize == 1 || stepsize == -1 -> { asmgen.translateExpression(range.to) + assignLoopvar(stmt, range) val varname = asmgen.asmIdentifierName(stmt.loopVar) - // TODO use AsmAssignment - val assignLoopvar = Assignment(AssignTarget(stmt.loopVar, null, null, stmt.loopVar.position), range.from, range.position) - assignLoopvar.linkParents(stmt) - asmgen.translate(assignLoopvar) asmgen.out(""" lda $ESTACK_HI_PLUS1_HEX,x sta $modifiedLabel+1 @@ -162,11 +163,8 @@ $modifiedLabel2 cmp #0 ; modified lda $ESTACK_LO_PLUS1_HEX,x sta $modifiedLabel2+1 """) + assignLoopvar(stmt, range) val varname = asmgen.asmIdentifierName(stmt.loopVar) - // TODO use AsmAssignment - val assignLoopvar = Assignment(AssignTarget(stmt.loopVar, null, null, stmt.loopVar.position), range.from, range.position) - assignLoopvar.linkParents(stmt) - asmgen.translate(assignLoopvar) asmgen.out(loopLabel) asmgen.translate(stmt.body) @@ -216,11 +214,8 @@ $endLabel inx""") lda $ESTACK_LO_PLUS1_HEX,x sta $modifiedLabel2+1 """) + assignLoopvar(stmt, range) val varname = asmgen.asmIdentifierName(stmt.loopVar) - // TODO use AsmAssignment - val assignLoopvar = Assignment(AssignTarget(stmt.loopVar, null, null, stmt.loopVar.position), range.from, range.position) - assignLoopvar.linkParents(stmt) - asmgen.translate(assignLoopvar) asmgen.out(loopLabel) asmgen.translate(stmt.body) @@ -268,6 +263,13 @@ $endLabel inx""") asmgen.loopEndLabels.pop() } + private fun assignLoopvar(stmt: ForLoop, range: RangeExpr) { + val target = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, stmt.loopVarDt(program).typeOrElse(DataType.STRUCT), variable=stmt.loopVar) + val src = AsmAssignSource.fromAstSource(range.from, program).adjustDataTypeToTarget(target) + val assign = AsmAssignment(src, target, false, range.position) + asmgen.translateNormalAssignment(assign) + } + private fun translateForOverIterableVar(stmt: ForLoop, iterableDt: DataType, ident: IdentifierReference) { val loopLabel = asmgen.makeLabel("for_loop") val endLabel = asmgen.makeLabel("for_end") diff --git a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt index b9d6d2f89..5e800d7ae 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/assignment/AsmAssignment.kt @@ -36,7 +36,7 @@ internal class AsmAssignTarget(val kind: TargetStorageKind, val array: ArrayIndexedExpression? = null, val memory: DirectMemoryWrite? = null, val register: RegisterOrPair? = null, - val origAstTarget: AssignTarget? = null // TODO get rid of this eventually? + val origAstTarget: AssignTarget? = null ) { val constMemoryAddress by lazy { memory?.addressExpression?.constValue(program)?.number?.toInt() ?: 0} @@ -131,8 +131,8 @@ internal class AsmAssignSource(val kind: SourceStorageKind, SourceStorageKind.ARRAY -> array!! SourceStorageKind.MEMORY -> memory!! SourceStorageKind.EXPRESSION -> expression!! - SourceStorageKind.REGISTER -> TODO() - SourceStorageKind.STACK -> TODO() + SourceStorageKind.REGISTER -> throw AssemblyError("cannot get a register source as Ast node") + SourceStorageKind.STACK -> throw AssemblyError("cannot get a stack source as Ast node") } fun withAdjustedDt(newType: DataType) = diff --git a/examples/test.p8 b/examples/test.p8 index 345f7f8db..f9b7678ed 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -3,6 +3,8 @@ main { + uword glob=11222 + sub start() { uword lines = 1 uword score = $1000 @@ -10,6 +12,12 @@ main { ubyte x ubyte y + c64scr.print_uw(lines) + c64.CHROUT('\n') + lines=glob + c64scr.print_uw(lines) + c64.CHROUT('\n') + lines = mkword(x, y) c64scr.print_uw(lines) c64.CHROUT('\n')