From d78ce775364843e4bcb35ec7f382e6eeecabc3c8 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 19 Nov 2024 20:36:00 +0100 Subject: [PATCH] improve vm error message when referencing a block name --- .../prog8/codegen/intermediate/IRCodeGen.kt | 4 +- docs/source/todo.rst | 6 +- examples/test.p8 | 69 ++++++------------- .../src/prog8/vm/VmProgramLoader.kt | 3 +- 4 files changed, 26 insertions(+), 56 deletions(-) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 5b50f6c20..1455d601e 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -92,7 +92,6 @@ class IRCodeGen( when (node) { is PtBuiltinFunctionCall -> require('.' !in node.name) { "builtin function call name should not be scoped: ${node.name}" } is PtFunctionCall -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } - is PtIdentifier -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } is PtAsmSub -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } is PtBlock -> require('.' !in node.name) { "block name should not be scoped: ${node.name}" } is PtConstant -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } @@ -102,8 +101,7 @@ class IRCodeGen( is PtVariable -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } is PtProgram -> require('.' !in node.name) { "program name should not be scoped: ${node.name}" } is PtSubroutineParameter -> require('.' in node.name) { "node $node name is not scoped: ${node.name}" } - else -> { /* node has no name */ - } + else -> { /* node has no name or is ok to have no dots in the name */ } } node.children.forEach { verifyPtNode(it) } } diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 57bac962a..cc3b5fb35 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -7,10 +7,10 @@ TODO Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ -- implement const long to store a 32 bit signed integer value. (constants should be able to be long?) -> const_long branch -- get rid of the BuiltinFunctionCall (and PtBuiltinFunctionCall) ast nodes distinction, just use 1 node type, they're mixed up now already anyways. -> remove-BFC-node branch - something to reduce the need to use fully qualified names all the time. 'with' ? Or 'using '? - Why are blocks without an addr moved BEHIND a block with an address? That's done in the StatementReorderer. +- Make extsub address a (constant) expression instead of a numeric literal +- rename 'string' module to 'strings' to be consistent with 'floats'? - on the C64: make the floating point routines @banked so that basic can be permanently banked out even if you use floats? But this will crash when the call is done from program code at $a000+ - Libraries: improve ability to create library files in prog8; for instance there's still stuff injected into the start of the start() routine AND there is separate setup logic going on before calling it. Make up our mind! Maybe all setup does need to be put into start() ? because the program cannot function correctly when the variables aren't initialized properly bss is not cleared etc. etc. @@ -20,8 +20,6 @@ Future Things and Ideas in certain situations, the "wrong" order of evaluation of function call arguments is done which results in overwriting registers that already got their value, which requires a lot of stack juggling (especially on plain 6502 cpu!) Maybe this routine can be made more intelligent. See usesOtherRegistersWhileEvaluating() and argumentsViaRegisters(). -- remove 'extsub' as a recognised alternative for 'extsub' -- remove the 'addmissingrts' compiler option. - Improve the SublimeText syntax file for prog8, you can also install this for 'bat': https://github.com/sharkdp/bat?tab=readme-ov-file#adding-new-syntaxes--language-definitions - Does it make codegen easier if everything is an expression? Start with the PtProgram ast , get rid of the statements there -> expressions that have Void data type - Can we support signed % (remainder) somehow? diff --git a/examples/test.p8 b/examples/test.p8 index 52164484c..58f2936e7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -1,53 +1,26 @@ -%import floats +%import textio main { sub start() { - float zz - thing() - zz = thang(1.22) - bool status - cx16.r0L, status = extfunction(42, 11223, 999, 1.22, true) - cx16.r0L, status = function(42, 11223, 999, 1.22, true) - func1(42) - func2(9999) - func3(42,9999) - func4(42,9999,12345) - } - - sub thing() -> bool { - cx16.r0++ - return true - } - - sub thang(float arg) -> float { - arg++ - return arg - } - - sub func1(ubyte arg) { - cx16.r0L +=arg - } - - sub func2(uword arg) { - cx16.r0 += arg - } - - sub func3(ubyte arg1, uword arg2) { - cx16.r0 += arg2 - cx16.r0L =+ arg1 - } - - sub func4(ubyte arg1, uword arg2, uword arg3) { - cx16.r0L =+ arg1 - cx16.r0 += arg2 - cx16.r1 += arg3 - } - - extsub $2000 = extfunction(ubyte arg1 @A, uword arg2 @XY, uword arg3 @R0, float frac @FAC1, bool flag @Pc) -> ubyte @Y, bool @Pz - - asmsub function(ubyte arg1 @A, uword arg2 @XY, uword arg3 @R0, float frac @FAC1, bool flag @Pc) -> ubyte @Y, bool @Pz { - %asm {{ - rts - }} + myblock.printit() + myblock2.printit2() + } +} + +myblock { + sub printit() { + txt.print_uwhex(&printit, true) + txt.nl() + txt.print_uwhex(&myblock, true) + txt.nl() + } +} + +myblock2 { + sub printit2() { + txt.print_uwhex(&printit2, true) + txt.nl() + txt.print_uwhex(&myblock2, true) + txt.nl() } } diff --git a/virtualmachine/src/prog8/vm/VmProgramLoader.kt b/virtualmachine/src/prog8/vm/VmProgramLoader.kt index 8c6a6efdb..617f0e337 100644 --- a/virtualmachine/src/prog8/vm/VmProgramLoader.kt +++ b/virtualmachine/src/prog8/vm/VmProgramLoader.kt @@ -153,12 +153,13 @@ class VmProgramLoader { // placeholder is not a variable, so it must be a label of a code chunk instead val target: IRCodeChunk? = chunks.firstOrNull { it.label==label } if(target==null) - throw IRParseException("placeholder not found in variables nor labels: $label") + throw IRParseException("label '$label' not found in variables nor labels. VM cannot reference other things such as blocks") else if(instr.opcode in OpcodesThatBranch) chunk.instructions[line] = instr.copy(branchTarget = target, address = null) else { var address = artificialLabelAddresses[label] if(address==null) { + // generate an artificial address address = 0xa000 + artificialLabelAddresses.size artificialLabelAddresses[label] = address }