mirror of
https://github.com/irmen/prog8.git
synced 2025-02-04 02:30:19 +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
|
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.FatalAstException
|
||||||
import prog8.ast.base.SyntaxError
|
import prog8.ast.base.SyntaxError
|
||||||
import prog8.ast.expressions.*
|
import prog8.ast.expressions.*
|
||||||
|
import prog8.ast.findParentNode
|
||||||
import prog8.ast.statements.*
|
import prog8.ast.statements.*
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
@ -113,11 +116,26 @@ class AstPreprocessor(val program: Program,
|
|||||||
movements.add(IAstModification.InsertFirst(decl, parentscope))
|
movements.add(IAstModification.InsertFirst(decl, parentscope))
|
||||||
replacements.add(IAstModification.Remove(decl, scope))
|
replacements.add(IAstModification.Remove(decl, scope))
|
||||||
} else {
|
} else {
|
||||||
|
val declToInsert: VarDecl
|
||||||
if(decl.names.size>1) {
|
if(decl.names.size>1) {
|
||||||
// we need to handle multi-decl here too, the desugarer maybe has not processed it here yet...
|
// 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 {
|
} else {
|
||||||
val declToInsert: VarDecl
|
// handle declaration of a single variable
|
||||||
if(decl.value!=null && decl.datatype in NumericDatatypes) {
|
if(decl.value!=null && decl.datatype in NumericDatatypes) {
|
||||||
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
|
val target = AssignTarget(IdentifierReference(listOf(decl.name), decl.position), null, null, decl.position)
|
||||||
val assign = Assignment(target, decl.value!!, AssignmentOrigin.VARINIT, 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))
|
replacements.add(IAstModification.Remove(decl, scope))
|
||||||
declToInsert = decl
|
declToInsert = decl
|
||||||
}
|
}
|
||||||
movements.add(IAstModification.InsertFirst(declToInsert, parentscope))
|
|
||||||
}
|
}
|
||||||
|
movements.add(IAstModification.InsertFirst(declToInsert, parentscope))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return movements + replacements
|
return movements + replacements
|
||||||
@ -152,20 +170,6 @@ class AstPreprocessor(val program: Program,
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun after(decl: VarDecl, parent: Node): Iterable<IAstModification> {
|
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
|
val nextAssignment = decl.nextSibling() as? Assignment
|
||||||
if(nextAssignment!=null && nextAssignment.origin!=AssignmentOrigin.VARINIT) {
|
if(nextAssignment!=null && nextAssignment.origin!=AssignmentOrigin.VARINIT) {
|
||||||
// check if it's a proper initializer assignment for the variable
|
// check if it's a proper initializer assignment for the variable
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package prog8.compiler.astprocessing
|
package prog8.compiler.astprocessing
|
||||||
|
|
||||||
import prog8.ast.IFunctionCall
|
import prog8.ast.IFunctionCall
|
||||||
|
import prog8.ast.IStatementContainer
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
import prog8.ast.Program
|
import prog8.ast.Program
|
||||||
import prog8.ast.expressions.ArrayLiteral
|
import prog8.ast.expressions.ArrayLiteral
|
||||||
@ -12,10 +13,7 @@ import prog8.ast.statements.VarDecl
|
|||||||
import prog8.ast.statements.WhenChoice
|
import prog8.ast.statements.WhenChoice
|
||||||
import prog8.ast.walk.AstWalker
|
import prog8.ast.walk.AstWalker
|
||||||
import prog8.ast.walk.IAstModification
|
import prog8.ast.walk.IAstModification
|
||||||
import prog8.code.core.DataType
|
import prog8.code.core.*
|
||||||
import prog8.code.core.ICompilationTarget
|
|
||||||
import prog8.code.core.IErrorReporter
|
|
||||||
import prog8.code.core.SplitWordArrayTypes
|
|
||||||
|
|
||||||
|
|
||||||
internal class LiteralsToAutoVars(private val program: Program,
|
internal class LiteralsToAutoVars(private val program: Program,
|
||||||
@ -73,4 +71,20 @@ internal class LiteralsToAutoVars(private val program: Program,
|
|||||||
}
|
}
|
||||||
return noModifications
|
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")
|
output(" @zp")
|
||||||
if(decl.sharedWithAsm)
|
if(decl.sharedWithAsm)
|
||||||
output(" @shared")
|
output(" @shared")
|
||||||
output(" ${decl.name} ")
|
if(decl.names.size>1)
|
||||||
|
output(decl.names.joinToString(prefix=" "))
|
||||||
|
else
|
||||||
|
output(" ${decl.name} ")
|
||||||
if(decl.value!=null) {
|
if(decl.value!=null) {
|
||||||
output("= ")
|
output("= ")
|
||||||
decl.value?.accept(this)
|
decl.value?.accept(this)
|
||||||
|
@ -2,8 +2,6 @@
|
|||||||
TODO
|
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 ....
|
- [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
|
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)
|
- 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?
|
- 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
|
- 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
|
const ubyte VAL = 11
|
||||||
sub start() {
|
sub start() {
|
||||||
uword w
|
uword w
|
||||||
ubyte @zp x,y,z = 99
|
|
||||||
|
|
||||||
txt.print_ub(x)
|
for w in 0 to 20 {
|
||||||
txt.spc()
|
ubyte x,y,z=13
|
||||||
txt.print_ub(y)
|
|
||||||
txt.spc()
|
txt.print_ub(x)
|
||||||
txt.print_ub(z)
|
txt.spc()
|
||||||
txt.spc()
|
txt.print_ub(y)
|
||||||
txt.print_uw(w)
|
txt.spc()
|
||||||
txt.nl()
|
txt.print_ub(z)
|
||||||
if x==y==z
|
txt.spc()
|
||||||
|
txt.print_uw(w)
|
||||||
|
txt.nl()
|
||||||
x++
|
x++
|
||||||
|
y++
|
||||||
|
z++
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user