mirror of
https://github.com/irmen/prog8.git
synced 2025-02-05 09:33:46 +00:00
fixed ast modifications on node arrays, in particular function call parameter lists
This commit is contained in:
parent
ec7b9f54c2
commit
a9d4b8b0fa
@ -230,7 +230,7 @@ class Program(val name: String, val modules: MutableList<Module>): Node {
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(node is Module && replacement is Module)
|
require(node is Module && replacement is Module)
|
||||||
val idx = modules.indexOf(node)
|
val idx = modules.withIndex().find { it.value===node }!!.index
|
||||||
modules[idx] = replacement
|
modules[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
@ -257,7 +257,7 @@ class Module(override val name: String,
|
|||||||
override fun definingScope(): INameScope = program.namespace
|
override fun definingScope(): INameScope = program.namespace
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(node is Statement && replacement is Statement)
|
require(node is Statement && replacement is Statement)
|
||||||
val idx = statements.indexOf(node)
|
val idx = statements.withIndex().find { it.value===node }!!.index
|
||||||
statements[idx] = replacement
|
statements[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
|
@ -529,7 +529,7 @@ class ArrayLiteralValue(val type: InferredTypes.InferredType, // inferred be
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(replacement is Expression)
|
require(replacement is Expression)
|
||||||
val idx = value.indexOf(node)
|
val idx = value.withIndex().find { it.value===node }!!.index
|
||||||
value[idx] = replacement
|
value[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
@ -800,7 +800,7 @@ class FunctionCall(override var target: IdentifierReference,
|
|||||||
if(node===target)
|
if(node===target)
|
||||||
target=replacement as IdentifierReference
|
target=replacement as IdentifierReference
|
||||||
else {
|
else {
|
||||||
val idx = args.indexOf(node)
|
val idx = args.withIndex().find { it.value===node }!!.index
|
||||||
args[idx] = replacement as Expression
|
args[idx] = replacement as Expression
|
||||||
}
|
}
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
|
@ -52,7 +52,7 @@ interface IAstModification {
|
|||||||
class InsertAfter(val after: Statement, val stmt: Statement, val parent: Node) : IAstModification {
|
class InsertAfter(val after: Statement, val stmt: Statement, val parent: Node) : IAstModification {
|
||||||
override fun perform() {
|
override fun perform() {
|
||||||
if(parent is INameScope) {
|
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)
|
parent.statements.add(idx, stmt)
|
||||||
stmt.linkParents(parent)
|
stmt.linkParents(parent)
|
||||||
} else {
|
} else {
|
||||||
|
@ -87,7 +87,9 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
|
|||||||
|
|
||||||
private fun afterFunctionCallArgs(call: IFunctionCall, scope: INameScope): Iterable<IAstModification> {
|
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
|
// 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 -> {
|
is Subroutine -> {
|
||||||
for(arg in sub.parameters.zip(call.args.withIndex())) {
|
for(arg in sub.parameters.zip(call.args.withIndex())) {
|
||||||
val argItype = arg.second.value.inferType(program)
|
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
|
val requiredType = arg.first.type
|
||||||
if (requiredType != argtype) {
|
if (requiredType != argtype) {
|
||||||
if (argtype isAssignableTo requiredType) {
|
if (argtype isAssignableTo requiredType) {
|
||||||
return listOf(IAstModification.ReplaceNode(
|
modifications += IAstModification.ReplaceNode(
|
||||||
call.args[arg.second.index],
|
call.args[arg.second.index],
|
||||||
TypecastExpression(arg.second.value, requiredType, true, arg.second.value.position),
|
TypecastExpression(arg.second.value, requiredType, true, arg.second.value.position),
|
||||||
call as Node))
|
call as Node)
|
||||||
} else if(requiredType == DataType.UWORD && argtype in PassByReferenceDatatypes) {
|
} else if(requiredType == DataType.UWORD && argtype in PassByReferenceDatatypes) {
|
||||||
// we allow STR/ARRAY values in place of UWORD parameters. Take their address instead.
|
// 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],
|
call.args[arg.second.index],
|
||||||
AddressOf(arg.second.value as IdentifierReference, arg.second.value.position),
|
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 -> {
|
is BuiltinFunctionStatementPlaceholder -> {
|
||||||
val func = BuiltinFunctions.getValue(sub.name)
|
val func = BuiltinFunctions.getValue(sub.name)
|
||||||
@ -124,20 +135,21 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke
|
|||||||
continue
|
continue
|
||||||
for (possibleType in arg.first.possibleDatatypes) {
|
for (possibleType in arg.first.possibleDatatypes) {
|
||||||
if (argtype isAssignableTo possibleType) {
|
if (argtype isAssignableTo possibleType) {
|
||||||
return listOf(IAstModification.ReplaceNode(
|
modifications += IAstModification.ReplaceNode(
|
||||||
call.args[arg.second.index],
|
call.args[arg.second.index],
|
||||||
TypecastExpression(arg.second.value, possibleType, true, arg.second.value.position),
|
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}")
|
else -> throw FatalAstException("call to something weird $sub ${call.target}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return modifications
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
override fun after(typecast: TypecastExpression, parent: Node): Iterable<IAstModification> {
|
||||||
|
@ -69,7 +69,7 @@ class Block(override val name: String,
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(replacement is Statement)
|
require(replacement is Statement)
|
||||||
val idx = statements.indexOf(node)
|
val idx = statements.withIndex().find { it.value===node }!!.index
|
||||||
statements[idx] = replacement
|
statements[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
@ -569,7 +569,7 @@ class FunctionCallStatement(override var target: IdentifierReference,
|
|||||||
if(node===target)
|
if(node===target)
|
||||||
target = replacement as IdentifierReference
|
target = replacement as IdentifierReference
|
||||||
else {
|
else {
|
||||||
val idx = args.indexOf(node)
|
val idx = args.withIndex().find { it.value===node }!!.index
|
||||||
args[idx] = replacement as Expression
|
args[idx] = replacement as Expression
|
||||||
}
|
}
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
@ -619,7 +619,7 @@ class AnonymousScope(override var statements: MutableList<Statement>,
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(replacement is Statement)
|
require(replacement is Statement)
|
||||||
val idx = statements.indexOf(node)
|
val idx = statements.withIndex().find { it.value===node }!!.index
|
||||||
statements[idx] = replacement
|
statements[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
@ -679,7 +679,7 @@ class Subroutine(override val name: String,
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(replacement is Statement)
|
require(replacement is Statement)
|
||||||
val idx = statements.indexOf(node)
|
val idx = statements.withIndex().find { it.value===node }!!.index
|
||||||
statements[idx] = replacement
|
statements[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
@ -923,7 +923,7 @@ class WhenStatement(var condition: Expression,
|
|||||||
if(node===condition)
|
if(node===condition)
|
||||||
condition = replacement as Expression
|
condition = replacement as Expression
|
||||||
else {
|
else {
|
||||||
val idx = choices.indexOf(node)
|
val idx = choices.withIndex().find { it.value===node }!!.index
|
||||||
choices[idx] = replacement as WhenChoice
|
choices[idx] = replacement as WhenChoice
|
||||||
}
|
}
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
@ -990,7 +990,7 @@ class StructDecl(override val name: String,
|
|||||||
|
|
||||||
override fun replaceChildNode(node: Node, replacement: Node) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
require(replacement is Statement)
|
require(replacement is Statement)
|
||||||
val idx = statements.indexOf(node)
|
val idx = statements.withIndex().find { it.value===node }!!.index
|
||||||
statements[idx] = replacement
|
statements[idx] = replacement
|
||||||
replacement.parent = this
|
replacement.parent = this
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@
|
|||||||
;%option enable_floats
|
;%option enable_floats
|
||||||
%zeropage dontuse
|
%zeropage dontuse
|
||||||
|
|
||||||
|
; TODO fix compiler errors when compiling without optimizations
|
||||||
|
|
||||||
|
|
||||||
main {
|
main {
|
||||||
|
|
||||||
sub start() {
|
sub start() {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user