removed BuiltinFunctionCallStatement redundant ast node type

This commit is contained in:
Irmen de Jong 2024-11-15 19:23:11 +01:00
parent 51a05ec4b7
commit d640cfbe13
9 changed files with 20 additions and 102 deletions

View File

@ -94,14 +94,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti
false 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 -> { is FunctionCallStatement -> {
val inline = val inline =
stmt.args.size <= 1 && stmt.args.all { it is NumericLiteral || it is IdentifierReference } 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) { private fun makeFullyScoped(call: FunctionCallStatement) {
makeFullyScoped(call.target) makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub -> call.target.targetSubroutine(program)?.let { sub ->

View File

@ -106,7 +106,7 @@ internal class AstChecker(private val program: Program,
if (iterations < 0 || iterations > 65535) if (iterations < 0 || iterations > 65535)
errors.err("invalid number of unrolls", unrollLoop.position) errors.err("invalid number of unrolls", unrollLoop.position)
unrollLoop.body.statements.forEach { 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) errors.err("invalid statement in unroll loop", it.position)
} }
if (iterations * unrollLoop.body.statements.size > 256) { if (iterations * unrollLoop.body.statements.size > 256) {

View File

@ -233,11 +233,6 @@ class AstPreprocessor(val program: Program,
return noModifications return noModifications
} }
override fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable<IAstModification> {
checkStringParam(bfcs as IFunctionCall, bfcs)
return noModifications
}
override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> { override fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
val stmtOfExpression = findParentNode<Statement>(functionCallExpr) val stmtOfExpression = findParentNode<Statement>(functionCallExpr)
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}") ?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}")

View File

@ -4,7 +4,6 @@ import prog8.ast.IFunctionCall
import prog8.ast.Node import prog8.ast.Node
import prog8.ast.Program import prog8.ast.Program
import prog8.ast.expressions.* import prog8.ast.expressions.*
import prog8.ast.statements.BuiltinFunctionCallStatement
import prog8.ast.statements.FunctionCallStatement import prog8.ast.statements.FunctionCallStatement
import prog8.ast.walk.AstWalker import prog8.ast.walk.AstWalker
import prog8.ast.walk.IAstModification import prog8.ast.walk.IAstModification
@ -70,25 +69,11 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
return noModifications return noModifications
} }
// also convert calls to builtin functions to BuiltinFunctionCall nodes to make things easier for codegen override fun after(fcs: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
if(fcs.target.nameInSource==listOf("cmp")) {
override fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
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<IAstModification> {
if(bfcs.name=="cmp") {
// if the datatype of the arguments of cmp() are different, cast the byte one to word. // if the datatype of the arguments of cmp() are different, cast the byte one to word.
val arg1 = bfcs.args[0] val arg1 = fcs.args[0]
val arg2 = bfcs.args[1] val arg2 = fcs.args[1]
val dt1 = arg1.inferType(program).getOr(DataType.UNDEFINED) val dt1 = arg1.inferType(program).getOr(DataType.UNDEFINED)
val dt2 = arg2.inferType(program).getOr(DataType.UNDEFINED) val dt2 = arg2.inferType(program).getOr(DataType.UNDEFINED)
if(dt1==DataType.BOOL && dt2==DataType.BOOL) if(dt1==DataType.BOOL && dt2==DataType.BOOL)
@ -98,13 +83,13 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
return noModifications return noModifications
val (replaced, cast) = arg1.typecastTo(if(dt1== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt1, true) val (replaced, cast) = arg1.typecastTo(if(dt1== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt1, true)
if(replaced) if(replaced)
return listOf(IAstModification.ReplaceNode(arg1, cast, bfcs)) return listOf(IAstModification.ReplaceNode(arg1, cast, fcs))
} else { } else {
if(dt2 in WordDatatypes) if(dt2 in WordDatatypes)
return noModifications return noModifications
val (replaced, cast) = arg2.typecastTo(if(dt2== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt2, true) val (replaced, cast) = arg2.typecastTo(if(dt2== DataType.UBYTE) DataType.UWORD else DataType.WORD, dt2, true)
if(replaced) if(replaced)
return listOf(IAstModification.ReplaceNode(arg2, cast, bfcs)) return listOf(IAstModification.ReplaceNode(arg2, cast, fcs))
} }
} }
return noModifications return noModifications

View File

@ -44,7 +44,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
is Alias -> throw FatalAstException("alias should have been desugared") is Alias -> throw FatalAstException("alias should have been desugared")
is Break -> throw FatalAstException("break should have been replaced by Goto") is Break -> throw FatalAstException("break should have been replaced by Goto")
is Continue -> throw FatalAstException("continue 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 BuiltinFunctionPlaceholder -> throw FatalAstException("BuiltinFunctionPlaceholder should not occur in Ast here")
is ConditionalBranch -> transform(statement) is ConditionalBranch -> transform(statement)
is Directive -> transform(statement) is Directive -> transform(statement)
@ -221,15 +220,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
return decls 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 { private fun transform(srcBranch: ConditionalBranch): PtConditionalBranch {
val branch = PtConditionalBranch(srcBranch.condition, srcBranch.position) val branch = PtConditionalBranch(srcBranch.condition, srcBranch.position)
val trueScope = PtNodeGroup() val trueScope = PtNodeGroup()
@ -290,7 +280,19 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
return forloop 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 (target, type) = srcCall.target.targetNameAndType(program)
val call = PtFunctionCall(target, true, type, srcCall.position) val call = PtFunctionCall(target, true, type, srcCall.position)
for (arg in srcCall.args) for (arg in srcCall.args)

View File

@ -259,10 +259,6 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
printout(functionCallStatement as IFunctionCall) printout(functionCallStatement as IFunctionCall)
} }
override fun visit(bfcs: BuiltinFunctionCallStatement) {
printout(bfcs as IFunctionCall)
}
private fun printout(call: IFunctionCall) { private fun printout(call: IFunctionCall) {
call.target.accept(this) call.target.accept(this)
output("(") output("(")

View File

@ -1200,35 +1200,3 @@ class DirectMemoryWrite(var addressExpression: Expression, override val position
override fun copy() = DirectMemoryWrite(addressExpression.copy(), position) override fun copy() = DirectMemoryWrite(addressExpression.copy(), position)
override fun referencesIdentifier(nameInSource: List<String>): Boolean = addressExpression.referencesIdentifier(nameInSource) override fun referencesIdentifier(nameInSource: List<String>): 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<Expression>,
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<String>): 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)"
}

View File

@ -115,7 +115,6 @@ abstract class AstWalker {
open fun before(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> = noModifications open fun before(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun before(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> = noModifications open fun before(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications open fun before(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun before(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications open fun before(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications
open fun before(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications open fun before(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications
open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications open fun before(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications
@ -161,7 +160,6 @@ abstract class AstWalker {
open fun after(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> = noModifications open fun after(unrollLoop: UnrollLoop, parent: Node): Iterable<IAstModification> = noModifications
open fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> = noModifications open fun after(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> = noModifications
open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications open fun after(functionCallStatement: FunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable<IAstModification> = noModifications
open fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications open fun after(identifier: IdentifierReference, parent: Node): Iterable<IAstModification> = noModifications
open fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications open fun after(ifElse: IfElse, parent: Node): Iterable<IAstModification> = noModifications
open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications open fun after(inlineAssembly: InlineAssembly, parent: Node): Iterable<IAstModification> = noModifications
@ -293,12 +291,6 @@ abstract class AstWalker {
track(after(functionCallStatement, parent), functionCallStatement, parent) 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) { fun visit(identifier: IdentifierReference, parent: Node) {
track(before(identifier, parent), identifier, parent) track(before(identifier, parent), identifier, parent)
track(after(identifier, parent), identifier, parent) track(after(identifier, parent), identifier, parent)

View File

@ -59,10 +59,6 @@ interface IAstVisitor {
functionCallStatement.args.forEach { it.accept(this) } functionCallStatement.args.forEach { it.accept(this) }
} }
fun visit(bfcs: BuiltinFunctionCallStatement) {
bfcs.args.forEach { it.accept(this) }
}
fun visit(identifier: IdentifierReference) { fun visit(identifier: IdentifierReference) {
} }