mirror of
https://github.com/irmen/prog8.git
synced 2024-10-19 07:23:56 +00:00
error when struct literal value element count doesn't match struct members in assignment
This commit is contained in:
parent
97d36243f2
commit
771ac7aba7
@ -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
|
||||
|
@ -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
|
||||
|
@ -356,16 +356,26 @@ 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)
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
super.visit(assignment)
|
||||
}
|
||||
|
@ -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!!
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user