fix countries[2]^^ = 0 compiler crash

This commit is contained in:
Irmen de Jong
2025-07-31 02:03:18 +02:00
parent 3d10882f57
commit eb8b408b82
5 changed files with 88 additions and 39 deletions

View File

@@ -688,10 +688,10 @@ _after:
// get rid of ArrayIndexedPtrDereference in the assignment target
// z[i]^^ = value --> pokeX(z[i], value)
val dt = deref.inferType(program).getOrUndef()
require(dt.isNumericOrBool)
if(dt.isNumericOrBool) {
// if it's something else beside number (like, a struct instance) we don't support rewriting that...
val (pokeFunc, cast) =
if(dt.isBool) "pokebool" to null
if (dt.isBool) "pokebool" to null
else if (dt.isUnsignedByte) "poke" to null
else if (dt.isSignedByte) "poke" to DataType.UBYTE
else if (dt.isUnsignedWord) "pokew" to null
@@ -705,15 +705,21 @@ _after:
val pokeIdent = IdentifierReference(listOf(pokeFunc), deref.position)
val assignment = parent.parent as Assignment
val pokeCall: FunctionCallStatement
if(cast==null) {
pokeCall = FunctionCallStatement(pokeIdent, mutableListOf(indexed, assignment.value), false, deref.position)
}
else {
if (cast == null) {
pokeCall = FunctionCallStatement(
pokeIdent,
mutableListOf(indexed, assignment.value),
false,
deref.position
)
} else {
val casted = TypecastExpression(assignment.value, cast, true, deref.position)
pokeCall = FunctionCallStatement(pokeIdent, mutableListOf(indexed, casted), false, deref.position)
pokeCall =
FunctionCallStatement(pokeIdent, mutableListOf(indexed, casted), false, deref.position)
}
return listOf(IAstModification.ReplaceNode(assignment, pokeCall, assignment.parent))
}
}
else {
TODO("cannot translate $deref here ${deref.position}")
}

View File

@@ -3,6 +3,7 @@ package prog8tests.compiler
import io.kotest.assertions.withClue
import io.kotest.core.spec.style.FunSpec
import io.kotest.engine.spec.tempdir
import io.kotest.matchers.comparables.shouldBeGreaterThanOrEqualTo
import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
@@ -1159,13 +1160,15 @@ other {
^^List[10] listarray
listarray[3]^^.value = cx16.r0
listarray[3]^^ = 999 ; cannot assign word value to struct instance
}
}"""
val errors = ErrorReporterForTests()
compileText(VMTarget(), false, src, outputDir, errors=errors) shouldBe null
errors.errors.size shouldBe 2
errors.errors.size shouldBeGreaterThanOrEqualTo 3
errors.errors[0] shouldContain "no support for"
errors.errors[1] shouldContain "no support for"
errors.errors[2] shouldContain "assigning this value to struct instance not supported"
}
xtest("array indexed assignment parses with and without explicit dereference after struct pointer [IGNORED because it's a parser error right now]") {

View File

@@ -1728,8 +1728,16 @@ class ArrayIndexedPtrDereference(
val arrayIdentifier = chain.map { it.first }
val symbol = definingScope.lookup(arrayIdentifier) as? VarDecl
if(symbol!=null) {
if(symbol.datatype.isArray)
if(symbol.datatype.isArray) {
if(symbol.datatype.sub!=null)
return InferredTypes.knownFor(symbol.datatype.sub!!)
else if(symbol.datatype.subType!=null) {
val structType = DataType.structInstance(symbol.datatype.subType!!)
return InferredTypes.knownFor(structType)
}
else
return InferredTypes.unknown()
}
else if(symbol.datatype.isPointer)
return InferredTypes.knownFor(symbol.datatype.dereference())
}

View File

@@ -3,7 +3,6 @@ TODO
fix ^^Node nodes / cx16.r0L = nodes[2].weight (TODO("IR datatype for struct instances")
fix bool bb2 = bptr[2]^^ ... peekbool(bptr[2]) gives a arg 1 type error... just omit peekbool() here?
fix countries[2]^^ = 0 compiler crash
fix passing array of structptrs to subroutine , arg type mismatches
disallow ^^str

View File

@@ -1,19 +1,52 @@
main {
sub start() {
struct Node {
ubyte weight
bool flag
}
^^Node nodes
^^Node[10] array
^^bool bptr
bool bb1 = bptr[2]
bool bb2 = bptr[2]^^ ; TODO fix this ... peekbool(bptr[2]) gives a arg 1 type error... just omit peekbool() here?
cx16.r0L = array[2].weight
cx16.r1L = nodes[2].weight ; TODO implement support for this one
^^Node[10] ptrs
sub start() {
ptrs[2]^^ = 999 ; should be normal compiler error
}
}
;%import textio
;
;main {
; bool bb1, bb2
;
; sub start() {
;; struct Node {
;; ubyte weight
;; }
;; ^^Node nodes
;; ^^Node[10] array
; ^^bool bptr = 2000
; bb1 = bptr[2]
; bb2 = bptr[2]^^ ; TODO fix this ... peekbool(bptr[2]) gives a arg 1 type error... just omit peekbool() here?
;
; bb1 = thing.routine.bptrx[2]
; bb2 = thing.routine.bptrx[2]^^ ; TODO fix this ... peekbool(bptr[2]) gives a arg 1 type error... just omit peekbool() here?
;
; bptr[2] = false
; bptr[3]^^ = false
; thing.routine.bptrx[2] = false
; thing.routine.bptrx[3]^^ = false
;
;
;; cx16.r0L = array[2].weight
;; cx16.r1L = nodes[2].weight ; TODO implement support for this one
; }
;}
;
;thing {
; sub routine() {
; ^^bool @shared bptrx = 3000
; }
;}
;%import floats
;%import textio
;