mirror of
https://github.com/irmen/prog8.git
synced 2025-01-28 02:34:01 +00:00
fix multi-var decl in nested scopes
This commit is contained in:
parent
ae3b2ddf5f
commit
e076b3aedc
@ -1,9 +1,12 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.*
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.FatalAstException
|
||||
import prog8.ast.base.SyntaxError
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.findParentNode
|
||||
import prog8.ast.statements.*
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
@ -113,11 +116,26 @@ class AstPreprocessor(val program: Program,
|
||||
movements.add(IAstModification.InsertFirst(decl, parentscope))
|
||||
replacements.add(IAstModification.Remove(decl, scope))
|
||||
} else {
|
||||
val declToInsert: VarDecl
|
||||
if(decl.names.size>1) {
|
||||
// we need to handle multi-decl here too, the desugarer maybe has not processed it here yet...
|
||||
TODO("handle multi-decl movement")
|
||||
if(decl.value!=null) {
|
||||
decl.names.forEach { name ->
|
||||
val target = AssignTarget(IdentifierReference(listOf(name), decl.position), null, null, decl.position)
|
||||
val assign = Assignment(target.copy(), decl.value!!.copy(), AssignmentOrigin.VARINIT, decl.position)
|
||||
replacements.add(IAstModification.InsertAfter(decl, assign, scope))
|
||||
}
|
||||
replacements.add(IAstModification.Remove(decl, scope))
|
||||
decl.value = null
|
||||
decl.allowInitializeWithZero = false
|
||||
declToInsert = decl
|
||||
} else {
|
||||
// just move it to the defining scope
|
||||
replacements.add(IAstModification.Remove(decl, scope))
|
||||
declToInsert = decl
|
||||
}
|
||||
} else {
|
||||
val declToInsert: VarDecl
|
||||
// handle declaration of a single variable
|
||||
if(decl.value!=null && decl.datatype in NumericDatatypes) {
|
||||
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
|
||||
val assign = Assignment(target, decl.value!!, AssignmentOrigin.VARINIT, decl.position)
|
||||
@ -129,8 +147,8 @@ class AstPreprocessor(val program: Program,
|
||||
replacements.add(IAstModification.Remove(decl, scope))
|
||||
declToInsert = decl
|
||||
}
|
||||
movements.add(IAstModification.InsertFirst(declToInsert, parentscope))
|
||||
}
|
||||
movements.add(IAstModification.InsertFirst(declToInsert, parentscope))
|
||||
}
|
||||
}
|
||||
return movements + replacements
|
||||
@ -152,20 +170,6 @@ class AstPreprocessor(val program: Program,
|
||||
}
|
||||
|
||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||
if(decl.names.size>1) {
|
||||
// note: the desugaring of a multi-variable vardecl has to be done here
|
||||
// and not in CodeDesugarer, that one is too late (identifiers can't be found otherwise)
|
||||
if(decl.datatype !in NumericDatatypes)
|
||||
errors.err("can only multi declare numeric variables", decl.position)
|
||||
return if(errors.noErrors()) {
|
||||
// desugar into individual vardecl per name.
|
||||
decl.desugarMultiDecl().map {
|
||||
IAstModification.InsertAfter(decl, it, parent as IStatementContainer)
|
||||
} + IAstModification.Remove(decl, parent as IStatementContainer)
|
||||
} else
|
||||
noModifications
|
||||
}
|
||||
|
||||
val nextAssignment = decl.nextSibling() as? Assignment
|
||||
if(nextAssignment!=null && nextAssignment.origin!=AssignmentOrigin.VARINIT) {
|
||||
// check if it's a proper initializer assignment for the variable
|
||||
|
@ -1,6 +1,7 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.IFunctionCall
|
||||
import prog8.ast.IStatementContainer
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.expressions.ArrayLiteral
|
||||
@ -12,10 +13,7 @@ import prog8.ast.statements.VarDecl
|
||||
import prog8.ast.statements.WhenChoice
|
||||
import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.ICompilationTarget
|
||||
import prog8.code.core.IErrorReporter
|
||||
import prog8.code.core.SplitWordArrayTypes
|
||||
import prog8.code.core.*
|
||||
|
||||
|
||||
internal class LiteralsToAutoVars(private val program: Program,
|
||||
@ -73,4 +71,20 @@ internal class LiteralsToAutoVars(private val program: Program,
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
||||
if(decl.names.size>1) {
|
||||
// note: the desugaring of a multi-variable vardecl has to be done here
|
||||
// and not in CodeDesugarer, that one is too late (identifiers can't be found otherwise)
|
||||
if(decl.datatype !in NumericDatatypes)
|
||||
errors.err("can only multi declare numeric variables", decl.position)
|
||||
if(errors.noErrors()) {
|
||||
// desugar into individual vardecl per name.
|
||||
return decl.desugarMultiDecl().map {
|
||||
IAstModification.InsertAfter(decl, it, parent as IStatementContainer)
|
||||
} + IAstModification.Remove(decl, parent as IStatementContainer)
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
@ -131,7 +131,10 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
||||
output(" @zp")
|
||||
if(decl.sharedWithAsm)
|
||||
output(" @shared")
|
||||
output(" ${decl.name} ")
|
||||
if(decl.names.size>1)
|
||||
output(decl.names.joinToString(prefix=" "))
|
||||
else
|
||||
output(" ${decl.name} ")
|
||||
if(decl.value!=null) {
|
||||
output("= ")
|
||||
decl.value?.accept(this)
|
||||
|
@ -2,8 +2,6 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
- fix multi-decl in for loops, see AstPreprocessor TODO("handle multi-decl movement")
|
||||
|
||||
- [on branch: shortcircuit] investigate McCarthy evaluation again? this may also reduce code size perhaps for things like if a>4 or a<2 ....
|
||||
|
||||
...
|
||||
@ -80,6 +78,7 @@ What if we were to re-introduce Structs in prog8? Some thoughts:
|
||||
Other language/syntax features to think about
|
||||
---------------------------------------------
|
||||
|
||||
- underscores in numeric literals for grouping
|
||||
- chained comparisons `10<x<20` , `x==y==z` (desugars to `10<x and x<20`, `x==y and y==z`) BUT this changes the semantics of what it is right now ! (x==(y==z) 0> x==true)
|
||||
- postincrdecr as expression, preincrdecr expression (`y = x++`, `y = ++x`) .... is this even possible, expression with side effects like this?
|
||||
- negative array index to refer to an element from the end of the array. Python `[-1]` or Raku syntax `[\*-1]` , `[\*/2]` .... \*=size of the array
|
||||
|
@ -5,17 +5,21 @@ main {
|
||||
const ubyte VAL = 11
|
||||
sub start() {
|
||||
uword w
|
||||
ubyte @zp x,y,z = 99
|
||||
|
||||
txt.print_ub(x)
|
||||
txt.spc()
|
||||
txt.print_ub(y)
|
||||
txt.spc()
|
||||
txt.print_ub(z)
|
||||
txt.spc()
|
||||
txt.print_uw(w)
|
||||
txt.nl()
|
||||
if x==y==z
|
||||
for w in 0 to 20 {
|
||||
ubyte x,y,z=13
|
||||
|
||||
txt.print_ub(x)
|
||||
txt.spc()
|
||||
txt.print_ub(y)
|
||||
txt.spc()
|
||||
txt.print_ub(z)
|
||||
txt.spc()
|
||||
txt.print_uw(w)
|
||||
txt.nl()
|
||||
x++
|
||||
y++
|
||||
z++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user