mirror of
https://github.com/irmen/prog8.git
synced 2024-10-18 01:24:51 +00:00
labels no longer start with '_' fixes #62
This commit is contained in:
parent
8966d2aa06
commit
d916027e75
@ -3,10 +3,10 @@ package prog8.codegen.target.cbm
|
|||||||
import com.github.michaelbull.result.Ok
|
import com.github.michaelbull.result.Ok
|
||||||
import com.github.michaelbull.result.Result
|
import com.github.michaelbull.result.Result
|
||||||
import com.github.michaelbull.result.mapError
|
import com.github.michaelbull.result.mapError
|
||||||
|
import prog8.codegen.target.cpu6502.codegen.generatedLabelPrefix
|
||||||
import prog8.compilerinterface.CompilationOptions
|
import prog8.compilerinterface.CompilationOptions
|
||||||
import prog8.compilerinterface.IAssemblyProgram
|
import prog8.compilerinterface.IAssemblyProgram
|
||||||
import prog8.compilerinterface.OutputType
|
import prog8.compilerinterface.OutputType
|
||||||
import prog8.compilerinterface.generatedLabelPrefix
|
|
||||||
import prog8.parser.SourceCode
|
import prog8.parser.SourceCode
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
@ -29,6 +29,11 @@ import kotlin.io.path.writeLines
|
|||||||
import kotlin.math.absoluteValue
|
import kotlin.math.absoluteValue
|
||||||
|
|
||||||
|
|
||||||
|
const val generatedLabelPrefix = "prog8_label_"
|
||||||
|
const val subroutineFloatEvalResultVar1 = "prog8_float_eval_result1"
|
||||||
|
const val subroutineFloatEvalResultVar2 = "prog8_float_eval_result2"
|
||||||
|
|
||||||
|
|
||||||
class AsmGen(private val program: Program,
|
class AsmGen(private val program: Program,
|
||||||
val errors: IErrorReporter,
|
val errors: IErrorReporter,
|
||||||
val zeropage: Zeropage,
|
val zeropage: Zeropage,
|
||||||
@ -196,9 +201,9 @@ class AsmGen(private val program: Program,
|
|||||||
out("* = ${program.actualLoadAddress.toHex()}")
|
out("* = ${program.actualLoadAddress.toHex()}")
|
||||||
val year = LocalDate.now().year
|
val year = LocalDate.now().year
|
||||||
out(" .word (+), $year")
|
out(" .word (+), $year")
|
||||||
out(" .null $9e, format(' %d ', _prog8_entrypoint), $3a, $8f, ' prog8'")
|
out(" .null $9e, format(' %d ', prog8_entrypoint), $3a, $8f, ' prog8'")
|
||||||
out("+\t.word 0")
|
out("+\t.word 0")
|
||||||
out("_prog8_entrypoint\t; assembly code starts here\n")
|
out("prog8_entrypoint\t; assembly code starts here\n")
|
||||||
if(!options.noSysInit)
|
if(!options.noSysInit)
|
||||||
out(" jsr ${compTarget.name}.init_system")
|
out(" jsr ${compTarget.name}.init_system")
|
||||||
out(" jsr ${compTarget.name}.init_system_phase2")
|
out(" jsr ${compTarget.name}.init_system_phase2")
|
||||||
@ -620,34 +625,16 @@ class AsmGen(private val program: Program,
|
|||||||
return identifier.nameInSource.joinToString(".")
|
return identifier.nameInSource.joinToString(".")
|
||||||
|
|
||||||
val tgt2 = identifier.targetStatement(program)
|
val tgt2 = identifier.targetStatement(program)
|
||||||
if (tgt2 == null && (identifier.nameInSource[0].startsWith("_prog8") || identifier.nameInSource[0].startsWith(
|
if (tgt2 == null && (identifier.nameInSource[0].startsWith("prog8")))
|
||||||
"prog8"
|
|
||||||
))
|
|
||||||
)
|
|
||||||
return identifier.nameInSource.joinToString(".")
|
return identifier.nameInSource.joinToString(".")
|
||||||
|
|
||||||
val target = identifier.targetStatement(program)!!
|
val target = identifier.targetStatement(program)!!
|
||||||
val targetScope = target.definingSubroutine
|
val targetScope = target.definingSubroutine
|
||||||
val identScope = identifier.definingSubroutine
|
val identScope = identifier.definingSubroutine
|
||||||
return if (targetScope !== identScope) {
|
return if (targetScope !== identScope)
|
||||||
val scopedName = (target as INamedStatement).scopedName
|
fixNameSymbols((target as INamedStatement).scopedName.joinToString("."))
|
||||||
if (target is Label) {
|
else
|
||||||
// make labels locally scoped in the asm. Is slightly problematic, see GitHub issue #62
|
fixNameSymbols(identifier.nameInSource.joinToString("."))
|
||||||
val newName = scopedName.dropLast(1) + ("_${scopedName.last()}")
|
|
||||||
fixNameSymbols(newName.joinToString("."))
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
fixNameSymbols(scopedName.joinToString("."))
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (target is Label) {
|
|
||||||
// make labels locally scoped in the asm. Is slightly problematic, see GitHub issue #62
|
|
||||||
val scopedName = identifier.nameInSource.toMutableList()
|
|
||||||
val last = scopedName.removeLast()
|
|
||||||
scopedName.add("_$last")
|
|
||||||
fixNameSymbols(scopedName.joinToString("."))
|
|
||||||
} else fixNameSymbols(identifier.nameInSource.joinToString("."))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return fixNameSymbols(internalName())
|
return fixNameSymbols(internalName())
|
||||||
@ -789,11 +776,11 @@ class AsmGen(private val program: Program,
|
|||||||
out(" pha")
|
out(" pha")
|
||||||
}
|
}
|
||||||
CpuRegister.X -> {
|
CpuRegister.X -> {
|
||||||
out(" stx _prog8_regsaveX")
|
out(" stx prog8_regsaveX")
|
||||||
scope.asmGenInfo.usedRegsaveX = true
|
scope.asmGenInfo.usedRegsaveX = true
|
||||||
}
|
}
|
||||||
CpuRegister.Y -> {
|
CpuRegister.Y -> {
|
||||||
out(" sty _prog8_regsaveY")
|
out(" sty prog8_regsaveY")
|
||||||
scope.asmGenInfo.usedRegsaveY = true
|
scope.asmGenInfo.usedRegsaveY = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -836,8 +823,8 @@ class AsmGen(private val program: Program,
|
|||||||
} else {
|
} else {
|
||||||
when (register) {
|
when (register) {
|
||||||
CpuRegister.A -> out(" pla") // this just used the stack but only for A
|
CpuRegister.A -> out(" pla") // this just used the stack but only for A
|
||||||
CpuRegister.X -> out(" ldx _prog8_regsaveX")
|
CpuRegister.X -> out(" ldx prog8_regsaveX")
|
||||||
CpuRegister.Y -> out(" ldy _prog8_regsaveY")
|
CpuRegister.Y -> out(" ldy prog8_regsaveY")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1163,12 +1150,12 @@ class AsmGen(private val program: Program,
|
|||||||
else -> throw AssemblyError("weird dt")
|
else -> throw AssemblyError("weird dt")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(sub.asmGenInfo.usedRegsaveA)
|
if(sub.asmGenInfo.usedRegsaveA) // will probably never occur
|
||||||
out("_prog8_regsaveA .byte 0")
|
out("prog8_regsaveA .byte 0")
|
||||||
if(sub.asmGenInfo.usedRegsaveX)
|
if(sub.asmGenInfo.usedRegsaveX)
|
||||||
out("_prog8_regsaveX .byte 0")
|
out("prog8_regsaveX .byte 0")
|
||||||
if(sub.asmGenInfo.usedRegsaveY)
|
if(sub.asmGenInfo.usedRegsaveY)
|
||||||
out("_prog8_regsaveY .byte 0")
|
out("prog8_regsaveY .byte 0")
|
||||||
if(sub.asmGenInfo.usedFloatEvalResultVar1)
|
if(sub.asmGenInfo.usedFloatEvalResultVar1)
|
||||||
out("$subroutineFloatEvalResultVar1 .byte 0,0,0,0,0")
|
out("$subroutineFloatEvalResultVar1 .byte 0,0,0,0,0")
|
||||||
if(sub.asmGenInfo.usedFloatEvalResultVar2)
|
if(sub.asmGenInfo.usedFloatEvalResultVar2)
|
||||||
@ -1561,8 +1548,7 @@ $repeatLabel lda $counterVar
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(stmt: Label) {
|
private fun translate(stmt: Label) {
|
||||||
// underscore prefix to make sure it's a local label. Is slightly problematic, see GitHub issue #62
|
out(stmt.name)
|
||||||
out("_${stmt.name}")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun translate(scope: AnonymousScope) {
|
private fun translate(scope: AnonymousScope) {
|
||||||
@ -1636,6 +1622,9 @@ $repeatLabel lda $counterVar
|
|||||||
"%breakpoint" -> {
|
"%breakpoint" -> {
|
||||||
val label = "_prog8_breakpoint_${breakpointLabels.size+1}"
|
val label = "_prog8_breakpoint_${breakpointLabels.size+1}"
|
||||||
breakpointLabels.add(label)
|
breakpointLabels.add(label)
|
||||||
|
|
||||||
|
// TODO still need 2 nops to make 64tass generate correc breakpoint list for vice???
|
||||||
|
|
||||||
out("""
|
out("""
|
||||||
nop
|
nop
|
||||||
$label nop""")
|
$label nop""")
|
||||||
|
@ -16,7 +16,7 @@ import prog8.codegen.target.cpu6502.codegen.assignment.*
|
|||||||
import prog8.compilerinterface.BuiltinFunctions
|
import prog8.compilerinterface.BuiltinFunctions
|
||||||
import prog8.compilerinterface.CpuType
|
import prog8.compilerinterface.CpuType
|
||||||
import prog8.compilerinterface.FSignature
|
import prog8.compilerinterface.FSignature
|
||||||
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
|
||||||
|
|
||||||
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
|
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
|
||||||
|
|
||||||
|
@ -163,7 +163,7 @@ graphics {
|
|||||||
lda addr+1
|
lda addr+1
|
||||||
sta P8ZP_SCRATCH_W1+1
|
sta P8ZP_SCRATCH_W1+1
|
||||||
ldy separate_pixels
|
ldy separate_pixels
|
||||||
lda _filled_right,y
|
lda hline_filled_right,y
|
||||||
eor #255
|
eor #255
|
||||||
ldy #0
|
ldy #0
|
||||||
ora (P8ZP_SCRATCH_W1),y
|
ora (P8ZP_SCRATCH_W1),y
|
||||||
@ -207,18 +207,18 @@ _modified stx $ffff ; modified
|
|||||||
_zero ldx P8ZP_SCRATCH_REG
|
_zero ldx P8ZP_SCRATCH_REG
|
||||||
|
|
||||||
ldy separate_pixels
|
ldy separate_pixels
|
||||||
beq _zero2
|
beq hline_zero2
|
||||||
lda _modified+1
|
lda _modified+1
|
||||||
sta P8ZP_SCRATCH_W1
|
sta P8ZP_SCRATCH_W1
|
||||||
lda _modified+2
|
lda _modified+2
|
||||||
sta P8ZP_SCRATCH_W1+1
|
sta P8ZP_SCRATCH_W1+1
|
||||||
lda _filled_right,y
|
lda hline_filled_right,y
|
||||||
ldy #0
|
ldy #0
|
||||||
ora (P8ZP_SCRATCH_W1),y
|
ora (P8ZP_SCRATCH_W1),y
|
||||||
sta (P8ZP_SCRATCH_W1),y
|
sta (P8ZP_SCRATCH_W1),y
|
||||||
jmp _zero2
|
jmp hline_zero2
|
||||||
_filled_right .byte 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110
|
hline_filled_right .byte 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110
|
||||||
_zero2
|
hline_zero2
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -242,18 +242,18 @@ close_end:
|
|||||||
void c64.CHKIN(11) ; use #11 as input channel again
|
void c64.CHKIN(11) ; use #11 as input channel again
|
||||||
%asm {{
|
%asm {{
|
||||||
lda bufferpointer
|
lda bufferpointer
|
||||||
sta _in_buffer+1
|
sta m_in_buffer+1
|
||||||
lda bufferpointer+1
|
lda bufferpointer+1
|
||||||
sta _in_buffer+2
|
sta m_in_buffer+2
|
||||||
}}
|
}}
|
||||||
repeat num_bytes {
|
repeat num_bytes {
|
||||||
%asm {{
|
%asm {{
|
||||||
jsr c64.CHRIN
|
jsr c64.CHRIN
|
||||||
sta cx16.r5
|
sta cx16.r5
|
||||||
_in_buffer sta $ffff
|
m_in_buffer sta $ffff
|
||||||
inc _in_buffer+1
|
inc m_in_buffer+1
|
||||||
bne +
|
bne +
|
||||||
inc _in_buffer+2
|
inc m_in_buffer+2
|
||||||
+ inc list_blocks
|
+ inc list_blocks
|
||||||
bne +
|
bne +
|
||||||
inc list_blocks+1
|
inc list_blocks+1
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package prog8tests.codegeneration
|
package prog8tests.codegeneration
|
||||||
|
|
||||||
import io.kotest.assertions.withClue
|
|
||||||
import io.kotest.core.spec.style.StringSpec
|
import io.kotest.core.spec.style.StringSpec
|
||||||
import io.kotest.matchers.shouldBe
|
import io.kotest.matchers.shouldBe
|
||||||
import prog8.ast.Module
|
import prog8.ast.Module
|
||||||
@ -121,28 +120,20 @@ class TestAsmGenSymbols: StringSpec({
|
|||||||
|
|
||||||
// local label
|
// local label
|
||||||
val localLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("locallabel") }.value as AddressOf).identifier
|
val localLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("locallabel") }.value as AddressOf).identifier
|
||||||
asmgen.asmSymbolName(localLabelIdent) shouldBe "_locallabel"
|
asmgen.asmSymbolName(localLabelIdent) shouldBe "locallabel"
|
||||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
|
||||||
asmgen.asmVariableName(localLabelIdent) shouldBe "locallabel"
|
asmgen.asmVariableName(localLabelIdent) shouldBe "locallabel"
|
||||||
}
|
|
||||||
val localLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","start","locallabel") }.value as AddressOf).identifier
|
val localLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","start","locallabel") }.value as AddressOf).identifier
|
||||||
asmgen.asmSymbolName(localLabelIdentScoped) shouldBe "main.start._locallabel"
|
asmgen.asmSymbolName(localLabelIdentScoped) shouldBe "main.start.locallabel"
|
||||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
|
||||||
asmgen.asmVariableName(localLabelIdentScoped) shouldBe "main.start.locallabel"
|
asmgen.asmVariableName(localLabelIdentScoped) shouldBe "main.start.locallabel"
|
||||||
}
|
|
||||||
|
|
||||||
// label from outer scope needs sope prefixes because it is outputted as a locally scoped symbol for the assembler
|
// label from outer scope needs sope prefixes because it is outputted as a locally scoped symbol for the assembler
|
||||||
val scopedLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("label_outside") }.value as AddressOf).identifier
|
val scopedLabelIdent = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("label_outside") }.value as AddressOf).identifier
|
||||||
asmgen.asmSymbolName(scopedLabelIdent) shouldBe "main._label_outside"
|
asmgen.asmSymbolName(scopedLabelIdent) shouldBe "main.label_outside"
|
||||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
|
||||||
asmgen.asmVariableName(scopedLabelIdent) shouldBe "label_outside"
|
asmgen.asmVariableName(scopedLabelIdent) shouldBe "label_outside"
|
||||||
}
|
|
||||||
val scopedLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","label_outside") }.value as AddressOf).identifier
|
val scopedLabelIdentScoped = (sub.statements.asSequence().filterIsInstance<Assignment>().first { (it.value as? AddressOf)?.identifier?.nameInSource==listOf("main","label_outside") }.value as AddressOf).identifier
|
||||||
asmgen.asmSymbolName(scopedLabelIdentScoped) shouldBe "main._label_outside"
|
asmgen.asmSymbolName(scopedLabelIdentScoped) shouldBe "main.label_outside"
|
||||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
|
||||||
asmgen.asmVariableName(scopedLabelIdentScoped) shouldBe "main.label_outside"
|
asmgen.asmVariableName(scopedLabelIdentScoped) shouldBe "main.label_outside"
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
"asm names for hooks to zp temp vars" {
|
"asm names for hooks to zp temp vars" {
|
||||||
/*
|
/*
|
||||||
|
@ -4,10 +4,6 @@ interface IAssemblyGenerator {
|
|||||||
fun compileToAssembly(): IAssemblyProgram
|
fun compileToAssembly(): IAssemblyProgram
|
||||||
}
|
}
|
||||||
|
|
||||||
const val generatedLabelPrefix = "_prog8_label_"
|
|
||||||
const val subroutineFloatEvalResultVar1 = "_prog8_float_eval_result1"
|
|
||||||
const val subroutineFloatEvalResultVar2 = "_prog8_float_eval_result2"
|
|
||||||
|
|
||||||
interface IAssemblyProgram {
|
interface IAssemblyProgram {
|
||||||
val valid: Boolean
|
val valid: Boolean
|
||||||
val name: String
|
val name: String
|
||||||
|
@ -3,7 +3,8 @@ TODO
|
|||||||
|
|
||||||
For next compiler release (7.7)
|
For next compiler release (7.7)
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
...
|
check AsmGen translate(stmt: Directive) breakpoint nop issue
|
||||||
|
|
||||||
|
|
||||||
Need help with
|
Need help with
|
||||||
^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^
|
||||||
@ -25,7 +26,6 @@ Future Things and Ideas
|
|||||||
- for the pipe operator: recognise a placeholder (``?`` or ``%`` or ``_``) in a non-unary function call to allow things as ``4 |> mkword(?, $44) |> print_uw``
|
- for the pipe operator: recognise a placeholder (``?`` or ``%`` or ``_``) in a non-unary function call to allow things as ``4 |> mkword(?, $44) |> print_uw``
|
||||||
- make it possible to use cpu opcodes such as 'nop' as variable names by prefixing all asm vars with something such as ``v_``
|
- 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?
|
then we can get rid of the instruction lists in the machinedefinitions as well?
|
||||||
- fix the asm-labels problem (github issue #62)
|
|
||||||
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
|
- make it possible to inline non-asmsub routines that just contain a single statement (return, functioncall, assignment)
|
||||||
but this requires all identifiers in the inlined expression to be changed to fully scoped names
|
but this requires all identifiers in the inlined expression to be changed to fully scoped names
|
||||||
- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation
|
- simplifyConditionalExpression() should not split expression if it still results in stack-based evaluation
|
||||||
|
@ -1,51 +1,16 @@
|
|||||||
%import textio
|
%import textio
|
||||||
%import test_stack
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
%option force_output
|
str myBar = "main.bar"
|
||||||
|
|
||||||
|
foo_bar:
|
||||||
|
%asm {{
|
||||||
|
nop
|
||||||
|
}}
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
test_stack.test()
|
txt.print(myBar)
|
||||||
uword ww = 10
|
txt.print(&foo_bar)
|
||||||
repeat 10 {
|
return
|
||||||
ww++
|
|
||||||
txt.print_uw(ww)
|
|
||||||
txt.nl()
|
|
||||||
}
|
|
||||||
test_stack.test()
|
|
||||||
|
|
||||||
repeat {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
;main {
|
|
||||||
; sub start() {
|
|
||||||
; %asm {{
|
|
||||||
; lda #<float5_111
|
|
||||||
; ldy #>float5_111
|
|
||||||
; jsr floats.MOVFM
|
|
||||||
; lda #<float5_122
|
|
||||||
; ldy #>float5_122
|
|
||||||
; jsr floats.FADD
|
|
||||||
; jsr floats.FOUT
|
|
||||||
; sta $7e
|
|
||||||
; sty $7f
|
|
||||||
; ldy #64
|
|
||||||
;_loop
|
|
||||||
; lda ($7e),y
|
|
||||||
; beq _done
|
|
||||||
; jsr c64.CHROUT
|
|
||||||
; iny
|
|
||||||
; bne _loop
|
|
||||||
;_done
|
|
||||||
; rts
|
|
||||||
;
|
|
||||||
;float5_111 .byte $81, $64e, $14, $7a, $e1 ; float 1.11
|
|
||||||
;float5_122 .byte $81, $1c, $28, $f5, $c2 ; float 1.22
|
|
||||||
;
|
|
||||||
; }}
|
|
||||||
; }
|
|
||||||
;
|
|
||||||
;}
|
|
||||||
|
Loading…
Reference in New Issue
Block a user