labels no longer start with '_' fixes #62

This commit is contained in:
Irmen de Jong 2022-01-17 22:03:53 +01:00
parent 8966d2aa06
commit d916027e75
9 changed files with 57 additions and 116 deletions

View File

@ -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

View File

@ -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""")

View File

@ -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) {

View File

@ -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
}}
}
}

View File

@ -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

View File

@ -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" {

View File

@ -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

View File

@ -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

View File

@ -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
;
; }}
; }
;
;}