mirror of
				https://github.com/irmen/prog8.git
				synced 2025-11-04 10:16:13 +00:00 
			
		
		
		
	actually disallow ^^str
This commit is contained in:
		@@ -599,6 +599,8 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            if (p.type.isPointer) {
 | 
					            if (p.type.isPointer) {
 | 
				
			||||||
 | 
					                if(p.type.sub==BaseDataType.STR)
 | 
				
			||||||
 | 
					                    errors.err("^^str is not a valid pointer type, use ^^ubyte?", p.position)
 | 
				
			||||||
                if (p.type.subType == null && p.type.subTypeFromAntlr!=null)
 | 
					                if (p.type.subType == null && p.type.subTypeFromAntlr!=null)
 | 
				
			||||||
                    errors.err("cannot find struct type ${p.type.subTypeFromAntlr?.joinToString(".")}", p.position)
 | 
					                    errors.err("cannot find struct type ${p.type.subTypeFromAntlr?.joinToString(".")}", p.position)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
@@ -613,6 +615,9 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
            if(r.isStructInstance)
 | 
					            if(r.isStructInstance)
 | 
				
			||||||
                err("structs can only be returned via a pointer")
 | 
					                err("structs can only be returned via a pointer")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(r.isPointer && r.sub==BaseDataType.STR)
 | 
				
			||||||
 | 
					                err("^^str is not a valid return type, use ^^ubyte?")
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -876,7 +881,8 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // ARRAY without size specifier MUST have an iterable initializer value
 | 
					        // ARRAY without size specifier MUST have an iterable initializer value
 | 
				
			||||||
        if(decl.isArray && decl.arraysize==null) {
 | 
					        if (decl.isArray) {
 | 
				
			||||||
 | 
					            if (decl.arraysize == null) {
 | 
				
			||||||
                if(decl.type== VarDeclType.MEMORY) {
 | 
					                if(decl.type== VarDeclType.MEMORY) {
 | 
				
			||||||
                    err("memory mapped array must have a size specification")
 | 
					                    err("memory mapped array must have a size specification")
 | 
				
			||||||
                    return
 | 
					                    return
 | 
				
			||||||
@@ -889,6 +895,10 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
                    throw InternalCompilerException("range expressions in vardecls should have been converted into array values during constFolding  $decl")
 | 
					                    throw InternalCompilerException("range expressions in vardecls should have been converted into array values during constFolding  $decl")
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            if(decl.datatype.isPointerArray && decl.datatype.sub==BaseDataType.STR)
 | 
				
			||||||
 | 
					                err("^^str is not a valid pointer type, use ^^ubyte?")
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        when(decl.type) {
 | 
					        when(decl.type) {
 | 
				
			||||||
            VarDeclType.VAR, VarDeclType.CONST -> {
 | 
					            VarDeclType.VAR, VarDeclType.CONST -> {
 | 
				
			||||||
                when(decl.value) {
 | 
					                when(decl.value) {
 | 
				
			||||||
@@ -973,6 +983,9 @@ internal class AstChecker(private val program: Program,
 | 
				
			|||||||
            }
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(decl.datatype.isPointer && decl.datatype.sub==BaseDataType.STR)
 | 
				
			||||||
 | 
					            err("^^str is not a valid pointer type, use ^^ubyte?")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if(decl.datatype.isString) {
 | 
					        if(decl.datatype.isString) {
 | 
				
			||||||
            if(decl.value==null) {
 | 
					            if(decl.value==null) {
 | 
				
			||||||
                // complain about uninitialized str, but only if it's a regular variable
 | 
					                // complain about uninitialized str, but only if it's a regular variable
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -33,15 +33,6 @@ internal class CodeDesugarer(val program: Program, private val target: ICompilat
 | 
				
			|||||||
        return listOf(IAstModification.Remove(alias, parent as IStatementContainer))
 | 
					        return listOf(IAstModification.Remove(alias, parent as IStatementContainer))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
 | 
					 | 
				
			||||||
        if(decl.datatype.isPointer && decl.datatype.sub==BaseDataType.STR) {
 | 
					 | 
				
			||||||
            errors.info("^^str replaced by ^^ubyte", decl.position)
 | 
					 | 
				
			||||||
            val decl2 = decl.copy(DataType.pointer(BaseDataType.UBYTE))
 | 
					 | 
				
			||||||
            return listOf(IAstModification.ReplaceNode(decl, decl2, parent))
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        return noModifications
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
 | 
					    override fun before(breakStmt: Break, parent: Node): Iterable<IAstModification> {
 | 
				
			||||||
        fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
 | 
					        fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
 | 
				
			||||||
            val label = program.makeLabel("after", breakStmt.position)
 | 
					            val label = program.makeLabel("after", breakStmt.position)
 | 
				
			||||||
@@ -731,24 +722,6 @@ _after:
 | 
				
			|||||||
        return noModifications
 | 
					        return noModifications
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun after(subroutine: Subroutine, parent: Node): Iterable<IAstModification> {
 | 
					 | 
				
			||||||
        subroutine.returntypes.withIndex().forEach { (idx, rt) ->
 | 
					 | 
				
			||||||
            if(rt.isPointer && rt.sub==BaseDataType.STR) {
 | 
					 | 
				
			||||||
                errors.info("^^str replaced by ^^ubyte in return type(s)", subroutine.position)
 | 
					 | 
				
			||||||
                subroutine.returntypes[idx] = DataType.pointer(BaseDataType.UBYTE)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        subroutine.parameters.withIndex().forEach { (idx, param) ->
 | 
					 | 
				
			||||||
            if(param.type.isPointer && param.type.sub==BaseDataType.STR) {
 | 
					 | 
				
			||||||
                errors.info("^^str replaced by ^^ubyte", param.position)
 | 
					 | 
				
			||||||
                subroutine.parameters[idx] = SubroutineParameter(param.name, DataType.pointer(BaseDataType.UBYTE), param.zp, param.registerOrPair, param.position)
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return noModifications
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
 | 
					    override fun after(assignment: Assignment, parent: Node): Iterable<IAstModification> {
 | 
				
			||||||
        val targetDt = assignment.target.inferType(program)
 | 
					        val targetDt = assignment.target.inferType(program)
 | 
				
			||||||
        val sourceDt = assignment.value.inferType(program)
 | 
					        val sourceDt = assignment.value.inferType(program)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1305,7 +1305,6 @@ main {
 | 
				
			|||||||
        ^^uword[4] array5
 | 
					        ^^uword[4] array5
 | 
				
			||||||
        ^^float[4] array6
 | 
					        ^^float[4] array6
 | 
				
			||||||
        ^^long[4] array7
 | 
					        ^^long[4] array7
 | 
				
			||||||
        ^^str[4] array8
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        ok(array1)
 | 
					        ok(array1)
 | 
				
			||||||
        ok(array2)
 | 
					        ok(array2)
 | 
				
			||||||
@@ -1314,7 +1313,6 @@ main {
 | 
				
			|||||||
        ok(array5)
 | 
					        ok(array5)
 | 
				
			||||||
        ok(array6)
 | 
					        ok(array6)
 | 
				
			||||||
        ok(array7)
 | 
					        ok(array7)
 | 
				
			||||||
        ok(array8)
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub ok(^^ubyte ptr) {
 | 
					    sub ok(^^ubyte ptr) {
 | 
				
			||||||
@@ -1495,7 +1493,6 @@ main {
 | 
				
			|||||||
        ^^uword[4] array5 = [1000, 1100, 1200, 1300]
 | 
					        ^^uword[4] array5 = [1000, 1100, 1200, 1300]
 | 
				
			||||||
        ^^float[4] array6 = [1000, 1100, 1200, 1300]
 | 
					        ^^float[4] array6 = [1000, 1100, 1200, 1300]
 | 
				
			||||||
        ^^long[4] array7 = [1000, 1100, 1200, 1300]
 | 
					        ^^long[4] array7 = [1000, 1100, 1200, 1300]
 | 
				
			||||||
        ^^str[4] array8 = [1000, 1100, 1200, 1300]
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cx16.r0 = array1[2]
 | 
					        cx16.r0 = array1[2]
 | 
				
			||||||
        cx16.r1 = array2[2]
 | 
					        cx16.r1 = array2[2]
 | 
				
			||||||
@@ -1504,7 +1501,6 @@ main {
 | 
				
			|||||||
        cx16.r4 = array5[2]
 | 
					        cx16.r4 = array5[2]
 | 
				
			||||||
        cx16.r5 = array6[2]
 | 
					        cx16.r5 = array6[2]
 | 
				
			||||||
        cx16.r6 = array7[2]
 | 
					        cx16.r6 = array7[2]
 | 
				
			||||||
        cx16.r7 = array8[2]
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}"""
 | 
					}"""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -1664,6 +1660,29 @@ main {
 | 
				
			|||||||
        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
					        compileText(VMTarget(), false, src, outputDir) shouldNotBe null
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    test("^^str is not valid") {
 | 
				
			||||||
 | 
					        val src="""
 | 
				
			||||||
 | 
					main {
 | 
				
			||||||
 | 
					    sub start() {
 | 
				
			||||||
 | 
					        str name = "test"
 | 
				
			||||||
 | 
					        ^^str ptr = &name
 | 
				
			||||||
 | 
					        ^^str[4] array
 | 
				
			||||||
 | 
					        ptr = foo(&name)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    sub foo(^^str arg) -> ^^str {
 | 
				
			||||||
 | 
					        return arg+2
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}"""
 | 
				
			||||||
 | 
					        val errors=ErrorReporterForTests()
 | 
				
			||||||
 | 
					        compileText(VMTarget(), false, src, outputDir, errors=errors, writeAssembly = false) shouldBe null
 | 
				
			||||||
 | 
					        errors.errors.size shouldBe 4
 | 
				
			||||||
 | 
					        errors.errors[0] shouldContain "^^str is not a valid pointer type"
 | 
				
			||||||
 | 
					        errors.errors[1] shouldContain "^^str is not a valid pointer type"
 | 
				
			||||||
 | 
					        errors.errors[2] shouldContain "^^str is not a valid pointer type"
 | 
				
			||||||
 | 
					        errors.errors[3] shouldContain "^^str is not a valid return type"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    test("various miscellaneous pointer syntax tests") {
 | 
					    test("various miscellaneous pointer syntax tests") {
 | 
				
			||||||
        val src="""
 | 
					        val src="""
 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,9 +1,6 @@
 | 
				
			|||||||
TODO
 | 
					TODO
 | 
				
			||||||
====
 | 
					====
 | 
				
			||||||
 | 
					
 | 
				
			||||||
disallow ^^str
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
STRUCTS and TYPED POINTERS
 | 
					STRUCTS and TYPED POINTERS
 | 
				
			||||||
--------------------------
 | 
					--------------------------
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,57 +1,16 @@
 | 
				
			|||||||
%import textio
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
main {
 | 
					main {
 | 
				
			||||||
    struct Node {
 | 
					 | 
				
			||||||
        ^^Node next
 | 
					 | 
				
			||||||
        ubyte weight
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ^^Node nodes = 2000
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    sub start() {
 | 
					    sub start() {
 | 
				
			||||||
        init()
 | 
					        str name = "test"
 | 
				
			||||||
        cx16.r0L = nodes[2].weight
 | 
					        ^^str ptr = &name
 | 
				
			||||||
        cx16.r1L = thing.things[2].weight
 | 
					        ^^str[4] array
 | 
				
			||||||
 | 
					        ptr = foo(&name)
 | 
				
			||||||
        txt.print_ub(cx16.r0L)
 | 
					 | 
				
			||||||
        txt.spc()
 | 
					 | 
				
			||||||
        txt.print_ub(cx16.r1L)
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        cx16.r9L = 3
 | 
					 | 
				
			||||||
        cx16.r0L = nodes[cx16.r9L].weight
 | 
					 | 
				
			||||||
        cx16.r1L = thing.things[cx16.r9L].weight
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        txt.print_ub(cx16.r0L)
 | 
					 | 
				
			||||||
        txt.spc()
 | 
					 | 
				
			||||||
        txt.print_ub(cx16.r1L)
 | 
					 | 
				
			||||||
        txt.nl()
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    sub init() {
 | 
					    sub foo(^^str arg) -> ^^str {
 | 
				
			||||||
        sys.memset(2000, 100, 99)
 | 
					        return arg+2
 | 
				
			||||||
        sys.memset(3000, 100, 99)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        ; NNW NNW NNW NNW
 | 
					 | 
				
			||||||
        @(2000+2) = 11
 | 
					 | 
				
			||||||
        @(2000+5) = 22
 | 
					 | 
				
			||||||
        @(2000+8) = 33
 | 
					 | 
				
			||||||
        @(2000+11) = 44
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        @(3000+2) = 101
 | 
					 | 
				
			||||||
        @(3000+5) = 102
 | 
					 | 
				
			||||||
        @(3000+8) = 103
 | 
					 | 
				
			||||||
        @(3000+11) = 104
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
thing {
 | 
					 | 
				
			||||||
    struct Thing {
 | 
					 | 
				
			||||||
        ^^Thing next
 | 
					 | 
				
			||||||
        ubyte weight
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    ^^Thing things = 3000
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
;%import floats
 | 
					;%import floats
 | 
				
			||||||
;%import textio
 | 
					;%import textio
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user