From e2b8c069d7e386e40b187e7351601b9c0374a391 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Mon, 24 Jan 2022 23:30:15 +0100 Subject: [PATCH] check for missing '&' in string + value expressions (can't just add a value to a string) --- .../compiler/astprocessing/AstChecker.kt | 7 +++ compiler/test/TestAstChecks.kt | 41 ++++++++++++++++ docs/source/todo.rst | 2 - examples/test.p8 | 48 +++++-------------- 4 files changed, 60 insertions(+), 38 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 2db3c8c0d..a06a387f8 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -835,6 +835,13 @@ internal class AstChecker(private val program: Program, val leftDt = leftIDt.getOr(DataType.UNDEFINED) val rightDt = rightIDt.getOr(DataType.UNDEFINED) + if(expr.operator=="+" || expr.operator=="-") { + if(leftDt == DataType.STR || rightDt == DataType.STR || leftDt in ArrayDatatypes || rightDt in ArrayDatatypes) { + errors.err("missing & (address-of) on the string operand", expr.position) + return + } + } + when(expr.operator){ "/", "%" -> { val constvalRight = expr.right.constValue(program) diff --git a/compiler/test/TestAstChecks.kt b/compiler/test/TestAstChecks.kt index 8c8e9532f..18a0fc2df 100644 --- a/compiler/test/TestAstChecks.kt +++ b/compiler/test/TestAstChecks.kt @@ -56,4 +56,45 @@ class TestAstChecks: FunSpec({ errors.errors[0] shouldContain ":7:28) assignment value is invalid" errors.errors[1] shouldContain ":8:28) assignment value is invalid" } + + test("can't do str or array expression without using address-of") { + val text = """ + %import textio + main { + sub start() { + ubyte[] array = [1,2,3,4] + str s1 = "test" + ubyte ff = 1 + txt.print(s1+ff) + txt.print(array+ff) + txt.print_uwhex(s1+ff, true) + txt.print_uwhex(array+ff, true) + } + } + """ + val errors = ErrorReporterForTests() + compileText(C64Target, false, text, writeAssembly = false, errors=errors).assertFailure() + errors.errors.filter { it.contains("missing &") }.size shouldBe 4 + } + + test("str or array expression with address-of") { + val text = """ + %import textio + main { + sub start() { + ubyte[] array = [1,2,3,4] + str s1 = "test" + ubyte ff = 1 + txt.print(&s1+ff) + txt.print(&array+ff) + txt.print_uwhex(&s1+ff, true) + txt.print_uwhex(&array+ff, true) + ; also good: + ff = (s1 == "derp") + ff = (s1 != "derp") + } + } + """ + compileText(C64Target, false, text, writeAssembly = false).assertSuccess() + } }) diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 5dd9f622e..56b51c94c 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- str s1, ubyte ff, txt.print_uwhex(s1+ff, true) ; TODO fix compiler crash on s1+ff. why no crash when using 1-argument functioncall? - ... diff --git a/examples/test.p8 b/examples/test.p8 index dfb219df5..b781b0192 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,43 +4,19 @@ main { sub start() { - str s1 = "irmen@razorvine.net" + str s1 = "irmen" + ubyte ff = 1 + txt.print(&s1+ff) + txt.nl() + txt.print(&s1+ff) + txt.nl() + txt.print_uwhex(&s1+ff, true) - ubyte qq = '@' - if qq in s1 - txt.print("good1\n") - else - txt.print("error1\n") - - if 'r' in s1 - txt.print("good2\n") - else - txt.print("error2\n") - - if qq in "irmen22@razorvine.netirmen22@razorvine.netirmen22@razorvine.netirmen22@razorvine.net" - txt.print("good3\n") - else - txt.print("error3\n") - - qq = 2 - if qq in [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] - txt.print("good4\n") - else - txt.print("error4\n") - - qq='z' - if qq in "irm@razo" - txt.print("good5\n") - else - txt.print("error5\n") - - uword zz = 2222 - if zz in [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,2222,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2] - txt.print("good6\n") - else - txt.print("error6\n") - - ; str s1, ubyte ff, txt.print_uwhex(s1+ff, true) ; TODO fix compiler crash on s1+ff. why no crash when using 1-argument functioncall? + ubyte[] array = [1,2,3,4] + txt.print_uwhex(&array+ff, true) + txt.nl() + txt.print_uwhex(&array+ff, true) + txt.nl() } }