mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 07:31:48 +00:00
better const-evaluation of addressOf a memory mapped variable
This commit is contained in:
parent
f70fa42eac
commit
3b0d7ea960
@ -251,7 +251,16 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
||||
return noModifications
|
||||
}
|
||||
|
||||
if(decl.type== VarDeclType.CONST || decl.type== VarDeclType.VAR) {
|
||||
if(decl.isArray && decl.type==VarDeclType.MEMORY) {
|
||||
val memaddr = decl.value?.constValue(program)
|
||||
if(memaddr!=null && memaddr !== decl.value) {
|
||||
return listOf(IAstModification.SetExpression(
|
||||
{ decl.value = it }, memaddr, decl
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
if(decl.type==VarDeclType.CONST || decl.type==VarDeclType.VAR) {
|
||||
if(decl.isArray){
|
||||
val arraysize = decl.arraysize
|
||||
if(arraysize==null) {
|
||||
@ -291,8 +300,11 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
||||
}
|
||||
|
||||
private fun createConstArrayInitializerValue(decl: VarDecl): ArrayLiteral? {
|
||||
// convert the initializer range expression from a range or int, to an actual array.
|
||||
|
||||
if(decl.type==VarDeclType.MEMORY)
|
||||
return null // memory mapped arrays can never have an initializer value other than the address where they're mapped.
|
||||
|
||||
// convert the initializer range expression from a range or int, to an actual array.
|
||||
when(decl.datatype) {
|
||||
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_W_SPLIT, DataType.ARRAY_UW_SPLIT -> {
|
||||
val rangeExpr = decl.value as? RangeExpression
|
||||
|
@ -366,5 +366,18 @@ main {
|
||||
compileText(VMTarget(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
|
||||
errors.errors.single() shouldContain "cannot use byte value"
|
||||
}
|
||||
|
||||
test("const eval of address-of a memory mapped variable") {
|
||||
val src = """
|
||||
main {
|
||||
sub start() {
|
||||
&ubyte mappedvar = 1000
|
||||
cx16.r0 = &mappedvar
|
||||
&ubyte[8] array = &mappedvar
|
||||
cx16.r0 = &array
|
||||
}
|
||||
}"""
|
||||
compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null
|
||||
}
|
||||
})
|
||||
|
||||
|
@ -395,7 +395,15 @@ data class AddressOf(var identifier: IdentifierReference, var arrayIndex: ArrayI
|
||||
}
|
||||
|
||||
override fun copy() = AddressOf(identifier.copy(), arrayIndex?.copy(), position)
|
||||
override fun constValue(program: Program): NumericLiteral? = null
|
||||
override fun constValue(program: Program): NumericLiteral? {
|
||||
val target = this.identifier.targetStatement(program) as? VarDecl
|
||||
if(target?.type==VarDeclType.MEMORY) {
|
||||
val address = target.value?.constValue(program)
|
||||
if(address!=null)
|
||||
return NumericLiteral(DataType.UWORD, address.number, position)
|
||||
}
|
||||
return null
|
||||
}
|
||||
override fun referencesIdentifier(nameInSource: List<String>) = identifier.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true
|
||||
override fun inferType(program: Program) = InferredTypes.knownFor(DataType.UWORD)
|
||||
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
|
||||
|
Loading…
x
Reference in New Issue
Block a user