mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +00:00
fix invalid range size check when stepval is not a positive integer
This commit is contained in:
parent
4ac169b210
commit
b438d8aec0
@ -146,7 +146,7 @@ internal class ConstantIdentifierReplacer(private val program: Program, private
|
||||
// convert the initializer range expression to an actual array
|
||||
val declArraySize = decl.arraysize?.constIndex()
|
||||
if(declArraySize!=null && declArraySize!=rangeExpr.size())
|
||||
errors.err("range expression size doesn't match declared array size", decl.value?.position!!)
|
||||
errors.err("range expression size (${rangeExpr.size()}) doesn't match declared array size ($declArraySize)", decl.value?.position!!)
|
||||
val constRange = rangeExpr.toConstantIntegerRange()
|
||||
if(constRange!=null) {
|
||||
val eltType = rangeExpr.inferType(program).getOr(DataType.UBYTE)
|
||||
|
@ -255,7 +255,7 @@ fun determineCompilationOptions(program: Program, compTarget: ICompilationTarget
|
||||
private fun processAst(program: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
||||
// perform initial syntax checks and processings
|
||||
println("Processing for target ${compilerOptions.compTarget.name}...")
|
||||
program.preprocessAst()
|
||||
program.preprocessAst(program)
|
||||
program.checkIdentifiers(errors, compilerOptions)
|
||||
errors.report()
|
||||
// TODO: turning char literals into UBYTEs via an encoding should really happen in code gen - but for that we'd need DataType.CHAR
|
||||
|
@ -65,8 +65,8 @@ internal fun Program.verifyFunctionArgTypes() {
|
||||
fixer.visit(this)
|
||||
}
|
||||
|
||||
internal fun Program.preprocessAst() {
|
||||
val transforms = AstPreprocessor()
|
||||
internal fun Program.preprocessAst(program: Program) {
|
||||
val transforms = AstPreprocessor(program)
|
||||
transforms.visit(this)
|
||||
var mods = transforms.applyModifications()
|
||||
while(mods>0)
|
||||
|
@ -1,9 +1,12 @@
|
||||
package prog8.compiler.astprocessing
|
||||
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.NumericDatatypes
|
||||
import prog8.ast.base.VarDeclType
|
||||
import prog8.ast.expressions.IdentifierReference
|
||||
import prog8.ast.expressions.NumericLiteralValue
|
||||
import prog8.ast.expressions.RangeExpr
|
||||
import prog8.ast.statements.AnonymousScope
|
||||
import prog8.ast.statements.AssignTarget
|
||||
import prog8.ast.statements.Assignment
|
||||
@ -12,7 +15,28 @@ import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
|
||||
|
||||
class AstPreprocessor : AstWalker() {
|
||||
class AstPreprocessor(val program: Program) : AstWalker() {
|
||||
|
||||
override fun after(range: RangeExpr, parent: Node): Iterable<IAstModification> {
|
||||
// has to be done before the constant folding, otherwise certain checks there will fail on invalid range sizes
|
||||
val modifications = mutableListOf<IAstModification>()
|
||||
if(range.from !is NumericLiteralValue) {
|
||||
val constval = range.from.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.from, constval, range)
|
||||
}
|
||||
if(range.to !is NumericLiteralValue) {
|
||||
val constval = range.to.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.to, constval, range)
|
||||
}
|
||||
if(range.step !is NumericLiteralValue) {
|
||||
val constval = range.step.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.step, constval, range)
|
||||
}
|
||||
return modifications
|
||||
}
|
||||
|
||||
override fun before(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
|
@ -69,11 +69,12 @@ fun RangeExpr.toConstantIntegerRange(): IntProgression? {
|
||||
|
||||
val fromLv = from as? NumericLiteralValue
|
||||
val toLv = to as? NumericLiteralValue
|
||||
if(fromLv==null || toLv==null)
|
||||
val stepLv = step as? NumericLiteralValue
|
||||
if(fromLv==null || toLv==null || stepLv==null)
|
||||
return null
|
||||
val fromVal = fromLv.number.toInt()
|
||||
val toVal = toLv.number.toInt()
|
||||
val stepVal = (step as? NumericLiteralValue)?.number?.toInt() ?: 1
|
||||
val stepVal = stepLv.number.toInt()
|
||||
return makeRange(fromVal, toVal, stepVal)
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,10 @@ For next compiler release (7.4)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
BUG: balls example crashes / animates wrong!
|
||||
caused by c83882161521378f20dc0076c01e18e8556e363e 'refactor function arguments codegen a bit'
|
||||
on the lines that call txt.setclr(BX[lp], BY[lp], BC[lp]) - they work with regular vars as args
|
||||
so, something wrong with clobber/arg order when passing array lookups??
|
||||
Add unit test to avoid this in the future?
|
||||
|
||||
|
||||
Use GoSub to call subroutines (statements):
|
||||
|
@ -6,6 +6,17 @@ main {
|
||||
sub start() {
|
||||
test_stack.test()
|
||||
|
||||
ubyte[50] xpos = 49 to 0 step -1
|
||||
ubyte[50] ypos = 49 to 0 step -1
|
||||
|
||||
ubyte ball
|
||||
for ball in 0 to len(xpos)-1 {
|
||||
txt.print_ub(xpos[ball])
|
||||
txt.spc()
|
||||
txt.print_ub(ypos[ball])
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
ubyte @shared x1 = 10
|
||||
ubyte @shared x2 = 20
|
||||
ubyte @shared x3 = 30
|
||||
|
Loading…
Reference in New Issue
Block a user