1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-25 19:29:49 +00:00

Refactoring

This commit is contained in:
Karol Stasiak 2019-07-30 22:25:05 +02:00
parent e2c8dad7a5
commit 613ddcf9a4
10 changed files with 79 additions and 77 deletions

View File

@ -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(

View File

@ -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
}

View File

@ -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)

View File

@ -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

View File

@ -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))

View File

@ -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)

View File

@ -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] =

View File

@ -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

View File

@ -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

View File

@ -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 {