mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 22:16:16 +00:00
fixing name lookup issue
This commit is contained in:
@@ -106,14 +106,14 @@ internal fun Program.preprocessAst(errors: IErrorReporter, options: CompilationO
|
||||
val mergeBlocks = BlockMerger(errors)
|
||||
mergeBlocks.visit(this)
|
||||
if(errors.noErrors()) {
|
||||
val structPreprocessor = AstStructPreprocessor(this)
|
||||
structPreprocessor.visit(this)
|
||||
structPreprocessor.applyModifications()
|
||||
|
||||
val transforms = AstPreprocessor(this, errors, options)
|
||||
transforms.visit(this)
|
||||
while (errors.noErrors() && transforms.applyModifications() > 0)
|
||||
transforms.visit(this)
|
||||
|
||||
val structPreprocessor = AstStructPreprocessor(this)
|
||||
structPreprocessor.visit(this)
|
||||
structPreprocessor.applyModifications()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -338,6 +338,18 @@ class AstPreprocessor(val program: Program,
|
||||
return noModifications
|
||||
}
|
||||
|
||||
override fun after(struct: StructDecl, parent: Node): Iterable<IAstModification> {
|
||||
// convert all antlr names to structs
|
||||
struct.fields.forEach {
|
||||
if(it.first.subTypeFromAntlr!=null) {
|
||||
val struct = struct.definingScope.lookup(it.first.subTypeFromAntlr!!) as? ISubType
|
||||
if(struct!=null)
|
||||
it.first.setActualSubType(struct)
|
||||
}
|
||||
}
|
||||
return noModifications
|
||||
}
|
||||
|
||||
|
||||
private fun checkStringParam(call: IFunctionCall, stmt: Statement) {
|
||||
val targetStatement = call.target.checkFunctionOrLabelExists(program, stmt, errors)
|
||||
|
||||
@@ -7,22 +7,13 @@ import prog8.ast.walk.AstWalker
|
||||
import prog8.ast.walk.IAstModification
|
||||
import prog8.code.core.BaseDataType
|
||||
import prog8.code.core.DataType
|
||||
import prog8.code.core.ISubType
|
||||
|
||||
// TODO integrate back into AstPreprocessor?
|
||||
|
||||
class AstStructPreprocessor(val program: Program) : AstWalker() {
|
||||
|
||||
override fun after(struct: StructDecl, parent: Node): Iterable<IAstModification> {
|
||||
|
||||
// convert all antlr names to structs
|
||||
struct.fields.forEach {
|
||||
if(it.first.subTypeFromAntlr!=null) {
|
||||
val struct = struct.definingScope.lookup(it.first.subTypeFromAntlr!!) as? ISubType
|
||||
if(struct!=null)
|
||||
it.first.setActualSubType(struct)
|
||||
}
|
||||
}
|
||||
|
||||
// convert str fields to ^^ubyte
|
||||
val convertedFields = struct.fields.map {
|
||||
if(it.first.isString)
|
||||
|
||||
@@ -1139,4 +1139,59 @@ main {
|
||||
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
|
||||
xtest("local and global struct pointer qualified name lookups") {
|
||||
val src="""
|
||||
main {
|
||||
struct Node {
|
||||
str question
|
||||
str animal
|
||||
^^Node negative
|
||||
^^Node positive
|
||||
}
|
||||
|
||||
^^Node @shared first
|
||||
|
||||
sub start() {
|
||||
cx16.r0 = first
|
||||
cx16.r1 = first.negative
|
||||
cx16.r0 = first^^.negative
|
||||
cx16.r1 = first.negative.animal
|
||||
cx16.r0 = first^^.negative^^.animal
|
||||
|
||||
cx16.r2 = db.first
|
||||
cx16.r3 = db.first.negative ; TODO fix symbol lookup errors
|
||||
cx16.r2 = db.first^^.negative ; TODO fix symbol lookup errors
|
||||
cx16.r3 = db.first.negative.animal
|
||||
cx16.r2 = db.first^^.negative^^.animal
|
||||
|
||||
|
||||
db.first.negative.animal = 0
|
||||
db.first.negative = 0 ; TODO fix symbol lookup errors
|
||||
db.first = 0
|
||||
|
||||
; TODO fix symbol lookup errors:
|
||||
func(db.first)
|
||||
func(db.first.negative)
|
||||
func(db.first.negative.animal)
|
||||
}
|
||||
|
||||
sub func(uword arg) {
|
||||
cx16.r0 = arg
|
||||
}
|
||||
}
|
||||
|
||||
db {
|
||||
struct Node {
|
||||
str question
|
||||
str animal
|
||||
^^Node negative
|
||||
^^Node positive
|
||||
}
|
||||
|
||||
^^Node @shared first
|
||||
}"""
|
||||
|
||||
compileText(VMTarget(), false, src, outputDir) shouldNotBe null
|
||||
}
|
||||
})
|
||||
@@ -176,13 +176,40 @@ interface INameScope: IStatementContainer, INamedStatement {
|
||||
|
||||
private fun lookupQualified(scopedName: List<String>): Statement? {
|
||||
val localSymbol = this.searchSymbol(scopedName[0]) ?: this.lookupUnqualified(scopedName[0])
|
||||
val fieldRef = searchStructFieldRef(localSymbol, scopedName)
|
||||
if(fieldRef!=null)
|
||||
return fieldRef
|
||||
|
||||
// a scoped name refers to a name in another namespace, and always starts from the root.
|
||||
for(module in (this as Node).definingModule.program.modules) {
|
||||
val block = module.searchSymbol(scopedName[0])
|
||||
if(block!=null) {
|
||||
var statement = block
|
||||
for((idx, name) in scopedName.drop(1).withIndex()) {
|
||||
val symbol = (statement as? IStatementContainer)?.searchSymbol(name)
|
||||
if(symbol==null) {
|
||||
val fieldRef = searchStructFieldRef(statement, scopedName.drop(idx+1))
|
||||
if(fieldRef!=null)
|
||||
return fieldRef
|
||||
println("LOOKUP FAIL $statement ${scopedName.drop(idx+1)}") // TODO FIX
|
||||
return null
|
||||
} else {
|
||||
statement = symbol
|
||||
}
|
||||
}
|
||||
return statement
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
|
||||
fun searchStructFieldRef(localSymbol: Statement?, scopedName: List<String>): StructFieldRef? {
|
||||
if(localSymbol is VarDecl && localSymbol.datatype.isPointer) {
|
||||
var struct = localSymbol.datatype.subType as? StructDecl
|
||||
if(struct!=null) {
|
||||
for ((idx, field) in scopedName.drop(1).withIndex()) {
|
||||
val fieldDt = struct!!.getFieldType(field)
|
||||
if (fieldDt == null)
|
||||
break
|
||||
val fieldDt = struct!!.getFieldType(field) ?:
|
||||
return null
|
||||
if (idx == scopedName.size - 2) {
|
||||
// was last path element
|
||||
val pointer = IdentifierReference(scopedName, Position.DUMMY)
|
||||
@@ -190,25 +217,13 @@ interface INameScope: IStatementContainer, INamedStatement {
|
||||
ref.linkParents(this as Node)
|
||||
return ref
|
||||
}
|
||||
struct = fieldDt.subType as? StructDecl
|
||||
if(struct==null)
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// a scoped name refers to a name in another namespace, and always starts from the root.
|
||||
for(module in (this as Node).definingModule.program.modules) {
|
||||
val block = module.searchSymbol(scopedName[0])
|
||||
if(block!=null) {
|
||||
var statement = block
|
||||
for(name in scopedName.drop(1)) {
|
||||
statement = (statement as? IStatementContainer)?.searchSymbol(name)
|
||||
if(statement==null) {
|
||||
struct = fieldDt.subType as? StructDecl ?:
|
||||
return null
|
||||
}
|
||||
}
|
||||
return statement
|
||||
} else {
|
||||
if(localSymbol.datatype.subTypeFromAntlr!=null)
|
||||
TODO("antlr subtype must have been converted to a struct type by now $localSymbol : ${localSymbol.datatype.subTypeFromAntlr}")
|
||||
return null
|
||||
}
|
||||
}
|
||||
return null
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
TODO
|
||||
====
|
||||
|
||||
Fix symbol lookup bug
|
||||
Fix symbol lookup bug "antlr subtype must have been converted to a struct type by now" , "LOOKUP FAIL"
|
||||
|
||||
Reintegrate AstStructPreprocessor into AstPreProcessor , if possible.
|
||||
|
||||
|
||||
STRUCTS and TYPED POINTERS
|
||||
|
||||
Reference in New Issue
Block a user