error when struct literal value element count doesn't match struct members in assignment

This commit is contained in:
Irmen de Jong 2020-03-20 23:14:03 +01:00
parent 97d36243f2
commit 771ac7aba7
6 changed files with 41 additions and 14 deletions

View File

@ -3,9 +3,9 @@ package prog8.ast
import prog8.ast.base.*
import prog8.ast.expressions.Expression
import prog8.ast.expressions.IdentifierReference
import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModifyingVisitor
import prog8.ast.processing.IAstVisitor
import prog8.ast.processing.AstWalker
import prog8.ast.statements.*
import prog8.functions.BuiltinFunctions
import java.nio.file.Path

View File

@ -3,9 +3,9 @@ package prog8.ast.expressions
import prog8.ast.*
import prog8.ast.antlr.escape
import prog8.ast.base.*
import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModifyingVisitor
import prog8.ast.processing.IAstVisitor
import prog8.ast.processing.AstWalker
import prog8.ast.statements.*
import prog8.compiler.target.CompilationTarget
import prog8.functions.BuiltinFunctions

View File

@ -356,14 +356,24 @@ internal class AstChecker(private val program: Program,
}
}
val sourceIdent = assignment.value as? IdentifierReference
val targetIdent = assignment.target.identifier
if(sourceIdent!=null && targetIdent!=null) {
val sourceVar = sourceIdent.targetVarDecl(program.namespace)
if(targetIdent!=null) {
val targetVar = targetIdent.targetVarDecl(program.namespace)
if(sourceVar?.struct!=null && targetVar?.struct!=null) {
if(sourceVar.struct!==targetVar.struct)
errors.err("assignment of different struct types", assignment.position)
if(targetVar?.struct != null) {
val sourceStructLv = assignment.value as? StructLiteralValue
if (sourceStructLv != null) {
if (sourceStructLv.values.size != targetVar.struct?.numberOfElements)
errors.err("number of elements doesn't match struct definition", sourceStructLv.position)
} else {
val sourceIdent = assignment.value as? IdentifierReference
if (sourceIdent != null) {
val sourceVar = sourceIdent.targetVarDecl(program.namespace)
if (sourceVar?.struct != null) {
if (sourceVar.struct !== targetVar.struct)
errors.err("assignment of different struct types", assignment.position)
}
}
}
}
}

View File

@ -179,10 +179,11 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
// struct assignments will be flattened (if it's not a struct literal)
if (valuetype == DataType.STRUCT && targettype == DataType.STRUCT) {
if (assg.value is StructLiteralValue)
return assg // do NOT flatten it at this point!! (the compiler will take care if it, later, if needed)
val assignments = flattenStructAssignmentFromIdentifier(assg, program) // 'structvar1 = structvar2'
val assignments = if (assg.value is StructLiteralValue) {
flattenStructAssignmentFromStructLiteral(assg, program) // 'structvar = { ..... } '
} else {
flattenStructAssignmentFromIdentifier(assg, program) // 'structvar1 = structvar2'
}
return if (assignments.isEmpty()) {
// something went wrong (probably incompatible struct types)
// we'll get an error later from the AstChecker
@ -216,6 +217,20 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
return assg
}
private fun flattenStructAssignmentFromStructLiteral(structAssignment: Assignment, program: Program): List<Assignment> {
val identifier = structAssignment.target.identifier!!
val identifierName = identifier.nameInSource.single()
val targetVar = identifier.targetVarDecl(program.namespace)!!
val struct = targetVar.struct!!
val slv = structAssignment.value as? StructLiteralValue
if(slv==null || slv.values.size != struct.numberOfElements)
return emptyList() // this error should be reported
println("STRUCT={...} ${structAssignment.position}")
return emptyList() // TODO
}
private fun flattenStructAssignmentFromIdentifier(structAssignment: Assignment, program: Program): List<Assignment> {
val identifier = structAssignment.target.identifier!!

View File

@ -3,9 +3,9 @@ package prog8.ast.statements
import prog8.ast.*
import prog8.ast.base.*
import prog8.ast.expressions.*
import prog8.ast.processing.AstWalker
import prog8.ast.processing.IAstModifyingVisitor
import prog8.ast.processing.IAstVisitor
import prog8.ast.processing.AstWalker
sealed class Statement : Node {

View File

@ -13,7 +13,9 @@ main {
sub start() {
Color c = {1,2,3}
c= {1,2,3}
Color c2 = {3,4,5}
c=c2
c= {1,2,3} ; TODO fix compiler crash AssemblyError: struct literal value assignment should have been flattened
}
}