mirror of
https://github.com/irmen/prog8.git
synced 2024-12-26 14:29:35 +00:00
now properly compile assignment of struct literal value to struct variable (outside of vardecl)
This commit is contained in:
parent
771ac7aba7
commit
270ea54ff7
@ -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<VarDecl>,
|
||||
val scope: AnonymousScope,
|
||||
val sub: Subroutine) : IAstModification {
|
||||
private class MoveVardecls(val decls: Collection<VarDecl>,
|
||||
val scope: AnonymousScope,
|
||||
val sub: Subroutine) : IAstModification {
|
||||
override fun perform() {
|
||||
decls.forEach { scope.remove(it) }
|
||||
sub.statements.addAll(0, decls)
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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> {
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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')
|
||||
}
|
||||
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user