mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 01:29:28 +00:00
allow passing byte/word for register/registerpair arguments, fix stackvm string parameter handling
This commit is contained in:
parent
8597ea2ec7
commit
b9958412c7
@ -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:
|
||||
|
@ -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, ")
|
||||
|
@ -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<secretnumber
|
||||
if guess<secretnumber
|
||||
vm_write_str("low!\n")
|
||||
else
|
||||
vm_write_str("high!\n")
|
||||
|
@ -7,219 +7,24 @@
|
||||
|
||||
ubyte ub1
|
||||
ubyte ub2
|
||||
byte b1
|
||||
byte b1 = -99
|
||||
byte b2
|
||||
uword uw1
|
||||
uword uw2
|
||||
word w1
|
||||
word w1 = -9999
|
||||
word w2
|
||||
float f1
|
||||
float f2
|
||||
float f3
|
||||
|
||||
; byte and ubyte output via print are all OK!
|
||||
c64scr.print_byte_decimal(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_byte_decimal(123)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_byte_decimal(b2ub(-99)) ; @todo allow signed values for register
|
||||
c64scr.print_byte_decimal(-99)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ubyte_decimal(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_decimal0(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_decimal(55)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_decimal0(55)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_decimal(254)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_decimal0(254)
|
||||
c64scr.print_byte_decimal(b1)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_ubyte_hex(0, 0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_hex(1, 0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_hex(0, $99)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_hex(1, $99)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_hex(0, $ea)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_ubyte_hex(1, $ea)
|
||||
c64scr.print_word_decimal(-9999)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
; print_uword_decimal are all OK!
|
||||
c64scr.print_uword_decimal(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_decimal0(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_decimal(987)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_decimal0(987)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_decimal(55666)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_decimal0(55666)
|
||||
c64scr.print_word_decimal(w1)
|
||||
c64.CHROUT('\n')
|
||||
c64scr.print_uword_hex(0, 0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(1, 0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(0, $99)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(1, $99)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(0, $1200)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(1, $1200)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(0, $fe98)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_uword_hex(1, $fe98)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
|
||||
; print_word_decimal works OK!
|
||||
c64scr.print_word_decimal(0)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(12345)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(32555)
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(uwrd(-1)) ; @todo allow signed values for registerpair
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(uwrd(-9999)) ; @todo allow signed values for registerpair
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(uwrd(-$5fff)) ; @todo allow signed values for registerpair
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(uwrd(-$6000)) ; @todo allow signed values for registerpair
|
||||
c64.CHROUT(' ')
|
||||
c64scr.print_word_decimal(uwrd(-$6001)) ; @todo allow signed values for registerpair
|
||||
c64.CHROUT('\n')
|
||||
|
||||
|
||||
b1 = -6
|
||||
b2 = 30
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_byte_decimal(b2ub(b2))
|
||||
c64.CHROUT('=')
|
||||
b1 += b2
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
b1 = 60
|
||||
b2 = -3
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_byte_decimal(b2ub(b2))
|
||||
c64.CHROUT('=')
|
||||
b1 += b2
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ub1 = 90
|
||||
ub2 = 50
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_ubyte_decimal(ub2)
|
||||
c64.CHROUT('=')
|
||||
ub1 += ub2
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ub1 = 50
|
||||
ub2 = 90
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_ubyte_decimal(ub2)
|
||||
c64.CHROUT('=')
|
||||
ub1 += ub2
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
|
||||
b1 = -6
|
||||
b2 = 30
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('-')
|
||||
c64scr.print_byte_decimal(b2ub(b2))
|
||||
c64.CHROUT('=')
|
||||
b1 -= b2
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
b1 = 60
|
||||
b2 = -3
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('-')
|
||||
c64scr.print_byte_decimal(b2ub(b2))
|
||||
c64.CHROUT('=')
|
||||
b1 -= b2
|
||||
c64scr.print_byte_decimal(b2ub(b1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ub1 = 90
|
||||
ub2 = 50
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('-')
|
||||
c64scr.print_ubyte_decimal(ub2)
|
||||
c64.CHROUT('=')
|
||||
ub1 -= ub2
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
ub1 = 50
|
||||
ub2 = 90
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('-')
|
||||
c64scr.print_ubyte_decimal(ub2)
|
||||
c64.CHROUT('=')
|
||||
ub1 -= ub2
|
||||
c64scr.print_ubyte_decimal(ub1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
w1 = -600
|
||||
w2 = 30000
|
||||
c64scr.print_uword_hex(1, uwrd(w1))
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_uword_hex(1, uwrd(w2))
|
||||
c64.CHROUT('=')
|
||||
w1 += w2
|
||||
c64scr.print_uword_hex(1, uwrd(w1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
w1 = 600
|
||||
w2 = -30000
|
||||
c64scr.print_uword_hex(1, uwrd(w1))
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_uword_hex(1, uwrd(w2))
|
||||
c64.CHROUT('=')
|
||||
w1 += w2
|
||||
c64scr.print_uword_hex(1, uwrd(w1))
|
||||
c64.CHROUT('\n')
|
||||
|
||||
uw1 = 600
|
||||
uw2 = 40000
|
||||
c64scr.print_uword_decimal(uw1)
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_uword_decimal(uw2)
|
||||
c64.CHROUT('=')
|
||||
uw1 += uw2
|
||||
c64scr.print_uword_decimal(uw1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
uw1 = 40000
|
||||
uw2 = 600
|
||||
c64scr.print_uword_decimal(uw1)
|
||||
c64.CHROUT('+')
|
||||
c64scr.print_uword_decimal(uw2)
|
||||
c64.CHROUT('=')
|
||||
uw1 += uw2
|
||||
c64scr.print_uword_decimal(uw1)
|
||||
c64.CHROUT('\n')
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -234,26 +234,32 @@ class AstChecker(private val namespace: INameScope,
|
||||
if(subroutine.asmReturnvaluesRegisters.size != subroutine.returntypes.size)
|
||||
err("number of return registers is not the same as number of return values")
|
||||
for(param in subroutine.parameters.zip(subroutine.asmParameterRegisters)) {
|
||||
if(param.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y))
|
||||
if(param.first.type!=DataType.UBYTE)
|
||||
err("parameter '${param.first.name}' should be ubyte")
|
||||
else if(param.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY))
|
||||
if(param.first.type!=DataType.UWORD)
|
||||
err("parameter '${param.first.name}' should be uword")
|
||||
else if(param.second.statusflag!=null)
|
||||
if(param.first.type!=DataType.UBYTE)
|
||||
if(param.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) {
|
||||
if (param.first.type != DataType.UBYTE && param.first.type != DataType.BYTE)
|
||||
err("parameter '${param.first.name}' should be (u)byte")
|
||||
}
|
||||
else if(param.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
|
||||
if (param.first.type != DataType.UWORD && param.first.type != DataType.WORD && param.first.type !in StringDatatypes && param.first.type !in ArrayDatatypes)
|
||||
err("parameter '${param.first.name}' should be (u)word/address")
|
||||
}
|
||||
else if(param.second.statusflag!=null) {
|
||||
if (param.first.type != DataType.UBYTE)
|
||||
err("parameter '${param.first.name}' should be ubyte")
|
||||
}
|
||||
}
|
||||
for(ret in subroutine.returntypes.withIndex().zip(subroutine.asmReturnvaluesRegisters)) {
|
||||
if(ret.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y))
|
||||
if(ret.first.value!=DataType.UBYTE)
|
||||
err("return value #${ret.first.index+1} should be ubyte")
|
||||
else if(ret.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY))
|
||||
if(ret.first.value!=DataType.UWORD)
|
||||
err("return value #${ret.first.index+1} should be uword")
|
||||
else if(ret.second.statusflag!=null)
|
||||
if(ret.first.value!=DataType.UBYTE)
|
||||
err("return value #${ret.first.index+1} should be ubyte")
|
||||
if(ret.second.registerOrPair in setOf(RegisterOrPair.A, RegisterOrPair.X, RegisterOrPair.Y)) {
|
||||
if (ret.first.value != DataType.UBYTE && ret.first.value != DataType.BYTE)
|
||||
err("return value #${ret.first.index + 1} should be (u)byte")
|
||||
}
|
||||
else if(ret.second.registerOrPair in setOf(RegisterOrPair.AX, RegisterOrPair.AY, RegisterOrPair.XY)) {
|
||||
if (ret.first.value != DataType.UWORD && ret.first.value != DataType.WORD && ret.first.value !in StringDatatypes && ret.first.value !in ArrayDatatypes)
|
||||
err("return value #${ret.first.index + 1} should be (u)word/address")
|
||||
}
|
||||
else if(ret.second.statusflag!=null) {
|
||||
if (ret.first.value != DataType.UBYTE)
|
||||
err("return value #${ret.first.index + 1} should be ubyte")
|
||||
}
|
||||
}
|
||||
|
||||
val regCounts = mutableMapOf<Register, Int>().withDefault { 0 }
|
||||
|
@ -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)
|
||||
|
@ -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()))
|
||||
}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user