mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
type error tweaks
This commit is contained in:
parent
7530f4407b
commit
ffdc658dc8
@ -160,7 +160,8 @@ val ElementToArrayTypes = mapOf(
|
|||||||
DataType.WORD to DataType.ARRAY_W,
|
DataType.WORD to DataType.ARRAY_W,
|
||||||
DataType.UWORD to DataType.ARRAY_UW,
|
DataType.UWORD to DataType.ARRAY_UW,
|
||||||
DataType.FLOAT to DataType.ARRAY_F,
|
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(
|
val Cx16VirtualRegisters = arrayOf(
|
||||||
|
@ -514,10 +514,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
if(assignment.target.identifier?.targetStatement(program)!=null)
|
if(assignment.target.identifier?.targetStatement(program)!=null)
|
||||||
errors.err("target datatype is unknown", assignment.target.position)
|
errors.err("target datatype is unknown", assignment.target.position)
|
||||||
// otherwise, another error about missing symbol is already reported.
|
// 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) {
|
if(target.value is StringLiteral) {
|
||||||
// check string lengths for non-memory mapped strings
|
// check string lengths for non-memory mapped strings
|
||||||
val stringLen = (target.value as StringLiteral).value.length
|
val stringLen = (target.value as StringLiteral).value.length
|
||||||
val index = arrayIndexedExpression.indexer.constIndex()
|
|
||||||
if (index != null && (index < 0 || index >= stringLen))
|
if (index != null && (index < 0 || index >= stringLen))
|
||||||
errors.err("index out of bounds", arrayIndexedExpression.indexer.position)
|
errors.err("index out of bounds", arrayIndexedExpression.indexer.position)
|
||||||
}
|
}
|
||||||
|
@ -283,9 +283,10 @@ internal class StatementReorderer(
|
|||||||
} else {
|
} else {
|
||||||
if (sourceVar.arraysize!!.constIndex() != targetVar.arraysize!!.constIndex())
|
if (sourceVar.arraysize!!.constIndex() != targetVar.arraysize!!.constIndex())
|
||||||
errors.err("element count mismatch", assign.position)
|
errors.err("element count mismatch", assign.position)
|
||||||
if (sourceVar.datatype != targetVar.datatype) {
|
val sourceEltDt = ArrayToElementTypes.getValue(sourceVar.datatype)
|
||||||
if(!targetVar.splitArray || (sourceVar.datatype!=DataType.ARRAY_W && sourceVar.datatype!=DataType.ARRAY_UW))
|
val targetEltDt = ArrayToElementTypes.getValue(targetVar.datatype)
|
||||||
errors.err("element type mismatch", assign.position)
|
if (!sourceEltDt.equalsSize(targetEltDt)) {
|
||||||
|
errors.err("element size mismatch", assign.position)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -525,9 +525,8 @@ class TestOptimization: FunSpec({
|
|||||||
"""
|
"""
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
|
compileText(C64Target(), optimize=false, src, writeAssembly=false, errors = errors) shouldBe null
|
||||||
errors.errors.size shouldBe 2
|
errors.errors.size shouldBe 1
|
||||||
errors.errors[0] shouldContain "type of value WORD doesn't match target UBYTE"
|
errors.errors[0] shouldContain "out of range"
|
||||||
errors.errors[1] shouldContain "out of range"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test("out of range cast should give error") {
|
test("out of range cast should give error") {
|
||||||
|
@ -1062,12 +1062,11 @@ main {
|
|||||||
}"""
|
}"""
|
||||||
val errors=ErrorReporterForTests()
|
val errors=ErrorReporterForTests()
|
||||||
compileText(C64Target(), false, src, writeAssembly = false, errors=errors) shouldBe null
|
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[0] shouldContain "no cast"
|
||||||
errors.errors[1] shouldContain "overflow"
|
errors.errors[1] shouldContain "overflow"
|
||||||
errors.errors[2] shouldContain "LONG doesn't match"
|
errors.errors[2] shouldContain "out of range"
|
||||||
errors.errors[3] shouldContain "out of range"
|
errors.errors[3] shouldContain "overflow"
|
||||||
errors.errors[4] shouldContain "overflow"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})
|
})
|
||||||
|
@ -6,7 +6,6 @@ import io.kotest.matchers.shouldNotBe
|
|||||||
import io.kotest.matchers.string.shouldContain
|
import io.kotest.matchers.string.shouldContain
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.code.target.VMTarget
|
import prog8.code.target.VMTarget
|
||||||
import prog8tests.helpers.ErrorReporterForTests
|
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
import kotlin.io.path.readText
|
import kotlin.io.path.readText
|
||||||
|
|
||||||
@ -94,23 +93,33 @@ main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
test("split only for word arrays") {
|
test("split only for word arrays") {
|
||||||
val text = """
|
val srcGood = """
|
||||||
main {
|
main {
|
||||||
ubyte[10] @split sb
|
|
||||||
uword[10] @split sw
|
uword[10] @split sw
|
||||||
word[10] @split sw2
|
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
|
float[10] @split sf
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
val errors = ErrorReporterForTests()
|
compileText(C64Target(), false, srcWrong2, writeAssembly = false) shouldBe null
|
||||||
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"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
test("split word arrays in asm as lsb/msb") {
|
test("split word arrays in asm as lsb/msb") {
|
||||||
@ -141,8 +150,9 @@ main {
|
|||||||
str name1 = "name1"
|
str name1 = "name1"
|
||||||
str name2 = "name2"
|
str name2 = "name2"
|
||||||
uword[] @split names = [name1, name2, "name3"]
|
uword[] @split names = [name1, name2, "name3"]
|
||||||
cx16.r0++
|
uword[] addresses = [0,0,0]
|
||||||
names = [1111,2222,3333]
|
names = [1111,2222,3333]
|
||||||
|
addresses = names
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
compileText(C64Target(), false, text, writeAssembly = true) shouldNotBe null
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
TODO
|
TODO
|
||||||
====
|
====
|
||||||
|
|
||||||
|
- get rid of vardecl.declareddatatype
|
||||||
- get rid of memory mapped variables: treat them as syntactic sugar for a poke/peek to the symbol.
|
- 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.
|
- add -nowarnunused, or %option ignore_unused (module and block scope), to suppress all warnings about unused symbols. Useful in libraries.
|
||||||
|
@ -4,22 +4,33 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
sys.push(11)
|
uword zz
|
||||||
sys.pushw(2222)
|
word zz2
|
||||||
floats.push(floats.π)
|
ubyte bb
|
||||||
cx16.r2++
|
byte bb2
|
||||||
|
|
||||||
float pi = floats.pop()
|
bb2 |= bb
|
||||||
floats.print_f(pi)
|
bb2 |= zz2
|
||||||
txt.nl()
|
|
||||||
|
|
||||||
cx16.r1 = sys.popw()
|
; uword[20] @split foobar
|
||||||
cx16.r0L = sys.pop()
|
; ubyte[20] @split foobar2
|
||||||
|
;
|
||||||
txt.print_ub(cx16.r0L)
|
; sys.push(11)
|
||||||
txt.nl()
|
; sys.pushw(2222)
|
||||||
txt.print_uw(cx16.r1)
|
; floats.push(floats.π)
|
||||||
txt.nl()
|
; 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()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user