mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-04 10:16:13 +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,17 +774,19 @@ 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)
 | 
					 | 
				
			||||||
                expr.add(transformExpression(srcExpr.left))
 | 
					 | 
				
			||||||
                expr.add(transformExpression(srcExpr.right))
 | 
					 | 
				
			||||||
                return expr
 | 
					 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					            val expr = PtBinaryExpression(srcExpr.operator, type, srcExpr.position)
 | 
				
			||||||
 | 
					            expr.add(transformExpression(srcExpr.left))
 | 
				
			||||||
 | 
					            expr.add(transformExpression(srcExpr.right))
 | 
				
			||||||
 | 
					            return expr
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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