From 4108a528e129cfc875539bbbcdfcfa9652dcf00e Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 26 Mar 2020 23:18:51 +0100 Subject: [PATCH] proepr compiler error when there's no main module --- compiler/src/prog8/ast/base/ErrorReporting.kt | 6 +- .../src/prog8/ast/processing/AstChecker.kt | 2 + .../ast/processing/AstRecursionChecker.kt | 3 +- compiler/src/prog8/compiler/Main.kt | 2 +- compiler/src/prog8/compiler/Zeropage.kt | 2 +- docs/source/todo.rst | 5 +- examples/invalid_assembly.p8 | 67 --------------- examples/lines-circles-gfx.p8 | 84 +++++++++---------- examples/test.p8 | 81 +----------------- 9 files changed, 50 insertions(+), 202 deletions(-) delete mode 100644 examples/invalid_assembly.p8 diff --git a/compiler/src/prog8/ast/base/ErrorReporting.kt b/compiler/src/prog8/ast/base/ErrorReporting.kt index 24da8ea6e..483c6c5e1 100644 --- a/compiler/src/prog8/ast/base/ErrorReporting.kt +++ b/compiler/src/prog8/ast/base/ErrorReporting.kt @@ -8,13 +8,13 @@ class ErrorReporter { WARNING, ERROR } - private class CompilerMessage(val severity: MessageSeverity, val message: String, val position: Position?) + private class CompilerMessage(val severity: MessageSeverity, val message: String, val position: Position) private val messages = mutableListOf() private val alreadyReportedMessages = mutableSetOf() - fun err(msg: String, position: Position?) = messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position)) - fun warn(msg: String, position: Position?) = messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position)) + fun err(msg: String, position: Position) = messages.add(CompilerMessage(MessageSeverity.ERROR, msg, position)) + fun warn(msg: String, position: Position) = messages.add(CompilerMessage(MessageSeverity.WARNING, msg, position)) fun handle() { var numErrors = 0 diff --git a/compiler/src/prog8/ast/processing/AstChecker.kt b/compiler/src/prog8/ast/processing/AstChecker.kt index be8ccf248..e9d8831c4 100644 --- a/compiler/src/prog8/ast/processing/AstChecker.kt +++ b/compiler/src/prog8/ast/processing/AstChecker.kt @@ -21,6 +21,8 @@ internal class AstChecker(private val program: Program, val mainBlocks = program.modules.flatMap { it.statements }.filter { b -> b is Block && b.name=="main" }.map { it as Block } if(mainBlocks.size>1) errors.err("more than one 'main' block", mainBlocks[0].position) + if(mainBlocks.isEmpty()) + errors.err("there is no 'main' block", program.position) for(mainBlock in mainBlocks) { val startSub = mainBlock.subScopes()["start"] as? Subroutine diff --git a/compiler/src/prog8/ast/processing/AstRecursionChecker.kt b/compiler/src/prog8/ast/processing/AstRecursionChecker.kt index cc7ff516d..a181bc29d 100644 --- a/compiler/src/prog8/ast/processing/AstRecursionChecker.kt +++ b/compiler/src/prog8/ast/processing/AstRecursionChecker.kt @@ -2,6 +2,7 @@ package prog8.ast.processing import prog8.ast.INameScope import prog8.ast.base.ErrorReporter +import prog8.ast.base.Position import prog8.ast.expressions.FunctionCall import prog8.ast.statements.FunctionCallStatement import prog8.ast.statements.Subroutine @@ -16,7 +17,7 @@ internal class AstRecursionChecker(private val namespace: INameScope, if(cycle.isEmpty()) return val chain = cycle.joinToString(" <-- ") { "${it.name} at ${it.position}" } - errors.err("Program contains recursive subroutine calls, this is not supported. Recursive chain:\n (a subroutine call in) $chain", null) + errors.err("Program contains recursive subroutine calls, this is not supported. Recursive chain:\n (a subroutine call in) $chain", Position.DUMMY) } override fun visit(functionCallStatement: FunctionCallStatement) { diff --git a/compiler/src/prog8/compiler/Main.kt b/compiler/src/prog8/compiler/Main.kt index f558f578f..95a47dc58 100644 --- a/compiler/src/prog8/compiler/Main.kt +++ b/compiler/src/prog8/compiler/Main.kt @@ -41,7 +41,7 @@ fun compileProgram(filepath: Path, optimizeAst(programAst, errors) postprocessAst(programAst, errors, compilationOptions) - printAst(programAst) // TODO + // printAst(programAst) if(writeAssembly) programName = writeAssembly(programAst, errors, outputDir, optimize, compilationOptions) diff --git a/compiler/src/prog8/compiler/Zeropage.kt b/compiler/src/prog8/compiler/Zeropage.kt index 5f32d5475..6ad868577 100644 --- a/compiler/src/prog8/compiler/Zeropage.kt +++ b/compiler/src/prog8/compiler/Zeropage.kt @@ -30,7 +30,7 @@ abstract class Zeropage(protected val options: CompilationOptions) { if(position!=null) errors.warn("allocated a large value (float) in zeropage", position) else - errors.warn("$scopedname: allocated a large value (float) in zeropage", null) + errors.warn("$scopedname: allocated a large value (float) in zeropage", position ?: Position.DUMMY) 5 } else throw CompilerException("floating point option not enabled") } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index abba832f0..e85e4b1cc 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,12 +2,9 @@ TODO ==== -- fix the invalid assembly generation problem for several direct memory operations (invalid_assembly.p8 / todo.p8) - - - implement the asm for bitshift on arrays (last missing assembly code generation) -- add a routine to plot a single bitmap pixel +- add a library asm routine to plot a single bitmap pixel - create real assembly routines for the bresenham line and circle and disc code in bitmap gfx - also add assembly routines for drawing rectangles (filled/open) in bitmap gfx - add a turtle example once we have such highres drawing routines diff --git a/examples/invalid_assembly.p8 b/examples/invalid_assembly.p8 deleted file mode 100644 index d9fb7c00a..000000000 --- a/examples/invalid_assembly.p8 +++ /dev/null @@ -1,67 +0,0 @@ -%import c64lib -%import c64utils -%zeropage basicsafe - -; TODO WHY DOES THIS GENERATE INVALID ASSEMBLY AT THE A=@(addr) line in Plot() ???? - - -main { - - sub start() { - circles() - lines() - } - - sub circles() { - ubyte xx - for xx in 1 to 5 { - circle(50 + xx*40, 50+xx*15, (xx+10)*4, xx) - disc(50 + xx*40, 50+xx*15, (xx+10)*2, xx) - } - } - - sub lines() { - uword xx - ubyte yy - ubyte color - ubyte iter - - for iter in 0 to 150 { - plot(xx, yy, color) - } - } - - - sub circle(uword xcenter, ubyte ycenter, ubyte radius, ubyte color) { - ubyte x = radius - ubyte y = 0 - byte decisionOver2 = 1-x - - while x>=y { - y++ - } - } - - sub disc(uword cx, ubyte cy, ubyte radius, ubyte color) { - ; Midpoint algorithm, filled - ubyte x = radius - ubyte y = 0 - byte decisionOver2 = 1-x - uword xx - - while x>=y { - for xx in cx to cx+x { - plot(100, 100, 2) - } - } - } - - sub plot(uword px, ubyte py, ubyte color) { - uword addr = 320 - A=@(addr) ; TODO invalid assemlby generated lda (addr),y something to do with zeropage allocation???? or simply direct memory write/read wrong translations? - @(addr) = A - } - -} - - diff --git a/examples/lines-circles-gfx.p8 b/examples/lines-circles-gfx.p8 index c276708b5..e147fdc97 100644 --- a/examples/lines-circles-gfx.p8 +++ b/examples/lines-circles-gfx.p8 @@ -21,13 +21,12 @@ main { } - ; fast asm plot via lookup tables http://codebase64.org/doku.php?id=base:various_techniques_to_calculate_adresses_fast_common_screen_formats_for_pixel_graphics sub circles() { ubyte xx for xx in 1 to 5 { circle(50 + xx*40, 50+xx*15, (xx+10)*4, xx) - ; disc(50 + xx*40, 50+xx*15, (xx+10)*2, xx) + disc(50 + xx*40, 50+xx*15, (xx+10)*2, xx) } } @@ -37,13 +36,13 @@ main { ubyte color ubyte iter - for color in 0 to 15 { + for color in 1 to 15 { xx = color * 16 yy = color + 20 - for iter in 0 to 150 { + for iter in 0 to 80 { plot(xx, yy, color) xx++ - yy++ + yy+=2 } } } @@ -74,56 +73,49 @@ main { } } -; sub disc(uword cx, ubyte cy, ubyte radius, ubyte color) { -; ; Midpoint algorithm, filled -; ubyte x = radius -; ubyte y = 0 -; byte decisionOver2 = 1-x -; uword xx -; -; while x>=y { -; for xx in cx to cx+x { -; plot(xx, cy + y as ubyte, color) -; plot(xx, cy - y as ubyte, color) -; } -; for xx in cx-x to cx-1 { -; plot(xx, cy + y as ubyte, color) -; plot(xx, cy - y as ubyte, color) -; } -; for xx in cx to cx+y { -; plot(xx, cy + x as ubyte, color) -; plot(xx, cy - x as ubyte, color) -; } -; for xx in cx-y to cx { -; plot(xx, cy + x as ubyte, color) -; plot(xx, cy - x as ubyte, color) -; } -; y++ -; if decisionOver2<=0 -; decisionOver2 += 2*y+1 -; else { -; x-- -; decisionOver2 += 2*(y-x)+1 -; } -; } -; } + sub disc(uword cx, ubyte cy, ubyte radius, ubyte color) { + ; Midpoint algorithm, filled + ubyte x = radius + ubyte y = 0 + byte decisionOver2 = 1-x + uword xx - ; uword[200] yoffsets_lo = $00 ; TODO fix compiler crash about init value type + while x>=y { + for xx in cx to cx+x { + plot(xx, cy + y as ubyte, color) + plot(xx, cy - y as ubyte, color) + } + for xx in cx-x to cx-1 { + plot(xx, cy + y as ubyte, color) + plot(xx, cy - y as ubyte, color) + } + for xx in cx to cx+y { + plot(xx, cy + x as ubyte, color) + plot(xx, cy - x as ubyte, color) + } + for xx in cx-y to cx { + plot(xx, cy + x as ubyte, color) + plot(xx, cy - x as ubyte, color) + } + y++ + if decisionOver2<=0 + decisionOver2 += 2*y+1 + else { + x-- + decisionOver2 += 2*(y-x)+1 + } + } + } sub plot(uword px, ubyte py, ubyte color) { + ; fast asm plot via lookup tables http://codebase64.org/doku.php?id=base:various_techniques_to_calculate_adresses_fast_common_screen_formats_for_pixel_graphics ubyte[] ormask = [128, 64, 32, 16, 8, 4, 2, 1] uword addr = bitmap_address + 320*(py>>3) + (py & 7) + (px & %0000001111111000) - - ; @(addr) |= 128 ; TODO FIX memory-OR/XOR and probably AND as well - ; @(addr) += 1 ; TODO fix += 1 - - A=@(addr) - @(addr) = A | ormask[lsb(px) & 7] + @(addr) |= ormask[lsb(px) & 7] ubyte sx = px >> 3 ubyte sy = py >> 3 c64.SCRATCH_ZPB1 = color << 4 c64scr.setchr(sx, sy) - } } diff --git a/examples/test.p8 b/examples/test.p8 index f3428164d..c52c09af8 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,88 +1,11 @@ %import c64lib %import c64utils -%zeropage basicsafe +%zeropage dontuse main { sub start() { - uword addr = $c000 - &ubyte addr2 = $c100 - - uword border = $d020 - &ubyte borderptr = $d020 -; @($d020) = 0 -; @(border) = 1 -; borderptr=2 - -; @($d020)+=9 -; @($d020)-=9 - @(border)+=9 ; TODO fix wrong assembly code - @(border)-=9 ; TODO fix wrong assembly code -; borderptr+=9 -; borderptr-=9 - - @($c000) |= 8 ; ok? - addr2 |= 8 ; ok? - @(addr) |= 8 ; ok? - - - - ; TODO Verify memory augmented assignment operations. - addr2 = 0 - addr2 |= 8 - addr2 |= 2 - addr2 |= 2 - - c64scr.print_ub(addr2) - c64.CHROUT('\n') - if(addr2 != 10) { - c64scr.print("error1\n") - } - addr2 += 1 - addr2 *=10 - c64scr.print_ub(addr2) - c64.CHROUT('\n') - if(addr2 != 110) { - c64scr.print("error2\n") - } - - @($c000) = 0 - @($c000) |= 8 ; TODO FIX result of memory-OR/XOR and probably AND as well - @($c000) |= 2 ; TODO FIX result of memory-OR/XOR and probably AND as well - @($c000) |= 2 ; TODO FIX result of memory-OR/XOR and probably AND as well - c64scr.print_ub( @($c000) ) - c64.CHROUT('\n') - if(@($c000) != 10) { - c64scr.print("error3\n") - } - - @($c000) += 1 ; TODO fix result of memory += 1 - @($c000) *=10 - c64scr.print_ub( @($c000) ) - c64.CHROUT('\n') - if(@($c000) != 110) { - c64scr.print("error4\n") - } - - - @(addr) = 0 - @(addr) |= 8 ; TODO FIX result of memory-OR/XOR and probably AND as well - @(addr) |= 2 ; TODO FIX result of memory-OR/XOR and probably AND as well - @(addr) |= 2 ; TODO FIX result of memory-OR/XOR and probably AND as well - c64scr.print_ub( @(addr) ) - c64.CHROUT('\n') - if(@(addr) != 10) { - c64scr.print("error5\n") - } - - @(addr) += 1 ; TODO fix result of memory += 1 - @(addr) *= 10 - c64scr.print_ub( @(addr) ) - c64.CHROUT('\n') - if(@(addr) != 110) { - c64scr.print("error6\n") - } - + A=5 } }