mirror of
https://github.com/irmen/prog8.git
synced 2025-11-06 08:17:10 +00:00
fix &x +/- offset pointer arithmetic expression
This commit is contained in:
@@ -17,6 +17,7 @@ import prog8.compiler.builtinFunctionReturnType
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.isRegularFile
|
import kotlin.io.path.isRegularFile
|
||||||
|
import kotlin.math.log2
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -773,19 +774,21 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if(srcExpr.left.inferType(program).isPointer || srcExpr.right.inferType(program).isPointer) {
|
if(srcExpr.left.inferType(program).isPointer || srcExpr.right.inferType(program).isPointer) {
|
||||||
|
if (srcExpr.operator == "+") return transformWithPointerArithmetic(srcExpr)
|
||||||
|
else if (srcExpr.operator in ComparisonOperators) return transformWithPointerComparison(srcExpr)
|
||||||
|
} else if(srcExpr.left.inferType(program).isPointer) {
|
||||||
return when (srcExpr.operator) {
|
return when (srcExpr.operator) {
|
||||||
"+", "-" -> transformWithPointerArithmetic(srcExpr)
|
"-" -> transformWithPointerArithmetic(srcExpr) // '+' is handled above
|
||||||
in ComparisonOperators -> transformWithPointerComparison(srcExpr)
|
in ComparisonOperators -> transformWithPointerComparison(srcExpr)
|
||||||
else -> throw FatalAstException("unsupported operator on pointer: ${srcExpr.operator} at ${srcExpr.position}")
|
else -> throw FatalAstException("unsupported operator on pointer: ${srcExpr.operator} at ${srcExpr.position}")
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
val expr = PtBinaryExpression(srcExpr.operator, type, srcExpr.position)
|
val expr = PtBinaryExpression(srcExpr.operator, type, srcExpr.position)
|
||||||
expr.add(transformExpression(srcExpr.left))
|
expr.add(transformExpression(srcExpr.left))
|
||||||
expr.add(transformExpression(srcExpr.right))
|
expr.add(transformExpression(srcExpr.right))
|
||||||
return expr
|
return expr
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private fun transformWithPointerComparison(expr: BinaryExpression): PtBinaryExpression {
|
private fun transformWithPointerComparison(expr: BinaryExpression): PtBinaryExpression {
|
||||||
val leftDt = expr.left.inferType(program)
|
val leftDt = expr.left.inferType(program)
|
||||||
@@ -830,12 +833,21 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
|||||||
return plus
|
return plus
|
||||||
} else {
|
} else {
|
||||||
// ptr + right * structSize
|
// ptr + right * structSize
|
||||||
val total = PtBinaryExpression("*", DataType.UWORD, expr.position)
|
val offset: PtExpression
|
||||||
total.add(transformExpression(expr.right))
|
if(structSize in powersOfTwoInt) {
|
||||||
total.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
// don't multiply simply shift
|
||||||
|
offset = PtBinaryExpression("<<", DataType.UWORD, expr.position)
|
||||||
|
offset.add(transformExpression(expr.right))
|
||||||
|
offset.add(PtNumber(BaseDataType.UWORD, log2(structSize.toDouble()), expr.position))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset = PtBinaryExpression("*", DataType.UWORD, expr.position)
|
||||||
|
offset.add(transformExpression(expr.right))
|
||||||
|
offset.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
||||||
|
}
|
||||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||||
plusorminus.add(transformExpression(expr.left))
|
plusorminus.add(transformExpression(expr.left))
|
||||||
plusorminus.add(total)
|
plusorminus.add(offset)
|
||||||
return plusorminus
|
return plusorminus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -863,12 +875,21 @@ class SimplifiedAstMaker(private val program: Program, private val errors: IErro
|
|||||||
return plus
|
return plus
|
||||||
} else {
|
} else {
|
||||||
// ptr + left * structSize
|
// ptr + left * structSize
|
||||||
val total = PtBinaryExpression("*", DataType.UWORD, expr.position)
|
val offset: PtExpression
|
||||||
total.add(transformExpression(expr.left))
|
if(structSize in powersOfTwoInt) {
|
||||||
total.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
// don't multiply simply shift
|
||||||
|
offset = PtBinaryExpression("<<", DataType.UWORD, expr.position)
|
||||||
|
offset.add(transformExpression(expr.left))
|
||||||
|
offset.add(PtNumber(BaseDataType.UWORD, log2(structSize.toDouble()), expr.position))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
offset = PtBinaryExpression("*", DataType.UWORD, expr.position)
|
||||||
|
offset.add(transformExpression(expr.left))
|
||||||
|
offset.add(PtNumber(BaseDataType.UWORD, structSize.toDouble(), expr.position))
|
||||||
|
}
|
||||||
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
val plusorminus = PtBinaryExpression(operator, resultDt, expr.position)
|
||||||
|
plusorminus.add(offset)
|
||||||
plusorminus.add(transformExpression(expr.right))
|
plusorminus.add(transformExpression(expr.right))
|
||||||
plusorminus.add(total)
|
|
||||||
return plusorminus
|
return plusorminus
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -574,6 +574,7 @@ data class AddressOf(var identifier: IdentifierReference?, var arrayIndex: Array
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
override fun referencesIdentifier(nameInSource: List<String>) = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true
|
override fun referencesIdentifier(nameInSource: List<String>) = identifier?.nameInSource==nameInSource || arrayIndex?.referencesIdentifier(nameInSource)==true || dereference?.referencesIdentifier(nameInSource)==true
|
||||||
|
// override fun inferType(program: Program): InferredTypes.InferredType = InferredTypes.knownFor(BaseDataType.UWORD) // TODO orignal behavior
|
||||||
override fun inferType(program: Program): InferredTypes.InferredType {
|
override fun inferType(program: Program): InferredTypes.InferredType {
|
||||||
if(identifier!=null) {
|
if(identifier!=null) {
|
||||||
val type = identifier!!.inferType(program).getOrUndef()
|
val type = identifier!!.inferType(program).getOrUndef()
|
||||||
|
|||||||
@@ -1,6 +1,10 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
What to do with the changed adress-of behavior? &x now returns a typed pointer to &x + 10 will now be calculated differently (C pointer arithmetic semantics rather than simply byte addition)
|
||||||
|
compiler flag to select old behavior? new operator that has the new behavior? Don't want to break existing code that used &....
|
||||||
|
Old behavior can be put back by always returning UWORD as the inferred type for AddressOf nodes
|
||||||
|
|
||||||
|
|
||||||
STRUCTS and TYPED POINTERS
|
STRUCTS and TYPED POINTERS
|
||||||
--------------------------
|
--------------------------
|
||||||
|
|||||||
124
examples/test.p8
124
examples/test.p8
@@ -1,92 +1,52 @@
|
|||||||
%import textio
|
|
||||||
%option enable_floats
|
%option enable_floats
|
||||||
|
%import textio
|
||||||
|
%zeropage basicsafe
|
||||||
|
%option no_sysinit
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
|
ubyte @shared thingIndex = 10
|
||||||
|
uword[20] @shared dummy
|
||||||
|
uword[10] @split curframesplit
|
||||||
|
uword[10] @nosplit curframe
|
||||||
|
uword p1, p2
|
||||||
|
float f
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
^^ubyte[4] array1
|
classic()
|
||||||
^^byte[4] array2
|
; new()
|
||||||
^^bool[4] array3
|
|
||||||
^^word[4] array4
|
|
||||||
^^uword[4] array5
|
|
||||||
^^float[4] array6
|
|
||||||
^^long[4] array7
|
|
||||||
^^str[4] array8
|
|
||||||
|
|
||||||
error1(array1)
|
|
||||||
error2(array2)
|
|
||||||
error3(array3)
|
|
||||||
error4(array4)
|
|
||||||
error5(array5)
|
|
||||||
error6(array6)
|
|
||||||
error7(array7)
|
|
||||||
error8(array8)
|
|
||||||
|
|
||||||
ok1(array1)
|
|
||||||
ok2(array2)
|
|
||||||
ok3(array3)
|
|
||||||
ok4(array4)
|
|
||||||
ok5(array5)
|
|
||||||
ok6(array6)
|
|
||||||
ok7(array7)
|
|
||||||
ok8(array8)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub error1(^^ubyte ptr) {
|
sub classic() {
|
||||||
cx16.r0++
|
txt.print("float pointer+1: ")
|
||||||
}
|
txt.print_uwhex(&f, true)
|
||||||
sub error2(^^byte ptr) {
|
txt.spc()
|
||||||
cx16.r0++
|
txt.print_uwhex(&f + 1, true)
|
||||||
}
|
txt.nl()
|
||||||
sub error3(^^bool ptr) {
|
|
||||||
cx16.r0++
|
p1 = &curframesplit[thingIndex]
|
||||||
}
|
p2 = &curframe[thingIndex]
|
||||||
sub error4(^^word ptr) {
|
|
||||||
cx16.r0++
|
txt.print("&array (split): ")
|
||||||
}
|
txt.print_uwhex(&curframesplit, true)
|
||||||
sub error5(^^uword ptr) {
|
txt.spc()
|
||||||
cx16.r0++
|
txt.print_uwhex(p1, true)
|
||||||
}
|
txt.spc()
|
||||||
sub error6(^^float ptr) {
|
txt.print_uw(p1 - &curframesplit)
|
||||||
cx16.r0++
|
txt.spc()
|
||||||
}
|
txt.print_uwhex(p1 + &curframesplit, true)
|
||||||
sub error7(^^long ptr) {
|
txt.nl()
|
||||||
cx16.r0++
|
|
||||||
}
|
txt.print("&array (normal): ")
|
||||||
sub error8(^^str ptr) {
|
txt.print_uwhex(&curframe, true)
|
||||||
cx16.r0++
|
txt.spc()
|
||||||
|
txt.print_uwhex(p2, true)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uw(p2 - &curframe)
|
||||||
|
txt.spc()
|
||||||
|
txt.print_uwhex(p2 + &curframe, true)
|
||||||
|
txt.nl()
|
||||||
}
|
}
|
||||||
|
|
||||||
sub ok1(^^ubyte[] ptr) {
|
; 6502 data size: $0251
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok2(^^byte[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok3(^^bool[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok4(^^word[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok5(^^uword[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok6(^^float[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok7(^^long[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
sub ok8(^^str[] ptr) {
|
|
||||||
txt.print_uw(ptr)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user