diff --git a/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt b/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt index c6c2f118f..9362e445f 100644 --- a/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt +++ b/compiler/src/prog8/ast/processing/AnonScopeVarsToSubroutineMover.kt @@ -22,14 +22,14 @@ class AnonScopeVarsToSubroutineMover(val errors: ErrorReporter): AstWalker() { } } if(!conflicts) - return listOf(MoveVardecl(decls, scope, sub)) + return listOf(MoveVardecls(decls, scope, sub)) } return emptyList() } - private class MoveVardecl(val decls: Collection, - val scope: AnonymousScope, - val sub: Subroutine) : IAstModification { + private class MoveVardecls(val decls: Collection, + val scope: AnonymousScope, + val sub: Subroutine) : IAstModification { override fun perform() { decls.forEach { scope.remove(it) } sub.statements.addAll(0, decls) diff --git a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt index 02296de1d..c5ec703e1 100644 --- a/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/ast/processing/AstIdentifiersChecker.kt @@ -82,8 +82,8 @@ internal class AstIdentifiersChecker(private val program: Program, return super.visit(decl) } - if(decl.value !is StructLiteralValue) { - errors.err("requires struct literal value to initialize a struct variable", decl.value?.position ?: decl.position) + if(decl.value != null && decl.value !is StructLiteralValue) { + errors.err("initializing requires struct literal value", decl.value?.position ?: decl.position) return super.visit(decl) } diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index 0668e7789..d1e3deb35 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -225,11 +225,17 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi val slv = structAssignment.value as? StructLiteralValue if(slv==null || slv.values.size != struct.numberOfElements) - return emptyList() // this error should be reported + throw FatalAstException("element count mismatch") - - println("STRUCT={...} ${structAssignment.position}") - return emptyList() // TODO + return struct.statements.zip(slv.values).map { (targetDecl, sourceValue) -> + targetDecl as VarDecl + val mangled = mangledStructMemberName(identifierName, targetDecl.name) + val idref = IdentifierReference(listOf(mangled), structAssignment.position) + val assign = Assignment(AssignTarget(null, idref, null, null, structAssignment.position), + null, sourceValue, sourceValue.position) + assign.linkParents(structAssignment) + assign + } } private fun flattenStructAssignmentFromIdentifier(structAssignment: Assignment, program: Program): List { diff --git a/compiler/src/prog8/ast/processing/TypecastsAdder.kt b/compiler/src/prog8/ast/processing/TypecastsAdder.kt index 33c376c49..df955185d 100644 --- a/compiler/src/prog8/ast/processing/TypecastsAdder.kt +++ b/compiler/src/prog8/ast/processing/TypecastsAdder.kt @@ -168,7 +168,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke memberValue } - class Replacer(val targetStructLv: StructLiteralValue, val typecastValues: List) : IAstModification { + class StructLvValueReplacer(val targetStructLv: StructLiteralValue, val typecastValues: List) : IAstModification { override fun perform() { targetStructLv.values = typecastValues typecastValues.forEach { it.linkParents(targetStructLv) } @@ -176,7 +176,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke } return if(structLv.values.zip(newValues).any { (v1, v2) -> v1 !== v2}) - listOf(Replacer(structLv, newValues)) + listOf(StructLvValueReplacer(structLv, newValues)) else emptyList() } diff --git a/examples/test.p8 b/examples/test.p8 index e2d0d503f..d18d5a494 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -15,7 +15,19 @@ main { Color 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 + c64scr.print_uw(c.red) + c64.CHROUT('\n') + c64scr.print_uw(c.green) + c64.CHROUT('\n') + c64scr.print_uw(c.blue) + c64.CHROUT('\n') + c= {111,222,333} + c64scr.print_uw(c.red) + c64.CHROUT('\n') + c64scr.print_uw(c.green) + c64.CHROUT('\n') + c64scr.print_uw(c.blue) + c64.CHROUT('\n') } }