fix warnings about unreachable code

This commit is contained in:
Irmen de Jong 2020-03-24 22:37:42 +01:00
parent 8805693ed2
commit a335ba519a
5 changed files with 43 additions and 43 deletions

View File

@ -1054,16 +1054,18 @@ internal class AstChecker(private val program: Program,
private fun visitStatements(statements: List<Statement>) { private fun visitStatements(statements: List<Statement>) {
for((index, stmt) in statements.withIndex()) { for((index, stmt) in statements.withIndex()) {
if(stmt is FunctionCallStatement if(index < statements.lastIndex && statements[index+1] !is Subroutine) {
&& stmt.target.nameInSource.last()=="exit" when {
&& index < statements.lastIndex) { stmt is FunctionCallStatement && stmt.target.nameInSource.last() == "exit" -> {
println("STMT AFTER EXIT ${statements[index+1]}") // TODO fix message if next stmt is not a regular stmt errors.warn("unreachable code, preceding exit call will never return", statements[index + 1].position)
errors.warn("unreachable code, preceding exit call will never return", statements[index + 1].position) }
} stmt is Return && statements[index + 1] !is Subroutine -> {
errors.warn("unreachable code, preceding return statement", statements[index + 1].position)
if(stmt is Return && index < statements.lastIndex) { }
println("STMT AFTER RETURN ${statements[index+1]}") // TODO fix message if next stmt is not a regular stmt stmt is Jump && statements[index + 1] !is Subroutine -> {
errors.warn("unreachable code, preceding return statement", statements[index + 1].position) errors.warn("unreachable code, preceding jump statement", statements[index + 1].position)
}
}
} }
stmt.accept(this) stmt.accept(this)

View File

@ -40,7 +40,6 @@ fun compileProgram(filepath: Path,
if (optimize) if (optimize)
optimizeAst(programAst, errors) optimizeAst(programAst, errors)
postprocessAst(programAst, errors, compilationOptions) postprocessAst(programAst, errors, compilationOptions)
printAst(programAst) // TODO
if(writeAssembly) if(writeAssembly)
programName = writeAssembly(programAst, errors, outputDir, optimize, compilationOptions) programName = writeAssembly(programAst, errors, outputDir, optimize, compilationOptions)
} }

View File

@ -135,31 +135,29 @@ Design principles and features
- It is a cross-compiler running on modern machines (Linux, MacOS, Windows, ...) - It is a cross-compiler running on modern machines (Linux, MacOS, Windows, ...)
The generated output is a machine code program runnable on actual 8-bit 6502 hardware. The generated output is a machine code program runnable on actual 8-bit 6502 hardware.
- Usable on most operating systems. - Based on simple and familiar imperative structured programming (it looks like a mix of C and Python)
- Based on simple and familiar imperative structured programming paradigm. - 'One statement per line' code, resulting in clear readable programs.
- 'One statement per line' code style, resulting in clear readable programs.
- Modular programming and scoping via modules, code blocks, and subroutines. - Modular programming and scoping via modules, code blocks, and subroutines.
- Provide high level programming constructs but stay close to the metal; - Provide high level programming constructs but at the same time stay close to the metal;
still able to directly use memory addresses, CPU registers and ROM subroutines, still able to directly use memory addresses, CPU registers and ROM subroutines,
and inline assembly to have full control when every cycle or byte matters and inline assembly to have full control when every cycle or byte matters
- Arbitrary number of subroutine parameters (constrained only by available memory) - Arbitrary number of subroutine parameters
- Nested subroutines can access variables from outer scopes, this avoids the need and overhead to pass everything via parameters
- Complex nested expressions are possible - Complex nested expressions are possible
- Values are typed. Types supported include signed and unsigned bytes and words, arrays, strings and floats. - Nested subroutines can access variables from outer scopes to avoids the overhead to pass everything via parameters
- Values are typed. Available data types include signed and unsigned bytes and words, arrays, strings and floats.
- No dynamic memory allocation or sizing! All variables stay fixed size as determined at compile time. - No dynamic memory allocation or sizing! All variables stay fixed size as determined at compile time.
- Provide various quality of life language features and library subroutines specifically for the target platform. - Provide various quality of life language features and library subroutines specifically for the target platform.
- Provide a very convenient edit/compile/run cycle by being able to directly launch - Provide a very convenient edit/compile/run cycle by being able to directly launch
the compiled program in an emulator and provide debugging information to the emulator. the compiled program in an emulator and provide debugging information to this emulator.
- The compiler outputs a regular 6502 assembly source code file, but doesn't assemble this itself.
The (separate) '64tass' cross-assembler tool is used for that.
- Arbitrary control flow jumps and branches are possible, - Arbitrary control flow jumps and branches are possible,
and will usually translate directly into the appropriate single 6502 jump/branch instruction. and will usually translate directly into the appropriate single 6502 jump/branch instruction.
- There are no complicated built-in error handling or overflow checks, you'll have to take care - There are no complicated built-in error handling or overflow checks, you'll have to take care
of this yourself if required. This keeps the language and code simple and efficient. of this yourself if required. This keeps the language and code simple and efficient.
- The compiler tries to optimize the program and generated code, but hand-tuning of the - The compiler tries to optimize the program and generated code a bit, but hand-tuning of the
performance or space-critical parts will likely still be required. This is supported by performance or space-critical parts will likely still be required. This is supported by
the ability to easily write embedded assembly code directly in the program source code. the ability to easily write embedded assembly code directly in the program source code.
- There are many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse`` - There are many built-in functions, such as ``sin``, ``cos``, ``rnd``, ``abs``, ``min``, ``max``, ``sqrt``, ``msb``, ``rol``, ``ror``, ``swap``, ``memset``, ``memcopy``, ``sort`` and ``reverse``
- Assembling the generated code into a program wil be done by an external cross-assembler tool.
.. _requirements: .. _requirements:

View File

@ -3,19 +3,14 @@ TODO
==== ====
- implement the asm for bitshift on arrays (last missing assembly code generation) - implement the asm for bitshift on arrays (last missing assembly code generation)
- remove statements after an exit() or return
- fix warnings about that unreachable code?
- add a compiler option to not include variable initialization code (useful if the program is expected to run only once, such as a game) - add a routine to plot a single bitmap pixel
the program will then rely solely on the values as they are in memory at the time of program startup. - 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
- create real assembly routines for the bresenham line and circle code - add a turtle example once we have such highres drawing routines
- also add assembly routines in c64scr for drawing rectangles (filled/open)
- add these routines for bitmap screen modes as well
- add a turtle example once we have highres drawing routines
- aliases for imported symbols for example perhaps '%alias print = c64scr.print' - aliases for imported symbols for example perhaps '%alias print = c64scr.print'
- option to load library files from a directory instead of the embedded ones - option to load library files from a directory instead of the embedded ones (easier library development/debugging)
@ -42,12 +37,14 @@ More optimizations
Add more compiler optimizations to the existing ones. Add more compiler optimizations to the existing ones.
- on the language AST level - remove unreachable code after an exit(), return or goto
- on the final assembly source level - working subroutine inlining (start with trivial routines, grow to taking care of vars and identifier refs to them)
- add a compiler option to not include variable initialization code (useful if the program is expected to run only once, such as a game)
the program will then rely solely on the values as they are in memory at the time of program startup.
- Also some library routines and code patterns could perhaps be optimized further
- can the parameter passing to subroutines be optimized to avoid copying? - can the parameter passing to subroutines be optimized to avoid copying?
- working subroutine inlining (taking care of vars and identifier refs to them) - more optimizations on the language AST level
- more optimizations on the final assembly source level
Also some library routines and code patterns could perhaps be optimized further
Eval stack redesign? (lot of work) Eval stack redesign? (lot of work)
@ -59,13 +56,14 @@ It could then even be moved into the zeropage to greatly reduce code size and sl
Or just move the LSB portion into a slab of the zeropage. Or just move the LSB portion into a slab of the zeropage.
Allocate a fixed word in ZP that is the TOS so we can always operate on TOS directly Allocate a fixed word in ZP that is the Top Of Stack value so we can always operate on TOS directly
without having to to index into the stack? without having to index with X into the eval stack all the time?
This could GREATLY improvde code size and speed for operatios that work on just a single value.
Bugs Bug Fixing
^^^^ ^^^^^^^^^^
Ofcourse there are still bugs to fix ;) Ofcourse there are always bugs to fix ;)
Misc Misc

View File

@ -12,16 +12,19 @@ main {
bla() bla()
exit(4) exit(4)
v1 = 100 v1 = 100
goto start ; TODO unreachable code warning
v2 = 127 v2 = 127
A=5 A=5
return
sub bla () { sub bla () {
A=99 A=99
bla2() bla2()
exit(99)
sub bla2 () { sub bla2 () {
A=100 A=100
return
foo.ding() foo.ding()
foo.ding2() foo.ding2()
} }