better const-evaluation of addressOf a memory mapped variable

This commit is contained in:
Irmen de Jong 2023-11-08 22:04:41 +01:00
parent f70fa42eac
commit 3b0d7ea960
3 changed files with 36 additions and 3 deletions

View File

@ -251,6 +251,15 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
return noModifications return noModifications
} }
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.type==VarDeclType.CONST || decl.type==VarDeclType.VAR) {
if(decl.isArray){ if(decl.isArray){
val arraysize = decl.arraysize val arraysize = decl.arraysize
@ -291,8 +300,11 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
} }
private fun createConstArrayInitializerValue(decl: VarDecl): ArrayLiteral? { 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) { when(decl.datatype) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W, DataType.ARRAY_W_SPLIT, DataType.ARRAY_UW_SPLIT -> { 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 val rangeExpr = decl.value as? RangeExpression

View File

@ -366,5 +366,18 @@ main {
compileText(VMTarget(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null compileText(VMTarget(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
errors.errors.single() shouldContain "cannot use byte value" 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
}
}) })

View File

@ -395,7 +395,15 @@ data class AddressOf(var identifier: IdentifierReference, var arrayIndex: ArrayI
} }
override fun copy() = AddressOf(identifier.copy(), arrayIndex?.copy(), position) 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 referencesIdentifier(nameInSource: List<String>) = identifier.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true
override fun inferType(program: Program) = InferredTypes.knownFor(DataType.UWORD) override fun inferType(program: Program) = InferredTypes.knownFor(DataType.UWORD)
override fun accept(visitor: IAstVisitor) = visitor.visit(this) override fun accept(visitor: IAstVisitor) = visitor.visit(this)