mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-03 19:16:13 +00:00 
			
		
		
		
	better error when trying to use a const pointer (which is not supported yet)
This commit is contained in:
		@@ -938,7 +938,7 @@ internal class ProgramAndVarsGen(
 | 
				
			|||||||
            asmgen.out("  ${it.name} = ${it.address.toHex()}")
 | 
					            asmgen.out("  ${it.name} = ${it.address.toHex()}")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        consts.sortedBy { it.name }.forEach {
 | 
					        consts.sortedBy { it.name }.forEach {
 | 
				
			||||||
            if(it.dt==BaseDataType.FLOAT)
 | 
					            if(it.dt.isFloat)
 | 
				
			||||||
                asmgen.out("  ${it.name} = ${it.value}")
 | 
					                asmgen.out("  ${it.name} = ${it.value}")
 | 
				
			||||||
            else
 | 
					            else
 | 
				
			||||||
                asmgen.out("  ${it.name} = ${it.value.toHex()}")
 | 
					                asmgen.out("  ${it.name} = ${it.value.toHex()}")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -122,7 +122,6 @@ private fun convert(variable: StMemVar): IRStMemVar {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
private fun convert(constant: StConstant): IRStConstant {
 | 
					private fun convert(constant: StConstant): IRStConstant {
 | 
				
			||||||
    val dt = DataType.forDt(constant.dt)
 | 
					 | 
				
			||||||
    val scopedName = if('.' in constant.name) {
 | 
					    val scopedName = if('.' in constant.name) {
 | 
				
			||||||
        constant.name
 | 
					        constant.name
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
@@ -132,7 +131,7 @@ private fun convert(constant: StConstant): IRStConstant {
 | 
				
			|||||||
            constant.name
 | 
					            constant.name
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return IRStConstant(scopedName, dt, constant.value)
 | 
					    return IRStConstant(scopedName, constant.dt, constant.value)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -874,9 +874,9 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
            err("recursive var declaration")
 | 
					            err("recursive var declaration")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // CONST can only occur on simple types (byte, word, float)
 | 
					        // CONST can only occur on simple types (byte, word, float)
 | 
				
			||||||
        if(decl.type== VarDeclType.CONST) {
 | 
					        if(decl.type==VarDeclType.CONST) {
 | 
				
			||||||
            if (!decl.datatype.isNumericOrBool)
 | 
					            if (!decl.datatype.isNumericOrBool)
 | 
				
			||||||
                err("const can only be used on numeric types or booleans")
 | 
					                err("const can only be used on numbers and booleans")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // FLOATS enabled?
 | 
					        // FLOATS enabled?
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -27,6 +27,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
 | 
				
			|||||||
            if(valueType.isUnknown)
 | 
					            if(valueType.isUnknown)
 | 
				
			||||||
                return noModifications
 | 
					                return noModifications
 | 
				
			||||||
            val valueDt = valueType.getOrUndef()
 | 
					            val valueDt = valueType.getOrUndef()
 | 
				
			||||||
 | 
					            if(!(valueDt.isWord && decl.datatype.isPointer)) {
 | 
				
			||||||
                when(decl.type) {
 | 
					                when(decl.type) {
 | 
				
			||||||
                    VarDeclType.VAR -> {
 | 
					                    VarDeclType.VAR -> {
 | 
				
			||||||
                        if(decl.isArray) {
 | 
					                        if(decl.isArray) {
 | 
				
			||||||
@@ -65,7 +66,7 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter,
 | 
				
			|||||||
                    VarDeclType.MEMORY -> if(!valueType.isWords && !valueType.isBytes)
 | 
					                    VarDeclType.MEMORY -> if(!valueType.isWords && !valueType.isBytes)
 | 
				
			||||||
                        throw FatalAstException("value type for a memory var should be word or byte (address)")
 | 
					                        throw FatalAstException("value type for a memory var should be word or byte (address)")
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // check splitting of word arrays
 | 
					        // check splitting of word arrays
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -690,20 +690,28 @@ main {
 | 
				
			|||||||
        this.text = next as uword       ; TODO fix type error; the cast should succeed
 | 
					        this.text = next as uword       ; TODO fix type error; the cast should succeed
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}"""
 | 
					}"""
 | 
				
			||||||
        compileText(VMTarget(), false, src, outputDir, writeAssembly = false) shouldNotBe null
 | 
					        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
				
			||||||
 | 
					        compileText(C64Target(), false, src, outputDir) shouldNotBe null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    xtest("const pointer") {
 | 
					    test("const pointer gives proper error") {
 | 
				
			||||||
        val src="""
 | 
					        val src="""
 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
    sub start() {
 | 
					    sub start() {
 | 
				
			||||||
        ^^uword @shared ptr = 7000
 | 
					        ^^uword @shared ptr = 7000
 | 
				
			||||||
        const ^^uword cptr = 8000            ; TODO fix type error; loses pointer
 | 
					        const ^^uword cptr = 8000
 | 
				
			||||||
        ptr^^ = 12345
 | 
					
 | 
				
			||||||
        cptr^^ = 12345
 | 
					        ;ptr^^ = 12345
 | 
				
			||||||
 | 
					        ;cptr^^ = 12345
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        cx16.r0 = cptr
 | 
				
			||||||
 | 
					        cx16.r1 = ptr
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}"""
 | 
					}"""
 | 
				
			||||||
        compileText(VMTarget(), false, src, outputDir, writeAssembly = false) shouldNotBe null
 | 
					        val errors = ErrorReporterForTests()
 | 
				
			||||||
 | 
					        compileText(VMTarget(), false, src, outputDir, errors=errors, writeAssembly = true) shouldBe null
 | 
				
			||||||
 | 
					        errors.errors.size shouldBe 1
 | 
				
			||||||
 | 
					        errors.errors[0] shouldContain("const can only be used on numbers and booleans")
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test("unknown field") {
 | 
					    test("unknown field") {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -208,8 +208,8 @@ private fun makeSt(): SymbolTable {
 | 
				
			|||||||
    val sub12 = StNode("sub2", StNodeType.SUBROUTINE, astSub2)
 | 
					    val sub12 = StNode("sub2", StNodeType.SUBROUTINE, astSub2)
 | 
				
			||||||
    block1.add(sub11)
 | 
					    block1.add(sub11)
 | 
				
			||||||
    block1.add(sub12)
 | 
					    block1.add(sub12)
 | 
				
			||||||
    block1.add(StConstant("c1", BaseDataType.UWORD, 12345.0, astConstant1))
 | 
					    block1.add(StConstant("c1", DataType.UWORD, 12345.0, astConstant1))
 | 
				
			||||||
    block1.add(StConstant("blockc", BaseDataType.UWORD, 999.0, astConstant2))
 | 
					    block1.add(StConstant("blockc", DataType.UWORD, 999.0, astConstant2))
 | 
				
			||||||
    sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v1))
 | 
					    sub11.add(StStaticVariable("v1", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v1))
 | 
				
			||||||
    sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v2))
 | 
					    sub11.add(StStaticVariable("v2", DataType.BYTE, null, null, null, ZeropageWish.DONTCARE, 0u, false, astSub1v2))
 | 
				
			||||||
    sub11.add(StMemVar("v3", DataType.FLOAT, 12345u, null, astSub1v3))
 | 
					    sub11.add(StMemVar("v3", DataType.FLOAT, 12345u, null, astSub1v3))
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,6 +13,7 @@ Future Things and Ideas
 | 
				
			|||||||
- struct/ptr: optimize the float copying in assignIndexedPointer() (also word and long?)
 | 
					- struct/ptr: optimize the float copying in assignIndexedPointer() (also word and long?)
 | 
				
			||||||
- struct/ptr: optimize augmented assignments to indexed pointer targets like sprptr[2]^^.y++  (these are now not performend in-place but as a regular assignment)
 | 
					- struct/ptr: optimize augmented assignments to indexed pointer targets like sprptr[2]^^.y++  (these are now not performend in-place but as a regular assignment)
 | 
				
			||||||
- struct/ptr: implement even more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs')
 | 
					- struct/ptr: implement even more struct instance assignments (via memcopy) in CodeDesugarer (see the TODO) (add to documentation as well, paragraph 'Structs')
 | 
				
			||||||
 | 
					- struct/ptr: support const pointers (simple and struct types)
 | 
				
			||||||
- struct/ptr: support @nosplit pointer arrays?
 | 
					- struct/ptr: support @nosplit pointer arrays?
 | 
				
			||||||
- struct/ptr: support pointer to pointer?
 | 
					- struct/ptr: support pointer to pointer?
 | 
				
			||||||
- struct/ptr: support for typed function pointers?  (&routine could be typed by default as well then)
 | 
					- struct/ptr: support for typed function pointers?  (&routine could be typed by default as well then)
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										149
									
								
								examples/test.p8
									
									
									
									
									
								
							
							
						
						
									
										149
									
								
								examples/test.p8
									
									
									
									
									
								
							@@ -1,135 +1,26 @@
 | 
				
			|||||||
;%zeropage basicsafe
 | 
					 | 
				
			||||||
;%import textio
 | 
					 | 
				
			||||||
;
 | 
					 | 
				
			||||||
;main {
 | 
					 | 
				
			||||||
;    sub start() {
 | 
					 | 
				
			||||||
;        ^^uword @shared ptr = 7000
 | 
					 | 
				
			||||||
;        const ^^uword cptr = 8000            ; TODO fix type error; loses pointer
 | 
					 | 
				
			||||||
;        ptr^^ = 12345
 | 
					 | 
				
			||||||
;        cptr^^ = 12345
 | 
					 | 
				
			||||||
;        txt.print_uw(peekw(7000))
 | 
					 | 
				
			||||||
;        txt.spc()
 | 
					 | 
				
			||||||
;        txt.print_uw(peekw(8000))
 | 
					 | 
				
			||||||
;    }
 | 
					 | 
				
			||||||
;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
; TYPE CAST CRASH:
 | 
					 | 
				
			||||||
;%zeropage basicsafe
 | 
					 | 
				
			||||||
;%import strings
 | 
					 | 
				
			||||||
;%import textio
 | 
					 | 
				
			||||||
;
 | 
					 | 
				
			||||||
;main {
 | 
					 | 
				
			||||||
;    struct Line {
 | 
					 | 
				
			||||||
;        ^^Line prev
 | 
					 | 
				
			||||||
;        ^^Line next
 | 
					 | 
				
			||||||
;        ^^ubyte text
 | 
					 | 
				
			||||||
;    }
 | 
					 | 
				
			||||||
;    uword buffer = memory("buffer", 100*sizeof(Line), 1)
 | 
					 | 
				
			||||||
;    ^^Line next = buffer
 | 
					 | 
				
			||||||
;
 | 
					 | 
				
			||||||
;    sub start() {
 | 
					 | 
				
			||||||
;        ^^Line line = next
 | 
					 | 
				
			||||||
;        next += 1
 | 
					 | 
				
			||||||
;        line.text = next as ^^ubyte        ; TODO fix crash here
 | 
					 | 
				
			||||||
;        next = (next as uword) + 81
 | 
					 | 
				
			||||||
;        txt.print_uwhex(buffer, true) txt.nl()
 | 
					 | 
				
			||||||
;        txt.print_uwhex(next, true) txt.nl()
 | 
					 | 
				
			||||||
;        txt.print_uwhex(line, true) txt.nl()
 | 
					 | 
				
			||||||
;        txt.print_uwhex(line.text, true) txt.nl()
 | 
					 | 
				
			||||||
;    }
 | 
					 | 
				
			||||||
;}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
%import floats
 | 
					 | 
				
			||||||
%import textio
 | 
					 | 
				
			||||||
%zeropage basicsafe
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
 | 
					    struct Node1 {
 | 
				
			||||||
 | 
					        ubyte type
 | 
				
			||||||
 | 
					        word ww
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    struct Node2 {
 | 
				
			||||||
 | 
					        ubyte type
 | 
				
			||||||
 | 
					        ^^ubyte text
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub start() {
 | 
					    sub start() {
 | 
				
			||||||
        bytetest()
 | 
					        ^^Node1 @shared next
 | 
				
			||||||
        wordtest()
 | 
					        ^^Node2 @shared this
 | 
				
			||||||
        longtest()
 | 
					        ^^ubyte ubptr
 | 
				
			||||||
        floattest()         ; TODO fix invalid 6502 code gen /crash
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub bytetest() {
 | 
					        ubptr = next as ^^ubyte
 | 
				
			||||||
        ubyte[] foo = [11, 22, 33]
 | 
					        ubptr = 12345
 | 
				
			||||||
        ubyte i
 | 
					        ubptr = cx16.r0
 | 
				
			||||||
        txt.print("before:")
 | 
					        ubptr = next as uword       ; TODO fix type error; the cast should succeed
 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_ub(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
        foo[2] = foo[1]
 | 
					 | 
				
			||||||
        foo[1] = foo[0]
 | 
					 | 
				
			||||||
        foo[0] = 0
 | 
					 | 
				
			||||||
        txt.print(" after:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_ub(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub wordtest() {
 | 
					        this.text = next as ^^ubyte
 | 
				
			||||||
        uword[] foo = [1111, 2222, 3333]
 | 
					        this.text = 12345
 | 
				
			||||||
        ubyte i
 | 
					        this.text = cx16.r0
 | 
				
			||||||
        txt.print("before:")
 | 
					        this.text = next as uword       ; TODO fix type error; the cast should succeed
 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_uw(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
        foo[2] = foo[1]
 | 
					 | 
				
			||||||
        foo[1] = foo[0]
 | 
					 | 
				
			||||||
        foo[0] = 0
 | 
					 | 
				
			||||||
        txt.print(" after:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_uw(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sub longtest() {
 | 
					 | 
				
			||||||
        long[] foo = [111111, 222222, 333333]
 | 
					 | 
				
			||||||
        ubyte i
 | 
					 | 
				
			||||||
        txt.print("before:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_l(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
        foo[2] = foo[1]
 | 
					 | 
				
			||||||
        foo[1] = foo[0]
 | 
					 | 
				
			||||||
        foo[0] = 0
 | 
					 | 
				
			||||||
        txt.print(" after:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_l(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sub floattest() {
 | 
					 | 
				
			||||||
        float[] foo = [1.1, 2.2, 3.3]
 | 
					 | 
				
			||||||
        ubyte i
 | 
					 | 
				
			||||||
        txt.print("before:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_f(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
        foo[2] = foo[1]
 | 
					 | 
				
			||||||
        foo[1] = foo[0]
 | 
					 | 
				
			||||||
        foo[0] = 0
 | 
					 | 
				
			||||||
        txt.print(" after:")
 | 
					 | 
				
			||||||
        for i in 0 to 2 {
 | 
					 | 
				
			||||||
            txt.chrout(' ')
 | 
					 | 
				
			||||||
            txt.print_f(foo[i])
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -270,6 +270,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
 | 
				
			|||||||
            val value: String = when {
 | 
					            val value: String = when {
 | 
				
			||||||
                dt.isBool -> constant.value.toInt().toString()
 | 
					                dt.isBool -> constant.value.toInt().toString()
 | 
				
			||||||
                dt.isFloat -> constant.value.toString()
 | 
					                dt.isFloat -> constant.value.toString()
 | 
				
			||||||
 | 
					                dt.isPointer -> TODO("constant pointer $constant")
 | 
				
			||||||
                dt.isInteger -> constant.value.toInt().toHex()
 | 
					                dt.isInteger -> constant.value.toInt().toHex()
 | 
				
			||||||
                else -> throw InternalCompilerException("weird dt")
 | 
					                else -> throw InternalCompilerException("weird dt")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -267,7 +267,7 @@ class StStaticVariable(name: String,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class StConstant(name: String, val dt: BaseDataType, val value: Double, astNode: PtNode?) :
 | 
					class StConstant(name: String, val dt: DataType, val value: Double, astNode: PtNode?) :
 | 
				
			||||||
    StNode(name, StNodeType.CONSTANT, astNode)
 | 
					    StNode(name, StNodeType.CONSTANT, astNode)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -48,7 +48,7 @@ class SymbolTableMaker(private val program: PtProgram, private val options: Comp
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
            is PtConstant -> {
 | 
					            is PtConstant -> {
 | 
				
			||||||
                require(node.type.isNumericOrBool)
 | 
					                require(node.type.isNumericOrBool)
 | 
				
			||||||
                StConstant(node.name, node.type.base, node.value, node)
 | 
					                StConstant(node.name, node.type, node.value, node)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            is PtLabel -> {
 | 
					            is PtLabel -> {
 | 
				
			||||||
                StNode(node.name, StNodeType.LABEL, node)
 | 
					                StNode(node.name, StNodeType.LABEL, node)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user