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,31 +688,37 @@ _after:
|
|||||||
// get rid of ArrayIndexedPtrDereference in the assignment target
|
// get rid of ArrayIndexedPtrDereference in the assignment target
|
||||||
// z[i]^^ = value --> pokeX(z[i], value)
|
// z[i]^^ = value --> pokeX(z[i], value)
|
||||||
val dt = deref.inferType(program).getOrUndef()
|
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) =
|
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.isUnsignedByte) "poke" to null
|
||||||
else if (dt.isSignedByte) "poke" to DataType.UBYTE
|
else if (dt.isSignedByte) "poke" to DataType.UBYTE
|
||||||
else if (dt.isUnsignedWord) "pokew" to null
|
else if (dt.isUnsignedWord) "pokew" to null
|
||||||
else if (dt.isSignedWord) "pokew" to DataType.UWORD
|
else if (dt.isSignedWord) "pokew" to DataType.UWORD
|
||||||
else if (dt.isLong) "pokel" to null
|
else if (dt.isLong) "pokel" to null
|
||||||
else if (dt.isFloat) "pokef" to null
|
else if (dt.isFloat) "pokef" to null
|
||||||
else throw FatalAstException("can only deref a numeric or boolean pointer here")
|
else throw FatalAstException("can only deref a numeric or boolean pointer here")
|
||||||
val indexer = deref.chain.last().second!!
|
val indexer = deref.chain.last().second!!
|
||||||
val identifier = IdentifierReference(deref.chain.map { it.first }, deref.position)
|
val identifier = IdentifierReference(deref.chain.map { it.first }, deref.position)
|
||||||
val indexed = ArrayIndexedExpression(identifier, null, indexer, deref.position)
|
val indexed = ArrayIndexedExpression(identifier, null, indexer, deref.position)
|
||||||
val pokeIdent = IdentifierReference(listOf(pokeFunc), deref.position)
|
val pokeIdent = IdentifierReference(listOf(pokeFunc), deref.position)
|
||||||
val assignment = parent.parent as Assignment
|
val assignment = parent.parent as Assignment
|
||||||
val pokeCall: FunctionCallStatement
|
val pokeCall: FunctionCallStatement
|
||||||
if(cast==null) {
|
if (cast == null) {
|
||||||
pokeCall = FunctionCallStatement(pokeIdent, mutableListOf(indexed, assignment.value), false, deref.position)
|
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)
|
||||||
|
}
|
||||||
|
return listOf(IAstModification.ReplaceNode(assignment, pokeCall, assignment.parent))
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
val casted = TypecastExpression(assignment.value, cast, true, deref.position)
|
|
||||||
pokeCall = FunctionCallStatement(pokeIdent, mutableListOf(indexed, casted), false, deref.position)
|
|
||||||
}
|
|
||||||
return listOf(IAstModification.ReplaceNode(assignment, pokeCall, assignment.parent))
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
TODO("cannot translate $deref here ${deref.position}")
|
TODO("cannot translate $deref here ${deref.position}")
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ package prog8tests.compiler
|
|||||||
import io.kotest.assertions.withClue
|
import io.kotest.assertions.withClue
|
||||||
import io.kotest.core.spec.style.FunSpec
|
import io.kotest.core.spec.style.FunSpec
|
||||||
import io.kotest.engine.spec.tempdir
|
import io.kotest.engine.spec.tempdir
|
||||||
|
import io.kotest.matchers.comparables.shouldBeGreaterThanOrEqualTo
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import io.kotest.matchers.string.shouldContain
|
import io.kotest.matchers.string.shouldContain
|
||||||
@@ -1159,13 +1160,15 @@ other {
|
|||||||
|
|
||||||
^^List[10] listarray
|
^^List[10] listarray
|
||||||
listarray[3]^^.value = cx16.r0
|
listarray[3]^^.value = cx16.r0
|
||||||
|
listarray[3]^^ = 999 ; cannot assign word value to struct instance
|
||||||
}
|
}
|
||||||
}"""
|
}"""
|
||||||
val errors = ErrorReporterForTests()
|
val errors = ErrorReporterForTests()
|
||||||
compileText(VMTarget(), false, src, outputDir, errors=errors) shouldBe null
|
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[0] shouldContain "no support for"
|
||||||
errors.errors[1] 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]") {
|
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 arrayIdentifier = chain.map { it.first }
|
||||||
val symbol = definingScope.lookup(arrayIdentifier) as? VarDecl
|
val symbol = definingScope.lookup(arrayIdentifier) as? VarDecl
|
||||||
if(symbol!=null) {
|
if(symbol!=null) {
|
||||||
if(symbol.datatype.isArray)
|
if(symbol.datatype.isArray) {
|
||||||
return InferredTypes.knownFor(symbol.datatype.sub!!)
|
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)
|
else if(symbol.datatype.isPointer)
|
||||||
return InferredTypes.knownFor(symbol.datatype.dereference())
|
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 ^^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 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
|
fix passing array of structptrs to subroutine , arg type mismatches
|
||||||
disallow ^^str
|
disallow ^^str
|
||||||
|
|
||||||
|
|||||||
@@ -1,19 +1,52 @@
|
|||||||
|
|
||||||
main {
|
main {
|
||||||
|
struct Node {
|
||||||
|
bool flag
|
||||||
|
}
|
||||||
|
^^Node[10] ptrs
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
struct Node {
|
ptrs[2]^^ = 999 ; should be normal compiler error
|
||||||
ubyte weight
|
|
||||||
}
|
|
||||||
^^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
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
;%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 floats
|
||||||
;%import textio
|
;%import textio
|
||||||
;
|
;
|
||||||
|
|||||||
Reference in New Issue
Block a user