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")
|
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)
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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)
|
||||||
*/
|
*/
|
||||||
|
@ -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)
|
||||||
|
@ -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' ;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user