fix invalid range size check when stepval is not a positive integer

This commit is contained in:
Irmen de Jong 2021-11-29 02:01:19 +01:00
parent 4ac169b210
commit b438d8aec0
7 changed files with 47 additions and 7 deletions

View File

@ -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)

View File

@ -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

View File

@ -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)

View File

@ -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> {

View File

@ -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)
}

View File

@ -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):

View File

@ -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