fix subroutine inlining symbol scope error

This commit is contained in:
Irmen de Jong 2024-06-29 17:47:13 +02:00
parent ead8aa7800
commit ddf990296b
6 changed files with 23 additions and 21 deletions

View File

@ -51,9 +51,9 @@ GNU GPL 3.0 (see file LICENSE), with exception for generated code:
What does Prog8 provide?
------------------------
- can produce smaller and faster running programs than equivalent C code compiled with CC65 or even LLVM-MOS
- all advantages of a higher level language over having to write assembly code manually
- programs run very fast because compilation to native machine code
- code often is smaller and faster than equivalent C code compiled with CC65 or even LLVM-MOS
- modularity, symbol scoping, subroutines
- various data types other than just bytes (16-bit words, floats, strings)
- floating point math is supported if the target system provides floating point library routines (C64 and Cx16 both do)

View File

@ -104,7 +104,7 @@ class ExpressionSimplifier(private val program: Program, private val options: Co
val leftIDt = expr.left.inferType(program)
val rightIDt = expr.right.inferType(program)
if (!leftIDt.isKnown || !rightIDt.isKnown)
throw FatalAstException("can't determine datatype of both expression operands $expr")
return noModifications
// X + (-A) --> X - A
if (expr.operator == "+" && (expr.right as? PrefixExpression)?.operator == "-") {

View File

@ -147,6 +147,7 @@ class Inliner(private val program: Program, private val options: CompilationOpti
}
private fun makeFullyScoped(call: FunctionCallStatement) {
makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub ->
val scopedName = IdentifierReference(sub.scopedName, call.target.position)
val scopedArgs = makeScopedArgs(call.args)
@ -169,6 +170,7 @@ class Inliner(private val program: Program, private val options: CompilationOpti
}
private fun makeFullyScoped(call: FunctionCallExpression) {
makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub ->
val scopedName = IdentifierReference(sub.scopedName, call.target.position)
val scopedArgs = makeScopedArgs(call.args)

View File

@ -1060,23 +1060,25 @@ main {
compileText(C64Target(), true, src, writeAssembly = true) shouldNotBe null
}
xtest("optimizing inlined functions must reference proper scopes") {
test("optimizing inlined functions must reference proper scopes") {
val src="""
main {
sub start() {
other.sub1()
void other.sub1()
cx16.r0L = other.sub1()+other.sub1()
}
}
other {
sub sub2() {
sub sub2() -> ubyte{
cx16.r0++
cx16.r1++
return cx16.r0L
}
sub sub1() {
sub2()
sub sub1() -> ubyte {
return sub2()
}
}"""

View File

@ -70,9 +70,9 @@ Features
--------
- it is a cross-compiler running on modern machines (Linux, MacOS, Windows, ...)
- can produce smaller and faster running programs than equivalent C code compiled with CC65 or even LLVM-MOS
- the compiled programs run very fast, because compilation to highly efficient native machine code.
- Provides a convenient and fast edit/compile/run cycle by being able to directly launch
- code often is smaller and faster than equivalent C code compiled with CC65 or even LLVM-MOS
- provides a convenient and fast edit/compile/run cycle by being able to directly launch
the compiled program in an emulator and provide debugging information to this emulator.
- the language looks like a mix of Python and C so should be quite easy to learn
- Modular programming, scoping via modules, code blocks, and subroutines. No need for forward declarations.

View File

@ -1,11 +1,9 @@
TODO
====
optimizer bug, see "optimizing inlined functions must reference proper scopes" unittest (skipped for now)
causes compiler error for virtual: just calling txt.cls() gives compile error undefined symbol clear_screen
https://github.com/irmen/prog8/issues/136 (string.find register order issue)
other issues on github.
optimize signed byte/word division by powers of 2 (and shift right?), it's now using divmod routine. (also % ?)
see inplacemodificationByteVariableWithLiteralval() and inplacemodificationSomeWordWithLiteralval()