From d665489054fd0517d8489bce1da71834a56be956 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 2 Jun 2020 00:31:56 +0200 Subject: [PATCH] implemented asm for addressof-assignment --- compiler/src/prog8/ast/base/Extensions.kt | 2 +- .../BeforeAsmGenerationAstChanger.kt | 22 ++++++++++++++----- .../target/c64/codegen/AssignmentAsmGen.kt | 12 +++++----- 3 files changed, 22 insertions(+), 14 deletions(-) rename compiler/src/prog8/compiler/{target => }/BeforeAsmGenerationAstChanger.kt (87%) diff --git a/compiler/src/prog8/ast/base/Extensions.kt b/compiler/src/prog8/ast/base/Extensions.kt index 6b61c56d1..e5b3afebd 100644 --- a/compiler/src/prog8/ast/base/Extensions.kt +++ b/compiler/src/prog8/ast/base/Extensions.kt @@ -4,7 +4,7 @@ import prog8.ast.Module import prog8.ast.Program import prog8.ast.processing.* import prog8.compiler.CompilationOptions -import prog8.compiler.target.BeforeAsmGenerationAstChanger +import prog8.compiler.BeforeAsmGenerationAstChanger import prog8.optimizer.FlattenAnonymousScopesAndNopRemover diff --git a/compiler/src/prog8/compiler/target/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt similarity index 87% rename from compiler/src/prog8/compiler/target/BeforeAsmGenerationAstChanger.kt rename to compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index c0113adf8..5bd417ffa 100644 --- a/compiler/src/prog8/compiler/target/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -1,18 +1,15 @@ -package prog8.compiler.target +package prog8.compiler import prog8.ast.Node import prog8.ast.Program import prog8.ast.base.* -import prog8.ast.expressions.BinaryExpression -import prog8.ast.expressions.Expression -import prog8.ast.expressions.IdentifierReference -import prog8.ast.expressions.TypecastExpression +import prog8.ast.expressions.* import prog8.ast.processing.AstWalker import prog8.ast.processing.IAstModification import prog8.ast.statements.* -class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter) : AstWalker() { +internal class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorReporter) : AstWalker() { override fun after(decl: VarDecl, parent: Node): Iterable { if (decl.value == null && decl.type == VarDeclType.VAR && decl.datatype in NumericDatatypes) { @@ -101,6 +98,7 @@ class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorRepor override fun after(typecast: TypecastExpression, parent: Node): Iterable { // see if we can remove superfluous typecasts (outside of expressions) // such as casting byte<->ubyte, word<->uword + // Also the special typecast of a reference type (str, array) to an UWORD will be changed into address-of. val sourceDt = typecast.expression.inferType(program).typeOrElse(DataType.STRUCT) if (typecast.type in ByteDatatypes && sourceDt in ByteDatatypes || typecast.type in WordDatatypes && sourceDt in WordDatatypes) { @@ -108,6 +106,18 @@ class BeforeAsmGenerationAstChanger(val program: Program, val errors: ErrorRepor return listOf(IAstModification.ReplaceNode(typecast, typecast.expression, parent)) } } + else if(sourceDt in PassByReferenceDatatypes) { + if(typecast.type==DataType.UWORD) { + return listOf(IAstModification.ReplaceNode( + typecast, + AddressOf(typecast.expression as IdentifierReference, typecast.position), + parent + )) + } else { + errors.err("cannot cast pass-by-reference value to type ${typecast.type} (only to UWORD)", typecast.position) + } + } + return emptyList() } } diff --git a/compiler/src/prog8/compiler/target/c64/codegen/AssignmentAsmGen.kt b/compiler/src/prog8/compiler/target/c64/codegen/AssignmentAsmGen.kt index 608696261..374f0106b 100644 --- a/compiler/src/prog8/compiler/target/c64/codegen/AssignmentAsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/codegen/AssignmentAsmGen.kt @@ -580,9 +580,7 @@ internal class AssignmentAsmGen(private val program: Program, private val errors // non-const value // !!! DON'T FORGET : CAN BE AUGMENTED ASSIGNMENT !!! when (assign.value) { - is RegisterExpr -> { - TODO("$assign") - } + is RegisterExpr -> throw AssemblyError("expected a typecast for assigning register to word") is IdentifierReference -> { val sourceName = asmgen.asmIdentifierName(assign.value as IdentifierReference) when (assign.aug_op) { @@ -624,11 +622,11 @@ internal class AssignmentAsmGen(private val program: Program, private val errors } return true } - is DirectMemoryRead -> { - TODO("$assign") - } + is DirectMemoryRead -> throw AssemblyError("expected a typecast for assigning memory read byte to word") is AddressOf -> { - TODO("$assign") + val name = asmgen.asmIdentifierName((assign.value as AddressOf).identifier) + asmgen.out(" lda #<$name | sta $targetName | lda #>$name | sta $targetName+1") + return true } is ArrayIndexedExpression -> { if (assign.aug_op == "setvalue") {