improve vm error message when referencing a block name

This commit is contained in:
Irmen de Jong 2024-11-19 20:36:00 +01:00
parent b4fb43bc80
commit d78ce77536
4 changed files with 26 additions and 56 deletions

View File

@ -92,7 +92,6 @@ class IRCodeGen(
when (node) { when (node) {
is PtBuiltinFunctionCall -> require('.' !in node.name) { "builtin function call name should not be scoped: ${node.name}" } 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 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 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 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}" } 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 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 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}" } 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) } node.children.forEach { verifyPtNode(it) }
} }

View File

@ -7,10 +7,10 @@ TODO
Future Things and Ideas 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 <prefix>'? - something to reduce the need to use fully qualified names all the time. 'with' ? Or 'using <prefix>'?
- Why are blocks without an addr moved BEHIND a block with an address? That's done in the StatementReorderer. - 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+ - 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. - 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. 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 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!) 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(). 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 - 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 - 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? - Can we support signed % (remainder) somehow?

View File

@ -1,53 +1,26 @@
%import floats %import textio
main { main {
sub start() { sub start() {
float zz myblock.printit()
thing() myblock2.printit2()
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 { myblock {
cx16.r0++ sub printit() {
return true txt.print_uwhex(&printit, true)
txt.nl()
txt.print_uwhex(&myblock, true)
txt.nl()
}
} }
sub thang(float arg) -> float { myblock2 {
arg++ sub printit2() {
return arg txt.print_uwhex(&printit2, true)
} txt.nl()
txt.print_uwhex(&myblock2, true)
sub func1(ubyte arg) { txt.nl()
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
}}
} }
} }

View File

@ -153,12 +153,13 @@ class VmProgramLoader {
// placeholder is not a variable, so it must be a label of a code chunk instead // placeholder is not a variable, so it must be a label of a code chunk instead
val target: IRCodeChunk? = chunks.firstOrNull { it.label==label } val target: IRCodeChunk? = chunks.firstOrNull { it.label==label }
if(target==null) 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) else if(instr.opcode in OpcodesThatBranch)
chunk.instructions[line] = instr.copy(branchTarget = target, address = null) chunk.instructions[line] = instr.copy(branchTarget = target, address = null)
else { else {
var address = artificialLabelAddresses[label] var address = artificialLabelAddresses[label]
if(address==null) { if(address==null) {
// generate an artificial address
address = 0xa000 + artificialLabelAddresses.size address = 0xa000 + artificialLabelAddresses.size
artificialLabelAddresses[label] = address artificialLabelAddresses[label] = address
} }