mirror of
https://github.com/irmen/prog8.git
synced 2024-12-22 18:30:01 +00:00
removed BuiltinFunctionCallStatement redundant ast node type
This commit is contained in:
parent
51a05ec4b7
commit
d640cfbe13
@ -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 ->
|
||||
|
@ -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) {
|
||||
|
@ -233,11 +233,6 @@ class AstPreprocessor(val program: Program,
|
||||
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> {
|
||||
val stmtOfExpression = findParentNode<Statement>(functionCallExpr)
|
||||
?: throw FatalAstException("cannot determine statement scope of function call expression at ${functionCallExpr.position}")
|
||||
|
@ -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<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") {
|
||||
override fun after(fcs: FunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||
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
|
||||
|
@ -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)
|
||||
|
@ -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("(")
|
||||
|
@ -1200,35 +1200,3 @@ class DirectMemoryWrite(var addressExpression: Expression, override val position
|
||||
override fun copy() = DirectMemoryWrite(addressExpression.copy(), position)
|
||||
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)"
|
||||
}
|
@ -115,7 +115,6 @@ abstract class AstWalker {
|
||||
open fun before(unrollLoop: UnrollLoop, 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(bfcs: BuiltinFunctionCallStatement, 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(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(functionCallExpr: FunctionCallExpression, 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(ifElse: IfElse, 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)
|
||||
}
|
||||
|
||||
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)
|
||||
|
@ -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) {
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user