mirror of
https://github.com/irmen/prog8.git
synced 2026-04-20 11:17:01 +00:00
%breakpoint! introduced to place after an assignment to make it parse correctly
This commit is contained in:
@@ -1092,7 +1092,7 @@ internal class AstChecker(private val program: Program,
|
||||
|
||||
if(decl.datatype.isStructInstance && decl.origin!=VarDeclOrigin.SUBROUTINEPARAM) {
|
||||
if(decl.type==VarDeclType.MEMORY)
|
||||
errors.err("cannot declare memory mapped struct instances, use a pointer and memory allocation call or direct address assignment instead", decl.position)
|
||||
errors.err("struct instances cannot be declared as memory-mapped currently, use a pointer and memory allocation call or direct address assignment instead", decl.position)
|
||||
else
|
||||
errors.err("struct instances cannot be declared directly, use a pointer and memory allocation call or direct address assignment instead", decl.position)
|
||||
}
|
||||
|
||||
@@ -1173,5 +1173,30 @@ main {
|
||||
compileText(VMTarget(), optimize=false, src, outputDir, writeAssembly=false) shouldNotBe null
|
||||
}
|
||||
|
||||
test("breakpoint after expression") {
|
||||
val src="""
|
||||
main {
|
||||
ubyte a,b
|
||||
|
||||
sub start() {
|
||||
func1()
|
||||
func2()
|
||||
}
|
||||
|
||||
sub func1() {
|
||||
a = b
|
||||
%breakpoint ; parse error
|
||||
}
|
||||
|
||||
sub func2() {
|
||||
a = b
|
||||
%breakpoint! ; parse ok
|
||||
}
|
||||
}"""
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(VMTarget(), optimize=false, src, outputDir, errors=errors) shouldBe null
|
||||
errors.errors.size shouldBe 3
|
||||
errors.errors[1] shouldContain "12:10: undefined symbol: breakpoint"
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -340,10 +340,20 @@ Directives
|
||||
}
|
||||
|
||||
|
||||
.. data:: %breakpoint
|
||||
.. data:: %breakpoint! or %breakpoint
|
||||
|
||||
Level: not at module scope.
|
||||
Defines a debugging breakpoint at this location. See :ref:`debugging`
|
||||
The version with the explamation point '!' at the end can be used even
|
||||
if the breakpoint follows an expression. If you don't use the '!' version in this case
|
||||
the compiler may think it is just a term in the expression (modulo operator and breakpoint operand value),
|
||||
instead of a breakpoint directive::
|
||||
|
||||
a = b
|
||||
%breakpoint ; parse error because it thinks it is part of the previous line
|
||||
|
||||
a = b
|
||||
%breakpoint! ; parsed correctly as directive
|
||||
|
||||
|
||||
.. data:: %encoding <encodingname>
|
||||
|
||||
@@ -154,9 +154,11 @@ Because it implies pointer dereferencing you can usually omit the explicit `^^`,
|
||||
|
||||
|
||||
.. note::
|
||||
Structs are only supported as a *reference type* (via a pointer). It is currently not possible to use them as a value type.
|
||||
Structs are currently only supported as a *reference type* (they always have to be accessed through a pointer).
|
||||
It is not yet possible to use them as a value type, or as memory-mapped types.
|
||||
This means you cannot create an array of structs either - only arrays of pointers to structs.
|
||||
There are a couple of simple case where the compiler allows assignment of struct instances. You are allowed to write::
|
||||
There are a couple of simple case where the compiler does allow assignment of struct instances though, and it will
|
||||
automatically copy all the fields for you. You are allowed to write::
|
||||
|
||||
ptr2^^ = ptr1^^
|
||||
ptr2^^ = ptr1[2]
|
||||
@@ -166,14 +168,14 @@ Because it implies pointer dereferencing you can usually omit the explicit `^^`,
|
||||
In the future more cases may be supported.
|
||||
|
||||
.. note::
|
||||
Using structs instead of plain arrays may result in less efficent code being generated.
|
||||
Using structs instead of plain arrays usually results in more and less efficent code being generated.
|
||||
This is because the 6502 CPU is not particularly well equipped to dealing with pointers and accessing struct fields via offsets,
|
||||
as compared to direct variable access or array indexing. The prog8 program code may be easier to work with though!
|
||||
|
||||
.. note::
|
||||
Accessing the first field in a struct is more efficient than subsequent fields, because it
|
||||
is at offset 0 so no additional addition has to be done on a pointer to reach the first field.
|
||||
Try to put the most often accessed field as the first field to gain a rather substantial code size and efficiency boost.
|
||||
is at offset 0 so no additional addition has to be computed on a pointer to reach the first field.
|
||||
Try to put the most often accessed field as the first field to potentially gain a rather substantial boost in code efficiency.
|
||||
|
||||
|
||||
Static initialization of structs
|
||||
|
||||
@@ -85,7 +85,6 @@ Future Things and Ideas
|
||||
9 }
|
||||
- improve ANTLR grammar with better error handling (according to Qwen AI)
|
||||
- allow memory() to occur in array initializer
|
||||
- %breakpoint after an assignment is parsed as part of the expression (x % breakpoint), that should not happen
|
||||
- when a complete block is removed because unused, suppress all info messages about everything in the block being removed
|
||||
- fix the line, cols in Position, sometimes they count from 0 sometimes from 1
|
||||
- is "checkAssignmentCompatible" redundant (gets called just 1 time!) when we also have "checkValueTypeAndRange" ?
|
||||
|
||||
+12
-28
@@ -1,34 +1,18 @@
|
||||
main {
|
||||
ubyte a,b
|
||||
|
||||
sub start() {
|
||||
^^uword @shared ptr
|
||||
func1()
|
||||
func2()
|
||||
}
|
||||
|
||||
add1()
|
||||
add2()
|
||||
sub1()
|
||||
sub2()
|
||||
sub func1() {
|
||||
a = b
|
||||
%breakpoint
|
||||
}
|
||||
|
||||
sub add1() {
|
||||
ptr += 5
|
||||
cx16.r0 = ptr + 5
|
||||
cx16.r0 = peekw(ptr + 5)
|
||||
}
|
||||
|
||||
sub add2() {
|
||||
ptr += cx16.r0L
|
||||
cx16.r0 = ptr + cx16.r0L
|
||||
cx16.r0 = peekw(ptr + cx16.r0L)
|
||||
}
|
||||
|
||||
sub sub1() {
|
||||
ptr -= 5
|
||||
cx16.r0 = ptr - 5
|
||||
cx16.r0 = peekw(ptr - 5)
|
||||
}
|
||||
|
||||
sub sub2() {
|
||||
ptr -= cx16.r0L
|
||||
cx16.r0 = ptr - cx16.r0L
|
||||
cx16.r0 = peekw(ptr - cx16.r0L)
|
||||
}
|
||||
sub func2() {
|
||||
a = b
|
||||
%breakpoint!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ labeldef : identifier ':' ;
|
||||
|
||||
unconditionaljump : GOTO expression ;
|
||||
|
||||
directive : directivename (directivenamelist | (directivearg? | directivearg (',' directivearg)*)) ;
|
||||
directive : directivename '!'? (directivenamelist | (directivearg? | directivearg (',' directivearg)*)) ;
|
||||
|
||||
directivename: '%' UNICODEDNAME;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user