mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-22 08:32:29 +00:00
Refactoring
This commit is contained in:
parent
e2c8dad7a5
commit
613ddcf9a4
@ -126,20 +126,14 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
ExpressionStatement(FunctionCallExpression("+=", List(vex, one)).pos(p)).pos(p)
|
||||
} else {
|
||||
Assignment(vex, FunctionCallExpression(indexType.name, List(
|
||||
SumExpression(List(
|
||||
false -> FunctionCallExpression("byte", List(vex)).pos(p),
|
||||
false -> LiteralExpression(1,1).pos(p),
|
||||
), decimal = false).pos(p)
|
||||
FunctionCallExpression("byte", List(vex)).pos(p) #+# 1
|
||||
)).pos(p)).pos(p)
|
||||
}
|
||||
val decrement = if (arithmetic) {
|
||||
ExpressionStatement(FunctionCallExpression("-=", List(vex, one)).pos(p)).pos(p)
|
||||
} else {
|
||||
Assignment(vex, FunctionCallExpression(indexType.name, List(
|
||||
SumExpression(List(
|
||||
false -> FunctionCallExpression("byte", List(vex)).pos(p),
|
||||
true -> LiteralExpression(1,1).pos(p),
|
||||
), decimal = false).pos(p)
|
||||
FunctionCallExpression("byte", List(vex)).pos(p) #-# 1
|
||||
)).pos(p)).pos(p)
|
||||
}
|
||||
val names = Set("", "for", f.variable)
|
||||
@ -213,11 +207,7 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
Assignment(
|
||||
vex,
|
||||
FunctionCallExpression("lo", List(
|
||||
SumExpression(List(
|
||||
false -> f.start,
|
||||
false -> LiteralExpression(1, 2).pos(p)),
|
||||
decimal = false
|
||||
).pos(p)
|
||||
(f.start #+# LiteralExpression(1, 2).pos(p)).pos(p)
|
||||
)).pos(p)
|
||||
).pos(p),
|
||||
DoWhileStatement(
|
||||
@ -272,7 +262,7 @@ abstract class AbstractStatementCompiler[T <: AbstractCode] {
|
||||
))
|
||||
case (ForDirection.DownTo, _, _) =>
|
||||
// TODO: smarter countdown if end is not a constant
|
||||
val endMinusOne = SumExpression(List(false -> f.end, true -> LiteralExpression(1, 1)), decimal = false).pos(p)
|
||||
val endMinusOne = (f.end #-# 1).pos(p)
|
||||
compile(ctx, List(
|
||||
Assignment(vex, f.start).pos(p),
|
||||
IfStatement(
|
||||
|
@ -130,10 +130,10 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
case Assignment(target:IndexedExpression, arg) if isWordPointy(target.name) =>
|
||||
cv = search(arg, cv)
|
||||
cv = search(target, cv)
|
||||
Assignment(DerefExpression(SumExpression(List(
|
||||
false -> FunctionCallExpression("pointer", List(VariableExpression(target.name).pos(pos))).pos(pos),
|
||||
false -> FunctionCallExpression("<<", List(optimizeExpr(target.index, cv), LiteralExpression(1, 1))).pos(pos)
|
||||
), decimal = false), 0, env.getPointy(target.name).elementType).pos(pos), optimizeExpr(arg, cv)).pos(pos) -> cv
|
||||
Assignment(DerefExpression(
|
||||
FunctionCallExpression("pointer", List(VariableExpression(target.name).pos(pos))).pos(pos) #+#
|
||||
FunctionCallExpression("<<", List(optimizeExpr(target.index, cv), LiteralExpression(1, 1))).pos(pos),
|
||||
0, env.getPointy(target.name).elementType).pos(pos), optimizeExpr(arg, cv)).pos(pos) -> cv
|
||||
case Assignment(target:IndexedExpression, arg) =>
|
||||
cv = search(arg, cv)
|
||||
cv = search(target, cv)
|
||||
@ -340,10 +340,9 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
}
|
||||
}
|
||||
// TODO: re-cast pointer type
|
||||
DerefExpression(("pointer." + targetType.name) <| SumExpression(List(
|
||||
false -> result,
|
||||
false -> optimizeExpr(scaledIndex, Map())
|
||||
), decimal = false), 0, targetType)
|
||||
DerefExpression(("pointer." + targetType.name) <| (
|
||||
result #+# optimizeExpr(scaledIndex, Map())
|
||||
), 0, targetType)
|
||||
}
|
||||
case _ =>
|
||||
ctx.log.error("Not a pointer type on the left-hand side of `[`", pos)
|
||||
@ -361,10 +360,9 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
case DerefExpression(inner, 0, _) =>
|
||||
optimizeExpr(inner, currentVarValues).pos(pos)
|
||||
case DerefExpression(inner, offset, targetType) =>
|
||||
("pointer." + targetType.name) <| SumExpression(List(
|
||||
false -> ("pointer" <| optimizeExpr(inner, currentVarValues).pos(pos)),
|
||||
false -> LiteralExpression(offset, 2)
|
||||
), decimal = false)
|
||||
("pointer." + targetType.name) <| (
|
||||
("pointer" <| optimizeExpr(inner, currentVarValues).pos(pos)) #+# LiteralExpression(offset, 2)
|
||||
)
|
||||
case IndexedExpression(name, index) =>
|
||||
ctx.log.fatal("Oops!")
|
||||
case _ =>
|
||||
@ -401,25 +399,19 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
case 0 =>
|
||||
DerefExpression(inner, fieldOffset, fieldType)
|
||||
case 1 =>
|
||||
("pointer." + fieldType.name) <| SumExpression(List(
|
||||
false -> ("pointer" <| inner),
|
||||
false -> LiteralExpression(fieldOffset, 2)
|
||||
), decimal = false)
|
||||
("pointer." + fieldType.name) <| (
|
||||
("pointer" <| inner) #+# LiteralExpression(fieldOffset, 2)
|
||||
)
|
||||
case 2 =>
|
||||
SumExpression(List(
|
||||
false -> ("pointer" <| inner),
|
||||
false -> LiteralExpression(fieldOffset, 2)
|
||||
), decimal = false)
|
||||
("pointer" <| inner) #+# LiteralExpression(fieldOffset, 2)
|
||||
case 10 =>
|
||||
"lo" <| SumExpression(List(
|
||||
false -> ("pointer" <| inner),
|
||||
false -> LiteralExpression(fieldOffset, 2)
|
||||
), decimal = false)
|
||||
"lo" <| (
|
||||
("pointer" <| inner) #+# LiteralExpression(fieldOffset, 2)
|
||||
)
|
||||
case 11 =>
|
||||
"hi" <| SumExpression(List(
|
||||
false -> ("pointer" <| inner),
|
||||
false -> LiteralExpression(fieldOffset, 2)
|
||||
), decimal = false)
|
||||
"hi" <| (
|
||||
("pointer" <| inner) #+# LiteralExpression(fieldOffset, 2)
|
||||
)
|
||||
case _ => throw new IllegalStateException
|
||||
}
|
||||
}
|
||||
@ -497,10 +489,9 @@ abstract class AbstractStatementPreprocessor(protected val ctx: CompilationConte
|
||||
case _ => "*" <| ("word" <| index, LiteralExpression(targetType.size, 1))
|
||||
}
|
||||
}
|
||||
DerefExpression(SumExpression(List(
|
||||
false -> ("pointer" <| VariableExpression(name).pos(pos)),
|
||||
false -> optimizeExpr(scaledIndex, Map())
|
||||
), decimal = false), 0, pointy.elementType).pos(pos)
|
||||
DerefExpression(
|
||||
("pointer" <| VariableExpression(name).pos(pos)) #+# optimizeExpr(scaledIndex, Map()),
|
||||
0, pointy.elementType).pos(pos)
|
||||
}
|
||||
case _ => expr // TODO
|
||||
}
|
||||
|
@ -21,11 +21,11 @@ object MosBulkMemoryOperations {
|
||||
ctx.env.getPointy(target.name)
|
||||
val sizeExpr = f.direction match {
|
||||
case ForDirection.DownTo =>
|
||||
SumExpression(List(false -> f.start, true -> f.end, false -> LiteralExpression(1, 1)), decimal = false)
|
||||
f.start #-# f.end #+# 1
|
||||
case ForDirection.To | ForDirection.ParallelTo =>
|
||||
SumExpression(List(false -> f.end, true -> f.start, false -> LiteralExpression(1, 1)), decimal = false)
|
||||
f.end #-# f.start #+# 1
|
||||
case ForDirection.Until | ForDirection.ParallelUntil =>
|
||||
SumExpression(List(false -> f.end, true -> f.start), decimal = false)
|
||||
f.end #-# f.start
|
||||
}
|
||||
val reg = ctx.env.get[VariableInMemory]("__reg.loword")
|
||||
val w = ctx.env.get[Type]("word")
|
||||
@ -37,7 +37,7 @@ object MosBulkMemoryOperations {
|
||||
val loadReg =
|
||||
if (useTwoRegs) {
|
||||
import millfork.assembly.mos.AddrMode._
|
||||
val first = MosExpressionCompiler.compile(ctx, SumExpression(List(false -> f.start, false -> target.index), decimal = false), Some(w -> reg), BranchSpec.None)
|
||||
val first = MosExpressionCompiler.compile(ctx, f.start #+# target.index, Some(w -> reg), BranchSpec.None)
|
||||
first ++ (first match {
|
||||
case List(AssemblyLine0(LDA, Immediate, l), AssemblyLine0(LDA, ZeroPage, r0), AssemblyLine0(LDA, Immediate, h), AssemblyLine0(LDA, ZeroPage, r1))
|
||||
if (r1-r0).quickSimplify.isProvably(1) =>
|
||||
@ -57,7 +57,7 @@ object MosBulkMemoryOperations {
|
||||
AssemblyLine.immediate(ADC, 0),
|
||||
AssemblyLine.zeropage(STA, reg, 3))
|
||||
})
|
||||
}else MosExpressionCompiler.compile(ctx, SumExpression(List(false -> f.start, false -> target.index), decimal = false), Some(w -> reg), BranchSpec.None)
|
||||
} else MosExpressionCompiler.compile(ctx, f.start #+# target.index, Some(w -> reg), BranchSpec.None)
|
||||
|
||||
val loadSource = MosExpressionCompiler.compileToA(ctx, source)
|
||||
val loadAll = if (MosExpressionCompiler.changesZpreg(loadSource, 0) || MosExpressionCompiler.changesZpreg(loadSource, 1)) {
|
||||
@ -193,7 +193,7 @@ object MosBulkMemoryOperations {
|
||||
val (prepareZpreg, addrMode, parameter) = env.getPointy(targetExpression.name) match {
|
||||
case _: VariablePointy | _:StackVariablePointy =>
|
||||
val offsetExpr = GeneratedConstantExpression(offset, env.get[Type]("word"))
|
||||
val pz = MosExpressionCompiler.compileToZReg(ctx, SumExpression(List(false -> VariableExpression(targetExpression.name), false -> offsetExpr), decimal = false))
|
||||
val pz = MosExpressionCompiler.compileToZReg(ctx, VariableExpression(targetExpression.name) #+# offsetExpr)
|
||||
(pz, AddrMode.IndexedY, reg.toAddress)
|
||||
case c: ConstantPointy =>
|
||||
if (indexVariable.typ.size == 1) (Nil, AddrMode.AbsoluteX, c.value)
|
||||
|
@ -686,7 +686,6 @@ object PseudoregisterBuiltIns {
|
||||
}
|
||||
|
||||
def doesMemoryAccessOverlap(l1: List[AssemblyLine], l2: List[AssemblyLine]): Boolean = {
|
||||
print()
|
||||
for{
|
||||
a1 <- l1
|
||||
if a1.addrMode != Immediate && a1.addrMode != Implied
|
||||
|
@ -22,7 +22,7 @@ object Z80BulkMemoryOperations {
|
||||
def compileMemcpy(ctx: CompilationContext, target: IndexedExpression, source: IndexedExpression, f: ForStatement): List[ZLine] = {
|
||||
val sourceOffset = removeVariableOnce(f.variable, source.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
if (!sourceOffset.isPure) return compileForStatement(ctx, f)._1
|
||||
val sourceIndexExpression = SumExpression(List(false -> sourceOffset, false -> f.start), decimal = false)
|
||||
val sourceIndexExpression = sourceOffset #+# f.start
|
||||
val calculateSource = Z80ExpressionCompiler.calculateAddressToHL(ctx, IndexedExpression(source.name, sourceIndexExpression).pos(source.position), forWriting = false)
|
||||
compileMemoryBulk(ctx, target, f,
|
||||
useDEForTarget = true,
|
||||
@ -47,18 +47,18 @@ object Z80BulkMemoryOperations {
|
||||
|
||||
def compileForZ80(targetOffset: Expression): List[ZLine] = {
|
||||
val targetIndexExpression = f.direction match {
|
||||
case ForDirection.DownTo => SumExpression(List(false -> targetOffset, false -> f.end), decimal = false)
|
||||
case _ => SumExpression(List(false -> targetOffset, false -> f.start), decimal = false)
|
||||
case ForDirection.DownTo => targetOffset #+# f.end
|
||||
case _ => targetOffset #+# f.start
|
||||
}
|
||||
val array = if (target.name != f.variable) target.name else "$0000"
|
||||
val calculateAddress = Z80ExpressionCompiler.calculateAddressToHL(ctx, IndexedExpression(array, targetIndexExpression).pos(targetIndexExpression.position), forWriting = true)
|
||||
val calculateSize = f.direction match {
|
||||
case ForDirection.DownTo =>
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, SumExpression(List(false -> f.start, true -> f.end), decimal = false)))
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, f.start #-# f.end))
|
||||
case ForDirection.To | ForDirection.ParallelTo =>
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, SumExpression(List(false -> f.end, true -> f.start), decimal = false)))
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, f.end #-# f.start))
|
||||
case ForDirection.Until | ForDirection.ParallelUntil =>
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, SumExpression(List(false -> f.end, true -> f.start, true -> LiteralExpression(1, 1)), decimal = false)))
|
||||
Z80ExpressionCompiler.stashHLIfChanged(ctx, Z80ExpressionCompiler.compileToBC(ctx, f.end #-# f.start #-# 1))
|
||||
}
|
||||
val (incOp, ldOp) = f.direction match {
|
||||
case ForDirection.DownTo => DEC_16 -> LDDR
|
||||
@ -134,14 +134,14 @@ object Z80BulkMemoryOperations {
|
||||
val target1Offset = removeVariableOnce(f.variable, target2.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
val target2Offset = removeVariableOnce(f.variable, target2.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
val target1IndexExpression = if (c.countDownDespiteSyntax) {
|
||||
SumExpression(List(false -> target1Offset, false -> f.end, true -> LiteralExpression(1, 1)), decimal = false)
|
||||
target1Offset #+# f.end #-# 1
|
||||
} else {
|
||||
SumExpression(List(false -> target1Offset, false -> f.start), decimal = false)
|
||||
target1Offset #+# f.start
|
||||
}
|
||||
val target2IndexExpression = if (c.countDownDespiteSyntax) {
|
||||
SumExpression(List(false -> target2Offset, false -> f.end, true -> LiteralExpression(1, 1)), decimal = false)
|
||||
target2Offset #+# f.end #-# 1
|
||||
} else {
|
||||
SumExpression(List(false -> target2Offset, false -> f.start), decimal = false)
|
||||
target2Offset #+# f.start
|
||||
}
|
||||
val fused = target1.name == target2.name && ((ctx.env.eval(target1Offset), ctx.env.eval(target2Offset)) match {
|
||||
case (Some(a), Some(b)) => a == b
|
||||
@ -209,7 +209,7 @@ object Z80BulkMemoryOperations {
|
||||
val countDownDespiteSyntax = f.direction == ForDirection.ParallelTo || f.direction == ForDirection.ParallelUntil
|
||||
val initC = if (useC) Z80ExpressionCompiler.compile8BitTo(ctx, f.direction match {
|
||||
case ForDirection.ParallelTo => f.end
|
||||
case ForDirection.ParallelUntil => SumExpression(List(false -> f.end, true -> LiteralExpression(1, 1)), decimal = false)
|
||||
case ForDirection.ParallelUntil => f.end #-# 1
|
||||
case _ => f.start
|
||||
}, ZRegister.C) else Nil
|
||||
val nextC = if (useC) List(ZLine.register(if (countDown) DEC else INC, ZRegister.C)) else Nil
|
||||
@ -397,7 +397,6 @@ object Z80BulkMemoryOperations {
|
||||
extraAddressCalculations: Boolean => (List[ZLine], List[ZLine]),
|
||||
loadA: ZOpcode.Value => List[ZLine],
|
||||
z80Bulk: Boolean => Option[ZOpcode.Value]): List[ZLine] = {
|
||||
val one = LiteralExpression(1, 1)
|
||||
val targetOffset = removeVariableOnce(f.variable, target.index).getOrElse(return compileForStatement(ctx, f)._1)
|
||||
if (!targetOffset.isPure) return compileForStatement(ctx, f)._1
|
||||
val indexVariableSize = ctx.env.get[Variable](f.variable).typ.size
|
||||
@ -406,13 +405,13 @@ object Z80BulkMemoryOperations {
|
||||
val decreasing = f.direction == ForDirection.DownTo || decreasingDespiteSyntax
|
||||
val plusOne = f.direction == ForDirection.To || f.direction == ForDirection.DownTo || f.direction == ForDirection.ParallelTo
|
||||
val byteCountExpression =
|
||||
if (f.direction == ForDirection.DownTo) SumExpression(List(false -> f.start, false -> one, true -> f.end), decimal = false)
|
||||
else if (plusOne) SumExpression(List(false -> f.end, false -> one, true -> f.start), decimal = false)
|
||||
else SumExpression(List(false -> f.end, true -> f.start), decimal = false)
|
||||
if (f.direction == ForDirection.DownTo) f.start #+# 1 #-# f.end
|
||||
else if (plusOne) f.end #+# 1 #-# f.start
|
||||
else f.end #-# f.start
|
||||
val targetIndexExpression = if (decreasingDespiteSyntax) {
|
||||
SumExpression(List(false -> targetOffset, false -> f.end, true -> one), decimal = false)
|
||||
targetOffset #+# f.end #-# 1
|
||||
} else {
|
||||
SumExpression(List(false -> targetOffset, false -> f.start), decimal = false)
|
||||
targetOffset #+# f.start
|
||||
}
|
||||
val ldr = z80Bulk(decreasing)
|
||||
val smallCount = indexVariableSize == 1 && (ldr.isEmpty || !ctx.options.flag(CompilationFlag.EmitZ80Opcodes))
|
||||
|
@ -752,11 +752,16 @@ object Z80ExpressionCompiler extends AbstractExpressionCompiler[ZLine] {
|
||||
case List(fp, param) =>
|
||||
getExpressionType(ctx, fp) match {
|
||||
case FunctionPointerType(_, _, _, Some(pt), Some(v)) =>
|
||||
if (pt.size != 1) {
|
||||
if (pt.size > 2 || pt.size < 1) {
|
||||
ctx.log.error("Invalid parameter type", param.position)
|
||||
compileToHL(ctx, fp) ++ compile(ctx, param, ZExpressionTarget.NOTHING)
|
||||
} else if (getExpressionType(ctx, param).isAssignableTo(pt)) {
|
||||
compileToDE(ctx, fp) ++ stashDEIfChanged(ctx, compileToA(ctx, param)) :+ callLine
|
||||
pt.size match {
|
||||
case 1 =>
|
||||
compileToDE(ctx, fp) ++ stashDEIfChanged(ctx, compileToA(ctx, param)) :+ callLine
|
||||
case 2 =>
|
||||
compileToDE(ctx, fp) ++ stashDEIfChanged(ctx, compileToHL(ctx, param)) :+ callLine
|
||||
}
|
||||
} else {
|
||||
ctx.log.error("Invalid parameter type", param.position)
|
||||
compileToHL(ctx, fp) ++ compile(ctx, param, ZExpressionTarget.NOTHING)
|
||||
|
@ -15,7 +15,7 @@ import scala.collection.GenTraversableOnce
|
||||
object Z80Shifting {
|
||||
|
||||
private def calculateIterationCountPlus1(ctx: CompilationContext, rhs: Expression) = {
|
||||
Z80ExpressionCompiler.compile8BitTo(ctx, SumExpression(List(false -> rhs, false -> LiteralExpression(1, 1)), decimal = false), ZRegister.B)
|
||||
Z80ExpressionCompiler.compile8BitTo(ctx, rhs #+# 1, ZRegister.B)
|
||||
}
|
||||
|
||||
private def fixAfterShiftIfNeeded(extendedOps: Boolean, left: Boolean, i: Long): List[ZLine] =
|
||||
|
@ -131,7 +131,7 @@ class Z80StatementPreprocessor(ctx: CompilationContext, statements: List[Executa
|
||||
Assignment(
|
||||
VariableExpression(newVariables(name, f.variable)),
|
||||
FunctionCallExpression("pointer", List(
|
||||
SumExpression(List(false -> VariableExpression(name + ".addr"), false -> optStart), decimal = false)
|
||||
VariableExpression(name + ".addr") #+# optStart
|
||||
)))
|
||||
}).toList :+ ForStatement(f.variable, optStart, optimizeExpr(f.end, Map()), newDirection, optimizeStmts(newBody, Map())._1),
|
||||
Nil
|
||||
|
@ -1168,7 +1168,6 @@ class Environment(val parent: Option[Environment], val prefix: String, val cpuFa
|
||||
case _ => ???
|
||||
}
|
||||
if (maybeGet[Thing](name).isEmpty) {
|
||||
println("registering text literal")
|
||||
root.registerArray(ArrayDeclarationStatement(name, None, None, "byte", None, const = true, Some(LiteralContents(literal.characters)), None, options.isBigEndian).pos(literal.position), options)
|
||||
}
|
||||
name
|
||||
|
@ -35,6 +35,15 @@ sealed trait Expression extends Node {
|
||||
def getPointies: Seq[String]
|
||||
def isPure: Boolean
|
||||
def getAllIdentifiers: Set[String]
|
||||
|
||||
def #+#(smallInt: Int): Expression = (this #+# LiteralExpression(smallInt, 1).pos(this.position)).pos(this.position)
|
||||
def #+#(that: Expression): Expression = that match {
|
||||
case SumExpression(params, false) => SumExpression((false -> this) :: params, decimal = false)
|
||||
case _ => SumExpression(List(false -> this, false -> that), decimal = false)
|
||||
}
|
||||
def #-#(smallInt: Int): Expression = (this #-# LiteralExpression(smallInt, 1).pos(this.position)).pos(this.position)
|
||||
def #-#(that: Expression): Expression = SumExpression(List(false -> this, true -> that), decimal = false)
|
||||
|
||||
@transient var typeCache: Type = _
|
||||
}
|
||||
|
||||
@ -99,7 +108,7 @@ case class SeparateBytesExpression(hi: Expression, lo: Expression) extends LhsEx
|
||||
SeparateBytesExpression(
|
||||
hi.replaceVariable(variable, actualParam),
|
||||
lo.replaceVariable(variable, actualParam)).pos(position)
|
||||
override def replaceIndexedExpression(predicate: IndexedExpression => Boolean, replacement: IndexedExpression => Expression): Expression =
|
||||
override def replaceIndexedExpression(predicate: IndexedExpression => Boolean, replacement: IndexedExpression => Expression): Expression =
|
||||
SeparateBytesExpression(
|
||||
hi.replaceIndexedExpression(predicate, replacement),
|
||||
lo.replaceIndexedExpression(predicate, replacement)).pos(position)
|
||||
@ -112,12 +121,22 @@ case class SeparateBytesExpression(hi: Expression, lo: Expression) extends LhsEx
|
||||
case class SumExpression(expressions: List[(Boolean, Expression)], decimal: Boolean) extends Expression {
|
||||
override def replaceVariable(variable: String, actualParam: Expression): Expression =
|
||||
SumExpression(expressions.map { case (n, e) => n -> e.replaceVariable(variable, actualParam) }, decimal).pos(position)
|
||||
override def replaceIndexedExpression(predicate: IndexedExpression => Boolean, replacement: IndexedExpression => Expression): Expression =
|
||||
override def replaceIndexedExpression(predicate: IndexedExpression => Boolean, replacement: IndexedExpression => Expression): Expression =
|
||||
SumExpression(expressions.map { case (n, e) => n -> e.replaceIndexedExpression(predicate, replacement) }, decimal).pos(position)
|
||||
override def containsVariable(variable: String): Boolean = expressions.exists(_._2.containsVariable(variable))
|
||||
override def getPointies: Seq[String] = expressions.flatMap(_._2.getPointies)
|
||||
override def isPure: Boolean = expressions.forall(_._2.isPure)
|
||||
override def getAllIdentifiers: Set[String] = expressions.map(_._2.getAllIdentifiers).fold(Set[String]())(_ ++ _)
|
||||
|
||||
override def #+#(that: Expression): Expression =
|
||||
if (decimal) super.#+#(that)
|
||||
else that match {
|
||||
case SumExpression(params, false) => SumExpression(expressions ++ params, decimal = false)
|
||||
case _ => SumExpression(expressions :+ (false -> that), decimal = false)
|
||||
}
|
||||
override def #-#(that: Expression): Expression =
|
||||
if (decimal) super.#-#(that)
|
||||
else SumExpression(expressions :+ (true -> that), decimal = false)
|
||||
}
|
||||
|
||||
case class FunctionCallExpression(functionName: String, expressions: List[Expression]) extends Expression {
|
||||
|
Loading…
x
Reference in New Issue
Block a user