diff --git a/codeCore/src/prog8/code/ast/AstBase.kt b/codeCore/src/prog8/code/ast/AstBase.kt index a3d853343..df78f7667 100644 --- a/codeCore/src/prog8/code/ast/AstBase.kt +++ b/codeCore/src/prog8/code/ast/AstBase.kt @@ -74,7 +74,10 @@ class PtProgram( fun transformToRPN(originalExpr: PtBinaryExpression): PtRpn { fun makeRpn(expr: PtExpression): PtRpn { val rpn = PtRpn(expr.type, expr.position) - rpn.addRpnNode(expr) + if(expr is PtBinaryExpression) + rpn.addRpnNode(transformToRPN(expr)) + else + rpn.addRpnNode(expr) return rpn } diff --git a/codeCore/src/prog8/code/ast/AstExpressions.kt b/codeCore/src/prog8/code/ast/AstExpressions.kt index 59fd02e95..f0650ee6c 100644 --- a/codeCore/src/prog8/code/ast/AstExpressions.kt +++ b/codeCore/src/prog8/code/ast/AstExpressions.kt @@ -175,6 +175,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) { } } else { + require(node !is PtBinaryExpression) children.add(node) node.parent = this } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt index 5ea64ef0c..2e78ab2f0 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmGen.kt @@ -52,7 +52,6 @@ class AsmGen6502Internal ( private val assignmentAsmGen = AssignmentAsmGen(program, symbolTable, this, allocator) private val expressionsAsmGen = ExpressionsAsmGen(program, this, allocator) private val builtinFunctionsAsmGen = BuiltinFunctionsAsmGen(program, this, assignmentAsmGen) - private val rpnAssignmentAsmGen = RpnExpressionAsmGen(program, symbolTable, this) fun compileToAssembly(): IAssemblyProgram? { @@ -1013,8 +1012,10 @@ $repeatLabel lda $counterVar when (pointerOffsetExpr) { is PtRpn -> { - if(pointerOffsetExpr.children.size>3) + if(pointerOffsetExpr.children.size>3) { + println("TODO: RPN: too complicated pointerViaIndexRegisterPossible") // TODO RPN return null // expression is too complex, we need just a pointer var + index + } val (leftNode, oper, rightNode) = pointerOffsetExpr.finalOperation() operator=oper.operator if (leftNode !is PtExpression || rightNode !is PtExpression) return null @@ -2909,6 +2910,8 @@ $repeatLabel lda $counterVar } is PtRpn -> { val addrExpr = expr.address as PtRpn + if(addrExpr.children.size>3) + println("TODO: RPN: too complicated translateDirectMemReadExpressionToRegAorStack") // TODO RPN if(addrExpr.children.size==3 && tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { if(pushResultOnEstack) out(" sta P8ESTACK_LO,x | dex") diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt index 5433ac687..a1f9d6220 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/BuiltinFunctionsAsmGen.kt @@ -682,6 +682,8 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, return } } + } else { + println("TODO: RPN: too complicated PokeW") // TODO RPN } } is PtBinaryExpression -> { @@ -763,7 +765,10 @@ internal class BuiltinFunctionsAsmGen(private val program: PtProgram, pla""") } else fallback() } else fallback() - } else fallback() + } else { + println("TODO: RPN: too complicated PeekW") // TODO RPN + fallback() + } } is PtBinaryExpression -> { if(addrExpr.operator=="+" && addrExpr.left is PtIdentifier && addrExpr.right is PtNumber) { diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt index 089fae6fb..0a10b73cc 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/ExpressionsAsmGen.kt @@ -248,21 +248,22 @@ internal class ExpressionsAsmGen(private val program: PtProgram, private fun translateRpnExpression(expr: PtRpn) { // Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED! val oper = expr.finalOperator() + val left = expr.finalLeftOperand() as? PtExpression val leftDt = oper.leftType val rightDt = oper.rightType // comparison against zero - if(oper.operator in ComparisonOperators) { + if(left != null && oper.operator in ComparisonOperators) { if(leftDt in NumericDatatypes && rightDt in NumericDatatypes) { val rightVal = (expr.finalRightOperand() as PtExpression).asConstInteger() if(rightVal==0) - return translateComparisonWithZero(expr.finalLeftOperand() as PtExpression, leftDt, oper.operator) + return translateComparisonWithZero(left, leftDt, oper.operator) } } // string compare - if(leftDt==DataType.STR && rightDt==DataType.STR && oper.operator in ComparisonOperators) { - return translateCompareStrings(expr.finalLeftOperand() as PtExpression, oper.operator, expr.finalRightOperand() as PtExpression) + if(left!=null && leftDt==DataType.STR && rightDt==DataType.STR && oper.operator in ComparisonOperators) { + return translateCompareStrings(left, oper.operator, expr.finalRightOperand() as PtExpression) } // TODO: RPN: add the other optimizations that BinaryExpression has, to avoid eval stack usage @@ -277,7 +278,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, if(it is PtRpnOperator) { when(it.leftType) { in ByteDatatypes -> translateBinaryOperatorBytes(it.operator, it.leftType) - in WordDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType) + in WordDatatypes, in PassByReferenceDatatypes -> translateBinaryOperatorWords(it.operator, it.leftType) DataType.FLOAT -> translateBinaryOperatorFloats(it.operator) else -> throw AssemblyError("non-numerical datatype ${it.leftType}") } @@ -292,6 +293,7 @@ internal class ExpressionsAsmGen(private val program: PtProgram, private fun translateExpression(expr: PtBinaryExpression) { // Uses evalstack to evaluate the given expression. THIS IS SLOW AND SHOULD BE AVOIDED! + require(!program.binaryExpressionsAreRPN) val leftDt = expr.left.type val rightDt = expr.right.type // see if we can apply some optimized routines still diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt index ef09083dd..685ee9834 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/assignment/AssignmentAsmGen.kt @@ -146,6 +146,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, } is PtRpn -> { val addrExpr = value.address as PtRpn + if(addrExpr.children.size>3) + println("TODO: RPN: too complex translateNormalAssignment") // TODO RPN if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { assignRegisterByte(assign.target, CpuRegister.A) } else { @@ -307,6 +309,7 @@ internal class AssignmentAsmGen(private val program: PtProgram, assignRegisterByte(assign.target, CpuRegister.A) } is PtBinaryExpression -> { + require(!program.binaryExpressionsAreRPN) 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, @@ -923,6 +926,9 @@ internal class AssignmentAsmGen(private val program: PtProgram, } is PtRpn -> { val addrExpr = value.address as PtRpn + if(addrExpr.children.size>3) { + println("TODO: RPN: too complex assignTypeCastedValue") // TODO RPN + } if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) { asmgen.out(" ldy #0") assignRegisterpairWord(target, RegisterOrPair.AY) @@ -2853,6 +2859,8 @@ internal class AssignmentAsmGen(private val program: PtProgram, asmgen.storeAIntoPointerVar(addressExpr) } addressExpr is PtRpn -> { + if(addressExpr.children.size>3) + println("TODO: RPN: too complex storeRegisterAInMemoryAddress $memoryAddress") // TODO RPN if(addressExpr.children.size!=3 || !asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true)) storeViaExprEval() } diff --git a/examples/test.p8 b/examples/test.p8 index e2d60ddf9..d807b8d55 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -9,11 +9,14 @@ main { sub start() { test_stack.test() - uword xx=32 - cx16.r0L = 3 + uword xx=4000 + ubyte a + ubyte b + ubyte c + ubyte d - cx16.r0 = peekw(xx + 44) - @(xx+44) = cx16.r0L + cx16.r0 = peekw(a+xx+b+c+d) + ; TODO @(a+xx+b+c+d) = cx16.r0L ; if cx16.r0L in "derp" { ; xx++