mirror of
https://github.com/irmen/prog8.git
synced 2025-07-23 13:24:32 +00:00
fix const value of AddressOf for certain types
This commit is contained in:
@@ -20,6 +20,11 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
|||||||
|
|
||||||
private val evaluator = ConstExprEvaluator()
|
private val evaluator = ConstExprEvaluator()
|
||||||
|
|
||||||
|
override fun after(addressOf: AddressOf, parent: Node): Iterable<IAstModification> {
|
||||||
|
val constAddr = addressOf.constValue(program) ?: return noModifications
|
||||||
|
return listOf(IAstModification.ReplaceNode(addressOf, constAddr, parent))
|
||||||
|
}
|
||||||
|
|
||||||
override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> {
|
override fun before(memread: DirectMemoryRead, parent: Node): Iterable<IAstModification> {
|
||||||
// @( &thing ) --> thing (but only if thing is a byte type!)
|
// @( &thing ) --> thing (but only if thing is a byte type!)
|
||||||
val addrOf = memread.addressExpression as? AddressOf
|
val addrOf = memread.addressExpression as? AddressOf
|
||||||
@@ -432,6 +437,11 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
val constValue = typecast.constValue(program) ?: return noModifications
|
||||||
|
return listOf(IAstModification.ReplaceNode(typecast, constValue, parent))
|
||||||
|
}
|
||||||
|
|
||||||
private class ShuffleOperands(val expr: BinaryExpression,
|
private class ShuffleOperands(val expr: BinaryExpression,
|
||||||
val exprOperator: String?,
|
val exprOperator: String?,
|
||||||
val subExpr: BinaryExpression,
|
val subExpr: BinaryExpression,
|
||||||
|
@@ -43,6 +43,10 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
val constValue = typecast.constValue(program)
|
||||||
|
if(constValue!=null)
|
||||||
|
return listOf(IAstModification.ReplaceNode(typecast, constValue, parent))
|
||||||
|
|
||||||
if(typecast.expression is NumericLiteral) {
|
if(typecast.expression is NumericLiteral) {
|
||||||
val value = (typecast.expression as NumericLiteral).cast(typecast.type)
|
val value = (typecast.expression as NumericLiteral).cast(typecast.type)
|
||||||
if(value.isValid)
|
if(value.isValid)
|
||||||
|
@@ -271,4 +271,27 @@ main {
|
|||||||
(assignv2 as NumericLiteral).number shouldBe 0.0
|
(assignv2 as NumericLiteral).number shouldBe 0.0
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("const address-of memory mapped arrays") {
|
||||||
|
val src="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
&uword[30] wb = ${'$'}2000
|
||||||
|
&uword[100] array1 = ${'$'}9e00
|
||||||
|
&uword[30] array2 = &array1[len(wb)]
|
||||||
|
|
||||||
|
cx16.r0 = &array1 ; ${'$'}9e00
|
||||||
|
cx16.r1 = &array1[len(wb)] ; ${'$'}9e3c
|
||||||
|
cx16.r2 = &array2 ; ${'$'}9e3c
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val result = compileText(Cx16Target(), false, src, writeAssembly = false)!!
|
||||||
|
val st = result.compilerAst.entrypoint.statements
|
||||||
|
st.size shouldBe 6
|
||||||
|
((st[0] as VarDecl).value as NumericLiteral).number shouldBe 0x2000
|
||||||
|
((st[1] as VarDecl).value as NumericLiteral).number shouldBe 0x9e00
|
||||||
|
((st[2] as VarDecl).value as NumericLiteral).number shouldBe 0x9e00+2*30
|
||||||
|
((st[3] as Assignment).value as NumericLiteral).number shouldBe 0x9e00
|
||||||
|
((st[4] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
|
||||||
|
((st[5] as Assignment).value as NumericLiteral).number shouldBe 0x9e00+2*30
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@@ -444,7 +444,11 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
|||||||
override fun visit(addressOf: AddressOf) {
|
override fun visit(addressOf: AddressOf) {
|
||||||
output("&")
|
output("&")
|
||||||
addressOf.identifier.accept(this)
|
addressOf.identifier.accept(this)
|
||||||
addressOf.arrayIndex?.accept(this)
|
if(addressOf.arrayIndex!=null) {
|
||||||
|
output("[")
|
||||||
|
addressOf.arrayIndex?.accept(this)
|
||||||
|
output("]")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(inlineAssembly: InlineAssembly) {
|
override fun visit(inlineAssembly: InlineAssembly) {
|
||||||
|
@@ -408,9 +408,17 @@ data class AddressOf(var identifier: IdentifierReference, var arrayIndex: ArrayI
|
|||||||
override fun constValue(program: Program): NumericLiteral? {
|
override fun constValue(program: Program): NumericLiteral? {
|
||||||
val target = this.identifier.targetStatement(program) as? VarDecl
|
val target = this.identifier.targetStatement(program) as? VarDecl
|
||||||
if(target?.type==VarDeclType.MEMORY) {
|
if(target?.type==VarDeclType.MEMORY) {
|
||||||
val address = target.value?.constValue(program)
|
var address = target.value?.constValue(program)?.number
|
||||||
if(address!=null)
|
if(address!=null) {
|
||||||
return NumericLiteral(DataType.UWORD, address.number, position)
|
if(arrayIndex!=null) {
|
||||||
|
val index = arrayIndex?.constIndex()
|
||||||
|
if (index != null)
|
||||||
|
address += program.memsizer.memorySize(target.datatype, index)
|
||||||
|
else
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
return NumericLiteral(DataType.UWORD, address, position)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
@@ -3,6 +3,8 @@ TODO
|
|||||||
|
|
||||||
IR: use SCC and SCS, to optimize some code that sets 0/1 based on carry flag status
|
IR: use SCC and SCS, to optimize some code that sets 0/1 based on carry flag status
|
||||||
|
|
||||||
|
try to get rid of ArrayIndex class
|
||||||
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@@ -1,17 +1,16 @@
|
|||||||
|
%import floats
|
||||||
%import textio
|
%import textio
|
||||||
%zeropage basicsafe
|
%zeropage basicsafe
|
||||||
%option no_sysinit
|
%option no_sysinit
|
||||||
|
|
||||||
mpb {
|
|
||||||
const uword HIGH_MEMORY_START = $A000
|
|
||||||
}
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
&uword[20] wa = mpb.HIGH_MEMORY_START
|
|
||||||
; &uword[20] wa = $A000
|
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
wa[0] = "smile"
|
&uword[30] wb = $2000
|
||||||
txt.print(wa[0])
|
&uword[100] array1 = $9e00
|
||||||
|
&uword[30] array2 = &array1[len(wb)]
|
||||||
|
|
||||||
|
txt.print_uwhex(&array1, true) ; $9e00
|
||||||
|
txt.print_uwhex(&array1[len(wb)], true) ; $9e3c
|
||||||
|
txt.print_uwhex(&array2, true) ; $9e3c
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user