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.Program
import prog8.ast.processing.* import prog8.ast.processing.*
import prog8.compiler.CompilationOptions import prog8.compiler.CompilationOptions
import prog8.compiler.target.BeforeAsmGenerationAstChanger import prog8.compiler.BeforeAsmGenerationAstChanger
import prog8.optimizer.FlattenAnonymousScopesAndNopRemover import prog8.optimizer.FlattenAnonymousScopesAndNopRemover

View File

@ -1,18 +1,15 @@
package prog8.compiler.target package prog8.compiler
import prog8.ast.Node import prog8.ast.Node
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.base.* import prog8.ast.base.*
import prog8.ast.expressions.BinaryExpression import prog8.ast.expressions.*
import prog8.ast.expressions.Expression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.expressions.TypecastExpression
import prog8.ast.processing.AstWalker import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModification import prog8.ast.processing.IAstModification
import prog8.ast.statements.* 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> { override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
if (decl.value == null && decl.type == VarDeclType.VAR && decl.datatype in NumericDatatypes) { 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> { override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
// see if we can remove superfluous typecasts (outside of expressions) // see if we can remove superfluous typecasts (outside of expressions)
// such as casting byte<->ubyte, word<->uword // 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) val sourceDt = typecast.expression.inferType(program).typeOrElse(DataType.STRUCT)
if (typecast.type in ByteDatatypes && sourceDt in ByteDatatypes if (typecast.type in ByteDatatypes && sourceDt in ByteDatatypes
|| typecast.type in WordDatatypes && sourceDt in WordDatatypes) { || 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)) 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() return emptyList()
} }
} }

View File

@ -580,9 +580,7 @@ internal class AssignmentAsmGen(private val program: Program, private val errors
// non-const value // non-const value
// !!! DON'T FORGET : CAN BE AUGMENTED ASSIGNMENT !!! // !!! DON'T FORGET : CAN BE AUGMENTED ASSIGNMENT !!!
when (assign.value) { when (assign.value) {
is RegisterExpr -> { is RegisterExpr -> throw AssemblyError("expected a typecast for assigning register to word")
TODO("$assign")
}
is IdentifierReference -> { is IdentifierReference -> {
val sourceName = asmgen.asmIdentifierName(assign.value as IdentifierReference) val sourceName = asmgen.asmIdentifierName(assign.value as IdentifierReference)
when (assign.aug_op) { when (assign.aug_op) {
@ -624,11 +622,11 @@ internal class AssignmentAsmGen(private val program: Program, private val errors
} }
return true return true
} }
is DirectMemoryRead -> { is DirectMemoryRead -> throw AssemblyError("expected a typecast for assigning memory read byte to word")
TODO("$assign")
}
is AddressOf -> { 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 -> { is ArrayIndexedExpression -> {
if (assign.aug_op == "setvalue") { if (assign.aug_op == "setvalue") {