mirror of
https://github.com/irmen/prog8.git
synced 2025-01-14 01:29:55 +00:00
fix faulty binexpr splitting
This commit is contained in:
parent
e0c5ccc16b
commit
526e4b8bdc
@ -1053,26 +1053,29 @@ internal class BuiltinFunctionsAsmGen(private val program: Program, private val
|
|||||||
when {
|
when {
|
||||||
conv.variable -> {
|
conv.variable -> {
|
||||||
val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
val varname = "prog8_lib.func_${signature.name}_cc._arg_${paramName}" // TODO after all builtin funcs have been changed into _cc, remove that suffix again
|
||||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||||
|
// put the address of the argument in AY
|
||||||
|
val addr = AddressOf(value as IdentifierReference, value.position)
|
||||||
|
AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||||
|
} else {
|
||||||
|
AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||||
|
}
|
||||||
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
|
val tgt = AsmAssignTarget(TargetStorageKind.VARIABLE, program, asmgen, conv.dt, null, variableAsmName = varname)
|
||||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||||
asmgen.translateNormalAssignment(assign)
|
asmgen.translateNormalAssignment(assign)
|
||||||
}
|
}
|
||||||
conv.reg != null -> {
|
conv.reg != null -> {
|
||||||
if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
val src = if(conv.dt==DataType.FLOAT || conv.dt in PassByReferenceDatatypes) {
|
||||||
// put the address of the argument in AY
|
// put the address of the argument in AY
|
||||||
val addr = AddressOf(value as IdentifierReference, value.position)
|
val addr = AddressOf(value as IdentifierReference, value.position)
|
||||||
val src = AsmAssignSource.fromAstSource(addr, program, asmgen)
|
AsmAssignSource.fromAstSource(addr, program, asmgen)
|
||||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
|
||||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
|
||||||
asmgen.translateNormalAssignment(assign)
|
|
||||||
} else {
|
} else {
|
||||||
val src = AsmAssignSource.fromAstSource(value, program, asmgen)
|
AsmAssignSource.fromAstSource(value, program, asmgen)
|
||||||
|
}
|
||||||
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
val tgt = AsmAssignTarget.fromRegisters(conv.reg, null, program, asmgen)
|
||||||
val assign = AsmAssignment(src, tgt, false, value.position)
|
val assign = AsmAssignment(src, tgt, false, value.position)
|
||||||
asmgen.translateNormalAssignment(assign)
|
asmgen.translateNormalAssignment(assign)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
else -> throw AssemblyError("callconv")
|
else -> throw AssemblyError("callconv")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,22 +38,26 @@ internal class BinExprSplitter(private val program: Program) : AstWalker() {
|
|||||||
if (binExpr != null) {
|
if (binExpr != null) {
|
||||||
/*
|
/*
|
||||||
|
|
||||||
reduce the complexity of a (binary) expression that has to be evaluated on the eval stack,
|
Reduce the complexity of a (binary) expression that has to be evaluated on the eval stack,
|
||||||
by attempting to splitting it up into individual simple steps:
|
by attempting to splitting it up into individual simple steps.
|
||||||
|
We only consider a binary expression *one* level deep (so the operands must not be a combined expression)
|
||||||
|
|
||||||
|
|
||||||
X = BinExpr X = LeftExpr
|
X = BinExpr X = LeftExpr
|
||||||
<operator> followed by
|
<operator> followed by
|
||||||
/ \ IF 'X' not used X = BinExpr
|
/ \ IF 'X' not used X = BinExpr
|
||||||
/ \ IN LEFTEXPR ==> <operator>
|
/ \ IN expression ==> <operator>
|
||||||
/ \ / \
|
/ \ / \
|
||||||
LeftExpr. RightExpr. / \
|
LeftExpr. RightExpr. / \
|
||||||
/ \ / \ X RightExpr.
|
X RightExpr.
|
||||||
.. .. .. ..
|
|
||||||
|
|
||||||
*/
|
*/
|
||||||
if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program.namespace)) {
|
if(binExpr.operator in augmentAssignmentOperators && isSimpleTarget(assignment.target, program.namespace)) {
|
||||||
if (!assignment.isAugmentable) {
|
if(assignment.target isSameAs binExpr.left || assignment.target isSameAs binExpr.right)
|
||||||
|
return noModifications
|
||||||
|
|
||||||
|
if(isSimpleExpression(binExpr.left) && isSimpleExpression(binExpr.right) && !assignment.isAugmentable) {
|
||||||
val firstAssign = Assignment(assignment.target, binExpr.left, binExpr.left.position)
|
val firstAssign = Assignment(assignment.target, binExpr.left, binExpr.left.position)
|
||||||
val targetExpr = assignment.target.toExpression()
|
val targetExpr = assignment.target.toExpression()
|
||||||
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.right, binExpr.right.position)
|
val augExpr = BinaryExpression(targetExpr, binExpr.operator, binExpr.right, binExpr.right.position)
|
||||||
@ -71,6 +75,9 @@ X = BinExpr X = LeftExpr
|
|||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun isSimpleExpression(expr: Expression) =
|
||||||
|
expr is IdentifierReference || expr is NumericLiteralValue || expr is AddressOf || expr is DirectMemoryRead || expr is StringLiteralValue || expr is ArrayLiteralValue || expr is RangeExpr
|
||||||
|
|
||||||
private fun isSimpleTarget(target: AssignTarget, namespace: INameScope) =
|
private fun isSimpleTarget(target: AssignTarget, namespace: INameScope) =
|
||||||
if (target.identifier!=null || target.memoryAddress!=null || target.arrayindexed!=null)
|
if (target.identifier!=null || target.memoryAddress!=null || target.arrayindexed!=null)
|
||||||
target.isInRegularRAM(namespace)
|
target.isInRegularRAM(namespace)
|
||||||
|
@ -8,9 +8,10 @@
|
|||||||
; Cleanup and porting to C by Ullrich von Bassewitz.
|
; Cleanup and porting to C by Ullrich von Bassewitz.
|
||||||
; Converted to prog8 by Irmen de Jong.
|
; Converted to prog8 by Irmen de Jong.
|
||||||
|
|
||||||
|
; TODO the random charset is all wrong
|
||||||
; TODO why has the prg become bigger since register args?
|
; TODO why has the prg become bigger since register args?
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
const uword SCREEN1 = $E000
|
const uword SCREEN1 = $E000
|
||||||
const uword SCREEN2 = $E400
|
const uword SCREEN2 = $E400
|
||||||
|
@ -12,28 +12,28 @@ main {
|
|||||||
const uword ADDR = $0400
|
const uword ADDR = $0400
|
||||||
|
|
||||||
byte zerob=0
|
byte zerob=0
|
||||||
word zerow=0
|
; word zerow=0
|
||||||
float zerof=0
|
; float zerof=0
|
||||||
byte bb
|
byte bb
|
||||||
word ww
|
; word ww
|
||||||
float fl
|
; float fl
|
||||||
|
|
||||||
testX()
|
testX()
|
||||||
|
|
||||||
bb = -100
|
bb = -100
|
||||||
bb = zerob+abs(bb)
|
bb = zerob+abs(bb) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||||
txt.print_b(bb)
|
txt.print_b(bb)
|
||||||
txt.chrout('\n')
|
txt.chrout('\n')
|
||||||
|
|
||||||
ww = -12345
|
; ww = -12345
|
||||||
ww = zerow+abs(ww)
|
; ww = zerow+abs(ww) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||||
txt.print_w(ww)
|
; txt.print_w(ww)
|
||||||
txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
|
;
|
||||||
fl = -9.876
|
; fl = -9.876
|
||||||
fl = zerof+abs(fl)
|
; fl = zerof+abs(fl) ; TODO optimizer generates wrong code for this (wrong order of splitted expression?)
|
||||||
floats.print_f(fl)
|
; floats.print_f(fl)
|
||||||
txt.chrout('\n')
|
; txt.chrout('\n')
|
||||||
|
|
||||||
; memset(ADDR, 40*25, 100)
|
; memset(ADDR, 40*25, 100)
|
||||||
; memsetw(ADDR, 20*10, $3031)
|
; memsetw(ADDR, 20*10, $3031)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user