mirror of
https://github.com/irmen/prog8.git
synced 2024-12-23 09:32:43 +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
|
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 ->
|
||||||
|
@ -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) {
|
||||||
|
@ -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}")
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
@ -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("(")
|
||||||
|
@ -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)"
|
|
||||||
}
|
|
@ -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)
|
||||||
|
@ -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) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user