From bf69219f9808325311a56520c57da03946346e0d Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 23 Jan 2021 22:39:30 +0100 Subject: [PATCH] allow uwordpointer[index] syntax as equivalent to @(uwordpointer+index) index can be >255 here! --- .../ast/processing/StatementReorderer.kt | 18 ++++++++++ docs/source/programming.rst | 11 ++++-- docs/source/syntaxreference.rst | 4 +++ docs/source/todo.rst | 3 +- examples/test.p8 | 34 ++++--------------- 5 files changed, 39 insertions(+), 31 deletions(-) diff --git a/compiler/src/prog8/ast/processing/StatementReorderer.kt b/compiler/src/prog8/ast/processing/StatementReorderer.kt index e78eb18ec..c37fb63d9 100644 --- a/compiler/src/prog8/ast/processing/StatementReorderer.kt +++ b/compiler/src/prog8/ast/processing/StatementReorderer.kt @@ -81,6 +81,24 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte } override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable { + + val arrayVar = arrayIndexedExpression.arrayvar.targetVarDecl(program.namespace) + if(arrayVar!=null && arrayVar.datatype == DataType.UWORD) { + // rewrite pointervar[index] into @(pointervar+index) + val indexer = arrayIndexedExpression.indexer + val index = (indexer.indexNum ?: indexer.indexVar)!! + val add = BinaryExpression(arrayIndexedExpression.arrayvar, "+", index, arrayIndexedExpression.position) + return if(parent is AssignTarget) { + // we're part of the target of an assignment, we have to actually change the assign target itself + val memwrite = DirectMemoryWrite(add, arrayIndexedExpression.position) + val newtarget = AssignTarget(null, null, memwrite, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(parent, newtarget, parent.parent)) + } else { + val memread = DirectMemoryRead(add, arrayIndexedExpression.position) + listOf(IAstModification.ReplaceNode(arrayIndexedExpression, memread, parent)) + } + } + when (val expr2 = arrayIndexedExpression.indexer.origExpression) { is NumericLiteralValue -> { arrayIndexedExpression.indexer.indexNum = expr2 diff --git a/docs/source/programming.rst b/docs/source/programming.rst index 05514bd99..be9105ad8 100644 --- a/docs/source/programming.rst +++ b/docs/source/programming.rst @@ -381,13 +381,20 @@ Direct access to memory locations Normally memory locations are accessed by a *memory mapped* name, such as ``c64.BGCOL0`` that is defined as the memory mapped address $d021. -If you want to access a memory location directly (by using the address itself), without defining -a memory mapped location, you can do so by enclosing the address in ``@(...)``:: +If you want to access a memory location directly (by using the address itself or via an uword pointer variable), +without defining a memory mapped location, you can do so by enclosing the address in ``@(...)``:: color = @($d020) ; set the variable 'color' to the current c64 screen border color ("peek(53280)") @($d020) = 0 ; set the c64 screen border to black ("poke 53280,0") @(vic+$20) = 6 ; you can also use expressions to 'calculate' the address +This is the official syntax to 'dereference a pointer' as it is often named in other languages. +You can actually also use the array indexing notation for this. It will be silently converted into +the direct memory access expression as explained above. Note that this also means that unlike regular arrays, +the index is not limited to an ubyte value. You can use a full uword to index a pointer variable like this:: + + pointervar[999] = 0 ; set memory byte to zero at location pointervar + 999. + Converting types into other types ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/docs/source/syntaxreference.rst b/docs/source/syntaxreference.rst index 121602857..e65cd2995 100644 --- a/docs/source/syntaxreference.rst +++ b/docs/source/syntaxreference.rst @@ -335,6 +335,10 @@ directly access the memory. Enclose a numeric expression or literal with ``@(... @($d020) = 0 ; set the c64 screen border to black ("poke 53280,0") @(vic+$20) = 6 ; a dynamic expression to 'calculate' the address +The array indexing notation is syntactic sugar for such a direct memory access expression:: + + pointervar[999] = 0 ; equivalent to @(pointervar+999) = 0 + Constants ^^^^^^^^^ diff --git a/docs/source/todo.rst b/docs/source/todo.rst index fd1e0473f..e2db74815 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -2,8 +2,7 @@ TODO ==== -- allow uwordpointer[index] syntax -> transform into @(uwordpointer+index) allow index to be >255! -- add offsetof() to get the byte offset of struct members +- add offsetof() to get the byte offset of struct members. - add any2(), all2(), max2(), min2(), reverse2(), sum2(), sort2() that take (array, startindex, length) arguments - optimize for loop iterations better to allow proper inx, cpx #value, bne loop instructions (like repeat loop) - why is there a beq _prog8_label_2_repeatend at the end of repeat loops? seems unused diff --git a/examples/test.p8 b/examples/test.p8 index 601a5863d..785428bd7 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -8,33 +8,13 @@ main { sub start() { - ; TODO test memcopy - ; counts: 0, 1, 2, 254, 255, 256, 257, 512, 1000 - uword buffer=memory("buffer",1000) - uword ones=memory("ones",1000) - - sys.memset(buffer, 1000, '.') - @(buffer) = '<' - @(buffer+255) = '>' - @(buffer+256) = '<' - @(buffer+511) = '>' - @(buffer+512) = '<' - @(buffer+767) = '>' - @(buffer+768) = '<' - @(buffer+999) = '!' - sys.memset(ones, 1000, '*') - - txt.clear_screen() - txt.print("\n\n\n\n\n\n\n\n\n") - - sys.memcopy(ones, buffer, 999) - - uword scr = $0400 - uword ix - for ix in 0 to 999 { - @(scr) = @(buffer+ix) - scr++ - } + diskio.directory(8) + diskio.save(8, "blabla", $2000, 1024) + diskio.directory(8) + diskio.rename(8, "blabla", "newname") + diskio.directory(8) + diskio.delete(8, "newname") + diskio.directory(8) } }