From d56565be258da0032f6b2c24340ef617a695e6b0 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 9 Dec 2023 12:32:41 +0100 Subject: [PATCH] fix multi-var decl --- .../astprocessing/AstIdentifiersChecker.kt | 20 ++++---- compiler/test/ast/TestVariousCompilerAst.kt | 50 +++++++++++++++++++ .../src/prog8/ast/antlr/Antlr2Kotlin.kt | 2 +- 3 files changed, 62 insertions(+), 10 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt index 34c2e7d56..bd186cc23 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstIdentifiersChecker.kt @@ -53,16 +53,18 @@ internal class AstIdentifiersChecker(private val errors: IErrorReporter, if(decl.name in BuiltinFunctions) errors.err("builtin function cannot be redefined", decl.position) - val existingInSameScope = decl.definingScope.lookup(listOf(decl.name)) - if(existingInSameScope!=null && existingInSameScope!==decl) - nameError(decl.name, decl.position, existingInSameScope) + if(decl.names.size<2) { + val existingInSameScope = decl.definingScope.lookup(listOf(decl.name)) + if (existingInSameScope != null && existingInSameScope !== decl) + nameError(decl.name, decl.position, existingInSameScope) - val existingOuter = decl.parent.definingScope.lookup(listOf(decl.name)) - if (existingOuter != null && existingOuter !== decl && existingOuter is VarDecl) { - if(existingOuter.parent!==decl.parent) - nameShadowWarning(decl.name, decl.position, existingOuter) - else - nameError(decl.name, decl.position, existingOuter) + val existingOuter = decl.parent.definingScope.lookup(listOf(decl.name)) + if (existingOuter != null && existingOuter !== decl && existingOuter is VarDecl) { + if (existingOuter.parent !== decl.parent) + nameShadowWarning(decl.name, decl.position, existingOuter) + else + nameError(decl.name, decl.position, existingOuter) + } } if(decl.definingBlock.name==decl.name) diff --git a/compiler/test/ast/TestVariousCompilerAst.kt b/compiler/test/ast/TestVariousCompilerAst.kt index 65c1fb3c1..42ef3fdbc 100644 --- a/compiler/test/ast/TestVariousCompilerAst.kt +++ b/compiler/test/ast/TestVariousCompilerAst.kt @@ -8,6 +8,7 @@ import io.kotest.matchers.types.instanceOf import prog8.ast.IFunctionCall import prog8.ast.expressions.* import prog8.ast.statements.Assignment +import prog8.ast.statements.ForLoop import prog8.ast.statements.InlineAssembly import prog8.ast.statements.VarDecl import prog8.code.core.DataType @@ -390,5 +391,54 @@ main { }""" compileText(VMTarget(), optimize=false, src, writeAssembly=false) shouldNotBe null } + + test("multi-var decls in scope with initializer") { + val src=""" +main { + sub start() { + ubyte w + + for w in 0 to 20 { + ubyte @zp x,y,z=13 + ubyte q,r,s + x++ + y++ + z++ + } + } +}""" + val result = compileText(VMTarget(), optimize = false, src, writeAssembly = false)!! + val st = result.compilerAst.entrypoint.statements + /* + sub start () { + ubyte s + s = 0 + ubyte r + r = 0 + ubyte q + q = 0 + ubyte @zp z + ubyte @zp y + ubyte @zp x + ubyte w + for w in 0 to 20 step 1 { + z = 13 + y = 13 + x = 13 + x++ + y++ + z++ + } + } + */ + 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") + val forloop = st.single { it is ForLoop } as ForLoop + forloop.body.statements[0] shouldBe instanceOf() + forloop.body.statements[1] shouldBe instanceOf() + forloop.body.statements[2] shouldBe instanceOf() + } }) diff --git a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt index efada3315..d0848091a 100644 --- a/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt +++ b/compilerAst/src/prog8/ast/antlr/Antlr2Kotlin.kt @@ -660,7 +660,7 @@ private fun VardeclContext.toAst(type: VarDeclType, value: Expression?): VarDecl zp, arrayindex()?.toAst(), name, - identifiers.map { it.NAME().text }, + if(identifiers.size==1) emptyList() else identifiers.map { it.NAME().text }, value, ARRAYSIG() != null || arrayindex() != null, options.SHARED().isNotEmpty(),