diff --git a/codeOptimizers/src/prog8/optimizer/Inliner.kt b/codeOptimizers/src/prog8/optimizer/Inliner.kt index 31027e7b6..c63baea06 100644 --- a/codeOptimizers/src/prog8/optimizer/Inliner.kt +++ b/codeOptimizers/src/prog8/optimizer/Inliner.kt @@ -94,14 +94,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti false } - is BuiltinFunctionCallStatement -> { - val inline = - stmt.args.size <= 1 && stmt.args.all { it is NumericLiteral || it is IdentifierReference } - if (inline) - makeFullyScoped(stmt) - inline - } - is FunctionCallStatement -> { val inline = stmt.args.size <= 1 && stmt.args.all { it is NumericLiteral || it is IdentifierReference } @@ -133,14 +125,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti } } - private fun makeFullyScoped(call: BuiltinFunctionCallStatement) { - val scopedArgs = makeScopedArgs(call.args) - if(scopedArgs.any()) { - val scopedCall = BuiltinFunctionCallStatement(call.target.copy(), scopedArgs.toMutableList(), call.position) - modifications += IAstModification.ReplaceNode(call, scopedCall, call.parent) - } - } - private fun makeFullyScoped(call: FunctionCallStatement) { makeFullyScoped(call.target) call.target.targetSubroutine(program)?.let { sub -> diff --git a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt index 80ee5b49c..6dac009df 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstChecker.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstChecker.kt @@ -106,7 +106,7 @@ internal class AstChecker(private val program: Program, if (iterations < 0 || iterations > 65535) errors.err("invalid number of unrolls", unrollLoop.position) unrollLoop.body.statements.forEach { - if (it !is InlineAssembly && it !is Assignment && it !is BuiltinFunctionCallStatement && it !is FunctionCallStatement) + if (it !is InlineAssembly && it !is Assignment && it !is FunctionCallStatement) errors.err("invalid statement in unroll loop", it.position) } if (iterations * unrollLoop.body.statements.size > 256) { diff --git a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt index a1fd9dc5a..09bfebc13 100644 --- a/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt +++ b/compiler/src/prog8/compiler/astprocessing/AstPreprocessor.kt @@ -233,11 +233,6 @@ class AstPreprocessor(val program: Program, return noModifications } - override fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable { - checkStringParam(bfcs as IFunctionCall, bfcs) - return noModifications - } - override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable { val stmtOfExpression = findParentNode(functionCallExpr) ?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}") diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmTypecastCleaner.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmTypecastCleaner.kt index dbd0899f1..c78c349e5 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmTypecastCleaner.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmTypecastCleaner.kt @@ -4,7 +4,6 @@ import prog8.ast.IFunctionCall import prog8.ast.Node import prog8.ast.Program import prog8.ast.expressions.* -import prog8.ast.statements.BuiltinFunctionCallStatement import prog8.ast.statements.FunctionCallStatement import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification @@ -70,25 +69,11 @@ internal class BeforeAsmTypecastCleaner(val program: Program, return noModifications } - // also convert calls to builtin functions to BuiltinFunctionCall nodes to make things easier for codegen - - override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable { - if(functionCallStatement.target.nameInSource.singleOrNull() in program.builtinFunctions.names) { - return listOf(IAstModification.ReplaceNode( - functionCallStatement, - BuiltinFunctionCallStatement(functionCallStatement.target, functionCallStatement.args, functionCallStatement.position), - parent - )) - } - - return noModifications - } - - override fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable { - if(bfcs.name=="cmp") { + override fun after(fcs: FunctionCallStatement, parent: Node): Iterable { + if(fcs.target.nameInSource==listOf("cmp")) { // if the datatype of the arguments of cmp() are different, cast the byte one to word. - val arg1 = bfcs.args[0] - val arg2 = bfcs.args[1] + val arg1 = fcs.args[0] + val arg2 = fcs.args[1] val dt1 = arg1.inferType(program).getOr(DataType.UNDEFINED) val dt2 = arg2.inferType(program).getOr(DataType.UNDEFINED) if(dt1==DataType.BOOL && dt2==DataType.BOOL) @@ -98,13 +83,13 @@ internal class BeforeAsmTypecastCleaner(val program: Program, return noModifications val (replaced, cast) = arg1.typecastTo(if(dt1== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt1, true) if(replaced) - return listOf(IAstModification.ReplaceNode(arg1, cast, bfcs)) + return listOf(IAstModification.ReplaceNode(arg1, cast, fcs)) } else { if(dt2 in WordDatatypes) return noModifications val (replaced, cast) = arg2.typecastTo(if(dt2== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt2, true) if(replaced) - return listOf(IAstModification.ReplaceNode(arg2, cast, bfcs)) + return listOf(IAstModification.ReplaceNode(arg2, cast, fcs)) } } return noModifications diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index 6cfec8365..077ebf550 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -44,7 +44,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr is Alias -> throw FatalAstException("alias should have been desugared") is Break -> throw FatalAstException("break should have been replaced by Goto") is Continue -> throw FatalAstException("continue should have been replaced by Goto") - is BuiltinFunctionCallStatement -> transform(statement) is BuiltinFunctionPlaceholder -> throw FatalAstException("BuiltinFunctionPlaceholder should not occur in Ast here") is ConditionalBranch -> transform(statement) is Directive -> transform(statement) @@ -221,15 +220,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr return decls } - private fun transform(srcNode: BuiltinFunctionCallStatement): PtBuiltinFunctionCall { - val type = builtinFunctionReturnType(srcNode.name).getOr(DataType.UNDEFINED) - val noSideFx = BuiltinFunctions.getValue(srcNode.name).pure - val call = PtBuiltinFunctionCall(srcNode.name, true, noSideFx, type, srcNode.position) - for (arg in srcNode.args) - call.add(transformExpression(arg)) - return call - } - private fun transform(srcBranch: ConditionalBranch): PtConditionalBranch { val branch = PtConditionalBranch(srcBranch.condition, srcBranch.position) val trueScope = PtNodeGroup() @@ -290,7 +280,19 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr return forloop } - private fun transform(srcCall: FunctionCallStatement): PtFunctionCall { + private fun transform(srcCall: FunctionCallStatement): PtExpression { + val singleName = srcCall.target.nameInSource.singleOrNull() + if(singleName!=null && singleName in BuiltinFunctions) { + // it is a builtin function. Create a special Ast node for that. + val type = builtinFunctionReturnType(singleName).getOr(DataType.UNDEFINED) + val noSideFx = BuiltinFunctions.getValue(singleName).pure + val call = PtBuiltinFunctionCall(singleName, true, noSideFx, type, srcCall.position) + for (arg in srcCall.args) + call.add(transformExpression(arg)) + return call + } + + // regular function call val (target, type) = srcCall.target.targetNameAndType(program) val call = PtFunctionCall(target, true, type, srcCall.position) for (arg in srcCall.args) diff --git a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt index 2e50cac43..7dbec9d98 100644 --- a/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt +++ b/compilerAst/src/prog8/ast/AstToSourceTextConverter.kt @@ -259,10 +259,6 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program: printout(functionCallStatement as IFunctionCall) } - override fun visit(bfcs: BuiltinFunctionCallStatement) { - printout(bfcs as IFunctionCall) - } - private fun printout(call: IFunctionCall) { call.target.accept(this) output("(") diff --git a/compilerAst/src/prog8/ast/statements/AstStatements.kt b/compilerAst/src/prog8/ast/statements/AstStatements.kt index 936390fb1..eb6b6fd1b 100644 --- a/compilerAst/src/prog8/ast/statements/AstStatements.kt +++ b/compilerAst/src/prog8/ast/statements/AstStatements.kt @@ -1200,35 +1200,3 @@ class DirectMemoryWrite(var addressExpression: Expression, override val position override fun copy() = DirectMemoryWrite(addressExpression.copy(), position) override fun referencesIdentifier(nameInSource: List): Boolean = addressExpression.referencesIdentifier(nameInSource) } - - -// Calls to builtin functions will be replaced with this node just before handing the Ast to the codegen. -// this is meant to eventually (?) be able to not have any FunctionCallStatement nodes to worry about anymore -// However, if/when the codegen is moved over to use the new CodeAst (PtProgram etc. etc.) this is all moot. -class BuiltinFunctionCallStatement(override var target: IdentifierReference, - override val args: MutableList, - override val position: Position) : Statement(), IFunctionCall { - val name: String = target.nameInSource.single() - - override lateinit var parent: Node - override fun linkParents(parent: Node) { - this.parent = parent - args.forEach { it.linkParents(this) } - } - - override fun copy() = throw NotImplementedError("no support for duplicating a BuiltinFunctionCallStatement") - override fun replaceChildNode(node: Node, replacement: Node) { - if(node===target) - target = replacement as IdentifierReference - else { - val idx = args.indexOfFirst { it===node } - args[idx] = replacement as Expression - } - replacement.parent = this - } - - override fun referencesIdentifier(nameInSource: List): Boolean = target.referencesIdentifier(nameInSource) || args.any { it.referencesIdentifier(nameInSource) } - override fun accept(visitor: IAstVisitor) = visitor.visit(this) - override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent) - override fun toString() = "BuiltinFunctionCallStatement(name=$name, pos=$position)" -} \ No newline at end of file diff --git a/compilerAst/src/prog8/ast/walk/AstWalker.kt b/compilerAst/src/prog8/ast/walk/AstWalker.kt index 7c03a8e12..91221651d 100644 --- a/compilerAst/src/prog8/ast/walk/AstWalker.kt +++ b/compilerAst/src/prog8/ast/walk/AstWalker.kt @@ -115,7 +115,6 @@ abstract class AstWalker { open fun before(unrollLoop: UnrollLoop, parent: Node): Iterable = noModifications open fun before(functionCallExpr: FunctionCallExpression, parent: Node): Iterable = noModifications open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = noModifications - open fun before(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable = noModifications open fun before(identifier: IdentifierReference, parent: Node): Iterable = noModifications open fun before(ifElse: IfElse, parent: Node): Iterable = noModifications open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable = noModifications @@ -161,7 +160,6 @@ abstract class AstWalker { open fun after(unrollLoop: UnrollLoop, parent: Node): Iterable = noModifications open fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable = noModifications open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable = noModifications - open fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable = noModifications open fun after(identifier: IdentifierReference, parent: Node): Iterable = noModifications open fun after(ifElse: IfElse, parent: Node): Iterable = noModifications open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable = noModifications @@ -293,12 +291,6 @@ abstract class AstWalker { track(after(functionCallStatement, parent), functionCallStatement, parent) } - fun visit(bfcs: BuiltinFunctionCallStatement, parent: Node) { - track(before(bfcs, parent), bfcs, parent) - bfcs.args.forEach { it.accept(this, bfcs) } - track(after(bfcs, parent), bfcs, parent) - } - fun visit(identifier: IdentifierReference, parent: Node) { track(before(identifier, parent), identifier, parent) track(after(identifier, parent), identifier, parent) diff --git a/compilerAst/src/prog8/ast/walk/IAstVisitor.kt b/compilerAst/src/prog8/ast/walk/IAstVisitor.kt index bdde208b4..566a6daa8 100644 --- a/compilerAst/src/prog8/ast/walk/IAstVisitor.kt +++ b/compilerAst/src/prog8/ast/walk/IAstVisitor.kt @@ -59,10 +59,6 @@ interface IAstVisitor { functionCallStatement.args.forEach { it.accept(this) } } - fun visit(bfcs: BuiltinFunctionCallStatement) { - bfcs.args.forEach { it.accept(this) } - } - fun visit(identifier: IdentifierReference) { }