cx16.set_screen_mode() no longer returns anything.

tweak when codegen slightly.
allow trailing comma in array literals.

set_screen_mode failure status is really uncommon and still returned by the real kernal routine screen_mode().
This commit is contained in:
Irmen de Jong 2024-12-19 20:27:22 +01:00
parent 3804fba0f1
commit b01555d75e
7 changed files with 39 additions and 18 deletions

View File

@ -929,7 +929,7 @@ $repeatLabel""")
} }
private fun translate(stmt: PtWhen) { private fun translate(stmt: PtWhen) {
val endLabel = makeLabel("choice_end") val endLabel = makeLabel("when_end")
val choiceBlocks = mutableListOf<Pair<String, PtNodeGroup>>() val choiceBlocks = mutableListOf<Pair<String, PtNodeGroup>>()
val conditionDt = stmt.value.type val conditionDt = stmt.value.type
if(conditionDt.isByte) if(conditionDt.isByte)
@ -939,23 +939,28 @@ $repeatLabel""")
for(choiceNode in stmt.choices.children) { for(choiceNode in stmt.choices.children) {
val choice = choiceNode as PtWhenChoice val choice = choiceNode as PtWhenChoice
val choiceLabel = makeLabel("choice") var choiceLabel = makeLabel("choice")
if(choice.isElse) { if(choice.isElse) {
translate(choice.statements) translate(choice.statements)
} else { } else {
choiceBlocks.add(choiceLabel to choice.statements) if(choice.statements.children.isEmpty()) {
// no statements for this choice value, jump to the end immediately
choiceLabel = endLabel
} else {
choiceBlocks.add(choiceLabel to choice.statements)
}
for (cv in choice.values.children) { for (cv in choice.values.children) {
val value = (cv as PtNumber).number.toInt() val value = (cv as PtNumber).number.toInt()
if(conditionDt.isByte) { if(conditionDt.isByte) {
out(" cmp #${value.toHex()} | beq $choiceLabel") out(" cmp #${value.toHex()} | beq $choiceLabel")
} else { } else {
out(""" out("""
cmp #<${value.toHex()} cmp #<${value.toHex()}
bne + bne +
cpy #>${value.toHex()} cpy #>${value.toHex()}
beq $choiceLabel beq $choiceLabel
+ +
""") """)
} }
} }
} }
@ -964,7 +969,7 @@ $repeatLabel""")
for(choiceBlock in choiceBlocks.withIndex()) { for(choiceBlock in choiceBlocks.withIndex()) {
out(choiceBlock.value.first) out(choiceBlock.value.first)
translate(choiceBlock.value.second) translate(choiceBlock.value.second)
if(choiceBlock.index<choiceBlocks.size-1) if (choiceBlock.index < choiceBlocks.size - 1)
jmp(endLabel) jmp(endLabel)
} }
out(endLabel) out(endLabel)

View File

@ -565,8 +565,8 @@ const ubyte EXTAPI16_stack_enter_kernal_stack = $03
const ubyte EXTAPI16_stack_leave_kernal_stack = $04 const ubyte EXTAPI16_stack_leave_kernal_stack = $04
asmsub set_screen_mode(ubyte mode @A) clobbers(A,X,Y) -> bool @Pc { asmsub set_screen_mode(ubyte mode @A) clobbers(A,X,Y) {
; -- convenience wrapper for screen_mode() to just set a new mode (and return success) ; -- convenience wrapper for screen_mode() to just set a new mode and ignore any return values
%asm {{ %asm {{
clc clc
jmp screen_mode jmp screen_mode

View File

@ -21,6 +21,7 @@ The language
- Ternary operator ``x ? value1 : value2`` is available in the form of an *if-expression*: ``if x value1 else value2`` - Ternary operator ``x ? value1 : value2`` is available in the form of an *if-expression*: ``if x value1 else value2``
- There's a Swift/Zig/Go style ``defer`` statement for delayed cleanup is available in the subroutine scope. - There's a Swift/Zig/Go style ``defer`` statement for delayed cleanup is available in the subroutine scope.
- Qualified names are searched from within the top level namespace (so you have to provide the full qualified name). Unqualified names are locally scoped. - Qualified names are searched from within the top level namespace (so you have to provide the full qualified name). Unqualified names are locally scoped.
- A trailing comma is allowed optionally in array literals: [1,2,3,] is a valid array of values 1, 2 and 3.
No linker No linker

View File

@ -264,7 +264,8 @@ Arrays
^^^^^^ ^^^^^^
Arrays can be created from a list of booleans, bytes, words, floats, or addresses of other variables Arrays can be created from a list of booleans, bytes, words, floats, or addresses of other variables
(such as explicit address-of expressions, strings, or other array variables) - values in an array literal (such as explicit address-of expressions, strings, or other array variables) - values in an array literal
always have to be constants. Here are some examples of arrays:: always have to be constants. A trailing comma is allowed, sometimes this is easier when copying values
or when adding more stuff to the array later. Here are some examples of arrays::
byte[10] array ; array of 10 bytes, initially set to 0 byte[10] array ; array of 10 bytes, initially set to 0
byte[] array = [1, 2, 3, 4] ; initialize the array, size taken from value byte[] array = [1, 2, 3, 4] ; initialize the array, size taken from value

View File

@ -15,7 +15,7 @@ main {
uword mx, my uword mx, my
sub start() { sub start() {
void cx16.set_screen_mode(3) cx16.set_screen_mode(3)
cx16.mouse_config2(1) cx16.mouse_config2(1)
sprites.set_mousepointer_hand() sprites.set_mousepointer_hand()

View File

@ -1,8 +1,22 @@
%import textio
%zeropage basicsafe
%option no_sysinit
main { main {
sub start() { sub start() {
cx16.r0 = $aabb ubyte[] array = [
cx16.r1 = $1122 11,
22,
goto cx16.r1+256 33,
44,
]
for cx16.r0L in [1,2,3,4,] {
txt.print_ub(cx16.r0L)
txt.nl()
}
for cx16.r0L in array {
txt.print_ub(cx16.r0L)
txt.nl()
}
} }
} }

View File

@ -256,7 +256,7 @@ integerliteral : intpart=(DEC_INTEGER | HEX_INTEGER | BIN_INTEGER) ;
booleanliteral : 'true' | 'false' ; booleanliteral : 'true' | 'false' ;
arrayliteral : '[' EOL? expression (',' EOL? expression)* EOL? ']' ; // you can split the values over several lines arrayliteral : '[' EOL? expression (',' EOL? expression)* ','? EOL? ']' ; // you can split the values over several lines, trailing comma allowed
stringliteral : (encoding=NAME ':')? STRING ; stringliteral : (encoding=NAME ':')? STRING ;