diff --git a/compiler/src/prog8/ast/AstToplevel.kt b/compiler/src/prog8/ast/AstToplevel.kt index 4596c7c9d..4bca37ebf 100644 --- a/compiler/src/prog8/ast/AstToplevel.kt +++ b/compiler/src/prog8/ast/AstToplevel.kt @@ -230,7 +230,7 @@ class Program(val name: String, val modules: MutableList): 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 } diff --git a/compiler/src/prog8/ast/expressions/AstExpressions.kt b/compiler/src/prog8/ast/expressions/AstExpressions.kt index 9b61c9cc8..a1c49e67d 100644 --- a/compiler/src/prog8/ast/expressions/AstExpressions.kt +++ b/compiler/src/prog8/ast/expressions/AstExpressions.kt @@ -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 diff --git a/compiler/src/prog8/ast/processing/AstWalker.kt b/compiler/src/prog8/ast/processing/AstWalker.kt index 0c1267d1c..cbc8feba5 100644 --- a/compiler/src/prog8/ast/processing/AstWalker.kt +++ b/compiler/src/prog8/ast/processing/AstWalker.kt @@ -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 { diff --git a/compiler/src/prog8/ast/processing/TypecastsAdder.kt b/compiler/src/prog8/ast/processing/TypecastsAdder.kt index ffe7d6e48..967044771 100644 --- a/compiler/src/prog8/ast/processing/TypecastsAdder.kt +++ b/compiler/src/prog8/ast/processing/TypecastsAdder.kt @@ -87,7 +87,9 @@ class TypecastsAdder(val program: Program, val errors: ErrorReporter) : AstWalke private fun afterFunctionCallArgs(call: IFunctionCall, scope: INameScope): Iterable { // 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() + + 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 { diff --git a/compiler/src/prog8/ast/statements/AstStatements.kt b/compiler/src/prog8/ast/statements/AstStatements.kt index 545a72346..a662bb9b2 100644 --- a/compiler/src/prog8/ast/statements/AstStatements.kt +++ b/compiler/src/prog8/ast/statements/AstStatements.kt @@ -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, 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 } diff --git a/examples/arithmetic/bitshift.p8 b/examples/arithmetic/bitshift.p8 index fd8b7de36..b0c39edb7 100644 --- a/examples/arithmetic/bitshift.p8 +++ b/examples/arithmetic/bitshift.p8 @@ -3,6 +3,9 @@ ;%option enable_floats %zeropage dontuse +; TODO fix compiler errors when compiling without optimizations + + main { sub start() {