implemented asm for addressof-assignment

This commit is contained in:
Irmen de Jong 2020-06-02 00:31:56 +02:00
parent 9200992024
commit d665489054
3 changed files with 22 additions and 14 deletions

View File

@ -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

View File

@ -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<IAstModification> {
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<IAstModification> {
// 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()
}
}

View File

@ -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") {