fix auto-insertion of AddressOf expression in function call arguments

This commit is contained in:
Irmen de Jong 2019-04-11 21:32:23 +02:00
parent 7780441524
commit 0a73125606
6 changed files with 29 additions and 20 deletions

View File

@ -334,6 +334,7 @@ private class AstChecker(private val namespace: INameScope,
err("a return register is also in the clobber list") err("a return register is also in the clobber list")
} else { } else {
// TODO: non-asm subroutines can only take numeric arguments for now. (not strings and arrays) // TODO: non-asm subroutines can only take numeric arguments for now. (not strings and arrays)
// TODO: AddressOf: can this be improved now that we have '&' ?
// the way string params are treated is almost okay (their address is passed) but the receiving subroutine treats it as an integer rather than referring back to the original string. // the way string params are treated is almost okay (their address is passed) but the receiving subroutine treats it as an integer rather than referring back to the original string.
// the way array params are treated is buggy; it thinks the subroutine needs a byte parameter in place of a byte[] ... // the way array params are treated is buggy; it thinks the subroutine needs a byte parameter in place of a byte[] ...
// This is not easy to fix because strings and arrays are treated a bit simplistic (a "virtual" pointer to the value on the heap) // This is not easy to fix because strings and arrays are treated a bit simplistic (a "virtual" pointer to the value on the heap)

View File

@ -214,7 +214,7 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
// Also takes care to insert AddressOf (&) expression where required (string params to a UWORD function param etc). // Also takes care to insert AddressOf (&) expression where required (string params to a UWORD function param etc).
private val vardeclsToAdd = mutableMapOf<INameScope, MutableList<VarDecl>>() private val vardeclsToAdd = mutableMapOf<INameScope, MutableMap<String, VarDecl>>()
override fun process(module: Module) { override fun process(module: Module) {
super.process(module) super.process(module)
@ -222,8 +222,8 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
// add any new vardecls to the various scopes // add any new vardecls to the various scopes
for(decl in vardeclsToAdd) for(decl in vardeclsToAdd)
for(d in decl.value) { for(d in decl.value) {
d.linkParents(decl.key as Node) d.value.linkParents(decl.key as Node)
decl.key.statements.add(0, d) decl.key.statements.add(0, d.value)
} }
} }
@ -234,9 +234,7 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
if(decl.datatype in NumericDatatypes) { if(decl.datatype in NumericDatatypes) {
val scope = decl.definingScope() val scope = decl.definingScope()
if(scope !in vardeclsToAdd) addVarDecl(scope, decl.asDefaultValueDecl(null))
vardeclsToAdd[scope] = mutableListOf()
vardeclsToAdd.getValue(scope).add(decl.asDefaultValueDecl(null))
val declvalue = decl.value!! val declvalue = decl.value!!
val value = val value =
if(declvalue is LiteralValue) { if(declvalue is LiteralValue) {
@ -269,7 +267,6 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
return functionCallStatement return functionCallStatement
} }
// TODO move this to StatementReorderer instead?
private fun addAddressOfExprIfNeeded(subroutine: Subroutine, arglist: MutableList<IExpression>, parent: Node) { private fun addAddressOfExprIfNeeded(subroutine: Subroutine, arglist: MutableList<IExpression>, parent: Node) {
// functions that accept UWORD and are given an array type, or string, will receive the AddressOf (memory location) of that value instead. // functions that accept UWORD and are given an array type, or string, will receive the AddressOf (memory location) of that value instead.
for(argparam in subroutine.parameters.withIndex().zip(arglist)) { for(argparam in subroutine.parameters.withIndex().zip(arglist)) {
@ -288,13 +285,15 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
} }
else if(strvalue!=null) { else if(strvalue!=null) {
if(strvalue.isString) { if(strvalue.isString) {
println("WANTING TO INSERT & for $strvalue") // TODO // replace the argument with &autovar
// TODO why does this result later in "pointer-of operand must be the name of a heap variable" val autoVarName = "$autoHeapValuePrefix${strvalue.heapId}"
// --> because the AstChecker runs before AstIdentifiersChecker which inserts the actual VarDecl? val autoHeapvarRef = IdentifierReference(listOf(autoVarName), strvalue.position)
val autoHeapvarRef = IdentifierReference(listOf("$autoHeapValuePrefix${strvalue.heapId}"), strvalue.position)
val pointerExpr = AddressOf(autoHeapvarRef, strvalue.position) val pointerExpr = AddressOf(autoHeapvarRef, strvalue.position)
pointerExpr.linkParents(arglist[argparam.first.index].parent) pointerExpr.linkParents(arglist[argparam.first.index].parent)
arglist[argparam.first.index] = pointerExpr arglist[argparam.first.index] = pointerExpr
// add a vardecl so that the autovar can be resolved in later lookups
val variable = VarDecl(VarDeclType.VAR, strvalue.type, false, null, autoVarName, strvalue, strvalue.position)
addVarDecl(strvalue.definingScope(), variable)
} }
} }
else throw FatalAstException("expected either an identifier or a literal as argument to $subroutine") else throw FatalAstException("expected either an identifier or a literal as argument to $subroutine")
@ -302,4 +301,10 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
} }
} }
private fun addVarDecl(scope: INameScope, variable: VarDecl) {
if(scope !in vardeclsToAdd)
vardeclsToAdd[scope] = mutableMapOf()
vardeclsToAdd.getValue(scope)[variable.name]=variable
}
} }

