mirror of
https://github.com/irmen/prog8.git
synced 2024-11-26 11:49:22 +00:00
slightly simplified const grouping
This commit is contained in:
parent
5e729e21ff
commit
99d63b13a8
@ -172,13 +172,13 @@ class ConstantFolding(private val namespace: INameScope) : IAstProcessor {
|
||||
* Compile-time constant sub expressions will be evaluated on the spot.
|
||||
* For instance, "9 * (4 + 2)" will be optimized into the integer literal 54.
|
||||
*
|
||||
* More complex: dealing with associative operators:
|
||||
* if our operator is +,-,*,/ THEN:
|
||||
* if one of our operands is a const, THEN:
|
||||
* if the other operand is also a binary expression THEN:
|
||||
* if its operator is in the same group as our operator (+ and -, * and /) THEN:
|
||||
* if one of its operands is a const THEN:
|
||||
* reorder the expression by lifting out the calculation on the 2 consts. (so that it can be const-folded later)
|
||||
* More complex stuff: reordering to group constants:
|
||||
* If one of our operands is a Constant,
|
||||
* and the other operand is a Binary expression,
|
||||
* and one of ITS operands is a Constant,
|
||||
* and ITS other operand is NOT a Constant,
|
||||
* ...it may be possible to rewrite the expression to group the two Constants together,
|
||||
* to allow them to be const-folded away.
|
||||
*/
|
||||
override fun process(expr: BinaryExpression): IExpression {
|
||||
return try {
|
||||
@ -186,31 +186,20 @@ class ConstantFolding(private val namespace: INameScope) : IAstProcessor {
|
||||
val leftconst = expr.left.constValue(namespace)
|
||||
val rightconst = expr.right.constValue(namespace)
|
||||
|
||||
// check associative operators and const operands
|
||||
if(setOf("+", "-", "*", "/").contains(expr.operator)) {
|
||||
val subExpr: BinaryExpression? = when {
|
||||
leftconst!=null -> expr.right as? BinaryExpression
|
||||
rightconst!=null -> expr.left as? BinaryExpression
|
||||
else -> null
|
||||
}
|
||||
if(subExpr!=null) {
|
||||
val sameGroupOperator =
|
||||
when (expr.operator) {
|
||||
"+", "-" -> subExpr.operator == "+" || subExpr.operator == "-"
|
||||
"*", "/" -> subExpr.operator == "*" || subExpr.operator == "/"
|
||||
else -> false
|
||||
}
|
||||
if (sameGroupOperator) {
|
||||
val subleftconst = subExpr.left.constValue(namespace)
|
||||
val subrightconst = subExpr.right.constValue(namespace)
|
||||
if (subleftconst != null || subrightconst != null) {
|
||||
// reorder!
|
||||
return reorderAssociativeConst(expr, subExpr, leftconst!=null, rightconst!=null, subleftconst!=null, subrightconst!=null)
|
||||
}
|
||||
}
|
||||
}
|
||||
val subExpr: BinaryExpression? = when {
|
||||
leftconst!=null -> expr.right as? BinaryExpression
|
||||
rightconst!=null -> expr.left as? BinaryExpression
|
||||
else -> null
|
||||
}
|
||||
if(subExpr!=null) {
|
||||
val subleftconst = subExpr.left.constValue(namespace)
|
||||
val subrightconst = subExpr.right.constValue(namespace)
|
||||
if ((subleftconst != null && subrightconst == null) || (subleftconst==null && subrightconst!=null))
|
||||
// try reordering.
|
||||
return groupTwoConstsTogether(expr, subExpr,
|
||||
leftconst!=null, rightconst!=null,
|
||||
subleftconst!=null, subrightconst!=null)
|
||||
}
|
||||
|
||||
|
||||
// const fold when both operands are a const
|
||||
val evaluator = ConstExprEvaluator()
|
||||
@ -227,16 +216,17 @@ class ConstantFolding(private val namespace: INameScope) : IAstProcessor {
|
||||
}
|
||||
}
|
||||
|
||||
private fun reorderAssociativeConst(expr: BinaryExpression,
|
||||
subExpr: BinaryExpression,
|
||||
leftIsConst: Boolean,
|
||||
rightIsConst: Boolean,
|
||||
subleftIsConst: Boolean,
|
||||
subrightIsConst: Boolean): IExpression {
|
||||
private fun groupTwoConstsTogether(expr: BinaryExpression,
|
||||
subExpr: BinaryExpression,
|
||||
leftIsConst: Boolean,
|
||||
rightIsConst: Boolean,
|
||||
subleftIsConst: Boolean,
|
||||
subrightIsConst: Boolean): IExpression
|
||||
{
|
||||
// @todo this implements only a small set of possible reorderings for now
|
||||
|
||||
if(expr.operator==subExpr.operator) {
|
||||
// both operators are the same.
|
||||
|
||||
// If + or *, we can simply swap the const of expr and Var in subexpr.
|
||||
if(expr.operator=="+" || expr.operator=="*") {
|
||||
if(leftIsConst) {
|
||||
@ -280,10 +270,11 @@ class ConstantFolding(private val namespace: INameScope) : IAstProcessor {
|
||||
return expr
|
||||
}
|
||||
|
||||
// todo: other combinations of operators and constants
|
||||
// todo: other cases where both operators are identical
|
||||
return expr
|
||||
} else {
|
||||
return expr // TODO reorder when operators are not identical
|
||||
// todo: other combinations of operators and constants (with different operator in subexpr)
|
||||
return expr
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -117,10 +117,10 @@ enum class Opcode {
|
||||
CLC, // clear carry status flag NOTE: is mostly fake, carry flag is not affected by any numeric operations
|
||||
SEI, // set irq-disable status flag
|
||||
CLI, // clear irq-disable status flag
|
||||
NOP,
|
||||
NOP, // do nothing
|
||||
BREAKPOINT, // breakpoint
|
||||
TERMINATE, // end the program
|
||||
LINE // record source file line number
|
||||
LINE // track source file line number
|
||||
}
|
||||
|
||||
enum class Syscall(val callNr: Short) {
|
||||
@ -162,7 +162,7 @@ enum class Syscall(val callNr: Short) {
|
||||
FUNC_RNDF(91), // push a random float on the stack (between 0.0 and 1.0)
|
||||
|
||||
// note: not all builtin functions of the Prog8 language are present as functions:
|
||||
// some of them are already opcodes (such as MSB, LSB, LSL, LSR, ROL, ROR, ROL2, ROR2, and FLT)!
|
||||
// some of them are straight opcodes (such as MSB, LSB, LSL, LSR, ROL, ROR, ROL2, ROR2, and FLT)!
|
||||
}
|
||||
|
||||
class Memory {
|
||||
|
Loading…
Reference in New Issue
Block a user