stackvm program tweaks

This commit is contained in:
Irmen de Jong 2018-09-16 17:45:51 +02:00
parent 719a446d19
commit 88a9f2d493
2 changed files with 413 additions and 355 deletions

View File

@ -122,7 +122,9 @@ class Compiler(private val options: CompilationOptions) {
} }
} }
class StatementTranslator(private val stackvmProg: StackVmProgram, private val namespace: INameScope): IAstProcessor { }
private class StatementTranslator(private val stackvmProg: StackVmProgram, private val namespace: INameScope): IAstProcessor {
var stmtUniqueSequenceNr = 0 var stmtUniqueSequenceNr = 0
private set private set
@ -478,13 +480,17 @@ class Compiler(private val options: CompilationOptions) {
private fun translate(loop: ForLoop) { private fun translate(loop: ForLoop) {
stackvmProg.line(loop.position) stackvmProg.line(loop.position)
println("@TODO: translate FOR LOOP $loop") // @todo FOR LOOP if(loop.loopRegister!=null) {
val reg = loop.loopRegister
println("@TODO translate for loop (register $reg)") // TODO
} else {
val loopvar = (loop.loopVar!!.targetStatement(namespace) as VarDecl)
println("@TODO translate for loop (variable $loopvar)") // TODO
} }
} }
} }
class StackVmProgram(val name: String) { class StackVmProgram(val name: String) {
val variables = mutableMapOf<String, VarDecl>() val variables = mutableMapOf<String, VarDecl>()

View File

@ -5,6 +5,7 @@ import prog8.compiler.Mflpt5
import prog8.compiler.Petscii import prog8.compiler.Petscii
import java.awt.EventQueue import java.awt.EventQueue
import java.io.File import java.io.File
import java.io.PrintStream
import java.io.PrintWriter import java.io.PrintWriter
import java.util.* import java.util.*
import java.util.regex.Pattern import java.util.regex.Pattern
@ -133,41 +134,41 @@ enum class Syscall(val callNr: Short) {
GFX_CLEARSCR(17), // clear the screen with color pushed on stack GFX_CLEARSCR(17), // clear the screen with color pushed on stack
GFX_TEXT(18), // write text on screen at (x,y,color,text) pushed on stack in that order GFX_TEXT(18), // write text on screen at (x,y,color,text) pushed on stack in that order
FUNC_P_CARRY(100), FUNC_P_CARRY(64),
FUNC_P_IRQD(101), FUNC_P_IRQD(65),
FUNC_ROL(102), FUNC_ROL(66),
FUNC_ROR(103), FUNC_ROR(67),
FUNC_ROL2(104), FUNC_ROL2(68),
FUNC_ROR2(105), FUNC_ROR2(69),
FUNC_LSL(106), FUNC_LSL(70),
FUNC_LSR(107), FUNC_LSR(71),
FUNC_SIN(108), FUNC_SIN(72),
FUNC_COS(109), FUNC_COS(73),
FUNC_ABS(110), FUNC_ABS(74),
FUNC_ACOS(111), FUNC_ACOS(75),
FUNC_ASIN(112), FUNC_ASIN(76),
FUNC_TAN(113), FUNC_TAN(77),
FUNC_ATAN(114), FUNC_ATAN(78),
FUNC_LOG(115), FUNC_LOG(79),
FUNC_LOG10(116), FUNC_LOG10(80),
FUNC_SQRT(117), FUNC_SQRT(81),
FUNC_RAD(118), FUNC_RAD(82),
FUNC_DEG(119), FUNC_DEG(83),
FUNC_ROUND(120), FUNC_ROUND(84),
FUNC_FLOOR(121), FUNC_FLOOR(85),
FUNC_CEIL(122), FUNC_CEIL(86),
FUNC_MAX(123), FUNC_MAX(87),
FUNC_MIN(124), FUNC_MIN(88),
FUNC_AVG(125), FUNC_AVG(89),
FUNC_SUM(126), FUNC_SUM(90),
FUNC_LEN(127), FUNC_LEN(91),
FUNC_ANY(128), FUNC_ANY(92),
FUNC_ALL(129), FUNC_ALL(93),
FUNC_LSB(130), FUNC_LSB(94),
FUNC_MSB(131), FUNC_MSB(95),
FUNC_RND(132), // push a random byte on the stack FUNC_RND(96), // push a random byte on the stack
FUNC_RNDW(133), // push a random word on the stack FUNC_RNDW(97), // push a random word on the stack
FUNC_RNDF(134) // push a random float on the stack (between 0.0 and 1.0) FUNC_RNDF(98) // push a random float on the stack (between 0.0 and 1.0)
} }
class Memory { class Memory {
@ -259,7 +260,15 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
} }
override fun toString(): String { override fun toString(): String {
return "$type: $numericvalue $stringvalue" return when(type) {
DataType.BYTE -> "%02x".format(byteval)
DataType.WORD -> "%04x".format(wordval)
DataType.FLOAT -> floatval.toString()
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> "\"$stringvalue\""
DataType.ARRAY -> TODO("array")
DataType.ARRAY_W -> TODO("word array")
DataType.MATRIX -> TODO("matrix")
}
} }
fun numericValue(): Number { fun numericValue(): Number {
@ -493,7 +502,7 @@ class Value(val type: DataType, private val numericvalue: Number?, val stringval
} }
data class Instruction(val opcode: Opcode, open class Instruction(val opcode: Opcode,
val arg: Value? = null, val arg: Value? = null,
val callLabel: String? = null) val callLabel: String? = null)
{ {
@ -501,13 +510,29 @@ data class Instruction(val opcode: Opcode,
var nextAlt: Instruction? = null var nextAlt: Instruction? = null
override fun toString(): String { override fun toString(): String {
return if(callLabel==null) val argStr = arg?.toString() ?: ""
"$opcode $arg" val result =
else when {
"$opcode $callLabel $arg" opcode==Opcode.SYSCALL -> {
val syscall = Syscall.values().find { it.callNr==arg!!.numericValue() }
"syscall $syscall"
}
callLabel==null -> "${opcode.toString().toLowerCase()} $argStr"
else -> "${opcode.toString().toLowerCase()} $callLabel $argStr"
}
.trimEnd()
if(opcode==Opcode.LINE)
return " _$result"
return " $result"
} }
} }
class Label(val name: String) : Instruction(opcode = Opcode.NOP) {
override fun toString(): String {
return "$name:"
}
}
private class VmExecutionException(msg: String?) : Exception(msg) private class VmExecutionException(msg: String?) : Exception(msg)
@ -527,8 +552,9 @@ private class MyStack<T> : Stack<T>() {
} }
} }
class Program (prog: MutableList<Instruction>, class Program (val name: String,
labels: Map<String, Instruction>, prog: MutableList<Instruction>,
val labels: Map<String, Instruction>,
val variables: Map<String, Value>, val variables: Map<String, Value>,
val memory: Map<Int, List<Value>>) val memory: Map<Int, List<Value>>)
{ {
@ -554,7 +580,7 @@ class Program (prog: MutableList<Instruction>,
} }
else throw VmExecutionException("syntax error at line ${lineNr+1}") else throw VmExecutionException("syntax error at line ${lineNr+1}")
} }
return Program(instructions, labels, vars, memory) return Program(filename, instructions, labels, vars, memory)
} }
private fun loadInstructions(lines: Iterator<IndexedValue<String>>): Pair<MutableList<Instruction>, Map<String, Instruction>> { private fun loadInstructions(lines: Iterator<IndexedValue<String>>): Pair<MutableList<Instruction>, Map<String, Instruction>> {
@ -706,10 +732,10 @@ class Program (prog: MutableList<Instruction>,
prog.add(Instruction(Opcode.TERMINATE)) prog.add(Instruction(Opcode.TERMINATE))
prog.add(Instruction(Opcode.NOP)) prog.add(Instruction(Opcode.NOP))
program = prog program = prog
connect(labels) connect()
} }
private fun connect(labels: Map<String, Instruction>) { private fun connect() {
val it1 = program.iterator() val it1 = program.iterator()
val it2 = program.iterator() val it2 = program.iterator()
it2.next() it2.next()
@ -753,6 +779,30 @@ class Program (prog: MutableList<Instruction>,
} }
} }
} }
fun print(out: PrintStream) {
out.println("; stackVM program code for '$name'")
out.println("%memory")
if(memory.isNotEmpty()) {
TODO("print out initial memory load")
}
out.println("%end_memory")
out.println("%variables")
for (variable in variables) {
val valuestr = variable.value.toString()
out.println("${variable.key} ${variable.value.type.toString().toLowerCase()} $valuestr")
}
out.println("%end_variables")
out.println("%instructions")
val labels = this.labels.entries.associateBy({it.value}) {it.key}
for(instr in this.program) {
val label = labels[instr]
if(label!=null)
out.println("$label:")
out.println(instr)
}
out.println("%end_instructions")
}
} }
@ -1324,6 +1374,8 @@ fun main(args: Array<String>) {
} }
val program = Program.load(args.first()) val program = Program.load(args.first())
program.print(System.out)
val vm = StackVm(traceOutputFile = null) val vm = StackVm(traceOutputFile = null)
val dialog = ScreenDialog() val dialog = ScreenDialog()
vm.load(program, dialog.canvas) vm.load(program, dialog.canvas)