mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 22:16:16 +00:00
avoid compiler crash when using char literal in str initialization
fix compiler crash when using str var in an expression without &
This commit is contained in:
@@ -3,6 +3,7 @@ package prog8.compiler.astprocessing
|
|||||||
import prog8.ast.IStatementContainer
|
import prog8.ast.IStatementContainer
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
|
import prog8.ast.expressions.BinaryExpression
|
||||||
import prog8.ast.expressions.CharLiteral
|
import prog8.ast.expressions.CharLiteral
|
||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
import prog8.ast.expressions.NumericLiteral
|
import prog8.ast.expressions.NumericLiteral
|
||||||
@@ -82,6 +83,18 @@ internal fun Program.charLiteralsToUByteLiterals(target: ICompilationTarget, err
|
|||||||
}
|
}
|
||||||
return noModifications
|
return noModifications
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||||
|
if(decl.datatype.isString) {
|
||||||
|
val initvalue = decl.value
|
||||||
|
if(initvalue!=null && initvalue is BinaryExpression) {
|
||||||
|
if(initvalue.left is CharLiteral || initvalue.right is CharLiteral) {
|
||||||
|
errors.err("using a char literal in a string initialization expression, should probably be a string literal with one character in it instead", initvalue.position)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return noModifications
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
walker.visit(this)
|
walker.visit(this)
|
||||||
|
|||||||
@@ -368,4 +368,19 @@ main {
|
|||||||
errors.warnings.size shouldBe 0
|
errors.warnings.size shouldBe 0
|
||||||
errors.errors[0] shouldContain "requires integer or boolean type"
|
errors.errors[0] shouldContain "requires integer or boolean type"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("missing address of in expression operand") {
|
||||||
|
val src="""
|
||||||
|
main {
|
||||||
|
sub start() {
|
||||||
|
str name = "foo"
|
||||||
|
cx16.r0 = name+2
|
||||||
|
}
|
||||||
|
}"""
|
||||||
|
val errors = ErrorReporterForTests()
|
||||||
|
compileText(C64Target(), false, src, writeAssembly = false, errors = errors) shouldBe null
|
||||||
|
errors.errors.size shouldBe 1
|
||||||
|
errors.warnings.size shouldBe 0
|
||||||
|
errors.errors[0] shouldContain "missing &"
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ class BinaryExpression(
|
|||||||
|
|
||||||
// if left or right is a numeric literal, and its value fits in the type of the other operand, use the other's operand type
|
// if left or right is a numeric literal, and its value fits in the type of the other operand, use the other's operand type
|
||||||
// EXCEPTION: if the numeric value is a word and the other operand is a byte type (to allow v * $0008 for example)
|
// EXCEPTION: if the numeric value is a word and the other operand is a byte type (to allow v * $0008 for example)
|
||||||
if (left is NumericLiteral) {
|
if (left is NumericLiteral && rightDt.isNumericOrBool) {
|
||||||
if(!(leftDt.isWord && rightDt.isByte)) {
|
if(!(leftDt.isWord && rightDt.isByte)) {
|
||||||
val optimal = NumericLiteral.optimalNumeric(rightDt.base, null, left.number, left.position)
|
val optimal = NumericLiteral.optimalNumeric(rightDt.base, null, left.number, left.position)
|
||||||
if (optimal.type != leftDt.base && DataType.forDt(optimal.type) isAssignableTo rightDt) {
|
if (optimal.type != leftDt.base && DataType.forDt(optimal.type) isAssignableTo rightDt) {
|
||||||
@@ -261,7 +261,7 @@ class BinaryExpression(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (right is NumericLiteral) {
|
if (right is NumericLiteral && leftDt.isNumericOrBool) {
|
||||||
if(!(rightDt.isWord && leftDt.isByte)) {
|
if(!(rightDt.isWord && leftDt.isByte)) {
|
||||||
val optimal = NumericLiteral.optimalNumeric(leftDt.base, null, right.number, right.position)
|
val optimal = NumericLiteral.optimalNumeric(leftDt.base, null, right.number, right.position)
|
||||||
if (optimal.type != rightDt.base && DataType.forDt(optimal.type) isAssignableTo leftDt) {
|
if (optimal.type != rightDt.base && DataType.forDt(optimal.type) isAssignableTo leftDt) {
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ Future Things and Ideas
|
|||||||
Make up our mind! Maybe all setup does need to be put into start() ? because the program cannot function correctly when the variables aren't initialized properly bss is not cleared etc. etc.
|
Make up our mind! Maybe all setup does need to be put into start() ? because the program cannot function correctly when the variables aren't initialized properly bss is not cleared etc. etc.
|
||||||
Add a -library $xxxx command line option (and/or some directive) to preselect every setting that is required to make a library at $xxxx rather than a normal loadable and runnable program?
|
Add a -library $xxxx command line option (and/or some directive) to preselect every setting that is required to make a library at $xxxx rather than a normal loadable and runnable program?
|
||||||
Need to add some way to generate a stable jump table at a given address.
|
Need to add some way to generate a stable jump table at a given address.
|
||||||
|
Need library to not call init_system AND init_system_phase2 not either.
|
||||||
|
Library must not include prog8_program_start stuff either.
|
||||||
- Fix missing cases where regular & has to return the start of the split array in memory whatever byte comes first. Search TODO("address of split word array")
|
- Fix missing cases where regular & has to return the start of the split array in memory whatever byte comes first. Search TODO("address of split word array")
|
||||||
- Add a syntax to access specific bits in a variable, to avoid manually shifts&ands, something like variable[4:8] ? (or something else this may be too similar to regular array indexing)
|
- Add a syntax to access specific bits in a variable, to avoid manually shifts&ands, something like variable[4:8] ? (or something else this may be too similar to regular array indexing)
|
||||||
- something to reduce the need to use fully qualified names all the time. 'with' ? Or 'using <prefix>'?
|
- something to reduce the need to use fully qualified names all the time. 'with' ? Or 'using <prefix>'?
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
main {
|
main {
|
||||||
sub start() {
|
sub start() {
|
||||||
uword[] tasklist = [1111,2222,3333]
|
;str test = '?' * 10
|
||||||
uword task_address = tasklist[0]
|
str name = "foo"
|
||||||
goto task_address
|
cx16.r0 = name+2
|
||||||
goto task_address+1
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user