From 771ac7aba770bdebaa6925f9b414726f17edba14 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 20 Mar 2020 23:14:03 +0100 Subject: [PATCH] error when struct literal value element count doesn't match struct members in assignment --- compiler/src/prog8/ast/AstToplevel.kt | 2 +- .../prog8/ast/expressions/AstExpressions.kt | 2 +- .../src/prog8/ast/processing/AstChecker.kt | 22 +++++++++++++----- .../ast/processing/StatementReorderer.kt | 23 +++++++++++++++---- .../src/prog8/ast/statements/AstStatements.kt | 2 +- examples/test.p8 | 4 +++- 6 files changed, 41 insertions(+), 14 deletions(-) diff --git a/compiler/src/prog8/ast/AstToplevel.kt b/compiler/src/prog8/ast/AstToplevel.kt index 6f70598fb..06bf59f0b 100644 --- a/compiler/src/prog8/ast/AstToplevel.kt +++ b/compiler/src/prog8/ast/AstToplevel.kt @@ -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 diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index 96d0b0129..1757d3b20 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -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 diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index 09038ef33..ce5b89e82 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -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) + } + } + } } } diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index eebe867ab..0668e7789 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -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 { + 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 { val identifier = structAssignment.target.identifier!! diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index e3d5a0920..cb768df7b 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -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 { diff --git a/examples/test.p8 b/examples/test.p8 index 94b3b73fe..e2d0d503f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -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 } }