diff --git a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt index fcf751679..cbe5b1d52 100644 --- a/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt +++ b/codeGeneration/src/prog8/codegen/target/cpu6502/codegen/AsmGen.kt @@ -786,8 +786,8 @@ class AsmGen(private val program: Program, is When -> translate(stmt) is AnonymousScope -> translate(stmt) is BuiltinFunctionPlaceholder -> throw AssemblyError("builtin function should not have placeholder anymore") - is UntilLoop -> throw AssemblyError("do..until should have been desugared to jumps") - is WhileLoop -> throw AssemblyError("while should have been desugared to jumps") + is UntilLoop -> throw AssemblyError("do..until should have been converted to jumps") + is WhileLoop -> throw AssemblyError("while should have been converted to jumps") is Block -> throw AssemblyError("block should have been handled elsewhere") is Break -> throw AssemblyError("break should have been replaced by goto") else -> throw AssemblyError("missing asm translation for $stmt") diff --git a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt index da3bcaf39..f9939ca9e 100644 --- a/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt +++ b/compiler/src/prog8/compiler/BeforeAsmGenerationAstChanger.kt @@ -36,11 +36,11 @@ internal class BeforeAsmGenerationAstChanger(val program: Program, private val o } override fun before(whileLoop: WhileLoop, parent: Node): Iterable { - throw FatalAstException("while should have been desugared to jumps") + throw FatalAstException("while should have been converted to jumps") } override fun before(untilLoop: UntilLoop, parent: Node): Iterable { - throw FatalAstException("do..until should have been desugared to jumps") + throw FatalAstException("do..until should have been converted to jumps") } override fun before(block: Block, parent: Node): Iterable { diff --git a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt index c482a026a..07e99f49d 100644 --- a/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt +++ b/compiler/src/prog8/compiler/astprocessing/VariousCleanups.kt @@ -91,6 +91,19 @@ internal class VariousCleanups(val program: Program, val errors: IErrorReporter) return noModifications } + override fun before(expr: BinaryExpression, parent: Node): Iterable { + if(expr.operator == "or") { + val leftBinExpr = expr.left as? BinaryExpression + val rightBinExpr = expr.right as? BinaryExpression + if(leftBinExpr!=null && leftBinExpr.operator=="==" && rightBinExpr!=null && rightBinExpr.operator=="==") { + if(leftBinExpr.right is NumericLiteralValue && rightBinExpr.right is NumericLiteralValue) { + errors.warn("consider using when statement to test for multiple values", expr.position) + } + } + } + return noModifications + } + override fun after(expr: BinaryExpression, parent: Node): Iterable { if(expr.operator in ComparisonOperators) { val leftConstVal = expr.left.constValue(program) diff --git a/compiler/test/TestCompilerOnImportsAndIncludes.kt b/compiler/test/TestCompilerOnImportsAndIncludes.kt index cbc2f7ea8..a02bee74f 100644 --- a/compiler/test/TestCompilerOnImportsAndIncludes.kt +++ b/compiler/test/TestCompilerOnImportsAndIncludes.kt @@ -11,9 +11,6 @@ import prog8.ast.statements.FunctionCallStatement import prog8.ast.statements.Label import prog8.codegen.target.Cx16Target import prog8tests.helpers.* -import prog8tests.helpers.assertFailure -import prog8tests.helpers.assertSuccess -import prog8tests.helpers.compileFile import kotlin.io.path.name diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 6c79256a4..772790af2 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,10 @@ TODO For next compiler release (7.6) ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -... +add "if X in [1,2,3] {...}" syntax , as an alternative to when X { 1,2,3-> {...} } +if the array is not a literal, do a normal containment test instead in an array or string or range +change "consider using when statement..." to "consider using if X in [..] or when statement..." + Blocked by an official Commander-x16 v39 release ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,12 +16,14 @@ Blocked by an official Commander-x16 v39 release Future ^^^^^^ -- rethink the whole "isAugmentable" business. Because the way this is determined, should always also be exactly mirrorred in the AugmentableAssignmentAsmGen or you'll get a crash at code gen time. -- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation +- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_`` + then we can get rid of the instruction lists in the machinedefinitions as well? - fix the asm-labels problem (github issue #62) +- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation - get rid of all TODO's in the code - improve testability further, add more tests - use more of Result<> and Either<> to handle errors/ nulls better +- rethink the whole "isAugmentable" business. Because the way this is determined, should always also be exactly mirrorred in the AugmentableAssignmentAsmGen or you'll get a crash at code gen time. - can we get rid of pieces of asmgen.AssignmentAsmGen by just reusing the AugmentableAssignment ? generated code should not suffer - add a switch to not create the globals-initialization logic, but instead create a smaller program (that can only run once though) - c64: make the graphics.BITMAP_ADDRESS configurable (VIC banking) @@ -27,7 +32,7 @@ Future - add a flood fill routine to gfx2? - add a diskio.f_seek() routine for the Cx16 that uses its seek dos api? - make it possible for diskio to read and write from more than one file at the same time (= use multiple io channels)? -- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_`` +- fix problems in c128 target - [problematic due to 64tass:] add a compiler option to not remove unused subroutines. this allows for building library programs. But this won't work with 64tass's .proc ... Perhaps replace all uses of .proc/.pend by .block/.bend will fix that? (but we lose the optimizing aspect of the assembler where it strips out unused code. @@ -36,13 +41,9 @@ Future More code optimization ideas ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +- automatically convert if statements that test for multiple values (if X==1 or X==2..) to if X in [1,2,..] statements - byte typed expressions should be evaluated in the accumulator where possible, without (temp)var for instance value = otherbyte >> 1 --> lda otherbite ; lsr a; sta value -- rewrite multiple choice if into when: - if X==1 or X==2 or X==3 { truepart } else { falsepart } - -> when X { 1,2,3->truepart else->falsepart } - same with assignment if the lhs is simple var or memaddr - - rewrite expression tree evaluation such that it doesn't use an eval stack but flatten the tree into linear code that uses a fixed number of predetermined value 'variables' - this removes the need for the BinExprSplitter? (which is problematic and very limited now) - introduce byte-index operator to avoid index multiplications in loops over arrays? see github issue #4 diff --git a/examples/test.p8 b/examples/test.p8 index 230fae544..9b9d512b0 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -9,6 +9,11 @@ main { if xx<100 { foobar() } + + if xx==9 or xx==10 or xx==11 or xx==12 or xx==13 { + txt.print("9 10 11\n") + } + txt.print("\nthe end\n") }