mirror of
https://github.com/irmen/prog8.git
synced 2025-11-01 06:16:15 +00:00
removed BuiltinFunctionCall redundant ast node type
This commit is contained in:
@@ -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> {
|
override fun after(forLoop: ForLoop, parent: Node): Iterable<IAstModification> {
|
||||||
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
|
fun adjustRangeDt(rangeFrom: NumericLiteral, targetDt: DataType, rangeTo: NumericLiteral, stepLiteral: NumericLiteral?, range: RangeExpression): RangeExpression? {
|
||||||
val fromCast = rangeFrom.cast(targetDt, true)
|
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!=null && rightNum.type==DataType.UWORD) {
|
||||||
if ((rightNum.number.toInt() and 0x00ff) == 0) {
|
if ((rightNum.number.toInt() and 0x00ff) == 0) {
|
||||||
// if WORD & $xx00 -> if msb(WORD) & $xx
|
// 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)
|
val bytevalue = NumericLiteral(DataType.UBYTE, (rightNum.number.toInt() shr 8).toDouble(), booleanCondition.right.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
IAstModification.ReplaceNode(booleanCondition.left, msb, booleanCondition),
|
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) {
|
else if ((rightNum.number.toInt() and 0xff00) == 0) {
|
||||||
// if WORD & $00ff -> if lsb(WORD) & $ff
|
// 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)
|
val bytevalue = NumericLiteral(DataType.UBYTE, rightNum.number, booleanCondition.right.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
IAstModification.ReplaceNode(booleanCondition.left, lsb, booleanCondition),
|
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!=null) {
|
||||||
if ((andNum and 0x00ff) == 0) {
|
if ((andNum and 0x00ff) == 0) {
|
||||||
// (WORD & $xx00)==y -> (msb(WORD) & $xx)==y
|
// (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 bytevalue = NumericLiteral(DataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position)
|
||||||
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position)
|
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position)
|
||||||
return listOf(
|
return listOf(
|
||||||
@@ -394,7 +394,7 @@ class ExpressionSimplifier(private val program: Program, private val errors: IEr
|
|||||||
}
|
}
|
||||||
else if((andNum and 0xff00) == 0) {
|
else if((andNum and 0xff00) == 0) {
|
||||||
// (WORD & $00xx)==y -> (lsb(WORD) & $xx)==y
|
// (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 bytevalue = NumericLiteral(DataType.UBYTE, andNum.toDouble(), bitwise.right.position)
|
||||||
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position)
|
val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position)
|
||||||
return listOf(
|
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.BYTE -> return null // is either 0 or -1 we cannot tell here
|
||||||
DataType.UWORD, DataType.WORD -> {
|
DataType.UWORD, DataType.WORD -> {
|
||||||
// just use: msb(value) as type
|
// 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)
|
return if(leftDt==DataType.WORD)
|
||||||
TypecastExpression(msb, DataType.BYTE, true, expr.position)
|
TypecastExpression(msb, DataType.BYTE, true, expr.position)
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -48,11 +48,6 @@ class Inliner(private val program: Program, private val options: CompilationOpti
|
|||||||
true
|
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 }) {
|
} 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) {
|
when (stmt.value) {
|
||||||
is BuiltinFunctionCall -> {
|
|
||||||
makeFullyScoped(stmt.value as BuiltinFunctionCall)
|
|
||||||
true
|
|
||||||
}
|
|
||||||
|
|
||||||
is FunctionCallExpression -> {
|
is FunctionCallExpression -> {
|
||||||
makeFullyScoped(stmt.value as FunctionCallExpression)
|
makeFullyScoped(stmt.value as FunctionCallExpression)
|
||||||
true
|
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) {
|
private fun makeFullyScoped(call: FunctionCallExpression) {
|
||||||
makeFullyScoped(call.target)
|
makeFullyScoped(call.target)
|
||||||
call.target.targetSubroutine(program)?.let { sub ->
|
call.target.targetSubroutine(program)?.let { sub ->
|
||||||
|
|||||||
@@ -1400,13 +1400,6 @@ internal class AstChecker(private val program: Program,
|
|||||||
super.visit(functionCallExpr)
|
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) {
|
override fun visit(functionCallStatement: FunctionCallStatement) {
|
||||||
// most function calls, even to builtin functions, are still regular FunctionCall nodes here.
|
// most function calls, even to builtin functions, are still regular FunctionCall nodes here.
|
||||||
// they get converted to the more specialized node type in BeforeAsmTypecastCleaner
|
// they get converted to the more specialized node type in BeforeAsmTypecastCleaner
|
||||||
|
|||||||
@@ -233,13 +233,6 @@ class AstPreprocessor(val program: Program,
|
|||||||
return noModifications
|
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> {
|
override fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||||
checkStringParam(bfcs as IFunctionCall, bfcs)
|
checkStringParam(bfcs as IFunctionCall, bfcs)
|
||||||
return noModifications
|
return noModifications
|
||||||
|
|||||||
@@ -84,18 +84,6 @@ internal class BeforeAsmTypecastCleaner(val program: Program,
|
|||||||
return noModifications
|
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> {
|
override fun after(bfcs: BuiltinFunctionCallStatement, parent: Node): Iterable<IAstModification> {
|
||||||
if(bfcs.name=="cmp") {
|
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.
|
||||||
|
|||||||
@@ -48,7 +48,7 @@ internal class CodeDesugarer(val program: Program, private val errors: IErrorRep
|
|||||||
is ForLoop,
|
is ForLoop,
|
||||||
is RepeatLoop,
|
is RepeatLoop,
|
||||||
is UntilLoop,
|
is UntilLoop,
|
||||||
is WhileLoop -> return jumpAfter(partof as Statement)
|
is WhileLoop -> return jumpAfter(partof)
|
||||||
else -> partof = partof.parent
|
else -> partof = partof.parent
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,7 +238,7 @@ _after:
|
|||||||
|
|
||||||
if(isStringComparison(leftDt, rightDt)) {
|
if(isStringComparison(leftDt, rightDt)) {
|
||||||
// replace string comparison expressions with calls to string.compare()
|
// replace string comparison expressions with calls to string.compare()
|
||||||
val stringCompare = BuiltinFunctionCall(
|
val stringCompare = FunctionCallExpression(
|
||||||
IdentifierReference(listOf("prog8_lib_stringcompare"), expr.position),
|
IdentifierReference(listOf("prog8_lib_stringcompare"), expr.position),
|
||||||
mutableListOf(expr.left.copy(), expr.right.copy()), expr.position)
|
mutableListOf(expr.left.copy(), expr.right.copy()), expr.position)
|
||||||
val zero = NumericLiteral.optimalInteger(0, 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) {
|
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
|
// 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 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),
|
IdentifierReference(listOf(function), expr.position),
|
||||||
mutableListOf(expr.left.copy()), expr.position)
|
mutableListOf(expr.left.copy()), expr.position)
|
||||||
return listOf(IAstModification.ReplaceNode(expr, squareCall, parent))
|
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 ArrayIndexedExpression -> transform(expr)
|
||||||
is ArrayLiteral -> transform(expr)
|
is ArrayLiteral -> transform(expr)
|
||||||
is BinaryExpression -> transform(expr)
|
is BinaryExpression -> transform(expr)
|
||||||
is BuiltinFunctionCall -> transform(expr)
|
|
||||||
is CharLiteral -> throw FatalAstException("char literals should have been converted into bytes")
|
is CharLiteral -> throw FatalAstException("char literals should have been converted into bytes")
|
||||||
is ContainmentCheck -> transform(expr)
|
is ContainmentCheck -> transform(expr)
|
||||||
is DirectMemoryRead -> transform(expr)
|
is DirectMemoryRead -> transform(expr)
|
||||||
@@ -299,7 +298,21 @@ class IntermediateAstMaker(private val program: Program, private val errors: IEr
|
|||||||
return call
|
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 (target, _) = srcCall.target.targetNameAndType(program)
|
||||||
val iType = srcCall.inferType(program)
|
val iType = srcCall.inferType(program)
|
||||||
val call = PtFunctionCall(target, iType.isUnknown && srcCall.parent !is Assignment, iType.getOrElse { DataType.UNDEFINED }, srcCall.position)
|
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
|
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 {
|
private fun transform(srcCheck: ContainmentCheck): PtExpression {
|
||||||
|
|
||||||
fun desugar(range: RangeExpression): 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 {
|
private fun transform(memory: DirectMemoryWrite): PtMemoryByte {
|
||||||
val mem = PtMemoryByte(memory.position)
|
val mem = PtMemoryByte(memory.position)
|
||||||
mem.add(transformExpression(memory.addressExpression))
|
mem.add(transformExpression(memory.addressExpression))
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ import io.kotest.matchers.shouldBe
|
|||||||
import io.kotest.matchers.shouldNotBe
|
import io.kotest.matchers.shouldNotBe
|
||||||
import io.kotest.matchers.string.shouldContain
|
import io.kotest.matchers.string.shouldContain
|
||||||
import io.kotest.matchers.string.shouldNotContain
|
import io.kotest.matchers.string.shouldNotContain
|
||||||
import prog8.ast.expressions.BuiltinFunctionCall
|
import prog8.ast.expressions.FunctionCallExpression
|
||||||
import prog8.ast.statements.Assignment
|
import prog8.ast.statements.Assignment
|
||||||
import prog8.code.target.C64Target
|
import prog8.code.target.C64Target
|
||||||
import prog8.code.target.Cx16Target
|
import prog8.code.target.Cx16Target
|
||||||
@@ -175,7 +175,7 @@ main {
|
|||||||
val result = compileText(target, true, src, writeAssembly = true)!!
|
val result = compileText(target, true, src, writeAssembly = true)!!
|
||||||
val start = result.compilerAst.entrypoint
|
val start = result.compilerAst.entrypoint
|
||||||
start.statements.size shouldBe 9
|
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")
|
val virtfile = result.compilationOptions.outputDir.resolve(result.compilerAst.name + ".p8ir")
|
||||||
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
|
VmRunner().runAndTestProgram(virtfile.readText()) { vm ->
|
||||||
vm.memory.getUB(2) shouldBe 42u
|
vm.memory.getUB(2) shouldBe 42u
|
||||||
|
|||||||
@@ -255,10 +255,6 @@ class AstToSourceTextConverter(val output: (text: String) -> Unit, val program:
|
|||||||
printout(functionCallExpr as IFunctionCall)
|
printout(functionCallExpr as IFunctionCall)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visit(bfc: BuiltinFunctionCall) {
|
|
||||||
printout(bfc as IFunctionCall)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visit(functionCallStatement: FunctionCallStatement) {
|
override fun visit(functionCallStatement: FunctionCallStatement) {
|
||||||
printout(functionCallStatement as IFunctionCall)
|
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 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) {
|
override fun replaceChildNode(node: Node, replacement: Node) {
|
||||||
if(node===target)
|
if(node===target)
|
||||||
target=replacement as IdentifierReference
|
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() {
|
class IfExpression(var condition: Expression, var truevalue: Expression, var falsevalue: Expression, override val position: Position) : Expression() {
|
||||||
|
|
||||||
override lateinit var parent: Node
|
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(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> = noModifications
|
||||||
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(bfc: BuiltinFunctionCall, 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(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
|
||||||
@@ -161,7 +160,6 @@ abstract class AstWalker {
|
|||||||
open fun after(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> = noModifications
|
open fun after(repeatLoop: RepeatLoop, parent: Node): Iterable<IAstModification> = noModifications
|
||||||
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(bfc: BuiltinFunctionCall, 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(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
|
||||||
@@ -288,13 +286,6 @@ abstract class AstWalker {
|
|||||||
track(after(functionCallExpr, parent), functionCallExpr, parent)
|
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) {
|
fun visit(functionCallStatement: FunctionCallStatement, parent: Node) {
|
||||||
track(before(functionCallStatement, parent), functionCallStatement, parent)
|
track(before(functionCallStatement, parent), functionCallStatement, parent)
|
||||||
functionCallStatement.target.accept(this, functionCallStatement)
|
functionCallStatement.target.accept(this, functionCallStatement)
|
||||||
|
|||||||
@@ -54,11 +54,6 @@ interface IAstVisitor {
|
|||||||
functionCallExpr.args.forEach { it.accept(this) }
|
functionCallExpr.args.forEach { it.accept(this) }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun visit(bfc: BuiltinFunctionCall) {
|
|
||||||
bfc.target.accept(this)
|
|
||||||
bfc.args.forEach { it.accept(this) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun visit(functionCallStatement: FunctionCallStatement) {
|
fun visit(functionCallStatement: FunctionCallStatement) {
|
||||||
functionCallStatement.target.accept(this)
|
functionCallStatement.target.accept(this)
|
||||||
functionCallStatement.args.forEach { it.accept(this) }
|
functionCallStatement.args.forEach { it.accept(this) }
|
||||||
|
|||||||
Reference in New Issue
Block a user