refactoring assignments codegen

This commit is contained in:
Irmen de Jong 2020-08-20 15:18:24 +02:00
parent c144d4e501
commit 6f3b2749b0
6 changed files with 127 additions and 190 deletions

View File

@ -328,7 +328,7 @@ open class Assignment(var target: AssignTarget, var value: Expression, override
return("Assignment(target: $target, value: $value, pos=$position)") return("Assignment(target: $target, value: $value, pos=$position)")
} }
val isInplace: Boolean val isAugmentable: Boolean
get() { get() {
val binExpr = value as? BinaryExpression val binExpr = value as? BinaryExpression
if(binExpr!=null) { if(binExpr!=null) {

View File

@ -1025,36 +1025,6 @@ $counterVar .byte 0""")
internal fun translateFunctionCall(functionCall: FunctionCall) = internal fun translateFunctionCall(functionCall: FunctionCall) =
functioncallAsmGen.translateFunctionCall(functionCall) functioncallAsmGen.translateFunctionCall(functionCall)
internal fun assignFromEvalResult(target: AssignTarget) = internal fun assignToRegister(reg: CpuRegister, value: Short?, identifier: IdentifierReference?) =
assignmentAsmGen.assignFromEvalResult(target)
fun assignFromByteConstant(target: AssignTarget, value: Short) =
assignmentAsmGen.assignFromByteConstant(target, value)
fun assignFromWordConstant(target: AssignTarget, value: Int) =
assignmentAsmGen.assignFromWordConstant(target, value)
fun assignFromFloatConstant(target: AssignTarget, value: Double) =
assignmentAsmGen.assignFromFloatConstant(target, value)
fun assignFromByteVariable(target: AssignTarget, variable: IdentifierReference) =
assignmentAsmGen.assignFromByteVariable(target, variable)
fun assignFromWordVariable(target: AssignTarget, variable: IdentifierReference) =
assignmentAsmGen.assignFromWordVariable(target, variable)
fun assignFromAddressOf(target: AssignTarget, variable: IdentifierReference) =
assignmentAsmGen.assignFromAddressOf(target, variable)
fun assignFromFloatVariable(target: AssignTarget, variable: IdentifierReference) =
assignmentAsmGen.assignFromFloatVariable(target, variable)
fun assignFromRegister(target: AssignTarget, register: CpuRegister) =
assignmentAsmGen.assignFromRegister(target, register)
fun assignFromMemoryByte(target: AssignTarget, address: Int?, identifier: IdentifierReference?) =
assignmentAsmGen.assignFromMemoryByte(target, address, identifier)
fun assignToRegister(reg: CpuRegister, value: Short?, identifier: IdentifierReference?) =
assignmentAsmGen.assignToRegister(reg, value, identifier) assignmentAsmGen.assignToRegister(reg, value, identifier)
} }

View File

@ -3,10 +3,7 @@ package prog8.compiler.target.c64.codegen
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.base.* import prog8.ast.base.*
import prog8.ast.expressions.* import prog8.ast.expressions.*
import prog8.ast.statements.AssignTarget import prog8.ast.statements.*
import prog8.ast.statements.Assignment
import prog8.ast.statements.DirectMemoryWrite
import prog8.ast.statements.VarDecl
import prog8.compiler.AssemblyError import prog8.compiler.AssemblyError
import prog8.compiler.target.c64.C64MachineDefinition import prog8.compiler.target.c64.C64MachineDefinition
import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage import prog8.compiler.target.c64.C64MachineDefinition.C64Zeropage
@ -18,33 +15,49 @@ import prog8.compiler.toHex
internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen) { internal class AssignmentAsmGen(private val program: Program, private val asmgen: AsmGen) {
internal fun translate(assign: Assignment) { internal fun translate(assign: Assignment) {
if(assign.isInplace) when {
translateNormalAssignment(assign) // TODO generate better code here for in-place assignments assign.value is NumericLiteralValue -> translateConstantValueAssignment(assign)
else assign.value is IdentifierReference -> translateVariableAssignment(assign)
translateNormalAssignment(assign) assign.isAugmentable -> {
println("TODO: optimize augmentable assignment ${assign.position}") // TODO
translateOtherAssignment(assign) // TODO generate better code here for augmentable assignments
}
else -> translateOtherAssignment(assign)
}
} }
// old code-generation below: internal fun assignToRegister(reg: CpuRegister, value: Short?, identifier: IdentifierReference?) {
// eventually, all of this should have been replaced by newer more optimized code. if(value!=null) {
private fun translateNormalAssignment(assign: Assignment) { asmgen.out(" ld${reg.toString().toLowerCase()} #${value.toHex()}")
} else if(identifier!=null) {
val name = asmgen.asmIdentifierName(identifier)
asmgen.out(" ld${reg.toString().toLowerCase()} $name")
}
}
private fun translateVariableAssignment(assign: Assignment) {
val identifier = assign.value as IdentifierReference
when (val type = assign.target.inferType(program, assign).typeOrElse(DataType.STRUCT)) {
DataType.UBYTE, DataType.BYTE -> assignFromByteVariable(assign.target, identifier)
DataType.UWORD, DataType.WORD -> assignFromWordVariable(assign.target, identifier)
DataType.FLOAT -> assignFromFloatVariable(assign.target, identifier)
in PassByReferenceDatatypes -> assignFromAddressOf(assign.target, identifier)
else -> throw AssemblyError("unsupported assignment target type $type")
}
}
private fun translateConstantValueAssignment(assign: Assignment) {
val numVal = assign.value as NumericLiteralValue
when (numVal.type) {
DataType.UBYTE, DataType.BYTE -> assignFromByteConstant(assign.target, numVal.number.toShort())
DataType.UWORD, DataType.WORD -> assignFromWordConstant(assign.target, numVal.number.toInt())
DataType.FLOAT -> assignFromFloatConstant(assign.target, numVal.number.toDouble())
else -> throw AssemblyError("weird numval type")
}
}
private fun translateOtherAssignment(assign: Assignment) {
when (assign.value) { when (assign.value) {
is NumericLiteralValue -> {
val numVal = assign.value as NumericLiteralValue
when (numVal.type) {
DataType.UBYTE, DataType.BYTE -> assignFromByteConstant(assign.target, numVal.number.toShort())
DataType.UWORD, DataType.WORD -> assignFromWordConstant(assign.target, numVal.number.toInt())
DataType.FLOAT -> assignFromFloatConstant(assign.target, numVal.number.toDouble())
else -> throw AssemblyError("weird numval type")
}
}
is IdentifierReference -> {
when (val type = assign.target.inferType(program, assign).typeOrElse(DataType.STRUCT)) {
DataType.UBYTE, DataType.BYTE -> assignFromByteVariable(assign.target, assign.value as IdentifierReference)
DataType.UWORD, DataType.WORD -> assignFromWordVariable(assign.target, assign.value as IdentifierReference)
DataType.FLOAT -> assignFromFloatVariable(assign.target, assign.value as IdentifierReference)
else -> throw AssemblyError("unsupported assignment target type $type")
}
}
is AddressOf -> { is AddressOf -> {
val identifier = (assign.value as AddressOf).identifier val identifier = (assign.value as AddressOf).identifier
assignFromAddressOf(assign.target, identifier) assignFromAddressOf(assign.target, identifier)
@ -60,7 +73,9 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
assignFromMemoryByte(assign.target, null, read.addressExpression as IdentifierReference) assignFromMemoryByte(assign.target, null, read.addressExpression as IdentifierReference)
} }
else -> { else -> {
throw AssemblyError("missing asm gen for memread assignment into ${assign.target}") asmgen.translateExpression(read.addressExpression)
asmgen.out(" jsr prog8_lib.read_byte_from_address | inx")
assignFromRegister(assign.target, CpuRegister.A)
} }
} }
} }
@ -120,10 +135,11 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array assignment $assign") is ArrayLiteralValue, is StringLiteralValue -> throw AssemblyError("no asm gen for string/array assignment $assign")
is RangeExpr -> throw AssemblyError("range expression should have been changed into array values ${assign.value.position}") is RangeExpr -> throw AssemblyError("range expression should have been changed into array values ${assign.value.position}")
else -> throw AssemblyError("assignment value type should have been handled elsewhere")
} }
} }
internal fun assignFromEvalResult(target: AssignTarget) { private fun assignFromEvalResult(target: AssignTarget) {
val targetIdent = target.identifier val targetIdent = target.identifier
when { when {
targetIdent != null -> { targetIdent != null -> {
@ -152,8 +168,8 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
target.memoryAddress != null -> { target.memoryAddress != null -> {
asmgen.out(" inx | ldy $ESTACK_LO_HEX,x") asmgen.out(" inx")
storeRegisterInMemoryAddress(CpuRegister.Y, target.memoryAddress) storeByteViaRegisterAInMemoryAddress("$ESTACK_LO_HEX,x", target.memoryAddress)
} }
target.arrayindexed != null -> { target.arrayindexed != null -> {
val arrayDt = target.arrayindexed!!.identifier.inferType(program).typeOrElse(DataType.STRUCT) val arrayDt = target.arrayindexed!!.identifier.inferType(program).typeOrElse(DataType.STRUCT)
@ -166,7 +182,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromAddressOf(target: AssignTarget, name: IdentifierReference) { private fun assignFromAddressOf(target: AssignTarget, name: IdentifierReference) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
val struct = name.memberOfStruct(program.namespace) val struct = name.memberOfStruct(program.namespace)
@ -204,7 +220,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromWordVariable(target: AssignTarget, variable: IdentifierReference) { private fun assignFromWordVariable(target: AssignTarget, variable: IdentifierReference) {
val sourceName = asmgen.asmIdentifierName(variable) val sourceName = asmgen.asmIdentifierName(variable)
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
@ -234,7 +250,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromFloatVariable(target: AssignTarget, variable: IdentifierReference) { private fun assignFromFloatVariable(target: AssignTarget, variable: IdentifierReference) {
val sourceName = asmgen.asmIdentifierName(variable) val sourceName = asmgen.asmIdentifierName(variable)
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
@ -265,7 +281,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromByteVariable(target: AssignTarget, variable: IdentifierReference) { private fun assignFromByteVariable(target: AssignTarget, variable: IdentifierReference) {
val sourceName = asmgen.asmIdentifierName(variable) val sourceName = asmgen.asmIdentifierName(variable)
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
@ -296,16 +312,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
asmgen.out(" lda $sourceName | sta $targetName") asmgen.out(" lda $sourceName | sta $targetName")
} }
else -> { else -> {
asmgen.translateExpression(addressExpr) storeByteViaRegisterAInMemoryAddress(sourceName, target.memoryAddress)
asmgen.out("""
inx
lda $ESTACK_LO_HEX,x
ldy $ESTACK_HI_HEX,x
sta (+) +1
sty (+) +2
lda $sourceName
+ sta ${'$'}ffff ; modified
""")
} }
} }
} }
@ -313,7 +320,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromRegister(target: AssignTarget, register: CpuRegister) { private fun assignFromRegister(target: AssignTarget, register: CpuRegister) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
when { when {
@ -372,7 +379,39 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
private fun storeByteViaRegisterAInMemoryAddress(ldaInstructionArg: String, memoryAddress: DirectMemoryWrite) {
val addressExpr = memoryAddress.addressExpression
val addressLv = addressExpr as? NumericLiteralValue
when {
addressLv != null -> asmgen.out(" lda $ldaInstructionArg | sta ${addressLv.number.toHex()}")
addressExpr is IdentifierReference -> {
val targetName = asmgen.asmIdentifierName(addressExpr)
asmgen.out("""
lda $targetName
sta ${C64Zeropage.SCRATCH_W1}
lda $targetName+1
sta ${C64Zeropage.SCRATCH_W1+1}
lda $ldaInstructionArg
ldy #0
sta (${C64Zeropage.SCRATCH_W1}),y""")
}
else -> {
asmgen.translateExpression(addressExpr)
asmgen.out("""
inx
lda $ESTACK_LO_HEX,x
sta ${C64Zeropage.SCRATCH_W1}
lda $ESTACK_HI_HEX,x
sta ${C64Zeropage.SCRATCH_W1+1}
lda $ldaInstructionArg
ldy #0
sta (${C64Zeropage.SCRATCH_W1}),y""")
}
}
}
private fun storeRegisterInMemoryAddress(register: CpuRegister, memoryAddress: DirectMemoryWrite) { private fun storeRegisterInMemoryAddress(register: CpuRegister, memoryAddress: DirectMemoryWrite) {
// this is optimized for register A.
val addressExpr = memoryAddress.addressExpression val addressExpr = memoryAddress.addressExpression
val addressLv = addressExpr as? NumericLiteralValue val addressLv = addressExpr as? NumericLiteralValue
val registerName = register.name.toLowerCase() val registerName = register.name.toLowerCase()
@ -381,48 +420,35 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
addressExpr is IdentifierReference -> { addressExpr is IdentifierReference -> {
val targetName = asmgen.asmIdentifierName(addressExpr) val targetName = asmgen.asmIdentifierName(addressExpr)
when (register) { when (register) {
CpuRegister.A -> asmgen.out(""" CpuRegister.A -> {}
ldy $targetName CpuRegister.X -> asmgen.out(" txa")
sty (+) +1 CpuRegister.Y -> asmgen.out(" tya")
ldy $targetName+1
sty (+) +2
+ sta ${'$'}ffff ; modified""")
CpuRegister.X -> asmgen.out("""
ldy $targetName
sty (+) +1
ldy $targetName+1
sty (+) +2
+ stx ${'$'}ffff ; modified""")
CpuRegister.Y -> asmgen.out("""
lda $targetName
sta (+) +1
lda $targetName+1
sta (+) +2
+ sty ${'$'}ffff ; modified""")
} }
asmgen.out("""
ldy $targetName
sty ${C64Zeropage.SCRATCH_W1}
ldy $targetName+1
sty ${C64Zeropage.SCRATCH_W1+1}
ldy #0
sta (${C64Zeropage.SCRATCH_W1}),y""")
} }
else -> { else -> {
asmgen.saveRegister(register) asmgen.saveRegister(register)
asmgen.translateExpression(addressExpr) asmgen.translateExpression(addressExpr)
asmgen.restoreRegister(register) asmgen.restoreRegister(CpuRegister.A)
when (register) {
CpuRegister.A -> asmgen.out(" tay")
CpuRegister.X -> throw AssemblyError("can't use X register here")
CpuRegister.Y -> {}
}
asmgen.out(""" asmgen.out("""
inx inx
lda $ESTACK_LO_HEX,x ldy $ESTACK_LO_HEX,x
sta (+) +1 sty ${C64Zeropage.SCRATCH_W1}
lda $ESTACK_HI_HEX,x ldy $ESTACK_HI_HEX,x
sta (+) +2 sty ${C64Zeropage.SCRATCH_W1+1}
+ sty ${'$'}ffff ; modified ldy #0
""") sta (${C64Zeropage.SCRATCH_W1}),y""")
} }
} }
} }
internal fun assignFromWordConstant(target: AssignTarget, word: Int) { private fun assignFromWordConstant(target: AssignTarget, word: Int) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
when { when {
@ -467,17 +493,17 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromByteConstant(target: AssignTarget, byte: Short) { private fun assignFromByteConstant(target: AssignTarget, byte: Short) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
val targetMemory = target.memoryAddress
when { when {
targetIdent != null -> { targetIdent != null -> {
val targetName = asmgen.asmIdentifierName(targetIdent) val targetName = asmgen.asmIdentifierName(targetIdent)
asmgen.out(" lda #${byte.toHex()} | sta $targetName ") asmgen.out(" lda #${byte.toHex()} | sta $targetName ")
} }
target.memoryAddress != null -> { targetMemory != null -> {
asmgen.out(" ldy #${byte.toHex()}") storeByteViaRegisterAInMemoryAddress("#${byte.toHex()}", targetMemory)
storeRegisterInMemoryAddress(CpuRegister.Y, target.memoryAddress)
} }
targetArrayIdx != null -> { targetArrayIdx != null -> {
val index = targetArrayIdx.arrayspec.index val index = targetArrayIdx.arrayspec.index
@ -495,7 +521,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromFloatConstant(target: AssignTarget, float: Double) { private fun assignFromFloatConstant(target: AssignTarget, float: Double) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
if (float == 0.0) { if (float == 0.0) {
@ -594,7 +620,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
} }
} }
internal fun assignFromMemoryByte(target: AssignTarget, address: Int?, identifier: IdentifierReference?) { private fun assignFromMemoryByte(target: AssignTarget, address: Int?, identifier: IdentifierReference?) {
val targetIdent = target.identifier val targetIdent = target.identifier
val targetArrayIdx = target.arrayindexed val targetArrayIdx = target.arrayindexed
if (address != null) { if (address != null) {
@ -607,8 +633,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
""") """)
} }
target.memoryAddress != null -> { target.memoryAddress != null -> {
asmgen.out(" ldy ${address.toHex()}") storeByteViaRegisterAInMemoryAddress(address.toHex(), target.memoryAddress)
storeRegisterInMemoryAddress(CpuRegister.Y, target.memoryAddress)
} }
targetArrayIdx != null -> { targetArrayIdx != null -> {
val index = targetArrayIdx.arrayspec.index val index = targetArrayIdx.arrayspec.index
@ -631,8 +656,7 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
sta $targetName""") sta $targetName""")
} }
target.memoryAddress != null -> { target.memoryAddress != null -> {
asmgen.out(" ldy $sourceName") storeByteViaRegisterAInMemoryAddress(sourceName, target.memoryAddress)
storeRegisterInMemoryAddress(CpuRegister.Y, target.memoryAddress)
} }
targetArrayIdx != null -> { targetArrayIdx != null -> {
val index = targetArrayIdx.arrayspec.index val index = targetArrayIdx.arrayspec.index
@ -663,13 +687,4 @@ internal class AssignmentAsmGen(private val program: Program, private val asmgen
throw AssemblyError("weird array type") throw AssemblyError("weird array type")
} }
} }
fun assignToRegister(reg: CpuRegister, value: Short?, identifier: IdentifierReference?) {
if(value!=null) {
asmgen.out(" ld${reg.toString().toLowerCase()} #${value.toHex()}")
} else if(identifier!=null) {
val name = asmgen.asmIdentifierName(identifier)
asmgen.out(" ld${reg.toString().toLowerCase()} $name")
}
}
} }

View File

@ -140,10 +140,11 @@ internal class ExpressionsAsmGen(private val program: Program, private val asmge
val sourceName = asmgen.asmIdentifierName(expr.addressExpression as IdentifierReference) val sourceName = asmgen.asmIdentifierName(expr.addressExpression as IdentifierReference)
asmgen.out(""" asmgen.out("""
lda $sourceName lda $sourceName
sta (+) +1 sta ${C64MachineDefinition.C64Zeropage.SCRATCH_W1}
lda $sourceName+1 lda $sourceName+1
sta (+) +2 sta ${C64MachineDefinition.C64Zeropage.SCRATCH_W1+1}
+ lda ${'$'}ffff ; modified ldy #0
lda (${C64MachineDefinition.C64Zeropage.SCRATCH_W1}),y
sta $ESTACK_LO_HEX,x sta $ESTACK_LO_HEX,x
dex""") dex""")
} }

View File

@ -5,6 +5,7 @@ import prog8.ast.Program
import prog8.ast.base.* import prog8.ast.base.*
import prog8.ast.expressions.* import prog8.ast.expressions.*
import prog8.ast.statements.AssignTarget import prog8.ast.statements.AssignTarget
import prog8.ast.statements.Assignment
import prog8.ast.statements.Subroutine import prog8.ast.statements.Subroutine
import prog8.ast.statements.SubroutineParameter import prog8.ast.statements.SubroutineParameter
import prog8.compiler.AssemblyError import prog8.compiler.AssemblyError
@ -107,48 +108,9 @@ internal class FunctionCallAsmGen(private val program: Program, private val asmg
val paramVar = parameter.value val paramVar = parameter.value
val scopedParamVar = (sub.scopedname+"."+paramVar.name).split(".") val scopedParamVar = (sub.scopedname+"."+paramVar.name).split(".")
val target = AssignTarget(IdentifierReference(scopedParamVar, sub.position), null, null, sub.position) val target = AssignTarget(IdentifierReference(scopedParamVar, sub.position), null, null, sub.position)
target.linkParents(value.parent) val assign = Assignment(target, value, value.position)
when (value) { assign.linkParents(value.parent)
is NumericLiteralValue -> { asmgen.translate(assign)
// optimize when the argument is a constant literal
when(parameter.value.type) {
in ByteDatatypes -> asmgen.assignFromByteConstant(target, value.number.toShort())
in WordDatatypes -> asmgen.assignFromWordConstant(target, value.number.toInt())
DataType.FLOAT -> asmgen.assignFromFloatConstant(target, value.number.toDouble())
else -> throw AssemblyError("weird parameter datatype")
}
}
is IdentifierReference -> {
// optimize when the argument is a variable
when (parameter.value.type) {
in ByteDatatypes -> asmgen.assignFromByteVariable(target, value)
in WordDatatypes -> asmgen.assignFromWordVariable(target, value)
DataType.FLOAT -> asmgen.assignFromFloatVariable(target, value)
in PassByReferenceDatatypes -> asmgen.assignFromAddressOf(target, value)
else -> throw AssemblyError("weird parameter datatype")
}
}
is DirectMemoryRead -> {
when(value.addressExpression) {
is NumericLiteralValue -> {
val address = (value.addressExpression as NumericLiteralValue).number.toInt()
asmgen.assignFromMemoryByte(target, address, null)
}
is IdentifierReference -> {
asmgen.assignFromMemoryByte(target, null, value.addressExpression as IdentifierReference)
}
else -> {
asmgen.translateExpression(value.addressExpression)
asmgen.out(" jsr prog8_lib.read_byte_from_address | inx")
asmgen.assignFromRegister(target, CpuRegister.A)
}
}
}
else -> {
asmgen.translateExpression(value)
asmgen.assignFromEvalResult(target)
}
}
} }
private fun argumentViaRegister(sub: Subroutine, parameter: IndexedValue<SubroutineParameter>, value: Expression) { private fun argumentViaRegister(sub: Subroutine, parameter: IndexedValue<SubroutineParameter>, value: Expression) {

View File

@ -7,21 +7,10 @@ main {
sub start() { sub start() {
c64scr.print_ub(5) ubyte A=5
c64.CHROUT('\n') uword clr = $d020
return @(clr+1) = A
c64scr.print_ub(5) ; uword xx = @(clr+1)
c64.CHROUT('\n')
goto start
c64scr.print_ub(5)
c64.CHROUT('\n')
exit(11)
c64scr.print_ub(5)
c64.CHROUT('\n')
} }
} }