vm: add sorting and reverse functions, fix value arg out of range errors

This commit is contained in:
Irmen de Jong
2022-04-05 17:48:49 +02:00
parent d78bfcc35c
commit 8e4c0f7c22
7 changed files with 125 additions and 4 deletions
@@ -4,6 +4,7 @@ import prog8.code.core.CompilationOptions
import prog8.code.core.IAssemblyProgram
import prog8.vm.Instruction
import prog8.vm.Opcode
import prog8.vm.OpcodesWithAddress
import prog8.vm.VmDataType
import java.io.BufferedWriter
import kotlin.io.path.bufferedWriter
@@ -66,7 +67,7 @@ internal class VmCodeInstruction(
val ins = Instruction(opcode, type, reg1, reg2, reg3, value, symbol)
init {
if(value!=null) {
if(value!=null && opcode !in OpcodesWithAddress) {
when (type) {
VmDataType.BYTE -> {
if (value < -128 || value > 255)
@@ -1,8 +1,12 @@
package prog8.codegen.virtual
import prog8.code.StArray
import prog8.code.StStaticVariable
import prog8.code.ast.PtBuiltinFunctionCall
import prog8.code.ast.PtIdentifier
import prog8.code.ast.PtNumber
import prog8.code.ast.PtString
import prog8.code.core.DataType
import prog8.code.core.WordDatatypes
import prog8.vm.Opcode
import prog8.vm.Syscall
@@ -127,6 +131,37 @@ internal class BuiltinFuncGen(private val codeGen: CodeGen, private val exprGen:
if(resultRegister!=0)
code += VmCodeInstruction(Opcode.LOADR, VmDataType.BYTE, reg1=resultRegister, reg2=0)
}
"sort" -> {
val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
val sortSyscall =
when(array.dt) {
DataType.ARRAY_UB -> Syscall.SORT_UBYTE
DataType.ARRAY_B -> Syscall.SORT_BYTE
DataType.ARRAY_UW -> Syscall.SORT_UWORD
DataType.ARRAY_W -> Syscall.SORT_WORD
DataType.FLOAT -> TODO("float sort")
DataType.STR -> Syscall.SORT_UBYTE
else -> throw IllegalArgumentException("weird type to sort")
}
code += exprGen.translateExpression(call.args[0], 0)
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += VmCodeInstruction(Opcode.SYSCALL, value=sortSyscall.ordinal)
}
"reverse" -> {
val arrayName = call.args[0] as PtIdentifier
val array = codeGen.symbolTable.flat.getValue(arrayName.targetName) as StStaticVariable
val sortSyscall =
when(array.dt) {
DataType.ARRAY_UB, DataType.ARRAY_B, DataType.STR -> Syscall.REVERSE_BYTES
DataType.ARRAY_UW, DataType.ARRAY_W -> Syscall.REVERSE_WORDS
DataType.FLOAT -> TODO("reverse floats")
else -> throw IllegalArgumentException("weird type to reverse")
}
code += exprGen.translateExpression(call.args[0], 0)
code += VmCodeInstruction(Opcode.LOAD, VmDataType.BYTE, reg1=1, value=array.length)
code += VmCodeInstruction(Opcode.SYSCALL, value=sortSyscall.ordinal)
}
else -> {
TODO("builtinfunc ${call.name}")
// code += VmCodeInstruction(Opcode.NOP))