fixed ast modifications on node arrays, in particular function call parameter lists

This commit is contained in:
Irmen de Jong 2020-07-01 21:58:24 +02:00
parent ec7b9f54c2
commit a9d4b8b0fa
6 changed files with 36 additions and 21 deletions

View File

@ -230,7 +230,7 @@ class Program(val name: String, val modules: MutableList<Module>): Node {
override fun replaceChildNode(node: Node, replacement: Node) {
require(node is Module && replacement is Module)
val idx = modules.indexOf(node)
val idx = modules.withIndex().find { it.value===node }!!.index
modules[idx] = replacement
replacement.parent = this
}
@ -257,7 +257,7 @@ class Module(override val name: String,
override fun definingScope(): INameScope = program.namespace
override fun replaceChildNode(node: Node, replacement: Node) {
require(node is Statement && replacement is Statement)
val idx = statements.indexOf(node)
val idx = statements.withIndex().find { it.value===node }!!.index
statements[idx] = replacement
replacement.parent = this
}

View File

@ -529,7 +529,7 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Expression)
val idx = value.indexOf(node)
val idx = value.withIndex().find { it.value===node }!!.index
value[idx] = replacement
replacement.parent = this
}
@ -800,7 +800,7 @@ class FunctionCall(override var target: IdentifierReference,
if(node===target)
target=replacement as IdentifierReference
else {
val idx = args.indexOf(node)
val idx = args.withIndex().find { it.value===node }!!.index
args[idx] = replacement as Expression
}
replacement.parent = this

View File

@ -52,7 +52,7 @@ interface IAstModification {
class InsertAfter(val after: Statement, val stmt: Statement, val parent: Node) : IAstModification {
override fun perform() {
if(parent is INameScope) {
val idx = parent.statements.indexOf(after)+1
val idx = parent.statements.withIndex().find { it.value===after }!!.index + 1
parent.statements.add(idx, stmt)
stmt.linkParents(parent)
} else {

View File

@ -87,7 +87,9 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
private fun afterFunctionCallArgs(call: IFunctionCall, scope: INameScope): Iterable<IAstModification> {
// see if a typecast is needed to convert the arguments into the required parameter's type
return when(val sub = call.target.targetStatement(scope)) {
val modifications = mutableListOf<IAstModification>()
when(val sub = call.target.targetStatement(scope)) {
is Subroutine -> {
for(arg in sub.parameters.zip(call.args.withIndex())) {
val argItype = arg.second.value.inferType(program)
@ -96,21 +98,30 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
val requiredType = arg.first.type
if (requiredType != argtype) {
if (argtype isAssignableTo requiredType) {
return listOf(IAstModification.ReplaceNode(
modifications += IAstModification.ReplaceNode(
call.args[arg.second.index],
TypecastExpression(arg.second.value, requiredType, true, arg.second.value.position),
call as Node))
call as Node)
} else if(requiredType == DataType.UWORD && argtype in PassByReferenceDatatypes) {
// we allow STR/ARRAY values in place of UWORD parameters. Take their address instead.
return listOf(IAstModification.ReplaceNode(
modifications += IAstModification.ReplaceNode(
call.args[arg.second.index],
AddressOf(arg.second.value as IdentifierReference, arg.second.value.position),
call as Node))
call as Node)
} else if(arg.second.value is NumericLiteralValue) {
try {
val castedValue = (arg.second.value as NumericLiteralValue).cast(requiredType)
modifications += IAstModification.ReplaceNode(
call.args[arg.second.index],
castedValue,
call as Node)
} catch (x: ExpressionError) {
// no cast possible
}
}
}
}
}
emptyList()
}
is BuiltinFunctionStatementPlaceholder -> {
val func = BuiltinFunctions.getValue(sub.name)
@ -124,20 +135,21 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
continue
for (possibleType in arg.first.possibleDatatypes) {
if (argtype isAssignableTo possibleType) {
return listOf(IAstModification.ReplaceNode(
modifications += IAstModification.ReplaceNode(
call.args[arg.second.index],
TypecastExpression(arg.second.value, possibleType, true, arg.second.value.position),
call as Node))
call as Node)
}
}
}
}
}
emptyList()
}
null -> emptyList()
null -> { }
else -> throw FatalAstException("call to something weird $sub ${call.target}")
}
return modifications
}
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {

View File

@ -69,7 +69,7 @@ class Block(override val name: String,
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Statement)
val idx = statements.indexOf(node)
val idx = statements.withIndex().find { it.value===node }!!.index
statements[idx] = replacement
replacement.parent = this
}
@ -569,7 +569,7 @@ class FunctionCallStatement(override var target: IdentifierReference,
if(node===target)
target = replacement as IdentifierReference
else {
val idx = args.indexOf(node)
val idx = args.withIndex().find { it.value===node }!!.index
args[idx] = replacement as Expression
}
replacement.parent = this
@ -619,7 +619,7 @@ class AnonymousScope(override var statements: MutableList<Statement>,
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Statement)
val idx = statements.indexOf(node)
val idx = statements.withIndex().find { it.value===node }!!.index
statements[idx] = replacement
replacement.parent = this
}
@ -679,7 +679,7 @@ class Subroutine(override val name: String,
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Statement)
val idx = statements.indexOf(node)
val idx = statements.withIndex().find { it.value===node }!!.index
statements[idx] = replacement
replacement.parent = this
}
@ -923,7 +923,7 @@ class WhenStatement(var condition: Expression,
if(node===condition)
condition = replacement as Expression
else {
val idx = choices.indexOf(node)
val idx = choices.withIndex().find { it.value===node }!!.index
choices[idx] = replacement as WhenChoice
}
replacement.parent = this
@ -990,7 +990,7 @@ class StructDecl(override val name: String,
override fun replaceChildNode(node: Node, replacement: Node) {
require(replacement is Statement)
val idx = statements.indexOf(node)
val idx = statements.withIndex().find { it.value===node }!!.index
statements[idx] = replacement
replacement.parent = this
}

View File

@ -3,6 +3,9 @@
;%option enable_floats
%zeropage dontuse
; TODO fix compiler errors when compiling without optimizations
main {
sub start() {