mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +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.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)
|
||||
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)
|
||||
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
|
||||
if(decl.isArray && decl.arraysize==null) {
|
||||
if (decl.isArray) {
|
||||
if (decl.arraysize == null) {
|
||||
if(decl.type== VarDeclType.MEMORY) {
|
||||
err("memory mapped array must have a size specification")
|
||||
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")
|
||||
}
|
||||
|
||||
if(decl.datatype.isPointerArray && decl.datatype.sub==BaseDataType.STR)
|
||||
err("^^str is not a valid pointer type, use ^^ubyte?")
|
||||
}
|
||||
|
||||
when(decl.type) {
|
||||
VarDeclType.VAR, VarDeclType.CONST -> {
|
||||
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.value==null) {
|
||||
// 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))
|
||||
}
|
||||
|
||||
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> {
|
||||
fun jumpAfter(stmt: Statement): Iterable<IAstModification> {
|
||||
val label = program.makeLabel("after", breakStmt.position)
|
||||
@@ -731,24 +722,6 @@ _after:
|
||||
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> {
|
||||
val targetDt = assignment.target.inferType(program)
|
||||
val sourceDt = assignment.value.inferType(program)
|
||||
|
||||
@@ -1305,7 +1305,6 @@ main {
|
||||
^^uword[4] array5
|
||||
^^float[4] array6
|
||||
^^long[4] array7
|
||||
^^str[4] array8
|
||||
|
||||
ok(array1)
|
||||
ok(array2)
|
||||
@@ -1314,7 +1313,6 @@ main {
|
||||
ok(array5)
|
||||
ok(array6)
|
||||
ok(array7)
|
||||
ok(array8)
|
||||
}
|
||||
|
||||
sub ok(^^ubyte ptr) {
|
||||
@@ -1495,7 +1493,6 @@ main {
|
||||
^^uword[4] array5 = [1000, 1100, 1200, 1300]
|
||||
^^float[4] array6 = [1000, 1100, 1200, 1300]
|
||||
^^long[4] array7 = [1000, 1100, 1200, 1300]
|
||||
^^str[4] array8 = [1000, 1100, 1200, 1300]
|
||||
|
||||
cx16.r0 = array1[2]
|
||||
cx16.r1 = array2[2]
|
||||
@@ -1504,7 +1501,6 @@ main {
|
||||
cx16.r4 = array5[2]
|
||||
cx16.r5 = array6[2]
|
||||
cx16.r6 = array7[2]
|
||||
cx16.r7 = array8[2]
|
||||
}
|
||||
}"""
|
||||
|
||||
@@ -1664,6 +1660,29 @@ main {
|
||||
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") {
|
||||
val src="""
|
||||
main {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
disallow ^^str
|
||||
|
||||
|
||||
STRUCTS and TYPED POINTERS
|
||||
--------------------------
|
||||
|
||||
|
||||
@@ -1,57 +1,16 @@
|
||||
%import textio
|
||||
|
||||
main {
|
||||
struct Node {
|
||||
^^Node next
|
||||
ubyte weight
|
||||
}
|
||||
^^Node nodes = 2000
|
||||
|
||||
sub start() {
|
||||
init()
|
||||
cx16.r0L = nodes[2].weight
|
||||
cx16.r1L = thing.things[2].weight
|
||||
|
||||
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()
|
||||
str name = "test"
|
||||
^^str ptr = &name
|
||||
^^str[4] array
|
||||
ptr = foo(&name)
|
||||
}
|
||||
|
||||
sub init() {
|
||||
sys.memset(2000, 100, 99)
|
||||
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
|
||||
sub foo(^^str arg) -> ^^str {
|
||||
return arg+2
|
||||
}
|
||||
}
|
||||
|
||||
thing {
|
||||
struct Thing {
|
||||
^^Thing next
|
||||
ubyte weight
|
||||
}
|
||||
^^Thing things = 3000
|
||||
}
|
||||
|
||||
|
||||
;%import floats
|
||||
;%import textio
|
||||
|
||||
Reference in New Issue
Block a user