fixing alias bugs

This commit is contained in:
Irmen de Jong
2025-09-07 21:53:47 +02:00
parent 6ababbf8f4
commit a1ab8ed208
6 changed files with 131 additions and 51 deletions

View File

@@ -210,6 +210,12 @@ class AstPreprocessor(val program: Program,
decl.datatype.setActualSubType(node) decl.datatype.setActualSubType(node)
} else if(antlrTypeName.size==1 && antlrTypeName[0] in program.builtinFunctions.names) { } else if(antlrTypeName.size==1 && antlrTypeName[0] in program.builtinFunctions.names) {
errors.err("builtin function can only be called, not used as a type name", decl.position) errors.err("builtin function can only be called, not used as a type name", decl.position)
} else if(node is Alias) {
val actual = decl.definingScope.lookup(node.target.nameInSource)
if(actual is StructDecl)
decl.datatype.setActualSubType(actual)
else if(actual==null)
errors.err("cannot find struct type ${node.target.nameInSource.joinToString(".")}", decl.position)
} }
} }

View File

@@ -530,7 +530,7 @@ _after:
var struct = firstDt.subType var struct = firstDt.subType
for(name in identifier.nameInSource.drop(1)) { for(name in identifier.nameInSource.drop(1)) {
if(struct==null) { if(struct==null) {
errors.err("unknown field '${name}", position = identifier.position) errors.err("unknown field '${name}'", position = identifier.position)
return noModifications return noModifications
} }
val fieldDt = struct.getFieldType(name) val fieldDt = struct.getFieldType(name)

View File

@@ -148,6 +148,15 @@ internal class LiteralsToAutoVarsAndRecombineIdentifiers(private val program: Pr
} }
} }
if(target==null && identifier.nameInSource.size>1) {
// maybe the first component of the scoped name is an alias?
val tgt2 = identifier.definingScope.lookup(identifier.nameInSource.take(1)) as? Alias
if(tgt2!=null && parent !is Alias) {
if(tgt2.target.targetStatement() !is Alias)
return listOf(IAstModification.ReplaceNode(identifier, tgt2.target.copy(position = identifier.position), parent))
}
}
// don't replace an identifier in an Alias or when the alias points to another alias (that will be resolved first elsewhere) // don't replace an identifier in an Alias or when the alias points to another alias (that will be resolved first elsewhere)
if(target is Alias && parent !is Alias) { if(target is Alias && parent !is Alias) {
if(target.target.targetStatement() !is Alias) if(target.target.targetStatement() !is Alias)

View File

@@ -2349,4 +2349,40 @@ main {
compileText(C64Target(), false, src, outputDir) shouldNotBe null compileText(C64Target(), false, src, outputDir) shouldNotBe null
} }
test("struct and pointer aliasing") {
val src="""
main {
sub start() {
alias1()
alias2()
alias3()
}
sub alias1() {
alias TheNode = structdefs.Node
^^TheNode node = 20000
node.value = 100 ; TODO fix unknown field 'value'
}
sub alias2() {
^^structdefs.Node node = 20000
alias thing = node
thing.value=200 ; TODO fix undefined symbol: thing.value
}
sub alias3() {
alias TheNode = structdefs.Node
^^TheNode node = 20000
node++ ;; TODO fix compiler crash Key POINTER is missing in the map
}
}
structdefs {
struct Node {
ubyte value
}
}"""
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
}
}) })

View File

@@ -56,6 +56,15 @@ main {
STRUCTS and TYPED POINTERS (6502 codegen specific) STRUCTS and TYPED POINTERS (6502 codegen specific)
-------------------------------------------------- --------------------------------------------------
- Bugs:
;node2.type = 10 ;; TODO: fix undefined symbol error
;^^StructAlias node3 = 30000
; node3.type = 10 ;; TODO: fix "unknown field 'type" error
^^OtherNodeAlias other = 20000
other++ ;; TODO fix compiler crash Key POINTER is missing in the map
- in CodeDesugarer there is support for ptr1[idx]^^ = ptr2^^ into memcopy() but it doesn't seem to trigger? - in CodeDesugarer there is support for ptr1[idx]^^ = ptr2^^ into memcopy() but it doesn't seem to trigger?
- allow struct initialization syntax in an array such as [ Node(), Node(), Node() ], update sorting example to use list of countries like that - allow struct initialization syntax in an array such as [ Node(), Node(), Node() ], update sorting example to use list of countries like that

View File

@@ -1,61 +1,81 @@
%import textio
%zeropage basicsafe
main { main {
struct Ptr {
word value
byte bvalue
}
sub start() { sub start() {
^^Ptr pp = Ptr() alias derp = structdefs.normal
uword @nozp plainptr = &pp.bvalue derp ++
pp.value = -999 alias1()
pp.bvalue = -99 alias2()
txt.print_w(clamp(pp.value, 10, 2000)) alias3()
txt.spc()
txt.print_b(clamp(pp.bvalue, 10, 100))
txt.spc()
pp.bvalue = 5
txt.print_ub(clamp(plainptr[0], 10, 100))
txt.nl()
pp.value = 5000
pp.bvalue = 120
txt.print_w(clamp(pp.value, 10, 2000))
txt.spc()
txt.print_b(clamp(pp.bvalue, 10, 100))
txt.spc()
pp.bvalue = 120
txt.print_ub(clamp(plainptr[0], 10, 100))
txt.nl()
pp.value = 1234
pp.bvalue = 66
txt.print_w(clamp(pp.value, 10, 2000))
txt.spc()
txt.print_b(clamp(pp.bvalue, 10, 100))
txt.spc()
pp.bvalue = 66
txt.print_ub(clamp(plainptr[0], 10, 100))
txt.nl()
} }
sub alias1() {
alias TheNode = structdefs.Node
^^TheNode node = 20000
node.value = 100
}
sub alias2() {
^^structdefs.Node node = 20000
alias thing = node
thing.value=200
}
sub alias3() {
alias TheNode = structdefs.Node
^^TheNode node = 20000
node++
}
} }
;%import floats structdefs {
struct Node {
ubyte value
}
ubyte @shared normal
}
;
;%import textio
;%zeropage kernalsafe
;
; ;
;main { ;main {
; struct Node {
; ubyte type, frame, framecounter
; }
;
;
; sub start() { ; sub start() {
; struct List { ; ^^Node storageElementBuffer = 20000
; uword s ; ^^Node t_element = 30000
; float fl ;
; uword n ; alias node2 = t_element
; } ; alias StructAlias = Node
; ^^List l = List() ; alias OtherNodeAlias = structdefs.OtherNode
; l.n[cx16.r0L] = 99 ;
;; l.s[cx16.r0L+2] = 42 ; ;node2.type = 10 ;; TODO: fix undefined symbol error
;; l.n[cx16.r0L+2] = 99 ; ;^^StructAlias node3 = 30000
; ; node3.type = 10 ;; TODO: fix "unknown field 'type" error
;
; ^^OtherNodeAlias other = 20000
; other++ ;; TODO fix compiler crash Key POINTER is missing in the map
;
;
; ubyte @shared i = 0
; storageElementBuffer[0] = t_element^^
; storageElementBuffer[0] = t_element^^
; storageElementBuffer[1] = t_element^^
; storageElementBuffer[2] = t_element^^
; storageElementBuffer[i] = t_element^^
; ;storageElementBuffer[10]^^ = t_element^^ ; TODO support this with memcopy it's the same as the one above
; ;storageElementBuffer[i]^^ = t_element^^
; }
;}
;
;structdefs {
; struct OtherNode {
; ubyte type, frame, framecounter
; } ; }
;} ;}