mirror of
https://github.com/irmen/prog8.git
synced 2025-01-11 13:29:45 +00:00
fix syntaxerror in const processing of ranges if it contained variables
This commit is contained in:
parent
7748c261da
commit
9ecf95b075
@ -3,6 +3,7 @@ package prog8.compiler.astprocessing
|
||||
import prog8.ast.Node
|
||||
import prog8.ast.Program
|
||||
import prog8.ast.base.NumericDatatypes
|
||||
import prog8.ast.base.SyntaxError
|
||||
import prog8.ast.base.VarDeclType
|
||||
import prog8.ast.expressions.IdentifierReference
|
||||
import prog8.ast.expressions.NumericLiteralValue
|
||||
@ -21,19 +22,31 @@ class AstPreprocessor(val program: Program) : AstWalker() {
|
||||
// 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)
|
||||
try {
|
||||
val constval = range.from.constValue(program)
|
||||
if (constval != null)
|
||||
modifications += IAstModification.ReplaceNode(range.from, constval, range)
|
||||
} catch (x: SyntaxError) {
|
||||
// syntax errors will be reported later
|
||||
}
|
||||
}
|
||||
if(range.to !is NumericLiteralValue) {
|
||||
val constval = range.to.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.to, constval, range)
|
||||
try {
|
||||
val constval = range.to.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.to, constval, range)
|
||||
} catch (x: SyntaxError) {
|
||||
// syntax errors will be reported later
|
||||
}
|
||||
}
|
||||
if(range.step !is NumericLiteralValue) {
|
||||
val constval = range.step.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.step, constval, range)
|
||||
try {
|
||||
val constval = range.step.constValue(program)
|
||||
if(constval!=null)
|
||||
modifications += IAstModification.ReplaceNode(range.step, constval, range)
|
||||
} catch (x: SyntaxError) {
|
||||
// syntax errors will be reported later
|
||||
}
|
||||
}
|
||||
return modifications
|
||||
}
|
||||
|
@ -4,11 +4,13 @@ import io.kotest.assertions.withClue
|
||||
import io.kotest.core.spec.style.FunSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import io.kotest.matchers.string.shouldContain
|
||||
import io.kotest.matchers.types.instanceOf
|
||||
import prog8.ast.base.DataType
|
||||
import prog8.ast.base.Position
|
||||
import prog8.ast.expressions.*
|
||||
import prog8.ast.statements.ForLoop
|
||||
import prog8.ast.statements.VarDecl
|
||||
import prog8.compiler.printProgram
|
||||
import prog8.compiler.target.C64Target
|
||||
import prog8.compiler.target.Cx16Target
|
||||
import prog8.compilerinterface.size
|
||||
@ -262,4 +264,42 @@ class TestCompilerOnRanges: FunSpec({
|
||||
expr.size() shouldBe 6
|
||||
expr.toConstantIntegerRange()
|
||||
}
|
||||
|
||||
test("range with negative step should be constvalue") {
|
||||
val result = compileText(C64Target, false, """
|
||||
main {
|
||||
sub start() {
|
||||
ubyte[] array = 100 to 50 step -2
|
||||
ubyte xx
|
||||
for xx in 100 to 50 step -2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
""").assertSuccess()
|
||||
val statements = result.program.entrypoint.statements
|
||||
val array = (statements[0] as VarDecl).value
|
||||
array shouldBe instanceOf<ArrayLiteralValue>()
|
||||
(array as ArrayLiteralValue).value.size shouldBe 26
|
||||
val forloop = (statements.dropLast(1).last() as ForLoop)
|
||||
forloop.iterable shouldBe instanceOf<RangeExpr>()
|
||||
(forloop.iterable as RangeExpr).step shouldBe NumericLiteralValue(DataType.UBYTE, -2.0, Position.DUMMY)
|
||||
}
|
||||
|
||||
test("range with start/end variables should be ok") {
|
||||
val result = compileText(C64Target, false, """
|
||||
main {
|
||||
sub start() {
|
||||
byte from = 100
|
||||
byte end = 50
|
||||
byte xx
|
||||
for xx in from to end step -2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
""").assertSuccess()
|
||||
val statements = result.program.entrypoint.statements
|
||||
val forloop = (statements.dropLast(1).last() as ForLoop)
|
||||
forloop.iterable shouldBe instanceOf<RangeExpr>()
|
||||
(forloop.iterable as RangeExpr).step shouldBe NumericLiteralValue(DataType.UBYTE, -2.0, Position.DUMMY)
|
||||
}
|
||||
})
|
||||
|
@ -4,10 +4,6 @@ TODO
|
||||
For next compiler release (7.4)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
BUG: line-circle-text doesn't compile anymore due to missing symbol!
|
||||
Add unit test to avoid this in the future?
|
||||
|
||||
|
||||
Use GoSub to call subroutines (statements):
|
||||
- [DONE] allow separate assigns to subroutine's parameter variables / registers
|
||||
- [DONE] turn a regular subroutine call into assignments to the parameters + GoSub (take code from gosub branch)
|
||||
|
@ -5,24 +5,6 @@
|
||||
main {
|
||||
|
||||
sub start() {
|
||||
test_stack.test()
|
||||
|
||||
ubyte[20] xpos = 19 to 0 step -1
|
||||
ubyte[20] ypos = 19 to 0 step -1
|
||||
|
||||
ubyte ball
|
||||
for ball in 0 to len(xpos)-1 {
|
||||
ubyte xx = xpos[ball] + 1
|
||||
ubyte yy = ypos[ball]
|
||||
txt.setchr(xx,yy,87) ; correct codegen
|
||||
txt.setclr(xx,yy,5) ; correct codegen
|
||||
txt.setchr(xpos[ball], ypos[ball], 81) ; TODO WRONG CODEGEN WITH NOOPT
|
||||
txt.setclr(xpos[ball], ypos[ball], 6) ; TODO WRONG CODEGEN WITH NOOPT
|
||||
}
|
||||
|
||||
test_stack.test()
|
||||
repeat {
|
||||
}
|
||||
|
||||
ubyte[] array = 100 to 50 step -2
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user