mirror of
https://github.com/irmen/prog8.git
synced 2025-11-02 13:16:07 +00:00
fix countries[2]^^ = 0 compiler crash
This commit is contained in:
@@ -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}")
|
||||
}
|
||||
|
||||
@@ -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]") {
|
||||
|
||||
@@ -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())
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
;
|
||||
|
||||
Reference in New Issue
Block a user