mirror of
https://github.com/irmen/prog8.git
synced 2024-07-05 22:29:04 +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
|
// convert the initializer range expression to an actual array
|
||||||
val declArraySize = decl.arraysize?.constIndex()
|
val declArraySize = decl.arraysize?.constIndex()
|
||||||
if(declArraySize!=null && declArraySize!=rangeExpr.size())
|
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()
|
val constRange = rangeExpr.toConstantIntegerRange()
|
||||||
if(constRange!=null) {
|
if(constRange!=null) {
|
||||||
val eltType = rangeExpr.inferType(program).getOr(DataType.UBYTE)
|
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) {
|
private fun processAst(program: Program, errors: IErrorReporter, compilerOptions: CompilationOptions) {
|
||||||
// perform initial syntax checks and processings
|
// perform initial syntax checks and processings
|
||||||
println("Processing for target ${compilerOptions.compTarget.name}...")
|
println("Processing for target ${compilerOptions.compTarget.name}...")
|
||||||
program.preprocessAst()
|
program.preprocessAst(program)
|
||||||
program.checkIdentifiers(errors, compilerOptions)
|
program.checkIdentifiers(errors, compilerOptions)
|
||||||
errors.report()
|
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
|
// 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)
|
fixer.visit(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Program.preprocessAst() {
|
internal fun Program.preprocessAst(program: Program) {
|
||||||
val transforms = AstPreprocessor()
|
val transforms = AstPreprocessor(program)
|
||||||
transforms.visit(this)
|
transforms.visit(this)
|
||||||
var mods = transforms.applyModifications()
|
var mods = transforms.applyModifications()
|
||||||
while(mods>0)
|
while(mods>0)
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
package prog8.compiler.astprocessing
|
package prog8.compiler.astprocessing
|
||||||
|
|
||||||
import prog8.ast.Node
|
import prog8.ast.Node
|
||||||
|
import prog8.ast.Program
|
||||||
import prog8.ast.base.NumericDatatypes
|
import prog8.ast.base.NumericDatatypes
|
||||||
import prog8.ast.base.VarDeclType
|
import prog8.ast.base.VarDeclType
|
||||||
import prog8.ast.expressions.IdentifierReference
|
import prog8.ast.expressions.IdentifierReference
|
||||||
|
import prog8.ast.expressions.NumericLiteralValue
|
||||||
|
import prog8.ast.expressions.RangeExpr
|
||||||
import prog8.ast.statements.AnonymousScope
|
import prog8.ast.statements.AnonymousScope
|
||||||
import prog8.ast.statements.AssignTarget
|
import prog8.ast.statements.AssignTarget
|
||||||
import prog8.ast.statements.Assignment
|
import prog8.ast.statements.Assignment
|
||||||
@ -12,7 +15,28 @@ import prog8.ast.walk.AstWalker
|
|||||||
import prog8.ast.walk.IAstModification
|
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> {
|
override fun before(scope: AnonymousScope, parent: Node): Iterable<IAstModification> {
|
||||||
|
|
||||||
|
@ -69,11 +69,12 @@ fun RangeExpr.toConstantIntegerRange(): IntProgression? {
|
|||||||
|
|
||||||
val fromLv = from as? NumericLiteralValue
|
val fromLv = from as? NumericLiteralValue
|
||||||
val toLv = to 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
|
return null
|
||||||
val fromVal = fromLv.number.toInt()
|
val fromVal = fromLv.number.toInt()
|
||||||
val toVal = toLv.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)
|
return makeRange(fromVal, toVal, stepVal)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,10 @@ For next compiler release (7.4)
|
|||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
BUG: balls example crashes / animates wrong!
|
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):
|
Use GoSub to call subroutines (statements):
|
||||||
|
@ -6,6 +6,17 @@ main {
|
|||||||
sub start() {
|
sub start() {
|
||||||
test_stack.test()
|
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 x1 = 10
|
||||||
ubyte @shared x2 = 20
|
ubyte @shared x2 = 20
|
||||||
ubyte @shared x3 = 30
|
ubyte @shared x3 = 30
|
||||||
|
Loading…
Reference in New Issue
Block a user