mirror of
https://github.com/irmen/prog8.git
synced 2025-02-20 03:29:01 +00:00
implemented asm for addressof-assignment
This commit is contained in:
parent
9200992024
commit
d665489054
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
@ -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()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -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") {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user