View File

@ -553,7 +553,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
} else if(array.any {it is AddressOf}) { } else if(array.any {it is AddressOf}) {
val arrayDt = DataType.UWORD val arrayDt = DataType.UWORD
val intArrayWithAddressOfs = mutableListOf<IntegerOrAddressOf>() val intArrayWithAddressOfs = mutableListOf<IntegerOrAddressOf>()
// TODO FILL THIS ARRAY // TODO AddressOf: FILL THIS ARRAY
val heapId = heap.addIntegerArray(DataType.UWORD, intArrayWithAddressOfs.toTypedArray()) val heapId = heap.addIntegerArray(DataType.UWORD, intArrayWithAddressOfs.toTypedArray())
return LiteralValue(arrayDt, heapId = heapId, position = arraylit.position) return LiteralValue(arrayDt, heapId = heapId, position = arraylit.position)
} else { } else {

View File

@ -17,7 +17,8 @@ import kotlin.math.floor
todo remove unused subroutines todo remove unused subroutines
todo remove unused strings and arrays from the heap todo remove unused strings and arrays from the heap
todo inline subroutines that are called exactly once (regardless of their size) todo inline subroutines that are called exactly once (regardless of their size)
todo inline subroutines that are only called a few times (3?) and that are "sufficiently small" (0-3 statements) todo inline subroutines that are only called a few times (max 3?)
todo inline subroutines that are "sufficiently small" (0-3 statements)
todo analyse for unreachable code and remove that (f.i. code after goto or return that has no label so can never be jumped to) todo analyse for unreachable code and remove that (f.i. code after goto or return that has no label so can never be jumped to)
*/ */

View File

@ -16,23 +16,25 @@
str string2="bye" str string2="bye"
uword pointer = &array1 uword pointer = &array1
uword pointer2
uword pointer3
byte bt byte bt
pointer = &array2 pointer2 = &array2
pointer = &string1 pointer3 = &string1
;uword[4] pointers = [&array1, &array2, &string1, &string2] ; @todo make it possible to initialize array with pointers ; uword[4] pointers = [&array1, &array2, &string1, &string2] ; @todo make it possible to initialize array with pointers
;ptrsubasm("moet werken") ; @todo rewrite ast into pointer-of expression (and remove special cases from Compiler) ptrsubasm("moet werken")
;pointersub("moet werken") ; @todo rewrite ast into pointer-of expression (and remove special cases from Compiler) pointersub("moet werken")
myprintasm(string1) myprintasm(string1)
myprintasm(string2) myprintasm(string2)
myprintasm("moet werken3") myprintasm("moet werken3")
myprintasm("moet werken3") myprintasm("moet werken3")
myprintasm("moet werken4") myprintasm("moet werken4")
c64scr.print("this print must work\n")
c64.CHROUT('\n') c64.CHROUT('\n')
ptrsubasm(&array1) ptrsubasm(&array1)

View File

@ -109,7 +109,7 @@ varinitializer : vardecl '=' expression ;
constdecl: 'const' varinitializer ; constdecl: 'const' varinitializer ;
memoryvardecl: 'memory' varinitializer; memoryvardecl: 'memory' varinitializer; // TODO replace 'memory' by '&'
datatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'float' | 'str' | 'str_s' ; datatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'float' | 'str' | 'str_s' ;