From 814b7ce6aa53a9e82150675b25175ced77f9ae04 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Fri, 28 Sep 2018 23:04:36 +0200 Subject: [PATCH] track vars per block for later 6502 generation --- compiler/src/prog8/compiler/Compiler.kt | 13 ++++++++----- compiler/src/prog8/stackvm/StackVm.kt | 20 +++++++++++++------- compiler/test/StackVMOpcodeTests.kt | 11 ++++++++++- 3 files changed, 31 insertions(+), 13 deletions(-) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index bf4672f56..fcda3f016 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -27,7 +27,7 @@ fun Number.toHex(): String { class StackVmProgram(val name: String) { private val instructions = mutableListOf() - private val variables = mutableMapOf() + private val variables = mutableMapOf>() private val memory = mutableMapOf>() private val labels = mutableMapOf() 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) } diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index f23eee33b..0737b502a 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -592,14 +592,14 @@ class MyStack : Stack() { class Program (val name: String, prog: MutableList, val labels: Map, - val variables: Map, + val variables: Map>, val memory: Map>) { companion object { fun load(filename: String): Program { val lines = File(filename).readLines().withIndex().iterator() var memory = mapOf>() - var vars = mapOf() + var vars = mapOf>() var instructions = mutableListOf() var labels = mapOf() while(lines.hasNext()) { @@ -689,8 +689,8 @@ class Program (val name: String, } } - private fun loadVars(lines: Iterator>): Map { - val vars = mutableMapOf() + private fun loadVars(lines: Iterator>): Map> { + val vars = mutableMapOf>() 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") || diff --git a/compiler/test/StackVMOpcodeTests.kt b/compiler/test/StackVMOpcodeTests.kt index e874066ac..b5020dcd5 100644 --- a/compiler/test/StackVMOpcodeTests.kt +++ b/compiler/test/StackVMOpcodeTests.kt @@ -44,7 +44,16 @@ class TestStackVmOpcodes { vars: Map?=null, labels: Map?=null, mem: Map>?=null) : Program { - return Program("test", ins, labels ?: mapOf(), vars ?: mapOf(), mem ?: mapOf()) + + val blockvars = mutableMapOf>() + 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