track vars per block for later 6502 generation

This commit is contained in:
Irmen de Jong 2018-09-28 23:04:36 +02:00
parent c5d251073f
commit 814b7ce6aa
3 changed files with 31 additions and 13 deletions

View File

@ -27,7 +27,7 @@ fun Number.toHex(): String {
class StackVmProgram(val name: String) {
private val instructions = mutableListOf<Instruction>()
private val variables = mutableMapOf<String, Value>()
private val variables = mutableMapOf<String, MutableMap<String, Value>>()
private val memory = mutableMapOf<Int, List<Value>>()
private val labels = mutableMapOf<String, Instruction>()
val numVariables: Int
@ -48,7 +48,12 @@ class StackVmProgram(val name: String) {
DataType.STR, DataType.STR_P, DataType.STR_S, DataType.STR_PS -> Value(decl.datatype, null, (decl.value as LiteralValue).strvalue)
DataType.ARRAY, DataType.ARRAY_W, DataType.MATRIX -> TODO("array/matrix variable values")
}
variables[scopedname] = value
// We keep the block structure intact: vars are stored per block. This is needed eventually for the actual 6502 code generation later...
val blockname = scopedname.substringBefore('.')
val blockvars = variables[blockname] ?: mutableMapOf()
variables[blockname] = blockvars
blockvars[scopedname] = value
}
fun writeAsText(out: PrintStream) {
@ -115,11 +120,9 @@ class Compiler(private val options: CompilationOptions) {
class VarGatherer(private val stackvmProg: StackVmProgram): IAstProcessor {
// collect all the VarDecls to make them into one global list
// @todo maybe keep the block structure intact and allocate them per block? this is needed eventually for the actual 6502 code generation so...
override fun process(decl: VarDecl): IStatement {
if (decl.type == VarDeclType.VAR) {
if (decl.type == VarDeclType.VAR)
stackvmProg.blockvar(decl.scopedname, decl)
}
// MEMORY variables are memory mapped and thus need no storage at all
return super.process(decl)
}

View File

@ -592,14 +592,14 @@ class MyStack<T> : Stack<T>() {
class Program (val name: String,
prog: MutableList<Instruction>,
val labels: Map<String, Instruction>,
val variables: Map<String, Value>,
val variables: Map<String, Map<String, Value>>,
val memory: Map<Int, List<Value>>)
{
companion object {
fun load(filename: String): Program {
val lines = File(filename).readLines().withIndex().iterator()
var memory = mapOf<Int, List<Value>>()
var vars = mapOf<String, Value>()
var vars = mapOf<String, Map<String, Value>>()
var instructions = mutableListOf<Instruction>()
var labels = mapOf<String, Instruction>()
while(lines.hasNext()) {
@ -689,8 +689,8 @@ class Program (val name: String,
}
}
private fun loadVars(lines: Iterator<IndexedValue<String>>): Map<String, Value> {
val vars = mutableMapOf<String, Value>()
private fun loadVars(lines: Iterator<IndexedValue<String>>): Map<String, Map<String, Value>> {
val vars = mutableMapOf<String, MutableMap<String, Value>>()
val splitpattern = Pattern.compile("\\s+")
while(true) {
val (lineNr, line) = lines.next()
@ -711,7 +711,10 @@ class Program (val name: String,
}
else -> throw VmExecutionException("invalid datatype at line ${lineNr+1}")
}
vars[name] = value
val blockname = name.substringBefore('.')
val blockvars = vars[blockname] ?: mutableMapOf()
vars[blockname] = blockvars
blockvars[name] = value
}
}
@ -828,7 +831,8 @@ class Program (val name: String,
}
out.println("%end_memory")
out.println("%variables")
for (variable in variables) {
// just flatten all block vars into one global list for now...
for(variable in variables.flatMap { e->e.value.entries}) {
val valuestr = variable.value.toString()
out.println("${variable.key} ${variable.value.type.toString().toLowerCase()} $valuestr")
}
@ -874,7 +878,9 @@ class StackVm(private var traceOutputFile: String?) {
fun load(program: Program, canvas: BitmapScreenPanel?) {
this.program = program.program
this.canvas = canvas
variables = program.variables.toMutableMap()
for(variable in program.variables.flatMap { e->e.value.entries })
variables[variable.key] = variable.value
if(variables.contains("A") ||
variables.contains("X") ||
variables.contains("Y") ||

View File

@ -44,7 +44,16 @@ class TestStackVmOpcodes {
vars: Map<String, Value>?=null,
labels: Map<String, Instruction>?=null,
mem: Map<Int, List<Value>>?=null) : Program {
return Program("test", ins, labels ?: mapOf(), vars ?: mapOf(), mem ?: mapOf())
val blockvars = mutableMapOf<String, MutableMap<String, Value>>()
if(vars!=null) {
for (blockvar in vars) {
val blockname = blockvar.key.substringBefore('.')
val variables = blockvars.getValue(blockname)
variables[blockvar.key] = blockvar.value
}
}
return Program("test", ins, labels ?: mapOf(), blockvars, mem ?: mapOf())
}
@Test