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