mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +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.Result
|
||||
import com.github.michaelbull.result.mapError
|
||||
import prog8.codegen.target.cpu6502.codegen.generatedLabelPrefix
|
||||
import prog8.compilerinterface.CompilationOptions
|
||||
import prog8.compilerinterface.IAssemblyProgram
|
||||
import prog8.compilerinterface.OutputType
|
||||
import prog8.compilerinterface.generatedLabelPrefix
|
||||
import prog8.parser.SourceCode
|
||||
import java.io.File
|
||||
import java.nio.file.Path
|
||||
|
@ -29,6 +29,11 @@ import kotlin.io.path.writeLines
|
||||
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,
|
||||
val errors: IErrorReporter,
|
||||
val zeropage: Zeropage,
|
||||
@ -196,9 +201,9 @@ class AsmGen(private val program: Program,
|
||||
out("* = ${program.actualLoadAddress.toHex()}")
|
||||
val year = LocalDate.now().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("_prog8_entrypoint\t; assembly code starts here\n")
|
||||
out("prog8_entrypoint\t; assembly code starts here\n")
|
||||
if(!options.noSysInit)
|
||||
out(" jsr ${compTarget.name}.init_system")
|
||||
out(" jsr ${compTarget.name}.init_system_phase2")
|
||||
@ -620,34 +625,16 @@ class AsmGen(private val program: Program,
|
||||
return identifier.nameInSource.joinToString(".")
|
||||
|
||||
val tgt2 = identifier.targetStatement(program)
|
||||
if (tgt2 == null && (identifier.nameInSource[0].startsWith("_prog8") || identifier.nameInSource[0].startsWith(
|
||||
"prog8"
|
||||
))
|
||||
)
|
||||
if (tgt2 == null && (identifier.nameInSource[0].startsWith("prog8")))
|
||||
return identifier.nameInSource.joinToString(".")
|
||||
|
||||
val target = identifier.targetStatement(program)!!
|
||||
val targetScope = target.definingSubroutine
|
||||
val identScope = identifier.definingSubroutine
|
||||
return if (targetScope !== identScope) {
|
||||
val scopedName = (target as INamedStatement).scopedName
|
||||
if (target is Label) {
|
||||
// make labels locally scoped in the asm. Is slightly problematic, see GitHub issue #62
|
||||
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 if (targetScope !== identScope)
|
||||
fixNameSymbols((target as INamedStatement).scopedName.joinToString("."))
|
||||
else
|
||||
fixNameSymbols(identifier.nameInSource.joinToString("."))
|
||||
}
|
||||
|
||||
return fixNameSymbols(internalName())
|
||||
@ -789,11 +776,11 @@ class AsmGen(private val program: Program,
|
||||
out(" pha")
|
||||
}
|
||||
CpuRegister.X -> {
|
||||
out(" stx _prog8_regsaveX")
|
||||
out(" stx prog8_regsaveX")
|
||||
scope.asmGenInfo.usedRegsaveX = true
|
||||
}
|
||||
CpuRegister.Y -> {
|
||||
out(" sty _prog8_regsaveY")
|
||||
out(" sty prog8_regsaveY")
|
||||
scope.asmGenInfo.usedRegsaveY = true
|
||||
}
|
||||
}
|
||||
@ -836,8 +823,8 @@ class AsmGen(private val program: Program,
|
||||
} else {
|
||||
when (register) {
|
||||
CpuRegister.A -> out(" pla") // this just used the stack but only for A
|
||||
CpuRegister.X -> out(" ldx _prog8_regsaveX")
|
||||
CpuRegister.Y -> out(" ldy _prog8_regsaveY")
|
||||
CpuRegister.X -> out(" ldx prog8_regsaveX")
|
||||
CpuRegister.Y -> out(" ldy prog8_regsaveY")
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1163,12 +1150,12 @@ class AsmGen(private val program: Program,
|
||||
else -> throw AssemblyError("weird dt")
|
||||
}
|
||||
}
|
||||
if(sub.asmGenInfo.usedRegsaveA)
|
||||
out("_prog8_regsaveA .byte 0")
|
||||
if(sub.asmGenInfo.usedRegsaveA) // will probably never occur
|
||||
out("prog8_regsaveA .byte 0")
|
||||
if(sub.asmGenInfo.usedRegsaveX)
|
||||
out("_prog8_regsaveX .byte 0")
|
||||
out("prog8_regsaveX .byte 0")
|
||||
if(sub.asmGenInfo.usedRegsaveY)
|
||||
out("_prog8_regsaveY .byte 0")
|
||||
out("prog8_regsaveY .byte 0")
|
||||
if(sub.asmGenInfo.usedFloatEvalResultVar1)
|
||||
out("$subroutineFloatEvalResultVar1 .byte 0,0,0,0,0")
|
||||
if(sub.asmGenInfo.usedFloatEvalResultVar2)
|
||||
@ -1561,8 +1548,7 @@ $repeatLabel lda $counterVar
|
||||
}
|
||||
|
||||
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) {
|
||||
@ -1636,6 +1622,9 @@ $repeatLabel lda $counterVar
|
||||
"%breakpoint" -> {
|
||||
val label = "_prog8_breakpoint_${breakpointLabels.size+1}"
|
||||
breakpointLabels.add(label)
|
||||
|
||||
// TODO still need 2 nops to make 64tass generate correc breakpoint list for vice???
|
||||
|
||||
out("""
|
||||
nop
|
||||
$label nop""")
|
||||
|
@ -16,7 +16,7 @@ import prog8.codegen.target.cpu6502.codegen.assignment.*
|
||||
import prog8.compilerinterface.BuiltinFunctions
|
||||
import prog8.compilerinterface.CpuType
|
||||
import prog8.compilerinterface.FSignature
|
||||
import prog8.compilerinterface.subroutineFloatEvalResultVar2
|
||||
|
||||
|
||||
internal class BuiltinFunctionsAsmGen(private val program: Program, private val asmgen: AsmGen, private val assignAsmGen: AssignmentAsmGen) {
|
||||
|
||||
|
@ -163,7 +163,7 @@ graphics {
|
||||
lda addr+1
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
ldy separate_pixels
|
||||
lda _filled_right,y
|
||||
lda hline_filled_right,y
|
||||
eor #255
|
||||
ldy #0
|
||||
ora (P8ZP_SCRATCH_W1),y
|
||||
@ -207,18 +207,18 @@ _modified stx $ffff ; modified
|
||||
_zero ldx P8ZP_SCRATCH_REG
|
||||
|
||||
ldy separate_pixels
|
||||
beq _zero2
|
||||
beq hline_zero2
|
||||
lda _modified+1
|
||||
sta P8ZP_SCRATCH_W1
|
||||
lda _modified+2
|
||||
sta P8ZP_SCRATCH_W1+1
|
||||
lda _filled_right,y
|
||||
lda hline_filled_right,y
|
||||
ldy #0
|
||||
ora (P8ZP_SCRATCH_W1),y
|
||||
sta (P8ZP_SCRATCH_W1),y
|
||||
jmp _zero2
|
||||
_filled_right .byte 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110
|
||||
_zero2
|
||||
jmp hline_zero2
|
||||
hline_filled_right .byte 0, %10000000, %11000000, %11100000, %11110000, %11111000, %11111100, %11111110
|
||||
hline_zero2
|
||||
}}
|
||||
}
|
||||
}
|
||||
|
@ -242,18 +242,18 @@ close_end:
|
||||
void c64.CHKIN(11) ; use #11 as input channel again
|
||||
%asm {{
|
||||
lda bufferpointer
|
||||
sta _in_buffer+1
|
||||
sta m_in_buffer+1
|
||||
lda bufferpointer+1
|
||||
sta _in_buffer+2
|
||||
sta m_in_buffer+2
|
||||
}}
|
||||
repeat num_bytes {
|
||||
%asm {{
|
||||
jsr c64.CHRIN
|
||||
sta cx16.r5
|
||||
_in_buffer sta $ffff
|
||||
inc _in_buffer+1
|
||||
m_in_buffer sta $ffff
|
||||
inc m_in_buffer+1
|
||||
bne +
|
||||
inc _in_buffer+2
|
||||
inc m_in_buffer+2
|
||||
+ inc list_blocks
|
||||
bne +
|
||||
inc list_blocks+1
|
||||
|
@ -1,6 +1,5 @@
|
||||
package prog8tests.codegeneration
|
||||
|
||||
import io.kotest.assertions.withClue
|
||||
import io.kotest.core.spec.style.StringSpec
|
||||
import io.kotest.matchers.shouldBe
|
||||
import prog8.ast.Module
|
||||
@ -121,27 +120,19 @@ class TestAsmGenSymbols: StringSpec({
|
||||
|
||||
// local label
|
||||
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"
|
||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
||||
asmgen.asmVariableName(localLabelIdent) shouldBe "locallabel"
|
||||
}
|
||||
asmgen.asmSymbolName(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
|
||||
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.asmSymbolName(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
|
||||
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"
|
||||
withClue("as a variable it uses different naming rules (no underscore prefix)") {
|
||||
asmgen.asmVariableName(scopedLabelIdent) shouldBe "label_outside"
|
||||
}
|
||||
asmgen.asmSymbolName(scopedLabelIdent) shouldBe "main.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
|
||||
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.asmSymbolName(scopedLabelIdentScoped) shouldBe "main.label_outside"
|
||||
asmgen.asmVariableName(scopedLabelIdentScoped) shouldBe "main.label_outside"
|
||||
}
|
||||
|
||||
"asm names for hooks to zp temp vars" {
|
||||
|
@ -4,10 +4,6 @@ interface IAssemblyGenerator {
|
||||
fun compileToAssembly(): IAssemblyProgram
|
||||
}
|
||||
|
||||
const val generatedLabelPrefix = "_prog8_label_"
|
||||
const val subroutineFloatEvalResultVar1 = "_prog8_float_eval_result1"
|
||||
const val subroutineFloatEvalResultVar2 = "_prog8_float_eval_result2"
|
||||
|
||||
interface IAssemblyProgram {
|
||||
val valid: Boolean
|
||||
val name: String
|
||||
|
@ -3,7 +3,8 @@ TODO
|
||||
|
||||
For next compiler release (7.7)
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
...
|
||||
check AsmGen translate(stmt: Directive) breakpoint nop issue
|
||||
|
||||
|
||||
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``
|
||||
- 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?
|
||||
- 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)
|
||||
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
|
||||
|
@ -1,51 +1,16 @@
|
||||
%import textio
|
||||
%import test_stack
|
||||
|
||||
main {
|
||||
%option force_output
|
||||
str myBar = "main.bar"
|
||||
|
||||
sub start() {
|
||||
test_stack.test()
|
||||
uword ww = 10
|
||||
repeat 10 {
|
||||
ww++
|
||||
txt.print_uw(ww)
|
||||
txt.nl()
|
||||
}
|
||||
test_stack.test()
|
||||
foo_bar:
|
||||
%asm {{
|
||||
nop
|
||||
}}
|
||||
|
||||
repeat {
|
||||
}
|
||||
}
|
||||
sub start() {
|
||||
txt.print(myBar)
|
||||
txt.print(&foo_bar)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
;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