mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
fix auto-insertion of AddressOf expression in function call arguments
This commit is contained in:
parent
7780441524
commit
0a73125606
@ -334,6 +334,7 @@ private class AstChecker(private val namespace: INameScope,
|
||||
err("a return register is also in the clobber list")
|
||||
} else {
|
||||
// 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 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)
|
||||
|
@ -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).
|
||||
|
||||
|
||||
private val vardeclsToAdd = mutableMapOf<INameScope, MutableList<VarDecl>>()
|
||||
private val vardeclsToAdd = mutableMapOf<INameScope, MutableMap<String, VarDecl>>()
|
||||
|
||||
override fun process(module: Module) {
|
||||
super.process(module)
|
||||
@ -222,8 +222,8 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
|
||||
// add any new vardecls to the various scopes
|
||||
for(decl in vardeclsToAdd)
|
||||
for(d in decl.value) {
|
||||
d.linkParents(decl.key as Node)
|
||||
decl.key.statements.add(0, d)
|
||||
d.value.linkParents(decl.key as Node)
|
||||
decl.key.statements.add(0, d.value)
|
||||
}
|
||||
}
|
||||
|
||||
@ -234,9 +234,7 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
|
||||
|
||||
if(decl.datatype in NumericDatatypes) {
|
||||
val scope = decl.definingScope()
|
||||
if(scope !in vardeclsToAdd)
|
||||
vardeclsToAdd[scope] = mutableListOf()
|
||||
vardeclsToAdd.getValue(scope).add(decl.asDefaultValueDecl(null))
|
||||
addVarDecl(scope, decl.asDefaultValueDecl(null))
|
||||
val declvalue = decl.value!!
|
||||
val value =
|
||||
if(declvalue is LiteralValue) {
|
||||
@ -269,7 +267,6 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
|
||||
return functionCallStatement
|
||||
}
|
||||
|
||||
// TODO move this to StatementReorderer instead?
|
||||
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.
|
||||
for(argparam in subroutine.parameters.withIndex().zip(arglist)) {
|
||||
@ -288,13 +285,15 @@ private class VarInitValueAndAddressOfCreator(private val namespace: INameScope)
|
||||
}
|
||||
else if(strvalue!=null) {
|
||||
if(strvalue.isString) {
|
||||
println("WANTING TO INSERT & for $strvalue") // TODO
|
||||
// TODO why does this result later in "pointer-of operand must be the name of a heap variable"
|
||||
// --> because the AstChecker runs before AstIdentifiersChecker which inserts the actual VarDecl?
|
||||
val autoHeapvarRef = IdentifierReference(listOf("$autoHeapValuePrefix${strvalue.heapId}"), strvalue.position)
|
||||
// replace the argument with &autovar
|
||||
val autoVarName = "$autoHeapValuePrefix${strvalue.heapId}"
|
||||
val autoHeapvarRef = IdentifierReference(listOf(autoVarName), strvalue.position)
|
||||
val pointerExpr = AddressOf(autoHeapvarRef, strvalue.position)
|
||||
pointerExpr.linkParents(arglist[argparam.first.index].parent)
|
||||
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")
|
||||
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -553,7 +553,7 @@ class ConstantFolding(private val namespace: INameScope, private val heap: HeapV
|
||||
} else if(array.any {it is AddressOf}) {
|
||||
val arrayDt = DataType.UWORD
|
||||
val intArrayWithAddressOfs = mutableListOf<IntegerOrAddressOf>()
|
||||
// TODO FILL THIS ARRAY
|
||||
// TODO AddressOf: FILL THIS ARRAY
|
||||
val heapId = heap.addIntegerArray(DataType.UWORD, intArrayWithAddressOfs.toTypedArray())
|
||||
return LiteralValue(arrayDt, heapId = heapId, position = arraylit.position)
|
||||
} else {
|
||||
|
@ -17,7 +17,8 @@ import kotlin.math.floor
|
||||
todo remove unused subroutines
|
||||
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 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)
|
||||
*/
|
||||
|
@ -16,23 +16,25 @@
|
||||
str string2="bye"
|
||||
|
||||
uword pointer = &array1
|
||||
uword pointer2
|
||||
uword pointer3
|
||||
byte bt
|
||||
|
||||
pointer = &array2
|
||||
pointer = &string1
|
||||
pointer2 = &array2
|
||||
pointer3 = &string1
|
||||
|
||||
; 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)
|
||||
;pointersub("moet werken") ; @todo rewrite ast into pointer-of expression (and remove special cases from Compiler)
|
||||
|
||||
ptrsubasm("moet werken")
|
||||
pointersub("moet werken")
|
||||
myprintasm(string1)
|
||||
myprintasm(string2)
|
||||
myprintasm("moet werken3")
|
||||
myprintasm("moet werken3")
|
||||
myprintasm("moet werken4")
|
||||
|
||||
c64scr.print("this print must work\n")
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ptrsubasm(&array1)
|
||||
|
@ -109,7 +109,7 @@ varinitializer : vardecl '=' expression ;
|
||||
|
||||
constdecl: 'const' varinitializer ;
|
||||
|
||||
memoryvardecl: 'memory' varinitializer;
|
||||
memoryvardecl: 'memory' varinitializer; // TODO replace 'memory' by '&'
|
||||
|
||||
datatype: 'ubyte' | 'byte' | 'uword' | 'word' | 'float' | 'str' | 'str_s' ;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user