mirror of
https://github.com/irmen/prog8.git
synced 2026-10-22 05:02:58 +00:00
improve ast source position tracking
This commit is contained in:
1 parent
05093e35c8
commit
331e2b8f2b
12 files changed
+46
-46
No files matched your search
@@ -169,7 +169,7 @@ class AsmGen6502(val prefixSymbols: Boolean, private val lastGeneratedLabelSeque
|
||||
functionCallsToPrefix.reversed().forEach { (parent, index) ->
|
||||
val node = parent.children[index]
|
||||
if(node is PtFunctionCall) {
|
||||
val prefixedName = PtIdentifier(node.name, DataType.UNDEFINED, Position.DUMMY).prefix(parent, st)
|
||||
val prefixedName = PtIdentifier(node.name, DataType.UNDEFINED, node.position).prefix(parent, st)
|
||||
val prefixedNode = node.withNewName(prefixedName.name)
|
||||
parent.children[index] = prefixedNode
|
||||
} else {
|
||||
|
||||
@@ -333,7 +333,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||
// we need to sign extend the source, do this via temporary word variable
|
||||
asmgen.assignExpressionToVariable(value, "P8ZP_SCRATCH_W1", DataType.UBYTE)
|
||||
asmgen.signExtendVariableLsb("P8ZP_SCRATCH_W1", value.type.base)
|
||||
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, Position.DUMMY)
|
||||
asmgen.assignVariableToRegister("P8ZP_SCRATCH_W1", register, null, value.position)
|
||||
} else {
|
||||
val scope = value.definingISub()
|
||||
val target: AsmAssignTarget =
|
||||
@@ -344,7 +344,7 @@ internal class FunctionCallAsmGen(private val program: PtProgram, private val as
|
||||
}
|
||||
val src = if(value.type.isPassByRef) {
|
||||
if(value is PtIdentifier) {
|
||||
val addr = PtAddressOf(value.type.typeForAddressOf(false), false, Position.DUMMY)
|
||||
val addr = PtAddressOf(value.type.typeForAddressOf(false), false, value.position)
|
||||
addr.add(value)
|
||||
addr.parent = scope as PtNode
|
||||
AsmAssignSource.fromAstSource(addr, program, asmgen).adjustSignedUnsigned(target)
|
||||
|
||||
@@ -742,7 +742,7 @@ internal class ProgramAndVarsGen(
|
||||
it.initializationStringValue!!.second,
|
||||
it.initializationStringValue!!.first
|
||||
)
|
||||
asmgen.romableError("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
|
||||
asmgen.romableError("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", it.astNode?.position ?: Position.DUMMY, false)
|
||||
}
|
||||
alignedStrings.sortedBy { it.align }.forEach {
|
||||
outputStringvar(
|
||||
@@ -751,22 +751,22 @@ internal class ProgramAndVarsGen(
|
||||
it.initializationStringValue!!.second,
|
||||
it.initializationStringValue!!.first
|
||||
)
|
||||
asmgen.romableError("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
|
||||
asmgen.romableError("string (${it.dt} ${it.name}) can only be used as read-only in ROMable code", it.astNode?.position ?: Position.DUMMY, false)
|
||||
}
|
||||
|
||||
notAlignedOther.sortedBy { it.type }.forEach {
|
||||
staticVariable2asm(it)
|
||||
if(it.dt.isArray)
|
||||
asmgen.romableError("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
|
||||
asmgen.romableError("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", it.astNode?.position ?: Position.DUMMY, false)
|
||||
else
|
||||
asmgen.romableError("inlined variable (${it.dt} ${it.name})", Position.DUMMY) // TODO print warning with position of the var
|
||||
asmgen.romableError("inlined variable (${it.dt} ${it.name})", it.astNode?.position ?: Position.DUMMY)
|
||||
}
|
||||
alignedOther.sortedBy { it.align }.sortedBy { it.type }.forEach {
|
||||
staticVariable2asm(it)
|
||||
if(it.dt.isArray)
|
||||
asmgen.romableError("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", Position.DUMMY, false) // TODO print warning with position of the var
|
||||
asmgen.romableError("array (${it.dt} ${it.name}) can only be used as read-only in ROMable code", it.astNode?.position ?: Position.DUMMY, false)
|
||||
else
|
||||
asmgen.romableError("inlined variable (${it.dt} ${it.name})", Position.DUMMY) // TODO print warning with position of the var
|
||||
asmgen.romableError("inlined variable (${it.dt} ${it.name})", it.astNode?.position ?: Position.DUMMY)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5434,7 +5434,7 @@ $endLabel""")
|
||||
internal fun assignVariableToRegister(asmVarName: String, register: RegisterOrPair, signed: Boolean, scope: IPtSubroutine?, pos: Position) {
|
||||
val tgt = AsmAssignTarget.fromRegisters(register, signed, pos, null, asmgen)
|
||||
val src = AsmAssignSource(SourceStorageKind.VARIABLE, program, asmgen, tgt.datatype, variableAsmName = asmVarName)
|
||||
val assign = AsmAssignment(src, listOf(tgt), program.memsizer, Position.DUMMY)
|
||||
val assign = AsmAssignment(src, listOf(tgt), program.memsizer, pos)
|
||||
translateNormalAssignment(assign, scope)
|
||||
}
|
||||
|
||||
|
||||
@@ -1193,9 +1193,9 @@ internal class AugmentableAssignmentAsmGen(private val program: PtProgram,
|
||||
val assignValue = AsmAssignment(value,
|
||||
listOf(
|
||||
AsmAssignTarget(TargetStorageKind.REGISTER, asmgen, DataType.UBYTE,
|
||||
address.definingISub(), Position.DUMMY, register = RegisterOrPair.A)
|
||||
address.definingISub(), address.position, register = RegisterOrPair.A)
|
||||
),
|
||||
program.memsizer, Position.DUMMY)
|
||||
program.memsizer, address.position)
|
||||
assignmentAsmGen.translateNormalAssignment(assignValue, address.definingISub()) // calculate value into A
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
// note: multi-value returns are passed throug A or AY (for the first value) then cx16.R15 down to R0
|
||||
// (this allows unencumbered use of many Rx registers if you don't return that many values)
|
||||
val returntypes = BuiltinFunctions.getValue(thing.name).returnTypes
|
||||
val signature = PtSubSignature(returntypes.map { DataType.forDt(it) }, Position.DUMMY)
|
||||
val signature = PtSubSignature(returntypes.map { DataType.forDt(it) }, values.position)
|
||||
val returnregs = signature.returnsWhatWhere()
|
||||
assignmentTargets.zip(returnregs).forEach {
|
||||
val target = it.first as PtAssignTarget
|
||||
@@ -1479,4 +1479,4 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val exprGen
|
||||
}
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -452,7 +452,7 @@ internal class ConstantIdentifierReplacer(
|
||||
if(targetDatatype.isArray) {
|
||||
val decl = VarDecl(VarDeclType.VAR, VarDeclOrigin.ARRAYLITERAL, targetDatatype.getOrUndef(),
|
||||
ZeropageWish.DONTCARE, SplitWish.NOSPLIT, null, "dummy", emptyList(),
|
||||
assignment.value, false, 0u, false, Position.DUMMY)
|
||||
assignment.value, false, 0u, false, assignment.value.position)
|
||||
val replaceValue = createConstArrayInitializerValue(decl)
|
||||
if(replaceValue!=null) {
|
||||
return listOf(IAstModification.ReplaceNode(assignment.value, replaceValue, assignment))
|
||||
|
||||
@@ -56,7 +56,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
||||
if(subroutine.returntypes.isNotEmpty())
|
||||
errors.err("subroutine is missing a return statement with value(s)", subroutine.position)
|
||||
else {
|
||||
val returnStmt = Return(arrayOf(), Position.DUMMY)
|
||||
val returnStmt = Return(arrayOf(), subroutine.position)
|
||||
mods += IAstModification.InsertLast(returnStmt, subroutine)
|
||||
}
|
||||
} else {
|
||||
@@ -68,7 +68,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
||||
// .... we cannot return this as an error, because that also breaks legitimate cases where the return is done from within a nested scope somewhere
|
||||
// errors.err("subroutine is missing a return statement with value(s)", subroutine.position)
|
||||
} else {
|
||||
val returnStmt = Return(arrayOf(), Position.DUMMY)
|
||||
val returnStmt = Return(arrayOf(), lastStatement?.position ?: subroutine.position)
|
||||
mods += IAstModification.InsertLast(returnStmt, subroutine)
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ internal class BeforeAsmAstChanger(val program: Program, private val options: Co
|
||||
if(outerScope.returntypes.size>1 || !(outerScope.returntypes[0].isNumericOrBool || outerScope.returntypes[0].isPointer)) {
|
||||
errors.err("subroutine is missing a return statement to avoid falling through into nested subroutine", outerStatements[subroutineStmtIdx-1].position)
|
||||
} else {
|
||||
val zero = defaultZero(outerScope.returntypes[0].base, Position.DUMMY)
|
||||
val zero = defaultZero(outerScope.returntypes[0].base, outerStatements[subroutineStmtIdx-1].position)
|
||||
val returnStmt = Return(arrayOf(zero), outerStatements[subroutineStmtIdx - 1].position)
|
||||
mods += IAstModification.InsertAfter(outerStatements[subroutineStmtIdx - 1], returnStmt, outerScope)
|
||||
}
|
||||
|
||||
@@ -170,33 +170,33 @@ internal object DeferProcessor {
|
||||
|
||||
for( (sub, defers) in subdefers) {
|
||||
// create the routine that calls the enabled defers in reverse order
|
||||
val defersRoutine = PtSub(invokeDefersRoutineName, emptyList(), emptyList(), Position.DUMMY)
|
||||
val defersRoutine = PtSub(invokeDefersRoutineName, emptyList(), emptyList(), sub.position)
|
||||
defersRoutine.parent=sub
|
||||
for((idx, defer) in defers.reversed().withIndex()) {
|
||||
val shift = PtAugmentedAssign(">>=", Position.DUMMY)
|
||||
shift.add(PtAssignTarget(false, sub.position).also {
|
||||
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, sub.position))
|
||||
val shift = PtAugmentedAssign(">>=", defer.position)
|
||||
shift.add(PtAssignTarget(false, defer.position).also {
|
||||
it.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, defer.position))
|
||||
})
|
||||
shift.add(PtNumber(BaseDataType.UBYTE, 1.0, sub.position))
|
||||
shift.add(PtNumber(BaseDataType.UBYTE, 1.0, defer.position))
|
||||
defersRoutine.add(shift)
|
||||
val skiplabel = "prog8_defer_skip_${idx+1}"
|
||||
val branchcc = PtConditionalBranch(BranchCondition.CC, Position.DUMMY)
|
||||
val branchcc = PtConditionalBranch(BranchCondition.CC, defer.position)
|
||||
branchcc.add(PtNodeGroup().also {
|
||||
val jump = PtJump(Position.DUMMY)
|
||||
jump.add(PtIdentifier(defersRoutine.scopedName+"."+skiplabel, DataType.UBYTE, Position.DUMMY))
|
||||
val jump = PtJump(defer.position)
|
||||
jump.add(PtIdentifier(defersRoutine.scopedName+"."+skiplabel, DataType.UBYTE, defer.position))
|
||||
it.add(jump)
|
||||
})
|
||||
branchcc.add(PtNodeGroup())
|
||||
defersRoutine.add(branchcc)
|
||||
transferChildren(defer, defersRoutine, true)
|
||||
defersRoutine.add(PtLabel(skiplabel, Position.DUMMY))
|
||||
defersRoutine.add(PtLabel(skiplabel, defer.position))
|
||||
}
|
||||
// val printMask = PtFunctionCall("txt.print_ubbin", true, DataType.UNDEFINED, Position.DUMMY)
|
||||
// printMask.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, Position.DUMMY))
|
||||
// printMask.add(PtBool(true, Position.DUMMY))
|
||||
// val printMask = PtFunctionCall("txt.print_ubbin", true, DataType.UNDEFINED, sub.position)
|
||||
// printMask.add(PtIdentifier(sub.scopedName+"."+maskVarName, DataType.UBYTE, sub.position))
|
||||
// printMask.add(PtBool(true, sub.position))
|
||||
// defersRoutine.add(printMask)
|
||||
|
||||
defersRoutine.add(PtReturn(Position.DUMMY))
|
||||
defersRoutine.add(PtReturn(sub.position))
|
||||
sub.add(defersRoutine)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -332,17 +332,17 @@ class TestCompilerOnExamplesVirtual: FunSpec({
|
||||
|
||||
val onlyVirtual = cartesianProduct(
|
||||
listOf(
|
||||
ExampleSizes("bouncegfx", virtualLineCountOptimized=890, virtualLineCountUnoptimized=3552),
|
||||
ExampleSizes("bsieve", virtualLineCountOptimized=800, virtualLineCountUnoptimized=4486),
|
||||
ExampleSizes("fountain", virtualLineCountOptimized=720, virtualLineCountUnoptimized=3397),
|
||||
ExampleSizes("pixelshader", virtualLineCountOptimized=368, virtualLineCountUnoptimized=1216),
|
||||
ExampleSizes("sincos", virtualLineCountOptimized=1075, virtualLineCountUnoptimized=3600),
|
||||
ExampleSizes("pointers/animalgame", virtualLineCountOptimized=879, virtualLineCountUnoptimized=8556),
|
||||
ExampleSizes("pointers/binarytree", virtualLineCountOptimized=1998, virtualLineCountUnoptimized=5657),
|
||||
ExampleSizes("pointers/hashtable", virtualLineCountOptimized=2232, virtualLineCountUnoptimized=9107),
|
||||
ExampleSizes("pointers/sortedlist", virtualLineCountOptimized=1102, virtualLineCountUnoptimized=6642),
|
||||
ExampleSizes("pointers/fountain-virtual", virtualLineCountOptimized=757, virtualLineCountUnoptimized=3436),
|
||||
ExampleSizes("pointers/sorting", virtualLineCountOptimized=1532, virtualLineCountUnoptimized=9329)
|
||||
ExampleSizes("bouncegfx", virtualLineCountOptimized=916, virtualLineCountUnoptimized=3604),
|
||||
ExampleSizes("bsieve", virtualLineCountOptimized=828, virtualLineCountUnoptimized=4546),
|
||||
ExampleSizes("fountain", virtualLineCountOptimized=746, virtualLineCountUnoptimized=3449),
|
||||
ExampleSizes("pixelshader", virtualLineCountOptimized=390, virtualLineCountUnoptimized=1260),
|
||||
ExampleSizes("sincos", virtualLineCountOptimized=1103, virtualLineCountUnoptimized=3654),
|
||||
ExampleSizes("pointers/animalgame", virtualLineCountOptimized=894, virtualLineCountUnoptimized=8629),
|
||||
ExampleSizes("pointers/binarytree", virtualLineCountOptimized=2023, virtualLineCountUnoptimized=5732),
|
||||
ExampleSizes("pointers/hashtable", virtualLineCountOptimized=2267, virtualLineCountUnoptimized=9178),
|
||||
ExampleSizes("pointers/sortedlist", virtualLineCountOptimized=1117, virtualLineCountUnoptimized=6713),
|
||||
ExampleSizes("pointers/fountain-virtual", virtualLineCountOptimized=786, virtualLineCountUnoptimized=3491),
|
||||
ExampleSizes("pointers/sorting", virtualLineCountOptimized=1548, virtualLineCountUnoptimized=9401)
|
||||
),
|
||||
listOf(false, true)
|
||||
)
|
||||
|
||||
@@ -229,8 +229,8 @@ interface INameScope: IStatementContainer, INamedStatement {
|
||||
return null
|
||||
if (idx == scopedName.size - 1) {
|
||||
// was last path element
|
||||
val pointer = IdentifierReference(scopedName, Position.DUMMY)
|
||||
val ref = StructFieldRef(pointer, struct as StructDecl, fieldDt, field, Position.DUMMY)
|
||||
val pointer = IdentifierReference(scopedName, localSymbol.position)
|
||||
val ref = StructFieldRef(pointer, struct as StructDecl, fieldDt, field, localSymbol.position)
|
||||
ref.linkParents(this as Node)
|
||||
return ref
|
||||
}
|
||||
@@ -451,4 +451,4 @@ fun defaultZero(dt: BaseDataType, position: Position) = when(dt) {
|
||||
else -> throw FatalAstException("can only determine default zero value for a numeric type, not for $dt at $position")
|
||||
}
|
||||
|
||||
fun defaultZero(idt: InferredTypes.InferredType, position: Position) = defaultZero(idt.getOrUndef().base, position)
|
||||
fun defaultZero(idt: InferredTypes.InferredType, position: Position) = defaultZero(idt.getOrUndef().base, position)
|
||||
@@ -798,7 +798,7 @@ class NumericLiteral(val type: BaseDataType, // only numerical types allowed
|
||||
operator fun compareTo(other: NumericLiteral): Int = number.compareTo(other.number)
|
||||
|
||||
class ValueAfterCast(val isValid: Boolean, val whyFailed: String?, private val value: NumericLiteral?) {
|
||||
fun valueOrZero() = if(isValid) value!! else NumericLiteral(BaseDataType.UBYTE, 0.0, Position.DUMMY)
|
||||
fun valueOrZero() = if(isValid) value!! else NumericLiteral(BaseDataType.UBYTE, 0.0, value?.position ?: Position.DUMMY)
|
||||
fun linkParent(parent: Node) {
|
||||
value?.linkParents(parent)
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user