removed BuiltinFunctionCall redundant ast node type

This commit is contained in:
Irmen de Jong 2024-11-15 04:29:53 +01:00
parent 1f5706bbeb
commit 51a05ec4b7
13 changed files with 29 additions and 136 deletions

View File

@ -359,14 +359,6 @@ class ConstantFoldingOptimizer(private val program: Program, private val errors:
}
}
override fun after(bfc: BuiltinFunctionCall, parent: Node): Iterable<IAstModification> {
val constvalue = bfc.constValue(program)
return if(constvalue!=null)
listOf(IAstModification.ReplaceNode(bfc, constvalue, parent))
else
noModifications
}
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
val fromCast = rangeFrom.cast(targetDt, true)

View File

@ -70,7 +70,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
if (rightNum!=null && rightNum.type==DataType.UWORD) {
if ((rightNum.number.toInt() and 0x00ff) == 0) {
// if WORD & $xx00 -> if msb(WORD) & $xx
val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, (rightNum.number.toInt() shr 8).toDouble(), booleanCondition.right.position)
return listOf(
IAstModification.ReplaceNode(booleanCondition.left, msb, booleanCondition),
@ -78,7 +78,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
}
else if ((rightNum.number.toInt() and 0xff00) == 0) {
// if WORD & $00ff -> if lsb(WORD) & $ff
val lsb = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, rightNum.number, booleanCondition.right.position)
return listOf(
IAstModification.ReplaceNode(booleanCondition.left, lsb, booleanCondition),
@ -383,7 +383,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
if (andNum!=null) {
if ((andNum and 0x00ff) == 0) {
// (WORD & $xx00)==y -> (msb(WORD) & $xx)==y
val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position)
return listOf(
@ -394,7 +394,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
}
else if((andNum and 0xff00) == 0) {
// (WORD & $00xx)==y -> (lsb(WORD) & $xx)==y
val lsb = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val lsb = FunctionCallExpression(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position)
val bytevalue = NumericLiteral(DataType.UBYTE, andNum.toDouble(), bitwise.right.position)
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position)
return listOf(
@ -696,7 +696,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
DataType.BYTE -> return null // is either 0 or -1 we cannot tell here
DataType.UWORD, DataType.WORD -> {
// just use: msb(value) as type
val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
val msb = FunctionCallExpression(IdentifierReference(listOf("msb"), expr.position), mutableListOf(expr.left), expr.position)
return if(leftDt==DataType.WORD)
TypecastExpression(msb, DataType.BYTE, true, expr.position)
else

View File

@ -48,11 +48,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti
true
} else if (stmt.value!! is IFunctionCall && (stmt.value as IFunctionCall).args.size <= 1 && (stmt.value as IFunctionCall).args.all { it is NumericLiteral || it is IdentifierReference }) {
when (stmt.value) {
is BuiltinFunctionCall -> {
makeFullyScoped(stmt.value as BuiltinFunctionCall)
true
}
is FunctionCallExpression -> {
makeFullyScoped(stmt.value as FunctionCallExpression)
true
@ -158,17 +153,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti
}
}
private fun makeFullyScoped(call: BuiltinFunctionCall) {
call.target.targetSubroutine(program)?.let { sub ->
val scopedName = IdentifierReference(sub.scopedName, call.target.position)
val scopedArgs = makeScopedArgs(call.args)
if(scopedArgs.any()) {
val scopedCall = BuiltinFunctionCall(scopedName, scopedArgs.toMutableList(), call.position)
modifications += IAstModification.ReplaceNode(call, scopedCall, call.parent)
}
}
}
private fun makeFullyScoped(call: FunctionCallExpression) {
makeFullyScoped(call.target)
call.target.targetSubroutine(program)?.let { sub ->

View File

@ -1400,13 +1400,6 @@ internal class AstChecker(private val program: Program,
super.visit(functionCallExpr)
}
override fun visit(bfc: BuiltinFunctionCall) {
// most function calls, even to builtin functions, are still regular FunctionCall nodes here.
// they get converted to the more specialized node type in BeforeAsmTypecastCleaner
checkLongType(bfc)
super.visit(bfc)
}
override fun visit(functionCallStatement: FunctionCallStatement) {
// most function calls, even to builtin functions, are still regular FunctionCall nodes here.
// they get converted to the more specialized node type in BeforeAsmTypecastCleaner

View File

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

View File

@ -84,18 +84,6 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
return noModifications
}
override fun before(functionCallExpr: FunctionCallExpression, parent: Node): Iterable<IAstModification> {
if(functionCallExpr.target.nameInSource.singleOrNull() in program.builtinFunctions.names) {
return listOf(IAstModification.ReplaceNode(
functionCallExpr,
BuiltinFunctionCall(functionCallExpr.target, functionCallExpr.args, functionCallExpr.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.

View File

@ -48,7 +48,7 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep
is ForLoop,
is RepeatLoop,
is UntilLoop,
is WhileLoop -> return jumpAfter(partof as Statement)
is WhileLoop -> return jumpAfter(partof)
else -> partof = partof.parent
}
}
@ -238,7 +238,7 @@ _after:
if(isStringComparison(leftDt, rightDt)) {
// replace string comparison expressions with calls to string.compare()
val stringCompare = BuiltinFunctionCall(
val stringCompare = FunctionCallExpression(
IdentifierReference(listOf("prog8_lib_stringcompare"), expr.position),
mutableListOf(expr.left.copy(), expr.right.copy()), expr.position)
val zero = NumericLiteral.optimalInteger(0, expr.position)
@ -250,7 +250,7 @@ _after:
if(expr.operator=="*" && expr.inferType(program).isInteger && expr.left isSameAs expr.right) {
// replace squaring with call to builtin function to do this in a more optimized way
val function = if(expr.left.inferType(program).isBytes) "prog8_lib_square_byte" else "prog8_lib_square_word"
val squareCall = BuiltinFunctionCall(
val squareCall = FunctionCallExpression(
IdentifierReference(listOf(function), expr.position),
mutableListOf(expr.left.copy()), expr.position)
return listOf(IAstModification.ReplaceNode(expr, squareCall, parent))

View File

@ -76,7 +76,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
is ArrayIndexedExpression -> transform(expr)
is ArrayLiteral -> transform(expr)
is BinaryExpression -> transform(expr)
is BuiltinFunctionCall -> transform(expr)
is CharLiteral -> throw FatalAstException("char literals should have been converted into bytes")
is ContainmentCheck -> transform(expr)
is DirectMemoryRead -> transform(expr)
@ -299,7 +298,21 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
return call
}
private fun transform(srcCall: FunctionCallExpression): PtFunctionCall {
private fun transform(srcCall: FunctionCallExpression): PtExpression {
val singleName = srcCall.target.nameInSource.singleOrNull()
if(singleName!=null) {
val builtinFunc = BuiltinFunctions[singleName]
if (builtinFunc != null) {
// it's a builtin function. Create special node type for this.
val noSideFx = builtinFunc.pure
val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val call = PtBuiltinFunctionCall(singleName, false, noSideFx, type, srcCall.position)
for (arg in srcCall.args)
call.add(transformExpression(arg))
return call
}
}
val (target, _) = srcCall.target.targetNameAndType(program)
val iType = srcCall.inferType(program)
val call = PtFunctionCall(target, iType.isUnknown && srcCall.parent !is Assignment, iType.getOrElse { DataType.UNDEFINED }, srcCall.position)
@ -608,15 +621,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
return expr
}
private fun transform(srcCall: BuiltinFunctionCall): PtBuiltinFunctionCall {
val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val noSideFx = BuiltinFunctions.getValue(srcCall.name).pure
val call = PtBuiltinFunctionCall(srcCall.name, false, noSideFx, type, srcCall.position)
for (arg in srcCall.args)
call.add(transformExpression(arg))
return call
}
private fun transform(srcCheck: ContainmentCheck): PtExpression {
fun desugar(range: RangeExpression): PtExpression {
@ -684,7 +688,6 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
}
}
private fun transform(memory: DirectMemoryWrite): PtMemoryByte {
val mem = PtMemoryByte(memory.position)
mem.add(transformExpression(memory.addressExpression))

View File

@ -6,7 +6,7 @@ import io.kotest.matchers.shouldBe
import io.kotest.matchers.shouldNotBe
import io.kotest.matchers.string.shouldContain
import io.kotest.matchers.string.shouldNotContain
import prog8.ast.expressions.BuiltinFunctionCall
import prog8.ast.expressions.FunctionCallExpression
import prog8.ast.statements.Assignment
import prog8.code.target.C64Target
import prog8.code.target.Cx16Target
@ -175,7 +175,7 @@ main {
val result = compileText(target, true, src, writeAssembly = true)!!
val start = result.compilerAst.entrypoint
start.statements.size shouldBe 9
((start.statements[1] as Assignment).value as BuiltinFunctionCall).name shouldBe "memory"
((start.statements[1] as Assignment).value as FunctionCallExpression).target.nameInSource shouldBe listOf("memory")
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
vm.memory.getUB(2) shouldBe 42u

View File

@ -255,10 +255,6 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
printout(functionCallExpr as IFunctionCall)
}
override fun visit(bfc: BuiltinFunctionCall) {
printout(bfc as IFunctionCall)
}
override fun visit(functionCallStatement: FunctionCallStatement) {
printout(functionCallStatement as IFunctionCall)
}

View File

@ -1214,8 +1214,10 @@ class FunctionCallExpression(override var target: IdentifierReference,
}
override fun copy() = FunctionCallExpression(target.copy(), args.map { it.copy() }.toMutableList(), position)
override val isSimple = false
override val isSimple = when (target.nameInSource.singleOrNull()) {
in arrayOf("msb", "lsb", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple }
else -> false
}
override fun replaceChildNode(node: Node, replacement: Node) {
if(node===target)
target=replacement as IdentifierReference
@ -1343,50 +1345,6 @@ class ContainmentCheck(var element: Expression,
}
}
class BuiltinFunctionCall(override var target: IdentifierReference,
override val args: MutableList<Expression>,
override val position: Position) : Expression(), IFunctionCall {
val name = target.nameInSource.single()
override lateinit var parent: Node
override fun linkParents(parent: Node) {
this.parent = parent
target.linkParents(this)
args.forEach { it.linkParents(this) }
}
override fun copy() = BuiltinFunctionCall(target.copy(), args.map { it.copy() }.toMutableList(), position)
override val isSimple = when (name) {
in arrayOf("msb", "lsb", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") -> this.args.all { it.isSimple }
else -> false
}
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 constValue(program: Program): NumericLiteral? {
val function = BuiltinFunctions.getValue(name)
if(function.pure) {
return program.builtinFunctions.constValue(name, args, position)
}
return null
}
override fun toString() = "BuiltinFunctionCall(name=$name, pos=$position)"
override fun accept(visitor: IAstVisitor) = visitor.visit(this)
override fun accept(visitor: AstWalker, parent: Node) = visitor.visit(this, parent)
override fun referencesIdentifier(nameInSource: List<String>): Boolean = target.referencesIdentifier(nameInSource) || args.any{it.referencesIdentifier(nameInSource)}
override fun inferType(program: Program) = program.builtinFunctions.returnType(name)
}
class IfExpression(var condition: Expression, var truevalue: Expression, var falsevalue: Expression, override val position: Position) : Expression() {
override lateinit var parent: Node

View File

@ -114,7 +114,6 @@ abstract class AstWalker {
open fun before(repeatLoop: RepeatLoop, 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(bfc: BuiltinFunctionCall, 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
@ -161,7 +160,6 @@ abstract class AstWalker {
open fun after(repeatLoop: RepeatLoop, 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(bfc: BuiltinFunctionCall, 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
@ -288,13 +286,6 @@ abstract class AstWalker {
track(after(functionCallExpr, parent), functionCallExpr, parent)
}
fun visit(bfc: BuiltinFunctionCall, parent: Node) {
track(before(bfc, parent), bfc, parent)
bfc.target.accept(this, bfc)
bfc.args.forEach { it.accept(this, bfc) }
track(after(bfc, parent), bfc, parent)
}
fun visit(functionCallStatement: FunctionCallStatement, parent: Node) {
track(before(functionCallStatement, parent), functionCallStatement, parent)
functionCallStatement.target.accept(this, functionCallStatement)

View File

@ -54,11 +54,6 @@ interface IAstVisitor {
functionCallExpr.args.forEach { it.accept(this) }
}
fun visit(bfc: BuiltinFunctionCall) {
bfc.target.accept(this)
bfc.args.forEach { it.accept(this) }
}
fun visit(functionCallStatement: FunctionCallStatement) {
functionCallStatement.target.accept(this)
functionCallStatement.args.forEach { it.accept(this) }