now properly compile assignment of struct literal value to struct variable (outside of vardecl)

This commit is contained in:
Irmen de Jong 2020-03-20 23:21:52 +01:00
parent 771ac7aba7
commit 270ea54ff7
5 changed files with 31 additions and 13 deletions

View File

@ -22,14 +22,14 @@ class AnonScopeVarsToSubroutineMover(val errors: ErrorReporter): AstWalker() {
} }
} }
if(!conflicts) if(!conflicts)
return listOf(MoveVardecl(decls, scope, sub)) return listOf(MoveVardecls(decls, scope, sub))
} }
return emptyList() return emptyList()
} }
private class MoveVardecl(val decls: Collection<VarDecl>, private class MoveVardecls(val decls: Collection<VarDecl>,
val scope: AnonymousScope, val scope: AnonymousScope,
val sub: Subroutine) : IAstModification { val sub: Subroutine) : IAstModification {
override fun perform() { override fun perform() {
decls.forEach { scope.remove(it) } decls.forEach { scope.remove(it) }
sub.statements.addAll(0, decls) sub.statements.addAll(0, decls)

View File

@ -82,8 +82,8 @@ internal class AstIdentifiersChecker(private val program: Program,
return super.visit(decl) return super.visit(decl)
} }
if(decl.value !is StructLiteralValue) { if(decl.value != null && decl.value !is StructLiteralValue) {
errors.err("requires struct literal value to initialize a struct variable", decl.value?.position ?: decl.position) errors.err("initializing requires struct literal value", decl.value?.position ?: decl.position)
return super.visit(decl) return super.visit(decl)
} }

View File

@ -225,11 +225,17 @@ internal class StatementReorderer(private val program: Program): IAstModifyingVi
val slv = structAssignment.value as? StructLiteralValue val slv = structAssignment.value as? StructLiteralValue
if(slv==null || slv.values.size != struct.numberOfElements) if(slv==null || slv.values.size != struct.numberOfElements)
return emptyList() // this error should be reported throw FatalAstException("element count mismatch")
return struct.statements.zip(slv.values).map { (targetDecl, sourceValue) ->
println("STRUCT={...} ${structAssignment.position}") targetDecl as VarDecl
return emptyList() // TODO 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<Assignment> { private fun flattenStructAssignmentFromIdentifier(structAssignment: Assignment, program: Program): List<Assignment> {

View File

@ -168,7 +168,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
memberValue memberValue
} }
class Replacer(val targetStructLv: StructLiteralValue, val typecastValues: List<Expression>) : IAstModification { class StructLvValueReplacer(val targetStructLv: StructLiteralValue, val typecastValues: List<Expression>) : IAstModification {
override fun perform() { override fun perform() {
targetStructLv.values = typecastValues targetStructLv.values = typecastValues
typecastValues.forEach { it.linkParents(targetStructLv) } 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}) return if(structLv.values.zip(newValues).any { (v1, v2) -> v1 !== v2})
listOf(Replacer(structLv, newValues)) listOf(StructLvValueReplacer(structLv, newValues))
else else
emptyList() emptyList()
} }

View File

@ -15,7 +15,19 @@ main {
Color c = {1,2,3} Color c = {1,2,3}
Color c2 = {3,4,5} Color c2 = {3,4,5}
c=c2 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')
} }
} }