From ffdc658dc84adbc1812b4fd448f3709c8e40fc2b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 26 Dec 2023 18:49:01 +0100 Subject: [PATCH] type error tweaks --- codeCore/src/prog8/code/core/Enumerations.kt | 3 +- .../compiler/astprocessing/AstChecker.kt | 5 --- .../astprocessing/StatementReorderer.kt | 7 ++-- compiler/test/TestOptimization.kt | 5 +-- compiler/test/TestTypecasts.kt | 7 ++-- .../test/codegeneration/TestArrayThings.kt | 32 +++++++++------ docs/source/todo.rst | 1 + examples/test.p8 | 39 ++++++++++++------- 8 files changed, 58 insertions(+), 41 deletions(-) diff --git a/codeCore/src/prog8/code/core/Enumerations.kt b/codeCore/src/prog8/code/core/Enumerations.kt index 3a960665b..750ac8304 100644 --- a/codeCore/src/prog8/code/core/Enumerations.kt +++ b/codeCore/src/prog8/code/core/Enumerations.kt @@ -160,7 +160,8 @@ val ElementToArrayTypes = mapOf( DataType.WORD to DataType.ARRAY_W, DataType.UWORD to DataType.ARRAY_UW, DataType.FLOAT to DataType.ARRAY_F, - DataType.BOOL to DataType.ARRAY_BOOL + DataType.BOOL to DataType.ARRAY_BOOL, + DataType.STR to DataType.UWORD // array of str is just an array of pointers ) val Cx16VirtualRegisters = arrayOf( diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 9dd982796..e77e1a2d8 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -514,10 +514,6 @@ internal class AstChecker(private val program: Program, if(assignment.target.identifier?.targetStatement(program)!=null) errors.err("target datatype is unknown", assignment.target.position) // otherwise, another error about missing symbol is already reported. - } else { - // allow bitwise operations on different types as long as the size is the same - if (!((assignment.value as? BinaryExpression)?.operator in BitwiseOperators && targetDt.isBytes && valueDt.isBytes || targetDt.isWords && valueDt.isWords)) - errors.err("type of value $valueDt doesn't match target $targetDt", assignment.value.position) } } } @@ -1369,7 +1365,6 @@ internal class AstChecker(private val program: Program, if(target.value is StringLiteral) { // check string lengths for non-memory mapped strings val stringLen = (target.value as StringLiteral).value.length - val index = arrayIndexedExpression.indexer.constIndex() if (index != null && (index < 0 || index >= stringLen)) errors.err("index out of bounds", arrayIndexedExpression.indexer.position) } diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 41f1d06ca..15e644efa 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -283,9 +283,10 @@ internal class StatementReorderer( } else { if (sourceVar.arraysize!!.constIndex() != targetVar.arraysize!!.constIndex()) errors.err("element count mismatch", assign.position) - if (sourceVar.datatype != targetVar.datatype) { - if(!targetVar.splitArray || (sourceVar.datatype!=DataType.ARRAY_W && sourceVar.datatype!=DataType.ARRAY_UW)) - errors.err("element type mismatch", assign.position) + val sourceEltDt = ArrayToElementTypes.getValue(sourceVar.datatype) + val targetEltDt = ArrayToElementTypes.getValue(targetVar.datatype) + if (!sourceEltDt.equalsSize(targetEltDt)) { + errors.err("element size mismatch", assign.position) } } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 7620ca782..a18568576 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -525,9 +525,8 @@ class TestOptimization: FunSpec({ """ val errors = ErrorReporterForTests() compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null - errors.errors.size shouldBe 2 - errors.errors[0] shouldContain "type of value WORD doesn't match target UBYTE" - errors.errors[1] shouldContain "out of range" + errors.errors.size shouldBe 1 + errors.errors[0] shouldContain "out of range" } test("out of range cast should give error") { diff --git a/compiler/test/TestTypecasts.kt b/compiler/test/TestTypecasts.kt index 45f6ebbb7..d27cf54ed 100644 --- a/compiler/test/TestTypecasts.kt +++ b/compiler/test/TestTypecasts.kt @@ -1062,12 +1062,11 @@ main { }""" val errors=ErrorReporterForTests() compileText(C64Target(), false, src, writeAssembly = false, errors=errors) shouldBe null - errors.errors.size shouldBe 5 + errors.errors.size shouldBe 4 errors.errors[0] shouldContain "no cast" errors.errors[1] shouldContain "overflow" - errors.errors[2] shouldContain "LONG doesn't match" - errors.errors[3] shouldContain "out of range" - errors.errors[4] shouldContain "overflow" + errors.errors[2] shouldContain "out of range" + errors.errors[3] shouldContain "overflow" } }) diff --git a/compiler/test/codegeneration/TestArrayThings.kt b/compiler/test/codegeneration/TestArrayThings.kt index dbff76987..4f1204bb7 100644 --- a/compiler/test/codegeneration/TestArrayThings.kt +++ b/compiler/test/codegeneration/TestArrayThings.kt @@ -6,7 +6,6 @@ import io.kotest.matchers.shouldNotBe import io.kotest.matchers.string.shouldContain import prog8.code.target.C64Target import prog8.code.target.VMTarget -import prog8tests.helpers.ErrorReporterForTests import prog8tests.helpers.compileText import kotlin.io.path.readText @@ -94,23 +93,33 @@ main { } test("split only for word arrays") { - val text = """ + val srcGood = """ main { - ubyte[10] @split sb uword[10] @split sw word[10] @split sw2 + + sub start() { + } +}""" + compileText(C64Target(), false, srcGood, writeAssembly = false) shouldNotBe null + + val srcWrong1 = """ +main { + ubyte[10] @split sb + + sub start() { + } +}""" + compileText(C64Target(), false, srcWrong1, writeAssembly = false) shouldBe null + + val srcWrong2 = """ +main { float[10] @split sf sub start() { } }""" - val errors = ErrorReporterForTests() - compileText(C64Target(), false, text, writeAssembly = false, errors = errors) shouldBe null - errors.errors.size shouldBe 2 - errors.errors.forEach { - it shouldContain "split" - it shouldContain "word arrays" - } + compileText(C64Target(), false, srcWrong2, writeAssembly = false) shouldBe null } test("split word arrays in asm as lsb/msb") { @@ -141,8 +150,9 @@ main { str name1 = "name1" str name2 = "name2" uword[] @split names = [name1, name2, "name3"] - cx16.r0++ + uword[] addresses = [0,0,0] names = [1111,2222,3333] + addresses = names } }""" compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null diff --git a/docs/source/todo.rst b/docs/source/todo.rst index e51d9590f..3f85226cb 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,6 +2,7 @@ TODO ==== +- get rid of vardecl.declareddatatype - get rid of memory mapped variables: treat them as syntactic sugar for a poke/peek to the symbol. - add -nowarnunused, or %option ignore_unused (module and block scope), to suppress all warnings about unused symbols. Useful in libraries. diff --git a/examples/test.p8 b/examples/test.p8 index 00c33aa06..b88e1caed 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,22 +4,33 @@ main { sub start() { - sys.push(11) - sys.pushw(2222) - floats.push(floats.π) - cx16.r2++ + uword zz + word zz2 + ubyte bb + byte bb2 - float pi = floats.pop() - floats.print_f(pi) - txt.nl() + bb2 |= bb + bb2 |= zz2 - cx16.r1 = sys.popw() - cx16.r0L = sys.pop() - - txt.print_ub(cx16.r0L) - txt.nl() - txt.print_uw(cx16.r1) - txt.nl() +; uword[20] @split foobar +; ubyte[20] @split foobar2 +; +; sys.push(11) +; sys.pushw(2222) +; floats.push(floats.π) +; cx16.r2++ +; +; float pi = floats.pop() +; floats.print_f(pi) +; txt.nl() +; +; cx16.r1 = sys.popw() +; cx16.r0L = sys.pop() +; +; txt.print_ub(cx16.r0L) +; txt.nl() +; txt.print_uw(cx16.r1) +; txt.nl() } }