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>) {
for((index, stmt) in statements.withIndex()) {
if(stmt is FunctionCallStatement
&& stmt.target.nameInSource.last()=="exit"
&& index < statements.lastIndex) {
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)
}
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
errors.warn("unreachable code, preceding return statement", statements[index + 1].position)
if(index < statements.lastIndex && statements[index+1] !is Subroutine) {
when {
stmt is FunctionCallStatement && stmt.target.nameInSource.last() == "exit" -> {
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)
}
stmt is Jump && statements[index + 1] !is Subroutine -> {
errors.warn("unreachable code, preceding jump statement", statements[index + 1].position)
}
}
}
stmt.accept(this)

View File

@ -40,7 +40,6 @@ fun compileProgram(filepath: Path,
if (optimize)
optimizeAst(programAst, errors)
postprocessAst(programAst, errors, compilationOptions)
printAst(programAst) // TODO
if(writeAssembly)
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, ...)
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 paradigm.
- 'One statement per line' code style, resulting in clear readable programs.
- Based on simple and familiar imperative structured programming (it looks like a mix of C and Python)
- 'One statement per line' code, resulting in clear readable programs.
- 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,
and inline assembly to have full control when every cycle or byte matters
- Arbitrary number of subroutine parameters (constrained only by available memory)
- Nested subroutines can access variables from outer scopes, this avoids the need and overhead to pass everything via parameters
- Arbitrary number of subroutine parameters
- 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.
- 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
the compiled program in an emulator and provide debugging information to the 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.
the compiled program in an emulator and provide debugging information to this emulator.
- Arbitrary control flow jumps and branches are possible,
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
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
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``
- Assembling the generated code into a program wil be done by an external cross-assembler tool.
.. _requirements:

View File

@ -3,19 +3,14 @@ TODO
====
- 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)
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 code
- 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
- add a 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
- 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.
- on the language AST level
- on the final assembly source level
- remove unreachable code after an exit(), return or goto
- 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?
- working subroutine inlining (taking care of vars and identifier refs to them)
Also some library routines and code patterns could perhaps be optimized further
- more optimizations on the language AST level
- more optimizations on the final assembly source level
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.
Allocate a fixed word in ZP that is the TOS so we can always operate on TOS directly
without having to to index into the stack?
Allocate a fixed word in ZP that is the Top Of Stack value so we can always operate on TOS directly
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
^^^^
Ofcourse there are still bugs to fix ;)
Bug Fixing
^^^^^^^^^^
Ofcourse there are always bugs to fix ;)
Misc

View File

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