From f675dbc726cff99156ec0db038328edbd8279650 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 30 Jun 2022 21:48:42 +0200 Subject: [PATCH] vm var allocator now also recognises the memory-mapped variables. no longer crashes --- codeAst/src/prog8/code/SymbolTable.kt | 20 +++++++- .../codegen/virtual/VariableAllocator.kt | 12 +++++ .../astprocessing/SymbolTableMaker.kt | 8 ++- docs/source/todo.rst | 4 +- examples/test.p8 | 50 +++++++++---------- 5 files changed, 65 insertions(+), 29 deletions(-) diff --git a/codeAst/src/prog8/code/SymbolTable.kt b/codeAst/src/prog8/code/SymbolTable.kt index e152af41b..1304f246f 100644 --- a/codeAst/src/prog8/code/SymbolTable.kt +++ b/codeAst/src/prog8/code/SymbolTable.kt @@ -40,6 +40,20 @@ class SymbolTable : StNode("", StNodeType.GLOBAL, Position.DUMMY) { vars } + val allMemMappedVariables: Collection by lazy { + val vars = mutableListOf() + fun collect(node: StNode) { + for(child in node.children) { + if(child.value.type== StNodeType.MEMVAR) + vars.add(child.value as StMemVar) + else + collect(child.value) + } + } + collect(this) + vars + } + override fun lookup(scopedName: List) = flat[scopedName] } @@ -186,7 +200,11 @@ class StConstant(name: String, val dt: DataType, val value: Double, position: Po } -class StMemVar(name: String, val dt: DataType, val address: UInt, position: Position) : +class StMemVar(name: String, + val dt: DataType, + val address: UInt, + val length: Int?, // for arrays: the number of elements, for strings: number of characters *including* the terminating 0-byte + position: Position) : StNode(name, StNodeType.MEMVAR, position) { override fun printProperties() { print("$name dt=$dt address=${address.toHex()}") diff --git a/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt b/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt index fdf767908..d2ab4cbb6 100644 --- a/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt +++ b/codeGenVirtual/src/prog8/codegen/virtual/VariableAllocator.kt @@ -26,6 +26,18 @@ class VariableAllocator(private val st: SymbolTable, private val program: PtProg allocations[variable.scopedName] = nextLocation nextLocation += memsize } + for (memvar in st.allMemMappedVariables) { + // TODO virtual machine doesn't have memory mapped variables, so treat them as regular allocated variables for now + val memsize = + when (memvar.dt) { + in NumericDatatypes -> program.memsizer.memorySize(memvar.dt) + in ArrayDatatypes -> program.memsizer.memorySize(memvar.dt, memvar.length!!) + else -> throw InternalCompilerException("weird dt") + } + + allocations[memvar.scopedName] = nextLocation + nextLocation += memsize + } freeMemoryStart = nextLocation } diff --git a/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt b/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt index 651eb4e6d..f5b2ee1f4 100644 --- a/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/SymbolTableMaker.kt @@ -72,7 +72,13 @@ internal class SymbolTableMaker: IAstVisitor { StStaticVariable(decl.name, decl.datatype, initialNumeric, initialString, initialArray, numElements, decl.zeropage, decl.position) } VarDeclType.CONST -> StConstant(decl.name, decl.datatype, (decl.value as NumericLiteral).number, decl.position) - VarDeclType.MEMORY -> StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), decl.position) + VarDeclType.MEMORY -> { + val numElements = + if(decl.datatype in ArrayDatatypes) + decl.arraysize!!.constIndex() + else null + StMemVar(decl.name, decl.datatype, (decl.value as NumericLiteral).number.toUInt(), numElements, decl.position) + } } scopestack.peek().add(node) // st.origAstLinks[decl] = node diff --git a/docs/source/todo.rst b/docs/source/todo.rst index f382859b2..c783ac76a 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,9 +3,9 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- assembler incorrectly assembles hello.asm now (crash when run) +- petaxian roller.p8 line 49 (also see test.p8) generates large code compared to 8.2 -- why can't while and until loops use NOT condition instead of Cond==0 ? Fix this! +- assembler incorrectly assembles hello.asm now (crash when run) - code gen for if statements has become inefficient? vm/6502? if not diskio.iteration_in_progress or not num_bytes diff --git a/examples/test.p8 b/examples/test.p8 index e94619f2d..836e28d2f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -6,38 +6,38 @@ main { sub start() { + ubyte a1 = 0 - ubyte a2 = 42 - ubyte a3 = 1 + ubyte a2 = 128 - if (a1==0)==0 - a3 = (a1==0)==0 - if (a1!=0)==0 - a3 = (a1!=0)==0 - if (a1==0)!=0 - a3 = (a1==0)!=0 + ; petaxian roller.p8 line 49 + ; super large in new version, ok in 8.2.... + ; TODO cx16.r0 = a2 + 25 + (a1/40) + ; txt.setcc( a1, a2 + 25 + (a1/40), 11,22) - if (a1!=0)!=0 - a3 = (a1!=0)!=0 + if a1 and a2 { + a1++ + } - if (a1==0) or (a2==0) - a3 = (a1==0) or (a2==0) + if a1!=99 and not a2 { + a1++ + } - if (a1==0) and (a2==0) - a3 = (a1==0) and (a2==0) - - if not a1 or not a2 or not(not(a3)) - a3=not a1 or not a2 or not(not(a3)) - - if (a1==0) or (a2==0) - a3 = (a1==0) or (a2==0) - - if (a1==0) and (a2==0) - a3 = (a1==0) and (a2==0) - - txt.print_ub(a3) +; while a1 != a2 { +; a1++ +; } +; +; while a1!='\"' { +; a1++ +; } +; do { +; a1++ +; } until a1==99 +; +;close_end: +; a1++ ; ; a "pixelshader":