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,12 +22,12 @@ 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<VarDecl>,
private class MoveVardecls(val decls: Collection<VarDecl>,
val scope: AnonymousScope,
val sub: Subroutine) : IAstModification {
override fun perform() {

View File

@ -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)
}

View File

@ -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<Assignment> {

View File

@ -168,7 +168,7 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
memberValue
}
class Replacer(val targetStructLv: StructLiteralValue, val typecastValues: List<Expression>) : IAstModification {
class StructLvValueReplacer(val targetStructLv: StructLiteralValue, val typecastValues: List<Expression>) : 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()
}

View File

@ -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')
}
}