diff --git a/compiler/src/prog8/buildversion/BuildVersion.kt b/compiler/src/prog8/buildversion/BuildVersion.kt index 33051e1c2..7d77c3590 100644 --- a/compiler/src/prog8/buildversion/BuildVersion.kt +++ b/compiler/src/prog8/buildversion/BuildVersion.kt @@ -5,11 +5,11 @@ package prog8.buildversion */ const val MAVEN_GROUP = "prog8" const val MAVEN_NAME = "compiler" -const val VERSION = "9.7-SNAPSHOT" -const val GIT_REVISION = 4212 -const val GIT_SHA = "f81061dd42403294e7cb5ebd3c0ed57d6c57c3d5" -const val GIT_DATE = "2023-11-18T00:03:34Z" -const val GIT_BRANCH = "continue-stmt" -const val BUILD_DATE = "2023-11-19T16:19:02Z" -const val BUILD_UNIX_TIME = 1700410742198L +const val VERSION = "9.7" +const val GIT_REVISION = 4286 +const val GIT_SHA = "cfc9c15f1e9fe96940e170fb14ad3a957109977c" +const val GIT_DATE = "2023-12-10T15:22:00Z" +const val GIT_BRANCH = "master" +const val BUILD_DATE = "2023-12-10T15:44:19Z" +const val BUILD_UNIX_TIME = 1702223059842L const val DIRTY = 1 diff --git a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt index 1da3c2ced..f12e2d91f 100644 --- a/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt +++ b/compiler/src/prog8/compiler/astprocessing/CodeDesugarer.kt @@ -294,10 +294,22 @@ _after: val assigns = mutableListOf(assign) var lastChained: ChainedAssignment = chainedAssignment var pc: ChainedAssignment? = chainedAssignment - while(pc!=null) { - lastChained = pc - assigns.add(0, Assignment(pc.target.copy(), assign.value.copy(), assign.origin, pc.position)) - pc = pc.parent as? ChainedAssignment + + if(assign.value.isSimple) { + // simply copy the RHS value to each component's assignment + while (pc != null) { + lastChained = pc + assigns.add(Assignment(pc.target.copy(), assign.value.copy(), assign.origin, pc.position)) + pc = pc.parent as? ChainedAssignment + } + } else if(pc!=null) { + // need to evaluate RHS once and reuse that in each component's assignment + val firstComponentAsValue = assign.target.toExpression() + while (pc != null) { + lastChained = pc + assigns.add(Assignment(pc.target.copy(), firstComponentAsValue.copy(), assign.origin, pc.position)) + pc = pc.parent as? ChainedAssignment + } } return listOf(IAstModification.ReplaceNode(lastChained, AnonymousScope(assigns, chainedAssignment.position), lastChained.parent)) diff --git a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt index c7634161c..c3e38151d 100644 --- a/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt +++ b/compiler/src/prog8/compiler/astprocessing/LiteralsToAutoVars.kt @@ -81,7 +81,7 @@ internal class LiteralsToAutoVars(private val program: Program, if(errors.noErrors()) { // desugar into individual vardecl per name. return decl.desugarMultiDecl().map { - IAstModification.InsertAfter(decl, it, parent as IStatementContainer) + IAstModification.InsertBefore(decl, it, parent as IStatementContainer) } + IAstModification.Remove(decl, parent as IStatementContainer) } } diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index 42ef3fdbc..77b73ddd4 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -434,7 +434,7 @@ main { val vars = st.filterIsInstance() vars.size shouldBe 7 vars.all { it.names.size<=1 } shouldBe true - vars.map { it.name } shouldBe listOf("s","r","q","z","y","x","w") + vars.map { it.name }.toSet() shouldBe setOf("s","r","q","z","y","x","w") val forloop = st.single { it is ForLoop } as ForLoop forloop.body.statements[0] shouldBe instanceOf() forloop.body.statements[1] shouldBe instanceOf() diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 0731a4fd9..8ce695e77 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -317,13 +317,34 @@ class VarDecl(val type: VarDeclType, this.arraysize?.referencesIdentifier(nameInSource)==true fun desugarMultiDecl(): List { - return names.map { - val copy = VarDecl(type, origin, declaredDatatype, zeropage, arraysize?.copy(), it, emptyList(), value?.copy(), + if(value?.isSimple==true) { + // just copy the initialization value to a separata vardecl for each component + return names.map { + val copy = VarDecl(type, origin, declaredDatatype, zeropage, arraysize?.copy(), it, emptyList(), value?.copy(), + isArray, sharedWithAsm, splitArray, position) + copy.allowInitializeWithZero = this.allowInitializeWithZero + copy + } + } else { + // evaluate the value once in the vardecl for the first component, and set the other components to the first + val first = VarDecl(type, origin, declaredDatatype, zeropage, arraysize?.copy(), names[0], emptyList(), value?.copy(), isArray, sharedWithAsm, splitArray, position) - copy.allowInitializeWithZero = this.allowInitializeWithZero - copy + first.allowInitializeWithZero = this.allowInitializeWithZero + val firstVar = firstVarAsValue(first) + return listOf(first) + names.drop(1 ).map { + val copy = VarDecl(type, origin, declaredDatatype, zeropage, arraysize?.copy(), it, emptyList(), firstVar.copy(), + isArray, sharedWithAsm, splitArray, position) + copy.allowInitializeWithZero = this.allowInitializeWithZero + copy + } } } + + private fun firstVarAsValue(first: VarDecl): Expression { + if(first.isArray || first.type!=VarDeclType.VAR) + throw FatalAstException("invalid multi decl type $first") + return IdentifierReference(listOf(first.name), first.position) + } } class ArrayIndex(var indexExpr: Expression, diff --git a/examples/test.p8 b/examples/test.p8 index 705953b6e..b0baed729 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,44 +1,24 @@ %import textio -%import string +%import math %zeropage basicsafe main { sub start() { - cx16.set_chrin_keyhandler(0, &keystroke_handler) - cbm.CHRIN() - } + ubyte x,y,z = math.rnd() - sub keystroke_handler() -> ubyte { - %asm {{ - sta cx16.r0L - }} - uword cmdxx = grab_cmdline() - if_cs { - ; first entry, decide if we want to override - if cx16.r0L==9 { - ; intercept TAB - sys.clear_carry() - return 0 - } - sys.set_carry() - return 0 - } else { - if cx16.r0L==9 { - %asm {{ - brk ; BOOM - }} - uword cmd = grab_cmdline() - if cmd and cmd[0] { - ;cx16.r5++ - } - return '!' - } - return 0 ; eat all other characters - } + txt.print_ub(x) + txt.nl() + txt.print_ub(y) + txt.nl() + txt.print_ub(z) + txt.nl() - sub grab_cmdline() -> uword { - cx16.r9++ - return $5000 - } + x=y=z=math.rnd() + txt.print_ub(x) + txt.nl() + txt.print_ub(y) + txt.nl() + txt.print_ub(z) + txt.nl() } }