mirror of
https://github.com/catseye/SixtyPical.git
synced 2025-02-19 20:30:45 +00:00
Write stored values, and read values, through pointers.
This commit is contained in:
parent
9874b11639
commit
d84566a880
@ -8,9 +8,7 @@ History of SixtyPical
|
|||||||
* Can `copy` literals into user-defined destinations.
|
* Can `copy` literals into user-defined destinations.
|
||||||
* `buffer` and `pointer` types.
|
* `buffer` and `pointer` types.
|
||||||
* `copy ^` syntax to load the addr of a buffer into a pointer.
|
* `copy ^` syntax to load the addr of a buffer into a pointer.
|
||||||
* `copy []+y` syntax to write a value into memory through a pointer.
|
* `copy []+y` syntax to read and write values to and from memory through a pointer.
|
||||||
* TODO: read through pointer.
|
|
||||||
* TODO: insist the buffer being read or written to through pointer, appears in approporiate set.
|
|
||||||
|
|
||||||
0.7
|
0.7
|
||||||
---
|
---
|
||||||
|
@ -41,6 +41,10 @@ Documentation
|
|||||||
TODO
|
TODO
|
||||||
----
|
----
|
||||||
|
|
||||||
|
Insist the buffer being read or written to through pointer, appears in approporiate set.
|
||||||
|
|
||||||
|
Add to pointer.
|
||||||
|
|
||||||
### `word table` and `vector table` types
|
### `word table` and `vector table` types
|
||||||
|
|
||||||
### `low` and `high` address operators
|
### `low` and `high` address operators
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
buffer[2048] buf
|
buffer[2048] buf
|
||||||
pointer ptr @ 254
|
pointer ptr @ 254
|
||||||
|
byte foo
|
||||||
|
|
||||||
routine main
|
routine main
|
||||||
inputs buf
|
inputs buf
|
||||||
outputs buf, y
|
outputs buf, y, foo
|
||||||
trashes a, z, n, ptr
|
trashes a, z, n, ptr
|
||||||
{
|
{
|
||||||
ld y, 0
|
ld y, 0
|
||||||
copy ^buf, ptr
|
copy ^buf, ptr
|
||||||
copy 123, [ptr] + y
|
copy 123, [ptr] + y
|
||||||
|
copy [ptr] + y, foo
|
||||||
|
copy foo, [ptr] + y
|
||||||
}
|
}
|
||||||
|
@ -295,17 +295,21 @@ class Analyzer(object):
|
|||||||
elif opcode == 'copy':
|
elif opcode == 'copy':
|
||||||
# 1. check that their types are compatible
|
# 1. check that their types are compatible
|
||||||
|
|
||||||
if isinstance(dest, IndirectRef):
|
if isinstance(src, AddressRef) and isinstance(dest, LocationRef):
|
||||||
if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType):
|
|
||||||
pass
|
|
||||||
else:
|
|
||||||
raise TypeMismatchError((src, dest))
|
|
||||||
elif isinstance(src, AddressRef):
|
|
||||||
if isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType):
|
if isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType):
|
||||||
pass
|
pass
|
||||||
else:
|
else:
|
||||||
raise TypeMismatchError((src, dest))
|
raise TypeMismatchError((src, dest))
|
||||||
|
elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef):
|
||||||
|
if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType):
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise TypeMismatchError((src, dest))
|
||||||
|
elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
|
||||||
|
if isinstance(src.ref.type, PointerType) and dest.type == TYPE_BYTE:
|
||||||
|
pass
|
||||||
|
else:
|
||||||
|
raise TypeMismatchError((src, dest))
|
||||||
elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, LocationRef):
|
elif isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, LocationRef):
|
||||||
if src.type == dest.type:
|
if src.type == dest.type:
|
||||||
pass
|
pass
|
||||||
@ -326,10 +330,15 @@ class Analyzer(object):
|
|||||||
|
|
||||||
# 2. check that the context is meaningful
|
# 2. check that the context is meaningful
|
||||||
|
|
||||||
if isinstance(dest, IndirectRef):
|
if isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef):
|
||||||
context.assert_meaningful(src, REG_Y)
|
context.assert_meaningful(src, REG_Y)
|
||||||
# TODO this will need to be more sophisticated. it's the thing ref points to that is written, not ref itself.
|
# TODO this will need to be more sophisticated. it's the thing ref points to that is written, not ref itself.
|
||||||
context.set_written(dest.ref)
|
context.set_written(dest.ref)
|
||||||
|
elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
|
||||||
|
context.assert_meaningful(src.ref, REG_Y)
|
||||||
|
# TODO this will need to be more sophisticated. the thing ref points to is touched, as well.
|
||||||
|
context.set_touched(src.ref)
|
||||||
|
context.set_written(dest)
|
||||||
else:
|
else:
|
||||||
context.assert_meaningful(src)
|
context.assert_meaningful(src)
|
||||||
context.set_written(dest)
|
context.set_written(dest)
|
||||||
|
@ -274,16 +274,29 @@ class Compiler(object):
|
|||||||
self.compile_block(instr.block)
|
self.compile_block(instr.block)
|
||||||
self.emitter.emit(CLI())
|
self.emitter.emit(CLI())
|
||||||
elif opcode == 'copy':
|
elif opcode == 'copy':
|
||||||
if isinstance(dest, IndirectRef):
|
if isinstance(src, (LocationRef, ConstantRef)) and isinstance(dest, IndirectRef):
|
||||||
if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType):
|
if src.type == TYPE_BYTE and isinstance(dest.ref.type, PointerType):
|
||||||
if isinstance(src, ConstantRef):
|
if isinstance(src, ConstantRef):
|
||||||
dest_label = self.labels[dest.ref.name]
|
dest_label = self.labels[dest.ref.name]
|
||||||
self.emitter.emit(LDA(Immediate(Byte(src.value))))
|
self.emitter.emit(LDA(Immediate(Byte(src.value))))
|
||||||
self.emitter.emit(STA(IndirectY(dest_label)))
|
self.emitter.emit(STA(IndirectY(dest_label)))
|
||||||
|
elif isinstance(src, LocationRef):
|
||||||
|
src_label = self.labels[src.name]
|
||||||
|
dest_label = self.labels[dest.ref.name]
|
||||||
|
self.emitter.emit(LDA(Absolute(src_label)))
|
||||||
|
self.emitter.emit(STA(IndirectY(dest_label)))
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError((src, dest))
|
raise NotImplementedError((src, dest))
|
||||||
else:
|
else:
|
||||||
raise NotImplementedError((src, dest))
|
raise NotImplementedError((src, dest))
|
||||||
|
elif isinstance(src, IndirectRef) and isinstance(dest, LocationRef):
|
||||||
|
if dest.type == TYPE_BYTE and isinstance(src.ref.type, PointerType):
|
||||||
|
src_label = self.labels[src.ref.name]
|
||||||
|
dest_label = self.labels[dest.name]
|
||||||
|
self.emitter.emit(LDA(IndirectY(src_label)))
|
||||||
|
self.emitter.emit(STA(Absolute(dest_label)))
|
||||||
|
else:
|
||||||
|
raise NotImplementedError((src, dest))
|
||||||
elif isinstance(src, AddressRef) and isinstance(dest, LocationRef) and \
|
elif isinstance(src, AddressRef) and isinstance(dest, LocationRef) and \
|
||||||
isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType):
|
isinstance(src.ref.type, BufferType) and isinstance(dest.type, PointerType):
|
||||||
src_label = self.labels[src.ref.name]
|
src_label = self.labels[src.ref.name]
|
||||||
|
@ -1177,13 +1177,16 @@ Can't `copy` from a `word` to a `byte`.
|
|||||||
Buffers and pointers.
|
Buffers and pointers.
|
||||||
|
|
||||||
Note that `^buf` is not considered "reading" buf, so does not require it in `inputs`.
|
Note that `^buf` is not considered "reading" buf, so does not require it in `inputs`.
|
||||||
TODO: It *should* require it in `outputs`.
|
TODO: If reading from it through a pointer, it *should* require it in `inputs`.
|
||||||
|
TODO: If writing to it through a pointer, it *should* require it in `outputs`.
|
||||||
|
|
||||||
|
Write literal through a pointer.
|
||||||
|
|
||||||
| buffer[2048] buf
|
| buffer[2048] buf
|
||||||
| pointer ptr
|
| pointer ptr
|
||||||
|
|
|
|
||||||
| routine main
|
| routine main
|
||||||
| outputs y
|
| outputs y //, buf
|
||||||
| trashes a, z, n, ptr
|
| trashes a, z, n, ptr
|
||||||
| {
|
| {
|
||||||
| ld y, 0
|
| ld y, 0
|
||||||
@ -1198,6 +1201,7 @@ It does use `y`.
|
|||||||
| pointer ptr
|
| pointer ptr
|
||||||
|
|
|
|
||||||
| routine main
|
| routine main
|
||||||
|
| // outputs buf
|
||||||
| trashes a, z, n, ptr
|
| trashes a, z, n, ptr
|
||||||
| {
|
| {
|
||||||
| copy ^buf, ptr
|
| copy ^buf, ptr
|
||||||
@ -1205,6 +1209,40 @@ It does use `y`.
|
|||||||
| }
|
| }
|
||||||
? UnmeaningfulReadError
|
? UnmeaningfulReadError
|
||||||
|
|
||||||
|
Write stored value through a pointer.
|
||||||
|
|
||||||
|
| buffer[2048] buf
|
||||||
|
| pointer ptr
|
||||||
|
| byte foo
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| inputs foo
|
||||||
|
| outputs y //, buf
|
||||||
|
| trashes a, z, n, ptr
|
||||||
|
| {
|
||||||
|
| ld y, 0
|
||||||
|
| copy ^buf, ptr
|
||||||
|
| copy foo, [ptr] + y
|
||||||
|
| }
|
||||||
|
= ok
|
||||||
|
|
||||||
|
Read through a pointer.
|
||||||
|
|
||||||
|
| buffer[2048] buf
|
||||||
|
| pointer ptr
|
||||||
|
| byte foo
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| // inputs buf
|
||||||
|
| outputs foo
|
||||||
|
| trashes a, y, z, n, ptr
|
||||||
|
| {
|
||||||
|
| ld y, 0
|
||||||
|
| copy ^buf, ptr
|
||||||
|
| copy [ptr] + y, foo
|
||||||
|
| }
|
||||||
|
= ok
|
||||||
|
|
||||||
### routines ###
|
### routines ###
|
||||||
|
|
||||||
Routines are constants. You need not, and in fact cannot, specify a constant
|
Routines are constants. You need not, and in fact cannot, specify a constant
|
||||||
|
@ -357,7 +357,7 @@ Buffers and pointers.
|
|||||||
| }
|
| }
|
||||||
= 00c0a000a90b85fea9c085ff60
|
= 00c0a000a90b85fea9c085ff60
|
||||||
|
|
||||||
Writing through a pointer.
|
Writing literal through a pointer.
|
||||||
|
|
||||||
| buffer[2048] buf
|
| buffer[2048] buf
|
||||||
| pointer ptr @ 254
|
| pointer ptr @ 254
|
||||||
@ -371,3 +371,37 @@ Writing through a pointer.
|
|||||||
| copy 123, [ptr] + y
|
| copy 123, [ptr] + y
|
||||||
| }
|
| }
|
||||||
= 00c0a000a90f85fea9c085ffa97b91fe60
|
= 00c0a000a90f85fea9c085ffa97b91fe60
|
||||||
|
|
||||||
|
Write stored value through a pointer.
|
||||||
|
|
||||||
|
| buffer[2048] buf
|
||||||
|
| pointer ptr @ 254
|
||||||
|
| byte foo
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| inputs foo
|
||||||
|
| outputs y //, buf
|
||||||
|
| trashes a, z, n, ptr
|
||||||
|
| {
|
||||||
|
| ld y, 0
|
||||||
|
| copy ^buf, ptr
|
||||||
|
| copy foo, [ptr] + y
|
||||||
|
| }
|
||||||
|
= 00c0a000a91085fea9c085ffad12c091fe60
|
||||||
|
|
||||||
|
Reading through a pointer.
|
||||||
|
|
||||||
|
| buffer[2048] buf
|
||||||
|
| pointer ptr @ 254
|
||||||
|
| byte foo
|
||||||
|
|
|
||||||
|
| routine main
|
||||||
|
| // inputs buf
|
||||||
|
| outputs y, foo
|
||||||
|
| trashes a, z, n, ptr
|
||||||
|
| {
|
||||||
|
| ld y, 0
|
||||||
|
| copy ^buf, ptr
|
||||||
|
| copy [ptr] + y, foo
|
||||||
|
| }
|
||||||
|
= 00c0a000a91085fea9c085ffb1fe8d12c060
|
||||||
|
@ -326,9 +326,11 @@ Buffers and pointers.
|
|||||||
|
|
||||||
| buffer[2048] buf
|
| buffer[2048] buf
|
||||||
| pointer ptr
|
| pointer ptr
|
||||||
|
| byte foo
|
||||||
|
|
|
|
||||||
| routine main {
|
| routine main {
|
||||||
| copy ^buf, ptr
|
| copy ^buf, ptr
|
||||||
| copy 123, [ptr] + y
|
| copy 123, [ptr] + y
|
||||||
|
| copy [ptr] + y, foo
|
||||||
| }
|
| }
|
||||||
= ok
|
= ok
|
||||||
|
Loading…
x
Reference in New Issue
Block a user