Merge branch 'master' into structs

# Conflicts:
#	compiler/test/codegeneration/TestVariables.kt
#	docs/source/_static/symboldumps/skeletons-c128.txt
#	docs/source/_static/symboldumps/skeletons-c64.txt
#	docs/source/_static/symboldumps/skeletons-cx16.txt
#	docs/source/_static/symboldumps/skeletons-pet32.txt
#	docs/source/_static/symboldumps/skeletons-virtual.txt
#	docs/source/todo.rst
#	examples/test.p8
This commit is contained in:
Irmen de Jong
2025-07-26 12:39:01 +02:00
5 changed files with 48 additions and 21 deletions
+6 -10
View File
@@ -3,6 +3,7 @@ package prog8.code.target
import prog8.code.core.*
import prog8.code.target.encodings.Encoder
import java.nio.file.Path
import kotlin.io.path.extension
import kotlin.io.path.isReadable
import kotlin.io.path.name
import kotlin.io.path.readText
@@ -73,16 +74,11 @@ class VMTarget: ICompilationTarget,
// to not have external module dependencies in our own module, we launch the virtual machine via reflection
val vm = Class.forName("prog8.vm.VmRunner").getDeclaredConstructor().newInstance() as IVirtualMachineRunner
val filename = programNameWithPath.name
if(programNameWithPath.isReadable()) {
vm.runProgram(programNameWithPath.readText(), quiet)
} else {
val withExt = programNameWithPath.resolveSibling("$filename.p8ir")
if(withExt.isReadable())
vm.runProgram(withExt.readText(), quiet)
else
throw java.nio.file.NoSuchFileException(withExt.name, null, "not a .p8ir file")
}
val withExt = if(programNameWithPath.extension=="p8ir") programNameWithPath else programNameWithPath.resolveSibling("${programNameWithPath.name}.p8ir")
if(withExt.isReadable())
vm.runProgram(withExt.readText(), quiet)
else
throw java.nio.file.NoSuchFileException(withExt.name, null, "not a .p8ir file")
}
override fun isIOAddress(address: UInt): Boolean = false
@@ -72,12 +72,12 @@ class IRCodeGen(
val initValue = initialization?.value
when(initValue){
is PtBool -> {
require(initValue.asInt()!=0) { "boolean var should not be initialized with false, it wil be set to false as part of BSS clear, initializer=$initialization" }
require(initValue.asInt()!=0 || variable.zpwish!=ZeropageWish.NOT_IN_ZEROPAGE) { "non-zp variable should not be initialized with 0, it will already be zeroed as part of BSS clear, initializer=$initialization" }
variable.setOnetimeInitNumeric(initValue.asInt().toDouble())
initsToRemove += block to initialization
}
is PtNumber -> {
require(initValue.number!=0.0 || variable.zpwish!=ZeropageWish.NOT_IN_ZEROPAGE) {"non-zp variable should not be initialized with 0, it will already be zeroed as part of BSS clear, initializer=$initialization" }
require(initValue.number!=0.0 || variable.zpwish!=ZeropageWish.NOT_IN_ZEROPAGE) { "non-zp variable should not be initialized with 0, it will already be zeroed as part of BSS clear, initializer=$initialization" }
variable.setOnetimeInitNumeric(initValue.number)
initsToRemove += block to initialization
}
+6
View File
@@ -47,6 +47,12 @@ emudbg {
}
}
sub console_nl() {
; write a newline to the debug output console.
; because '\n' gets encoded in the x16 value for it (13) which is different than what the shell expects (10).
console_chrout(10)
}
sub console_chrout(ubyte char) {
; note: make sure the character is in Iso encoding.
if is_emulator()
+23 -8
View File
@@ -11,9 +11,11 @@ import prog8.ast.statements.AssignmentOrigin
import prog8.ast.statements.ForLoop
import prog8.ast.statements.VarDecl
import prog8.code.ast.PtAssignment
import prog8.code.ast.PtBool
import prog8.code.ast.PtNumber
import prog8.code.target.C64Target
import prog8.code.target.Cx16Target
import prog8.code.target.VMTarget
import prog8tests.helpers.ErrorReporterForTests
import prog8tests.helpers.compileText
@@ -229,27 +231,40 @@ main {
val src="""
main {
ubyte @shared @requirezp zpvar
bool @shared @requirezp zpbool
ubyte @shared @requirezp @dirty dirtyzpvar
bool @shared @requirezp @dirty dirtyzpbool
sub start() {
ubyte @shared @requirezp zpvar2
bool @shared @requirezp zpbool2
ubyte @shared @requirezp @dirty dirtyzpvar2
bool @shared @requirezp @dirty dirtyzpbool2
}
}"""
val result = compileText(Cx16Target(), false, src, outputDir, writeAssembly = true)!!.codegenAst
val main = result!!.allBlocks().first { it.name=="p8b_main" }
main.children.size shouldBe 4
val zeroassignlobal = main.children.single { it is PtAssignment } as PtAssignment
(zeroassignlobal.value as PtNumber).number shouldBe 0.0
zeroassignlobal.target.identifier!!.name shouldBe "p8b_main.p8v_zpvar"
main.children.size shouldBe 7
val zeroassignsglobal = main.children.filterIsInstance<PtAssignment>()
zeroassignsglobal.size shouldBe 2
(zeroassignsglobal[0].value as PtNumber).number shouldBe 0.0
zeroassignsglobal[0].target.identifier!!.name shouldBe "p8b_main.p8v_zpvar"
(zeroassignsglobal[1].value as PtBool).value shouldBe false
zeroassignsglobal[1].target.identifier!!.name shouldBe "p8b_main.p8v_zpbool"
val st = result.entrypoint()!!.children
st.size shouldBe 5
val zeroassign = st.single { it is PtAssignment } as PtAssignment
(zeroassign.value as PtNumber).number shouldBe 0.0
zeroassign.target.identifier!!.name shouldBe "p8b_main.p8s_start.p8v_zpvar2"
st.size shouldBe 8
val zeroassigns = st.filterIsInstance<PtAssignment>()
zeroassigns.size shouldBe 2
(zeroassigns[0].value as PtNumber).number shouldBe 0.0
zeroassigns[0].target.identifier!!.name shouldBe "p8b_main.p8s_start.p8v_zpvar2"
(zeroassigns[1].value as PtBool).value shouldBe false
zeroassigns[1].target.identifier!!.name shouldBe "p8b_main.p8s_start.p8v_zpbool2"
compileText(VMTarget(), false, src, outputDir, writeAssembly = true) shouldNotBe null
}
test("nondirty non zp variables in block scope should not be explicitly initialized to 0 (bss clear takes care of it)") {
+11 -1
View File
@@ -496,7 +496,17 @@ emudbg (cx16 only)
X16Emu Emulator debug routines, for Cx16 only.
Allows you to interface with the emulator's debug routines/registers.
There's stuff like ``is_emulator`` to detect if running in the emulator,
and ``console_write`` to write a (iso) string to the emulator's console (stdout) etc.
and ``console_write`` to write a (iso) string to the emulator's console (stdout), etc.
*EOL (end of line) character handling:*
Writing ``iso:'\n'`` to the console doesn't produce a proper new line there, because prog8 encodes
the newline to character 13 on the X16 (this is what the X16 uses to print a newline on the screen).
You have to explicitly output a character 10 on the console to see a newline there. You can do that in several ways::
emudbg.console_nl()
emudbg.console_chrout(10)
emudbg.console_write(iso:"hello\x0a")
Read the `emudbg source code <https://github.com/irmen/prog8/tree/master/compiler/res/prog8lib/cx16/emudbg.p8>`_
to see what's in there.