From b9958412c70d75500c908342b6711030b3a10353 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 15 Dec 2018 00:07:25 +0100 Subject: [PATCH] allow passing byte/word for register/registerpair arguments, fix stackvm string parameter handling --- compiler/examples/numbergame-c64.p8 | 4 +- compiler/examples/numbergame-novm.p8 | 4 +- compiler/examples/numbergame.p8 | 10 +- compiler/examples/test.p8 | 207 +----------------------- compiler/src/prog8/ast/AstChecker.kt | 40 +++-- compiler/src/prog8/compiler/Compiler.kt | 5 +- compiler/src/prog8/stackvm/StackVm.kt | 31 ++-- prog8lib/c64utils.p8 | 4 +- 8 files changed, 56 insertions(+), 249 deletions(-) diff --git a/compiler/examples/numbergame-c64.p8 b/compiler/examples/numbergame-c64.p8 index db4f6987b..4b1f40181 100644 --- a/compiler/examples/numbergame-c64.p8 +++ b/compiler/examples/numbergame-c64.p8 @@ -39,7 +39,7 @@ ask_guess: c64.STROUT("\nYou have ") - c64scr.print_byte_decimal(attempts_left) + c64scr.print_ubyte_decimal(attempts_left) c64.STROUT(" guess") if(attempts_left>1) c64.STROUT("es") @@ -66,7 +66,7 @@ ask_guess: ; game over. c64.STROUT("\nToo bad! It was: ") - c64scr.print_byte_decimal(secretnumber) + c64scr.print_ubyte_decimal(secretnumber) c64.CHROUT('\n') goodbye: diff --git a/compiler/examples/numbergame-novm.p8 b/compiler/examples/numbergame-novm.p8 index 3ff9d97ec..aeccbd34f 100644 --- a/compiler/examples/numbergame-novm.p8 +++ b/compiler/examples/numbergame-novm.p8 @@ -26,7 +26,7 @@ ; c64.CHROUT('\n') c64scr.print_string("\nYou have ") - c64scr.print_byte_decimal(attempts_left) + c64scr.print_ubyte_decimal(attempts_left) c64scr.print_string(" guess") if attempts_left>1 c64scr.print_string("es") @@ -66,7 +66,7 @@ c64scr.print_string("\n\nYou guessed it, impressive!\n") else { c64scr.print_string("\nToo bad! My number was: ") - c64scr.print_byte_decimal(secretnumber) + c64scr.print_ubyte_decimal(secretnumber) c64scr.print_string(".\n") } c64scr.print_string("Thanks for playing, ") diff --git a/compiler/examples/numbergame.p8 b/compiler/examples/numbergame.p8 index 853dbb317..886541f3a 100644 --- a/compiler/examples/numbergame.p8 +++ b/compiler/examples/numbergame.p8 @@ -3,7 +3,7 @@ ~ main { sub start() { str name = "????????????????????????????????????????" - str guessstr = "??????????" + str input = "??????????" ubyte secretnumber = rnd() % 100 vm_write_str("Let's play a number guessing game!\n") @@ -20,15 +20,15 @@ if attempts_left>1 vm_write_str("es") vm_write_str(" left. What is your next guess? ") - vm_input_str(guess) - ubyte guessednumber = str2ubyte(guess) - if guessednumber==secretnumber { + vm_input_str(input) + ubyte guess = str2ubyte(input) + if guess==secretnumber { vm_write_str("\nYou guessed it, impressive!\n") vm_write_str("Thanks for playing.\n") return } else { vm_write_str("That is too ") - if guessednumber().withDefault { 0 } diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 08f95bcf7..418e193bf 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -847,7 +847,7 @@ private class StatementTranslator(private val prog: IntermediateProgram, translate(assignA) translate(assignY) } - DataType.UWORD -> { + DataType.UWORD, DataType.WORD -> { translate(arg.first) prog.instr(Opcode.POP_REGAY_WORD) } @@ -1212,7 +1212,8 @@ private class StatementTranslator(private val prog: IntermediateProgram, // convert value to target datatype if possible when(targetDt) { DataType.UBYTE, DataType.BYTE -> - throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt") + if(valueDt!=DataType.BYTE && valueDt!=DataType.UBYTE) + throw CompilerException("incompatible data types valueDt=$valueDt targetDt=$targetDt at $stmt") DataType.WORD -> { when (valueDt) { DataType.UBYTE -> prog.instr(Opcode.UB2UWORD) diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index 62ebb0f49..e387e444f 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -1417,20 +1417,15 @@ class StackVm(private var traceOutputFile: String?) { print(Petscii.decodePetscii(listOf(evalstack.pop().integerValue().toShort()), true)) } Syscall.VM_WRITE_STR -> { - val value = evalstack.pop() - when(value.type){ - DataType.UBYTE, DataType.BYTE, DataType.UWORD, DataType.WORD, DataType.FLOAT -> print(value.numericValue()) - DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> print(heap.get(value.heapId).str) - DataType.ARRAY_UB, DataType.ARRAY_B, DataType.ARRAY_UW, DataType.ARRAY_W -> print(heap.get(value.heapId).array!!.toList()) - DataType.ARRAY_F -> print(heap.get(value.heapId).doubleArray!!.toList()) - } + val heapId = evalstack.pop().integerValue() + print(heap.get(heapId).str?.substringBefore('\u0000')) } Syscall.VM_INPUT_STR -> { - val variable = evalstack.pop() - val value = heap.get(variable.heapId) + val heapId = evalstack.pop().integerValue() + val value = heap.get(heapId) val maxlen = value.str!!.length val input = readLine() ?: "" - heap.update(variable.heapId, input.padEnd(maxlen, '\u0000').substring(0, maxlen)) + heap.update(heapId, input.padEnd(maxlen, '\u0000').substring(0, maxlen)) } Syscall.VM_GFX_PIXEL -> { // plot pixel at (x, y, color) from stack @@ -1575,28 +1570,28 @@ class StackVm(private var traceOutputFile: String?) { evalstack.push(Value(DataType.BYTE, y.toShort())) } Syscall.FUNC_STR2UBYTE -> { - val strvar = evalstack.pop() - val str = heap.get(strvar.heapId) + val heapId = evalstack.pop().integerValue() + val str = heap.get(heapId) val y = str.str!!.trim().trimEnd('\u0000') val number = (y.toInt() and 255).toShort() evalstack.push(Value(DataType.UBYTE, number)) } Syscall.FUNC_STR2WORD -> { - val strvar = evalstack.pop() - val str = heap.get(strvar.heapId) + val heapId = evalstack.pop().integerValue() + val str = heap.get(heapId) val y = str.str!!.trim().trimEnd('\u0000') evalstack.push(Value(DataType.WORD, y.toInt())) } Syscall.FUNC_STR2UWORD -> { - val strvar = evalstack.pop() - val str = heap.get(strvar.heapId) + val heapId = evalstack.pop().integerValue() + val str = heap.get(heapId) val y = str.str!!.trim().trimEnd('\u0000') val number = y.toInt() and 65535 evalstack.push(Value(DataType.UWORD, number)) } Syscall.FUNC_STR2FLOAT -> { - val strvar = evalstack.pop() - val str = heap.get(strvar.heapId) + val heapId = evalstack.pop().integerValue() + val str = heap.get(heapId) val y = str.str!!.trim().trimEnd('\u0000') evalstack.push(Value(DataType.FLOAT, y.toDouble())) } diff --git a/prog8lib/c64utils.p8 b/prog8lib/c64utils.p8 index 691d95b8e..d11ca8cbc 100644 --- a/prog8lib/c64utils.p8 +++ b/prog8lib/c64utils.p8 @@ -649,7 +649,7 @@ _print_tens txa }} } -asmsub print_byte_decimal (value: ubyte @ A) -> clobbers(A,X,Y) -> () { +asmsub print_byte_decimal (value: byte @ A) -> clobbers(A,X,Y) -> () { ; ---- print the byte in A in decimal form, without left padding 0s %asm {{ pha @@ -745,7 +745,7 @@ _pr_decimal }} } -asmsub print_word_decimal (value: uword @ AY) -> clobbers(A,X,Y) -> () { +asmsub print_word_decimal (value: word @ AY) -> clobbers(A,X,Y) -> () { ; ---- print the (signed) word in A/Y in decimal form, without left padding 0s %asm {{ cpy #0