mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 22:16:16 +00:00
@(..) now also accepts pointer to ubyte address
This commit is contained in:
@@ -1970,15 +1970,8 @@ internal class AstChecker(private val program: Program,
|
||||
}
|
||||
|
||||
override fun visit(memread: DirectMemoryRead) {
|
||||
if(!(memread.addressExpression.inferType(program) issimpletype BaseDataType.UWORD)) {
|
||||
errors.err("address for memory access isn't uword", memread.position)
|
||||
}
|
||||
val tc = memread.addressExpression as? TypecastExpression
|
||||
if(tc!=null && tc.implicit) {
|
||||
if(!(tc.expression.inferType(program) issimpletype BaseDataType.UWORD)) {
|
||||
errors.err("address for memory access isn't uword", memread.position)
|
||||
}
|
||||
}
|
||||
if(!allowedMemoryAccessAddressExpression(memread.addressExpression, program))
|
||||
errors.err("invalid address type for memory access", memread.position)
|
||||
|
||||
val pointervar = memread.addressExpression as? IdentifierReference
|
||||
if(pointervar!=null)
|
||||
@@ -1990,16 +1983,22 @@ internal class AstChecker(private val program: Program,
|
||||
super.visit(memread)
|
||||
}
|
||||
|
||||
override fun visit(memwrite: DirectMemoryWrite) {
|
||||
if(!(memwrite.addressExpression.inferType(program) issimpletype BaseDataType.UWORD)) {
|
||||
errors.err("address for memory access isn't uword", memwrite.position)
|
||||
}
|
||||
val tc = memwrite.addressExpression as? TypecastExpression
|
||||
private fun allowedMemoryAccessAddressExpression(addressExpression: Expression, program: Program): Boolean {
|
||||
val dt = addressExpression.inferType(program)
|
||||
if(dt.isUnsignedWord || (dt.isPointer && dt.getOrUndef().sub==BaseDataType.UBYTE))
|
||||
return true
|
||||
val tc = addressExpression as? TypecastExpression
|
||||
if(tc!=null && tc.implicit) {
|
||||
if(!(tc.expression.inferType(program) issimpletype BaseDataType.UWORD)) {
|
||||
errors.err("address for memory access isn't uword", memwrite.position)
|
||||
}
|
||||
val dt = tc.expression.inferType(program)
|
||||
if(dt.isUnsignedWord || (dt.isPointer && dt.getOrUndef().sub==BaseDataType.UBYTE))
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun visit(memwrite: DirectMemoryWrite) {
|
||||
if(!allowedMemoryAccessAddressExpression(memwrite.addressExpression, program))
|
||||
errors.err("invalid address type for memory access", memwrite.position)
|
||||
|
||||
val pointervar = memwrite.addressExpression as? IdentifierReference
|
||||
if(pointervar!=null)
|
||||
@@ -2355,8 +2354,10 @@ internal class AstChecker(private val program: Program,
|
||||
if(sourceDatatype.isPointer) {
|
||||
if(!(sourceDatatype isAssignableTo targetDatatype))
|
||||
errors.err("cannot assign different pointer type", position)
|
||||
} else if(sourceDatatype.isString && targetDatatype.sub?.isByte==true) {
|
||||
// assigning a string to a byte pointer is allowed.
|
||||
} else if(!sourceDatatype.isUnsignedWord && !sourceDatatype.isStructInstance)
|
||||
errors.err("can only assign uword or correct pointer type to a pointer", position)
|
||||
errors.err("incompatible value type, can only assign uword or correct pointer type", position)
|
||||
}
|
||||
else if(targetDatatype.isString && sourceDatatype.isUnsignedWord)
|
||||
errors.err("can't assign uword to str. If the source is a string pointer and you actually want to overwrite the target string, use an explicit strings.copy(src,tgt) instead.", position)
|
||||
|
||||
@@ -26,6 +26,7 @@ internal class CodeDesugarer(val program: Program, private val target: ICompilat
|
||||
// - remove alias nodes
|
||||
// - convert on..goto/call to jumpaddr array and separate goto/call
|
||||
// - replace implicit pointer dereference chains (a.b.c.d) with explicit ones (a^^.b^^.c^^.d)
|
||||
// - replace ptr^^ by @(ptr) if ptr is just an uword.
|
||||
|
||||
override fun after(alias: Alias, parent: Node): Iterable<IAstModification> {
|
||||
return listOf(IAstModification.Remove(alias, parent as IStatementContainer))
|
||||
@@ -451,4 +452,17 @@ _after:
|
||||
, ongoto.position)
|
||||
return listOf(IAstModification.ReplaceNode(ongoto, replacementScope, parent))
|
||||
}
|
||||
|
||||
override fun after(deref: PtrDereference, parent: Node): Iterable<IAstModification> {
|
||||
// TODO what about DirectMemoryWrite ?? (LHS of assignment?)
|
||||
if(deref.field==null && deref.chain.isEmpty()) {
|
||||
val varDt = deref.identifier.targetVarDecl()?.datatype
|
||||
if(varDt?.isUnsignedWord==true || (varDt?.isPointer==true && varDt.sub==BaseDataType.UBYTE)) {
|
||||
// replace ptr^^ by @(ptr) when ptr is uword or ^^byte
|
||||
val memread = DirectMemoryRead(deref.identifier, deref.position)
|
||||
return listOf(IAstModification.ReplaceNode(deref, memread, parent))
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
}
|
||||
|
||||
@@ -243,7 +243,7 @@ main {
|
||||
compileText(VMTarget(), false, src, outputDir, errors=errors)
|
||||
val err = errors.errors
|
||||
err.size shouldBe 1
|
||||
err[0] shouldContain("15:16: can only assign uword or correct pointer type to a pointer")
|
||||
err[0] shouldContain("15:16: incompatible value type, can only assign uword or correct pointer")
|
||||
}
|
||||
|
||||
})
|
||||
@@ -131,7 +131,7 @@ main {
|
||||
val errors = ErrorReporterForTests()
|
||||
compileText(C64Target(), false, text, outputDir, writeAssembly = true, errors = errors)
|
||||
errors.errors.size shouldBe 2
|
||||
errors.errors[0] shouldContain "isn't uword"
|
||||
errors.errors[0] shouldContain "invalid address type"
|
||||
errors.errors[1] shouldContain "undefined symbol: doesnotexist"
|
||||
}
|
||||
|
||||
|
||||
@@ -44,8 +44,10 @@ STRUCTS and TYPED POINTERS
|
||||
- DONE: existing ARRAY type remains unchanged (it doesn't become a typed pointer) so we can keep doing register-indexed LDA array,Y addressing directly on them.
|
||||
- DONE: passing STR to a subroutine: parameter type becomes ^^UBYTE (rather than UWORD) (we still lose the bounds check)
|
||||
- DONE: passing ARRAY to a subroutine: parameter type becomes ^^ElementDt (rather than UWORD) (we still lose the bounds check)
|
||||
- DONE: @(ptr) complains that ptr is not uword when ptr is ^^ubyte (should be allowed)
|
||||
- fix actual _msb/_lsb storage of the split-words pointer-arrays
|
||||
- STR should be asssignment compatible with UBYTE^^ but local scoped STR should still be accessed directly using LDA str,Y instead of through the pointer, like arrays.
|
||||
- what about uword^^ -> @(uword) when it's assignment target (LHS)?
|
||||
- make typeForAddressOf() be even more specific about the typed pointers it returns for the address-of operator. + unit test. Needs fixes in 6502 codegen too though... (also recheck passing STR and ARRAY types to subroutines)
|
||||
- fixing the pointer dereferencing issues (cursed hybrid beween IdentifierReference, PtrDereferece and PtrIndexedDereference) may require getting rid of scoped identifiers altogether and treat '.' as a "scope or pointer following operator"
|
||||
- (later, nasty parser problem:) support chaining pointer dereference on function calls that return a pointer. (type checking now fails on stuff like func().field and func().next.field)
|
||||
|
||||
@@ -10,9 +10,25 @@ main {
|
||||
|
||||
word[] @nosplit values = [111,222,-999,-888]
|
||||
|
||||
stringinfo("hello")
|
||||
^^byte @shared bptr
|
||||
^^ubyte @shared ubptr
|
||||
|
||||
str name = "irmen"
|
||||
stringinfo1("hello")
|
||||
stringinfo2(name)
|
||||
stringinfo3("apple")
|
||||
arrayinfo(values)
|
||||
arrayinfo(&values[2])
|
||||
|
||||
|
||||
bptr = name
|
||||
ubptr = name
|
||||
txt.print_uw(&name)
|
||||
txt.spc()
|
||||
txt.print_uw(bptr)
|
||||
txt.spc()
|
||||
txt.print_uw(ubptr)
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub info(^^thing.Node node) {
|
||||
@@ -32,7 +48,8 @@ main {
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub stringinfo(^^ubyte message) {
|
||||
sub stringinfo1(^^ubyte message) {
|
||||
txt.print("string1: ")
|
||||
txt.print_uw(message)
|
||||
txt.spc()
|
||||
txt.print(message)
|
||||
@@ -44,6 +61,32 @@ main {
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub stringinfo2(str message) {
|
||||
txt.print("string2: ")
|
||||
txt.print_uw(message)
|
||||
txt.spc()
|
||||
txt.print(message)
|
||||
txt.spc()
|
||||
do {
|
||||
txt.chrout(message^^)
|
||||
message++
|
||||
} until message^^==0
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub stringinfo3(uword message) {
|
||||
txt.print("string3: ")
|
||||
txt.print_uw(message)
|
||||
txt.spc()
|
||||
txt.print(message)
|
||||
txt.spc()
|
||||
do {
|
||||
txt.chrout(message^^) ; equivalent to @(message) in this case
|
||||
message++
|
||||
} until message^^==0 ; equivalent to @(message) in this case
|
||||
txt.nl()
|
||||
}
|
||||
|
||||
sub arrayinfo(^^word valueptr) {
|
||||
txt.print_uw(valueptr)
|
||||
txt.spc()
|
||||
|
||||
Reference in New Issue
Block a user