mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-12 03:30:09 +00:00
Removal of the <<<< operator; nonet operation improvements
Use `nonet(a << b)` instead of `a <<<< b`
This commit is contained in:
parent
9680423691
commit
516d7eae26
@ -227,17 +227,6 @@ object BuiltIns {
|
||||
}
|
||||
}
|
||||
|
||||
@deprecated
|
||||
def compileNonetLeftShift(ctx: CompilationContext, lhs: Expression, rhs: Expression): List[AssemblyLine] = {
|
||||
val label = MfCompiler.nextLabel("sh")
|
||||
compileShiftOps(ASL, ctx, lhs, rhs) ++ List(
|
||||
AssemblyLine.immediate(LDX, 0),
|
||||
AssemblyLine.relative(BCC, label),
|
||||
AssemblyLine.implied(INX),
|
||||
AssemblyLine.label(label)
|
||||
)
|
||||
}
|
||||
|
||||
def compileInPlaceByteShiftOps(opcode: Opcode.Value, ctx: CompilationContext, lhs: LhsExpression, rhs: Expression): List[AssemblyLine] = {
|
||||
val env = ctx.env
|
||||
val b = env.get[Type]("byte")
|
||||
|
@ -62,7 +62,6 @@ object ExpressionCompiler {
|
||||
case FunctionCallExpression("<<'", params) => b
|
||||
case FunctionCallExpression(">>'", params) => b
|
||||
case FunctionCallExpression(">>>>", params) => b
|
||||
case FunctionCallExpression("<<<<", params) => w
|
||||
case FunctionCallExpression("&&", params) => bool
|
||||
case FunctionCallExpression("||", params) => bool
|
||||
case FunctionCallExpression("^^", params) => bool
|
||||
@ -832,7 +831,7 @@ object ExpressionCompiler {
|
||||
if (addends.size > 2) {
|
||||
ErrorReporting.warn("Nonet addition works correctly only for two operands", ctx.options, expr.position)
|
||||
}
|
||||
case FunctionCallExpression("+" | "+'" | "<<" | "<<<<" | "<<'" | "nonet", _) => // ok
|
||||
case FunctionCallExpression("+" | "+'" | "<<" | "<<'" | "nonet", _) => // ok
|
||||
case _ =>
|
||||
ErrorReporting.warn("Unspecified nonet operation, results might be unpredictable", ctx.options, expr.position)
|
||||
}
|
||||
@ -895,11 +894,6 @@ object ExpressionCompiler {
|
||||
case v: LhsExpression =>
|
||||
BuiltIns.compileNonetOps(ctx, v, r)
|
||||
}
|
||||
case "<<<<" =>
|
||||
ErrorReporting.warn("`x <<<< y` is obsolete, use `nonet(x << y)`", ctx.options, expr.position)
|
||||
assertAllBytes("Long shift ops not supported", ctx, params)
|
||||
val (l, r, 1) = assertBinary(ctx, params)
|
||||
BuiltIns.compileNonetLeftShift(ctx, l, r)
|
||||
case "<<" =>
|
||||
val (l, r, size) = assertBinary(ctx, params)
|
||||
size match {
|
||||
|
18
src/main/scala/millfork/env/Constant.scala
vendored
18
src/main/scala/millfork/env/Constant.scala
vendored
@ -150,8 +150,8 @@ case class SubbyteConstant(base: Constant, index: Int) extends Constant {
|
||||
}
|
||||
|
||||
object MathOperator extends Enumeration {
|
||||
val Plus, Minus, Times, Shl, Shr, Shl9, Shr9,
|
||||
DecimalPlus, DecimalMinus, DecimalTimes, DecimalShl, DecimalShr,
|
||||
val Plus, Minus, Times, Shl, Shr, Shl9, Shr9, Plus9, DecimalPlus9,
|
||||
DecimalPlus, DecimalMinus, DecimalTimes, DecimalShl, DecimalShl9, DecimalShr,
|
||||
And, Or, Exor = Value
|
||||
}
|
||||
|
||||
@ -170,6 +170,7 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
||||
case MathOperator.Shl => lv << rv
|
||||
case MathOperator.Shr => lv >> rv
|
||||
case MathOperator.Shl9 => (lv << rv) & 0x1ff
|
||||
case MathOperator.Plus9 => (lv + rv) & 0x1ff
|
||||
case MathOperator.Shr9 => (lv & 0x1ff) >> rv
|
||||
case MathOperator.Exor => lv ^ rv
|
||||
case MathOperator.Or => lv | rv
|
||||
@ -177,6 +178,8 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
||||
case _ => return this
|
||||
}
|
||||
operator match {
|
||||
case MathOperator.Plus9 | MathOperator.DecimalPlus9 =>
|
||||
size = 2
|
||||
case MathOperator.Times | MathOperator.Shl =>
|
||||
val mask = (1 << (size * 8)) - 1
|
||||
if (value != (value & mask)){
|
||||
@ -188,6 +191,9 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
||||
case (NumericConstant(0, 1), c) =>
|
||||
operator match {
|
||||
case MathOperator.Plus => c
|
||||
case MathOperator.Plus9 => c
|
||||
case MathOperator.DecimalPlus => c
|
||||
case MathOperator.DecimalPlus9 => c
|
||||
case MathOperator.Minus => CompoundConstant(operator, l, r)
|
||||
case MathOperator.Times => Constant.Zero
|
||||
case MathOperator.Shl => Constant.Zero
|
||||
@ -202,6 +208,9 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
||||
case (c, NumericConstant(0, 1)) =>
|
||||
operator match {
|
||||
case MathOperator.Plus => c
|
||||
case MathOperator.Plus9 => c
|
||||
case MathOperator.DecimalPlus => c
|
||||
case MathOperator.DecimalPlus9 => c
|
||||
case MathOperator.Minus => c
|
||||
case MathOperator.Times => Constant.Zero
|
||||
case MathOperator.Shl => c
|
||||
@ -259,16 +268,19 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
||||
override def toString: String = {
|
||||
operator match {
|
||||
case Plus => f"$plhs + $prhs"
|
||||
case Plus9 => f"nonet($plhs + $prhs)"
|
||||
case Minus => f"$plhs - $prhs"
|
||||
case Times => f"$plhs * $prhs"
|
||||
case Shl => f"$plhs << $prhs"
|
||||
case Shr => f"$plhs >> $prhs"
|
||||
case Shl9 => f"$plhs <<<< $prhs"
|
||||
case Shl9 => f"nonet($plhs << $prhs)"
|
||||
case Shr9 => f"$plhs >>>> $prhs"
|
||||
case DecimalPlus => f"$plhs +' $prhs"
|
||||
case DecimalPlus9 => f"nonet($plhs +' $prhs)"
|
||||
case DecimalMinus => f"$plhs -' $prhs"
|
||||
case DecimalTimes => f"$plhs *' $prhs"
|
||||
case DecimalShl => f"$plhs <<' $prhs"
|
||||
case DecimalShl9 => f"nonet($plhs <<' $prhs)"
|
||||
case DecimalShr => f"$plhs >>' $prhs"
|
||||
case And => f"$plhs & $prhs"
|
||||
case Or => f"$plhs | $prhs"
|
||||
|
17
src/main/scala/millfork/env/Environment.scala
vendored
17
src/main/scala/millfork/env/Environment.scala
vendored
@ -278,7 +278,7 @@ class Environment(val parent: Option[Environment], val prefix: String) {
|
||||
"<<" | ">>" |
|
||||
"<<'" | ">>'" |
|
||||
"&" | "|" | "^" |
|
||||
">>>>" | "<<<<" |
|
||||
">>>>" |
|
||||
"*" | "*'", _)) => variable -> constant
|
||||
case Some(FunctionCallExpression(fname, _)) =>
|
||||
maybeGet[Thing](fname) match {
|
||||
@ -332,6 +332,19 @@ class Environment(val parent: Option[Environment], val prefix: String) {
|
||||
} yield hc.asl(8) + lc
|
||||
case FunctionCallExpression(name, params) =>
|
||||
name match {
|
||||
case "nonet" =>
|
||||
params match {
|
||||
case List(FunctionCallExpression("<<", ps@List(_, _))) =>
|
||||
constantOperation(MathOperator.Shl9, ps)
|
||||
case List(FunctionCallExpression("<<'", ps@List(_, _))) =>
|
||||
constantOperation(MathOperator.DecimalShl9, ps)
|
||||
case List(SumExpression(ps@List((true,_),(true,_)), false)) =>
|
||||
constantOperation(MathOperator.Plus9, ps.map(_._2))
|
||||
case List(SumExpression(ps@List((true,_),(true,_)), true)) =>
|
||||
constantOperation(MathOperator.DecimalPlus9, ps.map(_._2))
|
||||
case _ =>
|
||||
None
|
||||
}
|
||||
case ">>'" =>
|
||||
constantOperation(MathOperator.DecimalShr, params)
|
||||
case "<<'" =>
|
||||
@ -340,8 +353,6 @@ class Environment(val parent: Option[Environment], val prefix: String) {
|
||||
constantOperation(MathOperator.Shr, params)
|
||||
case "<<" =>
|
||||
constantOperation(MathOperator.Shl, params)
|
||||
case "<<<<" =>
|
||||
constantOperation(MathOperator.Shl9, params)
|
||||
case ">>>>" =>
|
||||
constantOperation(MathOperator.Shr9, params)
|
||||
case "*'" =>
|
||||
|
@ -99,14 +99,18 @@ class Assembler(private val program: Program, private val rootEnv: Environment,
|
||||
val r = deepConstResolve(rc)
|
||||
operator match {
|
||||
case MathOperator.Plus => l + r
|
||||
case MathOperator.Plus9 => (l + r) & 0x1ff
|
||||
case MathOperator.Minus => l - r
|
||||
case MathOperator.Times => l * r
|
||||
case MathOperator.Shl => l << r
|
||||
case MathOperator.Shl9 => (l << r) & 0x1ff
|
||||
case MathOperator.Shr => l >>> r
|
||||
case MathOperator.DecimalPlus => asDecimal(l, r, _ + _)
|
||||
case MathOperator.DecimalPlus9 => asDecimal(l, r, _ + _) & 0x1ff
|
||||
case MathOperator.DecimalMinus => asDecimal(l, r, _ - _)
|
||||
case MathOperator.DecimalTimes => asDecimal(l, r, _ * _)
|
||||
case MathOperator.DecimalShl => asDecimal(l, 1 << r, _ * _)
|
||||
case MathOperator.DecimalShl9 => asDecimal(l, 1 << r, _ * _) & 0x1ff
|
||||
case MathOperator.DecimalShr => asDecimal(l, 1 << r, _ / _)
|
||||
case MathOperator.And => l & r
|
||||
case MathOperator.Exor => l ^ r
|
||||
|
@ -130,7 +130,7 @@ case class MfParser(filename: String, input: String, currentDirectory: String, o
|
||||
List("&&"),
|
||||
List("==", "<=", ">=", "!=", "<", ">"),
|
||||
List(":"),
|
||||
List("+'", "-'", "<<'", ">>'", "<<<<", ">>>>", "+", "-", "&", "|", "^", "<<", ">>"),
|
||||
List("+'", "-'", "<<'", ">>'", ">>>>", "+", "-", "&", "|", "^", "<<", ">>"),
|
||||
List("*'", "*"))
|
||||
|
||||
val nonStatementLevel = 1 // everything but not `=`
|
||||
|
@ -310,7 +310,7 @@ class AssemblyOptimizationSuite extends FunSuite with Matchers {
|
||||
| byte source @$C002
|
||||
| void main () {
|
||||
| init()
|
||||
| output += source <<<< 1
|
||||
| output += nonet(source << 1)
|
||||
| }
|
||||
| void init() {
|
||||
| output = 0
|
||||
|
@ -37,10 +37,10 @@ class NonetSuite extends FunSuite with Matchers {
|
||||
| void main () {
|
||||
| byte a
|
||||
| a = 3
|
||||
| output0 = a <<<< 1
|
||||
| output1 = a <<<< 2
|
||||
| output2 = a <<<< 6
|
||||
| output3 = a <<<< 7
|
||||
| output0 = nonet(a << 1)
|
||||
| output1 = nonet(a << 2)
|
||||
| output2 = nonet(a << 6)
|
||||
| output3 = nonet(a << 7)
|
||||
| }
|
||||
""".stripMargin) { m =>
|
||||
m.readWord(0xc000) should equal(0x06)
|
||||
|
Loading…
x
Reference in New Issue
Block a user