introduce PtRpn node to replace PtBinaryExpression later

This commit is contained in:
Irmen de Jong
2023-03-15 22:06:55 +01:00
parent 20dbdb20d2
commit 7fea0c124a
12 changed files with 430 additions and 266 deletions

View File

@@ -3,6 +3,7 @@ package prog8.code.ast
import prog8.code.core.* import prog8.code.core.*
import java.util.* import java.util.*
import kotlin.math.abs import kotlin.math.abs
import kotlin.math.max
import kotlin.math.round import kotlin.math.round
@@ -26,7 +27,8 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
return when(this) { return when(this) {
is PtAddressOf -> other is PtAddressOf && other.type==type && other.identifier isSameAs identifier is PtAddressOf -> other is PtAddressOf && other.type==type && other.identifier isSameAs identifier
is PtArrayIndexer -> other is PtArrayIndexer && other.type==type && other.variable isSameAs variable && other.index isSameAs index is PtArrayIndexer -> other is PtArrayIndexer && other.type==type && other.variable isSameAs variable && other.index isSameAs index
is PtBinaryExpression -> other is PtBinaryExpression && other.left isSameAs left && other.right isSameAs right is PtBinaryExpressionObsoleteUsePtRpn -> other is PtBinaryExpressionObsoleteUsePtRpn && other.left isSameAs left && other.right isSameAs right
is PtRpn -> other is PtRpn && this.isSame(other)
is PtContainmentCheck -> other is PtContainmentCheck && other.type==type && other.element isSameAs element && other.iterable isSameAs iterable is PtContainmentCheck -> other is PtContainmentCheck && other.type==type && other.element isSameAs element && other.iterable isSameAs iterable
is PtIdentifier -> other is PtIdentifier && other.type==type && other.name==name is PtIdentifier -> other is PtIdentifier && other.type==type && other.name==name
is PtMachineRegister -> other is PtMachineRegister && other.type==type && other.register==register is PtMachineRegister -> other is PtMachineRegister && other.type==type && other.register==register
@@ -61,7 +63,8 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit
is PtAddressOf -> true is PtAddressOf -> true
is PtArray -> true is PtArray -> true
is PtArrayIndexer -> index is PtNumber || index is PtIdentifier is PtArrayIndexer -> index is PtNumber || index is PtIdentifier
is PtBinaryExpression -> false is PtBinaryExpressionObsoleteUsePtRpn -> false
is PtRpn -> false
is PtBuiltinFunctionCall -> name in arrayOf("msb", "lsb", "peek", "peekw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") is PtBuiltinFunctionCall -> name in arrayOf("msb", "lsb", "peek", "peekw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd")
is PtContainmentCheck -> false is PtContainmentCheck -> false
is PtFunctionCall -> false is PtFunctionCall -> false
@@ -149,7 +152,7 @@ class PtBuiltinFunctionCall(val name: String,
} }
class PtBinaryExpression(val operator: String, type: DataType, position: Position): PtExpression(type, position) { class PtBinaryExpressionObsoleteUsePtRpn(val operator: String, type: DataType, position: Position): PtExpression(type, position) {
// note: "and", "or", "xor" do not occur anymore as operators. They've been replaced int the ast by their bitwise versions &, |, ^. // note: "and", "or", "xor" do not occur anymore as operators. They've been replaced int the ast by their bitwise versions &, |, ^.
val left: PtExpression val left: PtExpression
get() = children[0] as PtExpression get() = children[0] as PtExpression
@@ -158,6 +161,110 @@ class PtBinaryExpression(val operator: String, type: DataType, position: Positio
} }
class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
// contains only PtExpression (not PtRpn!) and PtRpnOperator nodes
operator fun plusAssign(node: PtNode) {
require(node is PtRpnOperator || node is PtExpression)
if(node is PtRpn)
children.addAll(node.children)
else
children += node
}
fun print() {
children.forEach {
when(it) {
is PtRpnOperator -> println(it.operator)
is PtExpression -> println("expr $it ${it.position}")
else -> {}
}
}
}
fun isSame(other: PtRpn): Boolean {
if(other.children.size==children.size) {
return other.children.zip(this.children).all { (first, second) ->
when (first) {
is PtRpnOperator -> second is PtRpnOperator && first.operator==second.operator
is PtExpression -> second is PtExpression && first isSameAs second
else -> false
}
}
}
return false
}
fun maxDepth(): Pair<Map<DataType, Int>, Int> {
val depths = mutableMapOf(
DataType.UBYTE to 0,
DataType.UWORD to 0,
DataType.FLOAT to 0
)
val maxDepths = mutableMapOf(
DataType.UBYTE to 0,
DataType.UWORD to 0,
DataType.FLOAT to 0
)
var numPushes = 0
var numPops = 0
fun push(type: DataType) {
when (type) {
in ByteDatatypes -> {
val depth = depths.getValue(DataType.UBYTE) + 1
depths[DataType.UBYTE] = depth
maxDepths[DataType.UBYTE] = max(maxDepths.getValue(DataType.UBYTE), depth)
}
in WordDatatypes -> {
val depth = depths.getValue(DataType.UWORD) + 1
depths[DataType.UWORD] = depth
maxDepths[DataType.UWORD] = max(maxDepths.getValue(DataType.UWORD), depth)
}
DataType.FLOAT -> {
val depth = depths.getValue(DataType.FLOAT) + 1
depths[DataType.FLOAT] = depth
maxDepths[DataType.FLOAT] = max(maxDepths.getValue(DataType.FLOAT), depth)
}
else -> throw IllegalArgumentException("invalid dt")
}
numPushes++
}
fun pop(type: DataType) {
when (type) {
in ByteDatatypes -> depths[DataType.UBYTE]=depths.getValue(DataType.UBYTE) - 1
in WordDatatypes -> depths[DataType.UWORD]=depths.getValue(DataType.UWORD) - 1
DataType.FLOAT -> depths[DataType.FLOAT]=depths.getValue(DataType.FLOAT) - 1
else -> throw IllegalArgumentException("invalid dt")
}
numPops++
}
children.withIndex().forEach { (index, node) ->
if (node is PtRpnOperator) {
pop(node.operand1Type)
pop(node.operand2Type)
push(node.type)
}
else {
push((node as PtExpression).type)
}
}
require(numPushes==numPops+1) {
"RPN not balanced, pushes=$numPushes pops=$numPops"
}
return Pair(maxDepths, numPushes)
}
}
class PtRpnOperator(val operator: String, val type: DataType, val operand1Type: DataType, val operand2Type: DataType, position: Position): PtNode(position) {
init {
require(type==operand1Type && type==operand2Type) // TODO if this is always true, can remove operand1 and 2 types again.
}
}
class PtContainmentCheck(position: Position): PtExpression(DataType.UBYTE, position) { class PtContainmentCheck(position: Position): PtExpression(DataType.UBYTE, position) {
val element: PtExpression val element: PtExpression
get() = children[0] as PtExpression get() = children[0] as PtExpression

View File

@@ -18,7 +18,9 @@ fun printAst(root: PtNode, output: (text: String) -> Unit) {
is PtAddressOf -> "&" is PtAddressOf -> "&"
is PtArray -> "array len=${node.children.size} ${type(node.type)}" is PtArray -> "array len=${node.children.size} ${type(node.type)}"
is PtArrayIndexer -> "<arrayindexer> ${type(node.type)}" is PtArrayIndexer -> "<arrayindexer> ${type(node.type)}"
is PtBinaryExpression -> "<expr> ${node.operator} ${type(node.type)}" is PtBinaryExpressionObsoleteUsePtRpn -> "<expr> ${node.operator} ${type(node.type)}"
is PtRpn -> "<rpnexpr>"
is PtRpnOperator -> node.operator
is PtBuiltinFunctionCall -> { is PtBuiltinFunctionCall -> {
val str = if(node.void) "void " else "" val str = if(node.void) "void " else ""
str + node.name + "()" str + node.name + "()"

View File

@@ -100,8 +100,8 @@ class PtForLoop(position: Position) : PtNode(position) {
class PtIfElse(position: Position) : PtNode(position) { class PtIfElse(position: Position) : PtNode(position) {
val condition: PtBinaryExpression val condition: PtBinaryExpressionObsoleteUsePtRpn
get() = children[0] as PtBinaryExpression get() = children[0] as PtBinaryExpressionObsoleteUsePtRpn
val ifScope: PtNodeGroup val ifScope: PtNodeGroup
get() = children[1] as PtNodeGroup get() = children[1] as PtNodeGroup
val elseScope: PtNodeGroup val elseScope: PtNodeGroup

View File

@@ -572,7 +572,7 @@ class AsmGen6502Internal (
} }
private fun requireComparisonExpression(condition: PtExpression) { private fun requireComparisonExpression(condition: PtExpression) {
if(condition !is PtBinaryExpression || condition.operator !in ComparisonOperators) if(condition !is PtBinaryExpressionObsoleteUsePtRpn || condition.operator !in ComparisonOperators)
throw AssemblyError("expected boolean comparison expression $condition") throw AssemblyError("expected boolean comparison expression $condition")
} }
@@ -977,7 +977,7 @@ $repeatLabel lda $counterVar
} }
internal fun pointerViaIndexRegisterPossible(pointerOffsetExpr: PtExpression): Pair<PtExpression, PtExpression>? { internal fun pointerViaIndexRegisterPossible(pointerOffsetExpr: PtExpression): Pair<PtExpression, PtExpression>? {
if(pointerOffsetExpr is PtBinaryExpression && pointerOffsetExpr.operator=="+") { if(pointerOffsetExpr is PtBinaryExpressionObsoleteUsePtRpn && pointerOffsetExpr.operator=="+") {
val leftDt = pointerOffsetExpr.left.type val leftDt = pointerOffsetExpr.left.type
val rightDt = pointerOffsetExpr.left.type val rightDt = pointerOffsetExpr.left.type
if(leftDt == DataType.UWORD && rightDt == DataType.UBYTE) if(leftDt == DataType.UWORD && rightDt == DataType.UBYTE)
@@ -1003,7 +1003,7 @@ $repeatLabel lda $counterVar
return null return null
} }
internal fun tryOptimizedPointerAccessWithA(expr: PtBinaryExpression, write: Boolean): Boolean { internal fun tryOptimizedPointerAccessWithA(expr: PtBinaryExpressionObsoleteUsePtRpn, write: Boolean): Boolean {
// optimize pointer,indexregister if possible // optimize pointer,indexregister if possible
fun evalBytevalueWillClobberA(expr: PtExpression): Boolean { fun evalBytevalueWillClobberA(expr: PtExpression): Boolean {
@@ -1095,7 +1095,7 @@ $repeatLabel lda $counterVar
return node.definingSub()?.parameters?.singleOrNull { it.name===name } return node.definingSub()?.parameters?.singleOrNull { it.name===name }
} }
private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpression, jump: PtJump) { private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpressionObsoleteUsePtRpn, jump: PtJump) {
if(expr.operator !in ComparisonOperators) if(expr.operator !in ComparisonOperators)
throw AssemblyError("must be comparison expression") throw AssemblyError("must be comparison expression")
@@ -1121,7 +1121,7 @@ $repeatLabel lda $counterVar
} }
} }
private fun translateCompareAndJumpIfFalse(expr: PtBinaryExpression, jumpIfFalseLabel: String) { private fun translateCompareAndJumpIfFalse(expr: PtBinaryExpressionObsoleteUsePtRpn, jumpIfFalseLabel: String) {
val left = expr.left val left = expr.left
val right = expr.right val right = expr.right
val operator = expr.operator val operator = expr.operator
@@ -2833,14 +2833,17 @@ $repeatLabel lda $counterVar
if(pushResultOnEstack) if(pushResultOnEstack)
out(" sta P8ESTACK_LO,x | dex") out(" sta P8ESTACK_LO,x | dex")
} }
is PtBinaryExpression -> { is PtBinaryExpressionObsoleteUsePtRpn -> {
if(tryOptimizedPointerAccessWithA(expr.address as PtBinaryExpression, false)) { if(tryOptimizedPointerAccessWithA(expr.address as PtBinaryExpressionObsoleteUsePtRpn, false)) {
if(pushResultOnEstack) if(pushResultOnEstack)
out(" sta P8ESTACK_LO,x | dex") out(" sta P8ESTACK_LO,x | dex")
} else { } else {
assignViaExprEval() assignViaExprEval()
} }
} }
is PtRpn -> {
TODO("translate RPN $expr")
}
else -> assignViaExprEval() else -> assignViaExprEval()
} }
} }

View File

@@ -661,7 +661,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
return return
} }
} }
is PtBinaryExpression -> { is PtRpn -> {
TODO("pokeW for RPN $addrExpr")
}
is PtBinaryExpressionObsoleteUsePtRpn -> {
if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) {
val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier)
if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) { if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) {
@@ -720,7 +723,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram,
asmgen.out(" jsr prog8_lib.func_peekw") asmgen.out(" jsr prog8_lib.func_peekw")
} }
} }
is PtBinaryExpression -> { is PtRpn -> {
TODO("peekW for RPN $addrExpr")
}
is PtBinaryExpressionObsoleteUsePtRpn -> {
if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) {
val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier)
if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) { if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) {

View File

@@ -24,7 +24,8 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
when(expression) { when(expression) {
is PtPrefix -> translateExpression(expression) is PtPrefix -> translateExpression(expression)
is PtBinaryExpression -> translateExpression(expression) is PtBinaryExpressionObsoleteUsePtRpn -> translateExpression(expression)
is PtRpn -> translateExpression(expression)
is PtArrayIndexer -> translateExpression(expression) is PtArrayIndexer -> translateExpression(expression)
is PtTypeCast -> translateExpression(expression) is PtTypeCast -> translateExpression(expression)
is PtAddressOf -> translateExpression(expression) is PtAddressOf -> translateExpression(expression)
@@ -239,7 +240,11 @@ internal class ExpressionsAsmGen(private val program: PtProgram,
} }
} }
private fun translateExpression(expr: PtBinaryExpression) { private fun translateExpression(expr: PtRpn) {
TODO("translate RPN $expr")
}
private fun translateExpression(expr: PtBinaryExpressionObsoleteUsePtRpn) {
// Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED! // Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED!
val leftDt = expr.left.type val leftDt = expr.left.type
val rightDt = expr.right.type val rightDt = expr.right.type

View File

@@ -141,8 +141,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtIdentifier -> { is PtIdentifier -> {
assignMemoryByte(assign.target, null, value.address as PtIdentifier) assignMemoryByte(assign.target, null, value.address as PtIdentifier)
} }
is PtBinaryExpression -> { is PtRpn -> {
if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { TODO("translate RPN ${value.address}")
}
is PtBinaryExpressionObsoleteUsePtRpn -> {
if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpressionObsoleteUsePtRpn, false)) {
assignRegisterByte(assign.target, CpuRegister.A) assignRegisterByte(assign.target, CpuRegister.A)
} else { } else {
assignViaExprEval(value.address) assignViaExprEval(value.address)
@@ -294,7 +297,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
containmentCheckIntoA(value) containmentCheckIntoA(value)
assignRegisterByte(assign.target, CpuRegister.A) assignRegisterByte(assign.target, CpuRegister.A)
} }
is PtBinaryExpression -> { is PtBinaryExpressionObsoleteUsePtRpn -> {
if(!attemptAssignOptimizedBinexpr(value, assign)) { if(!attemptAssignOptimizedBinexpr(value, assign)) {
// All remaining binary expressions just evaluate via the stack for now. // All remaining binary expressions just evaluate via the stack for now.
// (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here, // (we can't use the assignment helper functions (assignExpressionTo...) to do it via registers here,
@@ -302,6 +305,9 @@ internal class AssignmentAsmGen(private val program: PtProgram,
fallbackToStackEval(assign) fallbackToStackEval(assign)
} }
} }
is PtRpn ->{
TODO("assign RPN expression $value depth=${value.maxDepth()}")
}
else -> throw AssemblyError("weird assignment value type $value") else -> throw AssemblyError("weird assignment value type $value")
} }
} }
@@ -339,7 +345,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
} }
private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpressionObsoleteUsePtRpn, assign: AsmAssignment): Boolean {
if(expr.operator in ComparisonOperators) { if(expr.operator in ComparisonOperators) {
if(expr.right.asConstInteger() == 0) { if(expr.right.asConstInteger() == 0) {
if(expr.operator == "==" || expr.operator=="!=") { if(expr.operator == "==" || expr.operator=="!=") {
@@ -361,7 +367,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
assignTrue.add(assignment) assignTrue.add(assignment)
val assignFalse = PtNodeGroup() val assignFalse = PtNodeGroup()
val ifelse = PtIfElse(assign.position) val ifelse = PtIfElse(assign.position)
val exprClone = PtBinaryExpression(expr.operator, expr.type, expr.position) val exprClone = PtBinaryExpressionObsoleteUsePtRpn(expr.operator, expr.type, expr.position)
expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone
ifelse.add(exprClone) ifelse.add(exprClone)
ifelse.add(assignTrue) ifelse.add(assignTrue)
@@ -721,7 +727,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
assignRegisterpairWord(target, RegisterOrPair.AY) assignRegisterpairWord(target, RegisterOrPair.AY)
} }
private fun attemptAssignToByteCompareZero(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { private fun attemptAssignToByteCompareZero(expr: PtBinaryExpressionObsoleteUsePtRpn, assign: AsmAssignment): Boolean {
when (expr.operator) { when (expr.operator) {
"==" -> { "==" -> {
when(val dt = expr.left.type) { when(val dt = expr.left.type) {
@@ -900,8 +906,11 @@ internal class AssignmentAsmGen(private val program: PtProgram,
is PtIdentifier -> { is PtIdentifier -> {
assignMemoryByteIntoWord(target, null, value.address as PtIdentifier) assignMemoryByteIntoWord(target, null, value.address as PtIdentifier)
} }
is PtBinaryExpression -> { is PtRpn -> {
if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { TODO("translate RPN ${value.address}")
}
is PtBinaryExpressionObsoleteUsePtRpn -> {
if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpressionObsoleteUsePtRpn, false)) {
asmgen.out(" ldy #0") asmgen.out(" ldy #0")
assignRegisterpairWord(target, RegisterOrPair.AY) assignRegisterpairWord(target, RegisterOrPair.AY)
} else { } else {
@@ -2821,7 +2830,10 @@ internal class AssignmentAsmGen(private val program: PtProgram,
addressExpr is PtIdentifier -> { addressExpr is PtIdentifier -> {
asmgen.storeAIntoPointerVar(addressExpr) asmgen.storeAIntoPointerVar(addressExpr)
} }
addressExpr is PtBinaryExpression -> { addressExpr is PtRpn -> {
TODO("translate RPN $addressExpr")
}
addressExpr is PtBinaryExpressionObsoleteUsePtRpn -> {
if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true)) if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true))
storeViaExprEval() storeViaExprEval()
} }

View File

@@ -92,7 +92,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
value.add(origAssign.value) value.add(origAssign.value)
} else { } else {
require(origAssign.operator.endsWith('=')) require(origAssign.operator.endsWith('='))
value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position) value = PtBinaryExpressionObsoleteUsePtRpn(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position)
val left: PtExpression = origAssign.target.children.single() as PtExpression val left: PtExpression = origAssign.target.children.single() as PtExpression
value.add(left) value.add(left)
value.add(origAssign.value) value.add(origAssign.value)
@@ -262,7 +262,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express
val tr = if(itemsize==1) { val tr = if(itemsize==1) {
expressionEval.translateExpression(array.index) expressionEval.translateExpression(array.index)
} else { } else {
val mult = PtBinaryExpression("*", DataType.UBYTE, array.position) val mult = PtBinaryExpressionObsoleteUsePtRpn("*", DataType.UBYTE, array.position)
mult.children += array.index mult.children += array.index
mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position) mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position)
expressionEval.translateExpression(mult) expressionEval.translateExpression(mult)

View File

@@ -92,7 +92,8 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
is PtTypeCast -> translate(expr) is PtTypeCast -> translate(expr)
is PtPrefix -> translate(expr) is PtPrefix -> translate(expr)
is PtArrayIndexer -> translate(expr) is PtArrayIndexer -> translate(expr)
is PtBinaryExpression -> translate(expr) is PtBinaryExpressionObsoleteUsePtRpn -> translate(expr)
is PtRpn -> translate(expr)
is PtBuiltinFunctionCall -> codeGen.translateBuiltinFunc(expr) is PtBuiltinFunctionCall -> codeGen.translateBuiltinFunc(expr)
is PtFunctionCall -> translate(expr) is PtFunctionCall -> translate(expr)
is PtContainmentCheck -> translate(expr) is PtContainmentCheck -> translate(expr)
@@ -315,7 +316,11 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return ExpressionCodeResult(result, codeGen.irType(cast.type), actualResultReg2, actualResultFpReg2) return ExpressionCodeResult(result, codeGen.irType(cast.type), actualResultReg2, actualResultFpReg2)
} }
private fun translate(binExpr: PtBinaryExpression): ExpressionCodeResult { private fun translate(rpn: PtRpn): ExpressionCodeResult {
TODO("translate RPN expression $rpn")
}
private fun translate(binExpr: PtBinaryExpressionObsoleteUsePtRpn): ExpressionCodeResult {
val vmDt = codeGen.irType(binExpr.left.type) val vmDt = codeGen.irType(binExpr.left.type)
val signed = binExpr.left.type in SignedDatatypes val signed = binExpr.left.type in SignedDatatypes
return when(binExpr.operator) { return when(binExpr.operator) {
@@ -430,7 +435,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
private fun operatorGreaterThan( private fun operatorGreaterThan(
binExpr: PtBinaryExpression, binExpr: PtBinaryExpressionObsoleteUsePtRpn,
vmDt: IRDataType, vmDt: IRDataType,
signed: Boolean, signed: Boolean,
greaterEquals: Boolean greaterEquals: Boolean
@@ -486,7 +491,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
private fun operatorLessThan( private fun operatorLessThan(
binExpr: PtBinaryExpression, binExpr: PtBinaryExpressionObsoleteUsePtRpn,
vmDt: IRDataType, vmDt: IRDataType,
signed: Boolean, signed: Boolean,
lessEquals: Boolean lessEquals: Boolean
@@ -541,7 +546,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
private fun operatorEquals(binExpr: PtBinaryExpression, vmDt: IRDataType, notEquals: Boolean): ExpressionCodeResult { private fun operatorEquals(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, notEquals: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) { if(vmDt==IRDataType.FLOAT) {
val leftTr = translateExpression(binExpr.left) val leftTr = translateExpression(binExpr.left)
@@ -596,7 +601,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { private fun operatorShiftRight(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(codeGen.isOne(binExpr.right)) { return if(codeGen.isOne(binExpr.right)) {
val tr = translateExpression(binExpr.left) val tr = translateExpression(binExpr.left)
@@ -615,29 +620,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorShiftRightInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): ExpressionCodeResult { private fun operatorShiftLeft(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(codeGen.isOne(operand)) {
val opc = if (signed) Opcode.ASRM else Opcode.LSRM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, value=knownAddress)
else
IRInstruction(opc, vmDt, labelSymbol = symbol)
addInstr(result, ins, null)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, reg1 = tr.resultReg, value=knownAddress)
else
IRInstruction(opc, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
addInstr(result, ins, null)
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(codeGen.isOne(binExpr.right)){ return if(codeGen.isOne(binExpr.right)){
val tr = translateExpression(binExpr.left) val tr = translateExpression(binExpr.left)
@@ -654,27 +637,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorShiftLeftInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorXor(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(codeGen.isOne(operand)){
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
, null)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, value=knownAddress)
else
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorXor(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(binExpr.right is PtNumber) { return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left) val tr = translateExpression(binExpr.left)
@@ -691,19 +654,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorXorInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorAnd(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(binExpr.right is PtNumber) { return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left) val tr = translateExpression(binExpr.left)
@@ -720,19 +671,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorOr(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, value=knownAddress)
else
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorOr(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(binExpr.right is PtNumber) { return if(binExpr.right is PtNumber) {
val tr = translateExpression(binExpr.left) val tr = translateExpression(binExpr.left)
@@ -749,19 +688,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorModulo(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
require(vmDt!=IRDataType.FLOAT) {"floating-point modulo not supported ${binExpr.position}"} require(vmDt!=IRDataType.FLOAT) {"floating-point modulo not supported ${binExpr.position}"}
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
return if(binExpr.right is PtNumber) { return if(binExpr.right is PtNumber) {
@@ -779,7 +706,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { private fun operatorDivide(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val constFactorRight = binExpr.right as? PtNumber val constFactorRight = binExpr.right as? PtNumber
if(vmDt==IRDataType.FLOAT) { if(vmDt==IRDataType.FLOAT) {
@@ -834,56 +761,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorDivideInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): ExpressionCodeResult { private fun operatorMultiply(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val constFactorRight = operand as? PtNumber
if(vmDt==IRDataType.FLOAT) {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toFloat()
result += codeGen.divideByConstFloatInplace(knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
addInstr(result, ins, null)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toInt()
result += codeGen.divideByConstInplace(vmDt, knownAddress, symbol, factor, signed)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
addInstr(result, ins, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
val constFactorLeft = binExpr.left as? PtNumber val constFactorLeft = binExpr.left as? PtNumber
val constFactorRight = binExpr.right as? PtNumber val constFactorRight = binExpr.right as? PtNumber
@@ -932,40 +810,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorMultiplyInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorMinus(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val constFactorRight = operand as? PtNumber
if(vmDt==IRDataType.FLOAT) {
if(constFactorRight!=null) {
val factor = constFactorRight.number.toFloat()
result += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
, null)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toInt()
result += codeGen.multiplyByConstInplace(vmDt, knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) { if(vmDt==IRDataType.FLOAT) {
if((binExpr.right as? PtNumber)?.number==1.0) { if((binExpr.right as? PtNumber)?.number==1.0) {
@@ -1014,47 +859,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorMinusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { private fun operatorPlus(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
}
else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, value=knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, labelSymbol = symbol)
, null)
}
} else {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
}
else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) { if(vmDt==IRDataType.FLOAT) {
if((binExpr.left as? PtNumber)?.number==1.0) { if((binExpr.left as? PtNumber)?.number==1.0) {
@@ -1115,6 +920,153 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
} }
} }
internal fun operatorAndInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, value=knownAddress)
else
IRInstruction(Opcode.ANDM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorOrInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.ORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorDivideInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val constFactorRight = operand as? PtNumber
if(vmDt==IRDataType.FLOAT) {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toFloat()
result += codeGen.divideByConstFloatInplace(knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
}
addInstr(result, ins, null)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toInt()
result += codeGen.divideByConstInplace(vmDt, knownAddress, symbol, factor, signed)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
val ins = if(signed) {
if(knownAddress!=null)
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.DIVSM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
else {
if(knownAddress!=null)
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.DIVM, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
}
addInstr(result, ins, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorMultiplyInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val constFactorRight = operand as? PtNumber
if(vmDt==IRDataType.FLOAT) {
if(constFactorRight!=null) {
val factor = constFactorRight.number.toFloat()
result += codeGen.multiplyByConstFloatInplace(knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, value = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, fpReg1 = tr.resultFpReg, labelSymbol = symbol)
, null)
}
} else {
if(constFactorRight!=null && constFactorRight.type!=DataType.FLOAT) {
val factor = constFactorRight.number.toInt()
result += codeGen.multiplyByConstInplace(vmDt, knownAddress, symbol, factor)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.MULM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorMinusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
}
else {
val tr = translateExpression(operand)
addToResult(result, tr, -1, tr.resultFpReg)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, value=knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, fpReg1=tr.resultFpReg, labelSymbol = symbol)
, null)
}
} else {
if((operand as? PtNumber)?.number==1.0) {
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.DECM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.DECM, vmDt, labelSymbol = symbol)
, null)
}
else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.SUBM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
, null)
}
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorPlusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult { internal fun operatorPlusInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>() val result = mutableListOf<IRCodeChunkBase>()
if(vmDt==IRDataType.FLOAT) { if(vmDt==IRDataType.FLOAT) {
@@ -1155,6 +1107,60 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) {
return ExpressionCodeResult(result, vmDt, -1, -1) return ExpressionCodeResult(result, vmDt, -1, -1)
} }
internal fun operatorShiftRightInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, signed: Boolean, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(codeGen.isOne(operand)) {
val opc = if (signed) Opcode.ASRM else Opcode.LSRM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, value=knownAddress)
else
IRInstruction(opc, vmDt, labelSymbol = symbol)
addInstr(result, ins, null)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
val opc = if (signed) Opcode.ASRNM else Opcode.LSRNM
val ins = if(knownAddress!=null)
IRInstruction(opc, vmDt, reg1 = tr.resultReg, value=knownAddress)
else
IRInstruction(opc, vmDt, reg1 = tr.resultReg, labelSymbol = symbol)
addInstr(result, ins, null)
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorShiftLeftInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
if(codeGen.isOne(operand)){
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLM, vmDt, value=knownAddress)
else
IRInstruction(Opcode.LSLM, vmDt, labelSymbol = symbol)
, null)
} else {
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, value=knownAddress)
else
IRInstruction(Opcode.LSLNM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
}
return ExpressionCodeResult(result, vmDt, -1, -1)
}
internal fun operatorXorInplace(knownAddress: Int?, symbol: String?, vmDt: IRDataType, operand: PtExpression): ExpressionCodeResult {
val result = mutableListOf<IRCodeChunkBase>()
val tr = translateExpression(operand)
addToResult(result, tr, tr.resultReg, -1)
addInstr(result, if(knownAddress!=null)
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, value = knownAddress)
else
IRInstruction(Opcode.XORM, vmDt, reg1=tr.resultReg, labelSymbol = symbol)
,null)
return ExpressionCodeResult(result, vmDt, -1, -1)
}
} }

View File

@@ -268,7 +268,9 @@ class IRCodeGen(
is PtMemoryByte, is PtMemoryByte,
is PtProgram, is PtProgram,
is PtArrayIndexer, is PtArrayIndexer,
is PtBinaryExpression, is PtBinaryExpressionObsoleteUsePtRpn,
is PtRpn,
is PtRpnOperator,
is PtIdentifier, is PtIdentifier,
is PtWhenChoice, is PtWhenChoice,
is PtPrefix, is PtPrefix,

View File

@@ -122,7 +122,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -130,7 +130,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.UBYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.UBYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)
@@ -138,7 +138,7 @@ class TestVmCodeGen: FunSpec({
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2) sub.add(if2)
val if3 = PtIfElse(Position.DUMMY) val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.UBYTE, Position.DUMMY) val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.UBYTE, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp3.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) cmp3.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY))
if3.add(cmp3) if3.add(cmp3)
@@ -146,7 +146,7 @@ class TestVmCodeGen: FunSpec({
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3) sub.add(if3)
val if4 = PtIfElse(Position.DUMMY) val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp4.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) cmp4.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY))
if4.add(cmp4) if4.add(cmp4)
@@ -185,7 +185,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -193,7 +193,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.UBYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.UBYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)
@@ -201,7 +201,7 @@ class TestVmCodeGen: FunSpec({
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2) sub.add(if2)
val if3 = PtIfElse(Position.DUMMY) val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.UBYTE, Position.DUMMY) val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.UBYTE, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp3.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp3.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if3.add(cmp3) if3.add(cmp3)
@@ -209,7 +209,7 @@ class TestVmCodeGen: FunSpec({
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3) sub.add(if3)
val if4 = PtIfElse(Position.DUMMY) val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp4.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp4.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if4.add(cmp4) if4.add(cmp4)
@@ -244,7 +244,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -252,7 +252,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup()) if1.add(PtNodeGroup())
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY))
cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)
@@ -291,7 +291,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.BYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.BYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp1.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -299,7 +299,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.BYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.BYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp2.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)
@@ -307,7 +307,7 @@ class TestVmCodeGen: FunSpec({
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2) sub.add(if2)
val if3 = PtIfElse(Position.DUMMY) val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.BYTE, Position.DUMMY) val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.BYTE, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp3.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) cmp3.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY))
if3.add(cmp3) if3.add(cmp3)
@@ -315,7 +315,7 @@ class TestVmCodeGen: FunSpec({
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3) sub.add(if3)
val if4 = PtIfElse(Position.DUMMY) val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.BYTE, Position.DUMMY) val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.BYTE, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp4.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) cmp4.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY))
if4.add(cmp4) if4.add(cmp4)
@@ -354,7 +354,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.BYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.BYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp1.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -362,7 +362,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression("!=", DataType.BYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.BYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp2.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)
@@ -370,7 +370,7 @@ class TestVmCodeGen: FunSpec({
if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if2) sub.add(if2)
val if3 = PtIfElse(Position.DUMMY) val if3 = PtIfElse(Position.DUMMY)
val cmp3 = PtBinaryExpression("<", DataType.BYTE, Position.DUMMY) val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.BYTE, Position.DUMMY)
cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp3.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) cmp3.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY))
if3.add(cmp3) if3.add(cmp3)
@@ -378,7 +378,7 @@ class TestVmCodeGen: FunSpec({
if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) })
sub.add(if3) sub.add(if3)
val if4 = PtIfElse(Position.DUMMY) val if4 = PtIfElse(Position.DUMMY)
val cmp4 = PtBinaryExpression(">", DataType.BYTE, Position.DUMMY) val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.BYTE, Position.DUMMY)
cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY))
cmp4.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) cmp4.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY))
if4.add(cmp4) if4.add(cmp4)
@@ -413,7 +413,7 @@ class TestVmCodeGen: FunSpec({
val sub = PtSub("start", emptyList(), null, Position.DUMMY) val sub = PtSub("start", emptyList(), null, Position.DUMMY)
sub.add(PtVariable("ub1", DataType.UBYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) sub.add(PtVariable("ub1", DataType.UBYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY))
val if1 = PtIfElse(Position.DUMMY) val if1 = PtIfElse(Position.DUMMY)
val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY)
cmp1.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY)) cmp1.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY))
cmp1.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY)) cmp1.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY))
if1.add(cmp1) if1.add(cmp1)
@@ -421,7 +421,7 @@ class TestVmCodeGen: FunSpec({
if1.add(PtNodeGroup()) if1.add(PtNodeGroup())
sub.add(if1) sub.add(if1)
val if2 = PtIfElse(Position.DUMMY) val if2 = PtIfElse(Position.DUMMY)
val cmp2 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) val cmp2 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY)
cmp2.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY)) cmp2.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY))
cmp2.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY)) cmp2.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY))
if2.add(cmp2) if2.add(cmp2)

