mirror of
https://github.com/irmen/prog8.git
synced 2025-02-17 13:31:01 +00:00
now correctly requires using & (address-of) when assigning the address of a label or subroutine, used to generate invalid code when it was omitted
This commit is contained in:
parent
7bb41a30ed
commit
7afc96112b
compiler
compilerAst/src/prog8/ast/expressions
docs/source
examples
@ -497,7 +497,7 @@ internal class AstChecker(private val program: Program,
|
|||||||
val sourceDatatype = assignment.value.inferType(program)
|
val sourceDatatype = assignment.value.inferType(program)
|
||||||
if (sourceDatatype.isUnknown) {
|
if (sourceDatatype.isUnknown) {
|
||||||
if (assignment.value !is FunctionCallExpression)
|
if (assignment.value !is FunctionCallExpression)
|
||||||
errors.err("assignment value is invalid or has no proper datatype", assignment.value.position)
|
errors.err("assignment value is invalid or has no proper datatype, maybe forgot '&' (address-of)", assignment.value.position)
|
||||||
} else {
|
} else {
|
||||||
checkAssignmentCompatible(targetDatatype.getOr(DataType.BYTE),
|
checkAssignmentCompatible(targetDatatype.getOr(DataType.BYTE),
|
||||||
sourceDatatype.getOr(DataType.BYTE), assignment.value)
|
sourceDatatype.getOr(DataType.BYTE), assignment.value)
|
||||||
|
@ -5,6 +5,7 @@ import io.kotest.matchers.shouldBe
|
|||||||
import io.kotest.matchers.string.shouldContain
|
import io.kotest.matchers.string.shouldContain
|
||||||
import prog8.codegen.target.C64Target
|
import prog8.codegen.target.C64Target
|
||||||
import prog8tests.helpers.ErrorReporterForTests
|
import prog8tests.helpers.ErrorReporterForTests
|
||||||
|
import prog8tests.helpers.assertFailure
|
||||||
import prog8tests.helpers.assertSuccess
|
import prog8tests.helpers.assertSuccess
|
||||||
import prog8tests.helpers.compileText
|
import prog8tests.helpers.compileText
|
||||||
|
|
||||||
@ -30,4 +31,29 @@ class TestAstChecks: FunSpec({
|
|||||||
errors.warnings[0] shouldContain "converted to float"
|
errors.warnings[0] shouldContain "converted to float"
|
||||||
errors.warnings[1] shouldContain "converted to float"
|
errors.warnings[1] shouldContain "converted to float"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("can't assign label or subroutine without using address-of") {
|
||||||
|
val text = """
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
|
||||||
|
label:
|
||||||
|
uword @shared addr
|
||||||
|
addr = label
|
||||||
|
addr = thing
|
||||||
|
addr = &label
|
||||||
|
addr = &thing
|
||||||
|
}
|
||||||
|
|
||||||
|
sub thing() {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"""
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(C64Target, true, text, writeAssembly = true, errors=errors).assertFailure()
|
||||||
|
errors.errors.size shouldBe 2
|
||||||
|
errors.warnings.size shouldBe 0
|
||||||
|
errors.errors[0] shouldContain ":7:28) assignment value is invalid"
|
||||||
|
errors.errors[1] shouldContain ":8:28) assignment value is invalid"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
@ -896,7 +896,6 @@ data class IdentifierReference(val nameInSource: List<String>, override val posi
|
|||||||
override fun inferType(program: Program): InferredTypes.InferredType {
|
override fun inferType(program: Program): InferredTypes.InferredType {
|
||||||
return when (val targetStmt = targetStatement(program)) {
|
return when (val targetStmt = targetStatement(program)) {
|
||||||
is VarDecl -> InferredTypes.knownFor(targetStmt.datatype)
|
is VarDecl -> InferredTypes.knownFor(targetStmt.datatype)
|
||||||
is Label -> InferredTypes.InferredType.known(DataType.UWORD)
|
|
||||||
else -> InferredTypes.InferredType.unknown()
|
else -> InferredTypes.InferredType.unknown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@ TODO
|
|||||||
|
|
||||||
For next release
|
For next release
|
||||||
^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^
|
||||||
- Fix: uword addr = label ; addr will be 0! required to use &label!
|
|
||||||
- Fix compiler stack overflow crash:
|
- Fix compiler stack overflow crash:
|
||||||
sub sprite_y_for_row(ubyte row) -> word {
|
sub sprite_y_for_row(ubyte row) -> word {
|
||||||
return (8-row as byte)
|
return (8-row as byte)
|
||||||
@ -44,6 +43,7 @@ Blocked by an official Commander-x16 r39 release
|
|||||||
|
|
||||||
Future Things and Ideas
|
Future Things and Ideas
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
- Fix: don't report as recursion if code assign address of its own subroutine to something, rather than calling it
|
||||||
- allow "xxx" * constexpr (where constexpr is not a number literal, now gives expression error not same type)
|
- allow "xxx" * constexpr (where constexpr is not a number literal, now gives expression error not same type)
|
||||||
- can we promise a left-to-right function call argument evaluation? without sacrificing performance
|
- can we promise a left-to-right function call argument evaluation? without sacrificing performance
|
||||||
- unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement, may require moving Expression/Statement into interfaces instead of abstract base classes
|
- unify FunctioncallExpression + FunctioncallStatement and PipeExpression + Pipe statement, may require moving Expression/Statement into interfaces instead of abstract base classes
|
||||||
|
@ -3,7 +3,15 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword @shared qq = $2ff33
|
|
||||||
cx16.r0 = $1fc0f
|
label:
|
||||||
|
uword @shared addr
|
||||||
|
addr = label
|
||||||
|
addr = thing
|
||||||
|
addr = &label
|
||||||
|
addr = &thing
|
||||||
|
}
|
||||||
|
|
||||||
|
sub thing() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user