diff --git a/codeCore/src/prog8/code/ast/AstBase.kt b/codeCore/src/prog8/code/ast/AstBase.kt index 457d32f58..825ae7683 100644 --- a/codeCore/src/prog8/code/ast/AstBase.kt +++ b/codeCore/src/prog8/code/ast/AstBase.kt @@ -64,6 +64,40 @@ class PtProgram( fun entrypoint(): PtSub? = allBlocks().firstOrNull { it.name == "main" }?.children?.firstOrNull { it is PtSub && it.name == "start" } as PtSub? + + // If the code generator wants, it can transform binary expression nodes into flat RPN nodes. + // This will destroy the original binaryexpression nodes! + fun transformBinExprToRPN() { + + fun transformToRPN(originalExpr: PtBinaryExpression): PtRpn { + fun makeRpn(expr: PtExpression): PtRpn { + val rpn = PtRpn(expr.type, expr.position) + rpn.addRpnNode(expr) + return rpn + } + + val rpn = PtRpn(originalExpr.type, position) + rpn.addRpnNode(makeRpn(originalExpr.left)) + rpn.addRpnNode(makeRpn(originalExpr.right)) + rpn.addRpnNode(PtRpnOperator(originalExpr.operator, originalExpr.type, originalExpr.left.type, originalExpr.right.type, position)) + return rpn + } + + fun transformBinExprToRPN(node: PtNode, parent: PtNode) { + if(node is PtBinaryExpression) { + val rpn = transformToRPN(node) + val idx = parent.children.indexOf(node) + rpn.parent = parent + parent.children[idx] = rpn + } + + node.children.forEach {child -> + transformBinExprToRPN(child, node) + } + } + + children.forEach { transformBinExprToRPN(it, this) } + } } diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index c070ff111..a20aff336 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -27,7 +27,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit return when(this) { 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 PtBinaryExpressionObsoleteUsePtRpn -> other is PtBinaryExpressionObsoleteUsePtRpn && other.left isSameAs left && other.right isSameAs right + is PtBinaryExpression -> other is PtBinaryExpression && 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 PtIdentifier -> other is PtIdentifier && other.type==type && other.name==name @@ -63,7 +63,7 @@ sealed class PtExpression(val type: DataType, position: Position) : PtNode(posit is PtAddressOf -> true is PtArray -> true is PtArrayIndexer -> index is PtNumber || index is PtIdentifier - is PtBinaryExpressionObsoleteUsePtRpn -> false + is PtBinaryExpression -> false is PtRpn -> false is PtBuiltinFunctionCall -> name in arrayOf("msb", "lsb", "peek", "peekw", "mkword", "set_carry", "set_irqd", "clear_carry", "clear_irqd") is PtContainmentCheck -> false @@ -152,7 +152,7 @@ class PtBuiltinFunctionCall(val name: String, } -class PtBinaryExpressionObsoleteUsePtRpn(val operator: String, type: DataType, position: Position): PtExpression(type, position) { +class PtBinaryExpression(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 &, |, ^. val left: PtExpression get() = children[0] as PtExpression @@ -163,13 +163,21 @@ class PtBinaryExpressionObsoleteUsePtRpn(val operator: String, type: DataType, p class PtRpn(type: DataType, position: Position): PtExpression(type, position) { // contains only PtExpression (not PtRpn!) and PtRpnOperator nodes + // not created directly by the compiler for now, if code generators prefer this over PtBinaryExpression, + // they have to transform the ast themselves first using the utility routine on PtProgram for it. - operator fun plusAssign(node: PtNode) { + fun addRpnNode(node: PtNode) { require(node is PtRpnOperator || node is PtExpression) - if(node is PtRpn) - children.addAll(node.children) - else + if(node is PtRpn) { + node.children.forEach { + children += it + it.parent = this + } + } + else { children += node + node.parent = this + } } fun print() { @@ -259,9 +267,16 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) { } 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. - } +// init { +// require(operand1Type equalsSize operand2Type) { +// "operator $operator : operand1 and 2 types aren't equal sizes: $operand1Type $operand2Type" +// } +// if(operator !in ComparisonOperators) { +// require(type equalsSize operand1Type && type equalsSize operand2Type) { +// "operator $operator : type $type size not equal to operand1 and 2 types: $operand1Type $operand2Type" +// } +// } +// } } diff --git a/codeCore/src/prog8/code/ast/AstPrinter.kt b/codeCore/src/prog8/code/ast/AstPrinter.kt index b7342c1f2..ca1aad133 100644 --- a/codeCore/src/prog8/code/ast/AstPrinter.kt +++ b/codeCore/src/prog8/code/ast/AstPrinter.kt @@ -18,7 +18,7 @@ fun printAst(root: PtNode, output: (text: String) -> Unit) { is PtAddressOf -> "&" is PtArray -> "array len=${node.children.size} ${type(node.type)}" is PtArrayIndexer -> " ${type(node.type)}" - is PtBinaryExpressionObsoleteUsePtRpn -> " ${node.operator} ${type(node.type)}" + is PtBinaryExpression -> " ${node.operator} ${type(node.type)}" is PtRpn -> "" is PtRpnOperator -> node.operator is PtBuiltinFunctionCall -> { diff --git a/codeCore/src/prog8/code/ast/AstStatements.kt b/codeCore/src/prog8/code/ast/AstStatements.kt index 9bd310d0b..89dfe0ab3 100644 --- a/codeCore/src/prog8/code/ast/AstStatements.kt +++ b/codeCore/src/prog8/code/ast/AstStatements.kt @@ -100,8 +100,8 @@ class PtForLoop(position: Position) : PtNode(position) { class PtIfElse(position: Position) : PtNode(position) { - val condition: PtBinaryExpressionObsoleteUsePtRpn - get() = children[0] as PtBinaryExpressionObsoleteUsePtRpn + val condition: PtNode + get() = children[0] as PtNode val ifScope: PtNodeGroup get() = children[1] as PtNodeGroup val elseScope: PtNodeGroup diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 8aaf2d3b0..1744ca8ea 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -21,6 +21,9 @@ class AsmGen6502: ICodeGeneratorBackend { options: CompilationOptions, errors: IErrorReporter ): IAssemblyProgram? { + // If we want RPN expressions instead, use this: + // TODO program.transformBinExprToRPN() + val asmgen = AsmGen6502Internal(program, symbolTable, options, errors) return asmgen.compileToAssembly() } @@ -544,16 +547,16 @@ class AsmGen6502Internal ( } private fun translate(stmt: PtIfElse) { - requireComparisonExpression(stmt.condition) // IfStatement: condition must be of form 'x ' - val booleanCondition = stmt.condition + val condition = stmt.condition as PtBinaryExpression + requireComparisonExpression(condition) // IfStatement: condition must be of form 'x ' if (stmt.elseScope.children.isEmpty()) { val jump = stmt.ifScope.children.singleOrNull() if(jump is PtJump) { - translateCompareAndJumpIfTrue(booleanCondition, jump) + translateCompareAndJumpIfTrue(condition, jump) } else { val endLabel = makeLabel("if_end") - translateCompareAndJumpIfFalse(booleanCondition, endLabel) + translateCompareAndJumpIfFalse(condition, endLabel) translate(stmt.ifScope) out(endLabel) } @@ -562,7 +565,7 @@ class AsmGen6502Internal ( // both true and else parts val elseLabel = makeLabel("if_else") val endLabel = makeLabel("if_end") - translateCompareAndJumpIfFalse(booleanCondition, elseLabel) + translateCompareAndJumpIfFalse(condition, elseLabel) translate(stmt.ifScope) jmp(endLabel) out(elseLabel) @@ -572,7 +575,7 @@ class AsmGen6502Internal ( } private fun requireComparisonExpression(condition: PtExpression) { - if(condition !is PtBinaryExpressionObsoleteUsePtRpn || condition.operator !in ComparisonOperators) + if(condition !is PtBinaryExpression || condition.operator !in ComparisonOperators) throw AssemblyError("expected boolean comparison expression $condition") } @@ -977,7 +980,7 @@ $repeatLabel lda $counterVar } internal fun pointerViaIndexRegisterPossible(pointerOffsetExpr: PtExpression): Pair? { - if(pointerOffsetExpr is PtBinaryExpressionObsoleteUsePtRpn && pointerOffsetExpr.operator=="+") { + if(pointerOffsetExpr is PtBinaryExpression && pointerOffsetExpr.operator=="+") { val leftDt = pointerOffsetExpr.left.type val rightDt = pointerOffsetExpr.left.type if(leftDt == DataType.UWORD && rightDt == DataType.UBYTE) @@ -1003,7 +1006,7 @@ $repeatLabel lda $counterVar return null } - internal fun tryOptimizedPointerAccessWithA(expr: PtBinaryExpressionObsoleteUsePtRpn, write: Boolean): Boolean { + internal fun tryOptimizedPointerAccessWithA(expr: PtBinaryExpression, write: Boolean): Boolean { // optimize pointer,indexregister if possible fun evalBytevalueWillClobberA(expr: PtExpression): Boolean { @@ -1095,7 +1098,7 @@ $repeatLabel lda $counterVar return node.definingSub()?.parameters?.singleOrNull { it.name===name } } - private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpressionObsoleteUsePtRpn, jump: PtJump) { + private fun translateCompareAndJumpIfTrue(expr: PtBinaryExpression, jump: PtJump) { if(expr.operator !in ComparisonOperators) throw AssemblyError("must be comparison expression") @@ -1121,7 +1124,7 @@ $repeatLabel lda $counterVar } } - private fun translateCompareAndJumpIfFalse(expr: PtBinaryExpressionObsoleteUsePtRpn, jumpIfFalseLabel: String) { + private fun translateCompareAndJumpIfFalse(expr: PtBinaryExpression, jumpIfFalseLabel: String) { val left = expr.left val right = expr.right val operator = expr.operator @@ -2833,8 +2836,8 @@ $repeatLabel lda $counterVar if(pushResultOnEstack) out(" sta P8ESTACK_LO,x | dex") } - is PtBinaryExpressionObsoleteUsePtRpn -> { - if(tryOptimizedPointerAccessWithA(expr.address as PtBinaryExpressionObsoleteUsePtRpn, false)) { + is PtBinaryExpression -> { + if(tryOptimizedPointerAccessWithA(expr.address as PtBinaryExpression, false)) { if(pushResultOnEstack) out(" sta P8ESTACK_LO,x | dex") } else { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index df9536536..33285c5ce 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -664,7 +664,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, is PtRpn -> { TODO("pokeW for RPN $addrExpr") } - is PtBinaryExpressionObsoleteUsePtRpn -> { + is PtBinaryExpression -> { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) { @@ -726,7 +726,7 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, is PtRpn -> { TODO("peekW for RPN $addrExpr") } - is PtBinaryExpressionObsoleteUsePtRpn -> { + is PtBinaryExpression -> { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { val varname = asmgen.asmVariableName(addrExpr.left as PtIdentifier) if(asmgen.isZpVar(addrExpr.left as PtIdentifier)) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index 39bba8642..97c0a02a8 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -24,7 +24,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, when(expression) { is PtPrefix -> translateExpression(expression) - is PtBinaryExpressionObsoleteUsePtRpn -> translateExpression(expression) + is PtBinaryExpression -> translateExpression(expression) is PtRpn -> translateExpression(expression) is PtArrayIndexer -> translateExpression(expression) is PtTypeCast -> translateExpression(expression) @@ -244,7 +244,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, TODO("translate RPN $expr") } - private fun translateExpression(expr: PtBinaryExpressionObsoleteUsePtRpn) { + private fun translateExpression(expr: PtBinaryExpression) { // Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED! val leftDt = expr.left.type val rightDt = expr.right.type diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index 225e1829d..2bcd5d89d 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -144,8 +144,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, is PtRpn -> { TODO("translate RPN ${value.address}") } - is PtBinaryExpressionObsoleteUsePtRpn -> { - if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpressionObsoleteUsePtRpn, false)) { + is PtBinaryExpression -> { + if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { assignRegisterByte(assign.target, CpuRegister.A) } else { assignViaExprEval(value.address) @@ -297,7 +297,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, containmentCheckIntoA(value) assignRegisterByte(assign.target, CpuRegister.A) } - is PtBinaryExpressionObsoleteUsePtRpn -> { + is PtBinaryExpression -> { if(!attemptAssignOptimizedBinexpr(value, assign)) { // 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, @@ -345,7 +345,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, } } - private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpressionObsoleteUsePtRpn, assign: AsmAssignment): Boolean { + private fun attemptAssignOptimizedBinexpr(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { if(expr.operator in ComparisonOperators) { if(expr.right.asConstInteger() == 0) { if(expr.operator == "==" || expr.operator=="!=") { @@ -367,7 +367,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignTrue.add(assignment) val assignFalse = PtNodeGroup() val ifelse = PtIfElse(assign.position) - val exprClone = PtBinaryExpressionObsoleteUsePtRpn(expr.operator, expr.type, expr.position) + val exprClone = PtBinaryExpression(expr.operator, expr.type, expr.position) expr.children.forEach { exprClone.children.add(it) } // doesn't seem to need a deep clone ifelse.add(exprClone) ifelse.add(assignTrue) @@ -727,7 +727,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignRegisterpairWord(target, RegisterOrPair.AY) } - private fun attemptAssignToByteCompareZero(expr: PtBinaryExpressionObsoleteUsePtRpn, assign: AsmAssignment): Boolean { + private fun attemptAssignToByteCompareZero(expr: PtBinaryExpression, assign: AsmAssignment): Boolean { when (expr.operator) { "==" -> { when(val dt = expr.left.type) { @@ -909,8 +909,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, is PtRpn -> { TODO("translate RPN ${value.address}") } - is PtBinaryExpressionObsoleteUsePtRpn -> { - if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpressionObsoleteUsePtRpn, false)) { + is PtBinaryExpression -> { + if(asmgen.tryOptimizedPointerAccessWithA(value.address as PtBinaryExpression, false)) { asmgen.out(" ldy #0") assignRegisterpairWord(target, RegisterOrPair.AY) } else { @@ -2833,7 +2833,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, addressExpr is PtRpn -> { TODO("translate RPN $addressExpr") } - addressExpr is PtBinaryExpressionObsoleteUsePtRpn -> { + addressExpr is PtBinaryExpression -> { if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, true)) storeViaExprEval() } diff --git a/codeGenExperimental/src/prog8/codegen/experimental/ExperiCodeGen.kt b/codeGenExperimental/src/prog8/codegen/experimental/ExperiCodeGen.kt index 617f2f50b..c4a56c64e 100644 --- a/codeGenExperimental/src/prog8/codegen/experimental/ExperiCodeGen.kt +++ b/codeGenExperimental/src/prog8/codegen/experimental/ExperiCodeGen.kt @@ -16,6 +16,10 @@ class ExperiCodeGen: ICodeGeneratorBackend { options: CompilationOptions, errors: IErrorReporter ): IAssemblyProgram? { + + // If we want RPN expressions instead, use this: + // program.transformBinExprToRPN() + // you could write a code generator directly on the PtProgram AST, // but you can also use the Intermediate Representation to build a codegen on: val irCodeGen = IRCodeGen(program, symbolTable, options, errors) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt index e59df6fb6..66fa38f45 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/AssignmentGen.kt @@ -92,7 +92,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express value.add(origAssign.value) } else { require(origAssign.operator.endsWith('=')) - value = PtBinaryExpressionObsoleteUsePtRpn(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position) + value = PtBinaryExpression(origAssign.operator.dropLast(1), origAssign.value.type, origAssign.value.position) val left: PtExpression = origAssign.target.children.single() as PtExpression value.add(left) value.add(origAssign.value) @@ -262,7 +262,7 @@ internal class AssignmentGen(private val codeGen: IRCodeGen, private val express val tr = if(itemsize==1) { expressionEval.translateExpression(array.index) } else { - val mult = PtBinaryExpressionObsoleteUsePtRpn("*", DataType.UBYTE, array.position) + val mult = PtBinaryExpression("*", DataType.UBYTE, array.position) mult.children += array.index mult.children += PtNumber(DataType.UBYTE, itemsize.toDouble(), array.position) expressionEval.translateExpression(mult) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt index af202768b..f4e135b7a 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/ExpressionGen.kt @@ -92,7 +92,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { is PtTypeCast -> translate(expr) is PtPrefix -> translate(expr) is PtArrayIndexer -> translate(expr) - is PtBinaryExpressionObsoleteUsePtRpn -> translate(expr) + is PtBinaryExpression -> translate(expr) is PtRpn -> translate(expr) is PtBuiltinFunctionCall -> codeGen.translateBuiltinFunc(expr) is PtFunctionCall -> translate(expr) @@ -320,7 +320,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { TODO("translate RPN expression $rpn") } - private fun translate(binExpr: PtBinaryExpressionObsoleteUsePtRpn): ExpressionCodeResult { + private fun translate(binExpr: PtBinaryExpression): ExpressionCodeResult { val vmDt = codeGen.irType(binExpr.left.type) val signed = binExpr.left.type in SignedDatatypes return when(binExpr.operator) { @@ -435,7 +435,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun operatorGreaterThan( - binExpr: PtBinaryExpressionObsoleteUsePtRpn, + binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean, greaterEquals: Boolean @@ -491,7 +491,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } private fun operatorLessThan( - binExpr: PtBinaryExpressionObsoleteUsePtRpn, + binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean, lessEquals: Boolean @@ -546,7 +546,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorEquals(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, notEquals: Boolean): ExpressionCodeResult { + private fun operatorEquals(binExpr: PtBinaryExpression, vmDt: IRDataType, notEquals: Boolean): ExpressionCodeResult { val result = mutableListOf() if(vmDt==IRDataType.FLOAT) { val leftTr = translateExpression(binExpr.left) @@ -601,7 +601,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorShiftRight(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { + private fun operatorShiftRight(binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { val result = mutableListOf() return if(codeGen.isOne(binExpr.right)) { val tr = translateExpression(binExpr.left) @@ -620,7 +620,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorShiftLeft(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorShiftLeft(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() return if(codeGen.isOne(binExpr.right)){ val tr = translateExpression(binExpr.left) @@ -637,7 +637,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorXor(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorXor(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() return if(binExpr.right is PtNumber) { val tr = translateExpression(binExpr.left) @@ -654,7 +654,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorAnd(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorAnd(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() return if(binExpr.right is PtNumber) { val tr = translateExpression(binExpr.left) @@ -671,7 +671,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorOr(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorOr(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() return if(binExpr.right is PtNumber) { val tr = translateExpression(binExpr.left) @@ -688,7 +688,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorModulo(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorModulo(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { require(vmDt!=IRDataType.FLOAT) {"floating-point modulo not supported ${binExpr.position}"} val result = mutableListOf() return if(binExpr.right is PtNumber) { @@ -706,7 +706,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorDivide(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { + private fun operatorDivide(binExpr: PtBinaryExpression, vmDt: IRDataType, signed: Boolean): ExpressionCodeResult { val result = mutableListOf() val constFactorRight = binExpr.right as? PtNumber if(vmDt==IRDataType.FLOAT) { @@ -761,7 +761,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorMultiply(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorMultiply(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() val constFactorLeft = binExpr.left as? PtNumber val constFactorRight = binExpr.right as? PtNumber @@ -810,7 +810,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorMinus(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorMinus(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() if(vmDt==IRDataType.FLOAT) { if((binExpr.right as? PtNumber)?.number==1.0) { @@ -859,7 +859,7 @@ internal class ExpressionGen(private val codeGen: IRCodeGen) { } } - private fun operatorPlus(binExpr: PtBinaryExpressionObsoleteUsePtRpn, vmDt: IRDataType): ExpressionCodeResult { + private fun operatorPlus(binExpr: PtBinaryExpression, vmDt: IRDataType): ExpressionCodeResult { val result = mutableListOf() if(vmDt==IRDataType.FLOAT) { if((binExpr.left as? PtNumber)?.number==1.0) { diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index b803bc0f9..963560e3f 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -268,7 +268,7 @@ class IRCodeGen( is PtMemoryByte, is PtProgram, is PtArrayIndexer, - is PtBinaryExpressionObsoleteUsePtRpn, + is PtBinaryExpression, is PtRpn, is PtRpnOperator, is PtIdentifier, @@ -898,30 +898,35 @@ class IRCodeGen( private fun translate(ifElse: PtIfElse): IRCodeChunks { val condition = ifElse.condition - if(condition.operator !in ComparisonOperators) - throw AssemblyError("if condition should only be a binary comparison expression") + if(condition is PtBinaryExpression) { + if(condition.operator !in ComparisonOperators) + throw AssemblyError("if condition should only be a binary comparison expression") - val signed = condition.left.type in SignedDatatypes - val irDtLeft = irType(condition.left.type) - val goto = ifElse.ifScope.children.firstOrNull() as? PtJump - return when { - goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGoto(ifElse, goto, irDtLeft, signed) - constValue(condition.right) == 0.0 -> translateIfElseZeroComparison(ifElse, irDtLeft, signed) - else -> translateIfElseNonZeroComparison(ifElse, irDtLeft, signed) + val signed = condition.left.type in SignedDatatypes + val irDtLeft = irType(condition.left.type) + val goto = ifElse.ifScope.children.firstOrNull() as? PtJump + return when { + goto!=null && ifElse.elseScope.children.isEmpty() -> translateIfFollowedByJustGoto(ifElse, goto, irDtLeft, signed) + constValue(condition.right) == 0.0 -> translateIfElseZeroComparison(ifElse, irDtLeft, signed) + else -> translateIfElseNonZeroComparison(ifElse, irDtLeft, signed) + } + } else { + TODO("weird condition node: $condition") } } private fun translateIfFollowedByJustGoto(ifElse: PtIfElse, goto: PtJump, irDtLeft: IRDataType, signed: Boolean): MutableList { val result = mutableListOf() + val condition = ifElse.condition as PtBinaryExpression if(irDtLeft==IRDataType.FLOAT) { - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, -1, leftTr.resultFpReg) - val rightTr = expressionEval.translateExpression(ifElse.condition.right) + val rightTr = expressionEval.translateExpression(condition.right) addToResult(result, rightTr, -1, rightTr.resultFpReg) result += IRCodeChunk(null,null).also { val compResultReg = registers.nextFree() it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg) - val gotoOpcode = when (ifElse.condition.operator) { + val gotoOpcode = when (condition.operator) { "==" -> Opcode.BZ "!=" -> Opcode.BNZ "<" -> Opcode.BLEZS @@ -939,7 +944,7 @@ class IRCodeGen( } return result } else { - val rightConst = ifElse.condition.right.asConstInteger() + val rightConst = condition.right.asConstInteger() return if(rightConst==0) ifZeroIntThenJump(result, ifElse, signed, irDtLeft, goto) else { @@ -955,9 +960,10 @@ class IRCodeGen( irDtLeft: IRDataType, goto: PtJump ): MutableList { - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val condition = ifElse.condition as PtBinaryExpression + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, leftTr.resultReg, -1) - val opcode = when (ifElse.condition.operator) { + val opcode = when (condition.operator) { "==" -> Opcode.BZ "!=" -> Opcode.BNZ "<" -> if (signed) Opcode.BLZS else throw AssemblyError("unsigned < 0 shouldn't occur in codegen") @@ -982,14 +988,15 @@ class IRCodeGen( irDtLeft: IRDataType, goto: PtJump ): MutableList { - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val condition = ifElse.condition as PtBinaryExpression + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, leftTr.resultReg, -1) - val rightTr = expressionEval.translateExpression(ifElse.condition.right) + val rightTr = expressionEval.translateExpression(condition.right) addToResult(result, rightTr, rightTr.resultReg, -1) val opcode: Opcode val firstReg: Int val secondReg: Int - when (ifElse.condition.operator) { + when (condition.operator) { "==" -> { opcode = Opcode.BEQ firstReg = leftTr.resultReg @@ -1038,17 +1045,18 @@ class IRCodeGen( val elseBranch: Opcode val compResultReg: Int val branchDt: IRDataType + val condition = ifElse.condition as PtBinaryExpression if(irDtLeft==IRDataType.FLOAT) { branchDt = IRDataType.BYTE compResultReg = registers.nextFree() - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, -1, leftTr.resultFpReg) result += IRCodeChunk(null, null).also { val rightFpReg = registers.nextFreeFloat() it += IRInstruction(Opcode.LOAD, IRDataType.FLOAT, fpReg1 = rightFpReg, fpValue = 0f) it += IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightFpReg) } - elseBranch = when (ifElse.condition.operator) { + elseBranch = when (condition.operator) { "==" -> Opcode.BNZ "!=" -> Opcode.BZ "<" -> Opcode.BGEZS @@ -1060,10 +1068,10 @@ class IRCodeGen( } else { // integer comparisons branchDt = irDtLeft - val tr = expressionEval.translateExpression(ifElse.condition.left) + val tr = expressionEval.translateExpression(condition.left) compResultReg = tr.resultReg addToResult(result, tr, tr.resultReg, -1) - elseBranch = when (ifElse.condition.operator) { + elseBranch = when (condition.operator) { "==" -> Opcode.BNZ "!=" -> Opcode.BZ "<" -> if (signed) Opcode.BGEZS else throw AssemblyError("unsigned < 0 shouldn't occur in codegen") @@ -1100,14 +1108,15 @@ class IRCodeGen( val elseBranchFirstReg: Int val elseBranchSecondReg: Int val branchDt: IRDataType + val condition = ifElse.condition as PtBinaryExpression if(irDtLeft==IRDataType.FLOAT) { - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, -1, leftTr.resultFpReg) - val rightTr = expressionEval.translateExpression(ifElse.condition.right) + val rightTr = expressionEval.translateExpression(condition.right) addToResult(result, rightTr, -1, rightTr.resultFpReg) val compResultReg = registers.nextFree() addInstr(result, IRInstruction(Opcode.FCOMP, IRDataType.FLOAT, reg1=compResultReg, fpReg1 = leftTr.resultFpReg, fpReg2 = rightTr.resultFpReg), null) - val elseBranch = when (ifElse.condition.operator) { + val elseBranch = when (condition.operator) { "==" -> Opcode.BNZ "!=" -> Opcode.BZ "<" -> Opcode.BGEZS @@ -1135,11 +1144,11 @@ class IRCodeGen( } else { // integer comparisons branchDt = irDtLeft - val leftTr = expressionEval.translateExpression(ifElse.condition.left) + val leftTr = expressionEval.translateExpression(condition.left) addToResult(result, leftTr, leftTr.resultReg, -1) - val rightTr = expressionEval.translateExpression(ifElse.condition.right) + val rightTr = expressionEval.translateExpression(condition.right) addToResult(result, rightTr, rightTr.resultReg, -1) - when (ifElse.condition.operator) { + when (condition.operator) { "==" -> { elseBranchOpcode = Opcode.BNE elseBranchFirstReg = leftTr.resultReg diff --git a/codeGenIntermediate/src/prog8/codegen/vm/VmCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/vm/VmCodeGen.kt index 7bc6195ce..98d2b04cb 100644 --- a/codeGenIntermediate/src/prog8/codegen/vm/VmCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/vm/VmCodeGen.kt @@ -17,6 +17,8 @@ class VmCodeGen: ICodeGeneratorBackend { options: CompilationOptions, errors: IErrorReporter ): IAssemblyProgram? { + // If we want RPN expressions instead, use this: + // program.transformBinExprToRPN() val irCodeGen = IRCodeGen(program, symbolTable, options, errors) val irProgram = irCodeGen.generate() return VmAssemblyProgram(irProgram.name, irProgram) diff --git a/codeGenIntermediate/test/TestVmCodeGen.kt b/codeGenIntermediate/test/TestVmCodeGen.kt index a6fbd60d9..055592b5e 100644 --- a/codeGenIntermediate/test/TestVmCodeGen.kt +++ b/codeGenIntermediate/test/TestVmCodeGen.kt @@ -122,7 +122,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) if1.add(cmp1) @@ -130,7 +130,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.UBYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression("!=", DataType.UBYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) if2.add(cmp2) @@ -138,7 +138,7 @@ class TestVmCodeGen: FunSpec({ if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if2) val if3 = PtIfElse(Position.DUMMY) - val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.UBYTE, Position.DUMMY) + val cmp3 = PtBinaryExpression("<", DataType.UBYTE, Position.DUMMY) cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp3.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) if3.add(cmp3) @@ -146,7 +146,7 @@ class TestVmCodeGen: FunSpec({ if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if3) val if4 = PtIfElse(Position.DUMMY) - val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY) + val cmp4 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp4.add(PtNumber(DataType.FLOAT, 0.0, Position.DUMMY)) if4.add(cmp4) @@ -185,7 +185,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if1.add(cmp1) @@ -193,7 +193,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.UBYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression("!=", DataType.UBYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if2.add(cmp2) @@ -201,7 +201,7 @@ class TestVmCodeGen: FunSpec({ if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if2) val if3 = PtIfElse(Position.DUMMY) - val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.UBYTE, Position.DUMMY) + val cmp3 = PtBinaryExpression("<", DataType.UBYTE, Position.DUMMY) cmp3.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp3.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if3.add(cmp3) @@ -209,7 +209,7 @@ class TestVmCodeGen: FunSpec({ if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if3) val if4 = PtIfElse(Position.DUMMY) - val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY) + val cmp4 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) cmp4.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp4.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if4.add(cmp4) @@ -244,7 +244,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("f1", DataType.FLOAT, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp1.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if1.add(cmp1) @@ -252,7 +252,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup()) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.f1", DataType.FLOAT, Position.DUMMY)) cmp2.add(PtNumber(DataType.FLOAT, 42.0, Position.DUMMY)) if2.add(cmp2) @@ -291,7 +291,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.BYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.BYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp1.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) if1.add(cmp1) @@ -299,7 +299,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.BYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression("!=", DataType.BYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp2.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) if2.add(cmp2) @@ -307,7 +307,7 @@ class TestVmCodeGen: FunSpec({ if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if2) val if3 = PtIfElse(Position.DUMMY) - val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.BYTE, Position.DUMMY) + val cmp3 = PtBinaryExpression("<", DataType.BYTE, Position.DUMMY) cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp3.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) if3.add(cmp3) @@ -315,7 +315,7 @@ class TestVmCodeGen: FunSpec({ if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if3) val if4 = PtIfElse(Position.DUMMY) - val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.BYTE, Position.DUMMY) + val cmp4 = PtBinaryExpression(">", DataType.BYTE, Position.DUMMY) cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp4.add(PtNumber(DataType.BYTE, 0.0, Position.DUMMY)) if4.add(cmp4) @@ -354,7 +354,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("sb1", DataType.BYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.BYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.BYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp1.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) if1.add(cmp1) @@ -362,7 +362,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn("!=", DataType.BYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression("!=", DataType.BYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp2.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) if2.add(cmp2) @@ -370,7 +370,7 @@ class TestVmCodeGen: FunSpec({ if2.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if2) val if3 = PtIfElse(Position.DUMMY) - val cmp3 = PtBinaryExpressionObsoleteUsePtRpn("<", DataType.BYTE, Position.DUMMY) + val cmp3 = PtBinaryExpression("<", DataType.BYTE, Position.DUMMY) cmp3.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp3.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) if3.add(cmp3) @@ -378,7 +378,7 @@ class TestVmCodeGen: FunSpec({ if3.add(PtNodeGroup().also { it.add(PtNop(Position.DUMMY)) }) sub.add(if3) val if4 = PtIfElse(Position.DUMMY) - val cmp4 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.BYTE, Position.DUMMY) + val cmp4 = PtBinaryExpression(">", DataType.BYTE, Position.DUMMY) cmp4.add(PtIdentifier("main.start.sb1", DataType.BYTE, Position.DUMMY)) cmp4.add(PtNumber(DataType.BYTE, 42.0, Position.DUMMY)) if4.add(cmp4) @@ -413,7 +413,7 @@ class TestVmCodeGen: FunSpec({ val sub = PtSub("start", emptyList(), null, Position.DUMMY) sub.add(PtVariable("ub1", DataType.UBYTE, ZeropageWish.DONTCARE, null, null, Position.DUMMY)) val if1 = PtIfElse(Position.DUMMY) - val cmp1 = PtBinaryExpressionObsoleteUsePtRpn("==", DataType.UBYTE, Position.DUMMY) + val cmp1 = PtBinaryExpression("==", DataType.UBYTE, Position.DUMMY) cmp1.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY)) cmp1.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY)) if1.add(cmp1) @@ -421,7 +421,7 @@ class TestVmCodeGen: FunSpec({ if1.add(PtNodeGroup()) sub.add(if1) val if2 = PtIfElse(Position.DUMMY) - val cmp2 = PtBinaryExpressionObsoleteUsePtRpn(">", DataType.UBYTE, Position.DUMMY) + val cmp2 = PtBinaryExpression(">", DataType.UBYTE, Position.DUMMY) cmp2.add(PtIdentifier("main.start.ub1", DataType.UBYTE, Position.DUMMY)) cmp2.add(PtNumber(DataType.UBYTE, 42.0, Position.DUMMY)) if2.add(cmp2) diff --git a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt index 8b7cc8aea..ee0ffa98b 100644 --- a/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt +++ b/compiler/src/prog8/compiler/astprocessing/IntermediateAstMaker.kt @@ -456,36 +456,17 @@ class IntermediateAstMaker(private val program: Program, private val options: Co return arr } - private fun transform(srcExpr: BinaryExpression): PtBinaryExpressionObsoleteUsePtRpn { + private fun transform(srcExpr: BinaryExpression): PtBinaryExpression { + // NOTE: the Ast maker here will NOT create RPN-expression nodes for the code generator. + // If the code generator prefers RPN expressions, it has to transform the PtBinaryExpression itself into PtRpn. val type = srcExpr.inferType(program).getOrElse { throw FatalAstException("unknown dt") } val actualType = if(type==DataType.BOOL) DataType.UBYTE else type - val expr = PtBinaryExpressionObsoleteUsePtRpn(srcExpr.operator, actualType, srcExpr.position) + val expr = PtBinaryExpression(srcExpr.operator, actualType, srcExpr.position) expr.add(transformExpression(srcExpr.left)) expr.add(transformExpression(srcExpr.right)) 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 { val type = srcCall.inferType(program).getOrElse { throw FatalAstException("unknown dt") } val noSideFx = BuiltinFunctions.getValue(srcCall.name).pure