mirror of
https://github.com/irmen/prog8.git
synced 2025-02-16 07:31:48 +00:00
removed BuiltinFunctionCall redundant ast node type
This commit is contained in:
parent
1f5706bbeb
commit
51a05ec4b7
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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 ->
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
@ -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))
|
||||
|
@ -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))
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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) }
|
||||
|
Loading…
x
Reference in New Issue
Block a user