View File

@@ -456,15 +456,36 @@ class IntermediateAstMaker(private val program: Program, private val options: Co
return arr return arr
} }
private fun transform(srcExpr: BinaryExpression): PtBinaryExpression { private fun transform(srcExpr: BinaryExpression): PtBinaryExpressionObsoleteUsePtRpn {
val type = srcExpr.inferType(program).getOrElse { throw FatalAstException("unknown dt") } val type = srcExpr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val actualType = if(type==DataType.BOOL) DataType.UBYTE else type val actualType = if(type==DataType.BOOL) DataType.UBYTE else type
val expr = PtBinaryExpression(srcExpr.operator, actualType, srcExpr.position) val expr = PtBinaryExpressionObsoleteUsePtRpn(srcExpr.operator, actualType, srcExpr.position)
expr.add(transformExpression(srcExpr.left)) expr.add(transformExpression(srcExpr.left))
expr.add(transformExpression(srcExpr.right)) expr.add(transformExpression(srcExpr.right))
return expr return expr
} }
// TODO replace the above with this, to generete RPN expression nodes:
// private fun transform(srcExpr: BinaryExpression): PtRpn {
// fun makeRpn(expr: Expression): PtRpn {
// val type = expr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
// val actualType = if(type==DataType.BOOL) DataType.UBYTE else type
// val rpn = PtRpn(actualType, expr.position)
// rpn += transformExpression(expr)
// return rpn
// }
//
// val leftDt = srcExpr.left.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
// val rightDt = srcExpr.left.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
// val type = srcExpr.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
// val actualType = if(type==DataType.BOOL) DataType.UBYTE else type
// val rpn = PtRpn(actualType, srcExpr.position)
// rpn += makeRpn(srcExpr.left)
// rpn += makeRpn(srcExpr.right)
// rpn += PtRpnOperator(srcExpr.operator, actualType, leftDt, rightDt, srcExpr.position)
// return rpn
// }
private fun transform(srcCall: BuiltinFunctionCall): PtBuiltinFunctionCall { private fun transform(srcCall: BuiltinFunctionCall): PtBuiltinFunctionCall {
val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") } val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") }
val noSideFx = BuiltinFunctions.getValue(srcCall.name).pure val noSideFx = BuiltinFunctions.getValue(srcCall.name).pure