allow uwordpointer[index] syntax as equivalent to @(uwordpointer+index) index can be >255 here!

This commit is contained in:
Irmen de Jong 2021-01-23 22:39:30 +01:00
parent f34f9329f1
commit bf69219f98
5 changed files with 39 additions and 31 deletions

View File

@ -81,6 +81,24 @@ internal class StatementReorderer(val program: Program, val errors: ErrorReporte
}
override fun after(arrayIndexedExpression: ArrayIndexedExpression, parent: Node): Iterable<IAstModification> {
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

View File

@ -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
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

View File

@ -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
^^^^^^^^^

View File

@ -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

View File

@ -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)
}
}