mirror of
https://github.com/KarolS/millfork.git
synced 2025-08-08 18:25:03 +00:00
Macro expansion fix, improved constant folding
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -5,6 +5,7 @@ project/target
|
|||||||
project/project/target/
|
project/project/target/
|
||||||
stuff
|
stuff
|
||||||
releases
|
releases
|
||||||
|
src/test/scala/experiments/
|
||||||
|
|
||||||
# hidden files
|
# hidden files
|
||||||
*.~
|
*.~
|
||||||
|
@@ -771,10 +771,23 @@ object MfCompiler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
case SumExpression(params, decimal) =>
|
case SumExpression(params, decimal) =>
|
||||||
assertAllBytesForSum("Long addition not supported", ctx, params)
|
val a = params.map{case (n, p) => env.eval(p).map(n -> _)}
|
||||||
val calculate = BuiltIns.compileAddition(ctx, params, decimal = decimal)
|
if (a.forall(_.isDefined)) {
|
||||||
val store = expressionStorageFromAX(ctx, exprTypeAndVariable, expr.position)
|
val value = a.foldLeft(Constant.Zero){(c, pair) =>
|
||||||
calculate ++ store
|
val Some((neg, v)) = pair
|
||||||
|
CompoundConstant(if (decimal) {
|
||||||
|
if (neg) MathOperator.DecimalMinus else MathOperator.DecimalPlus
|
||||||
|
} else {
|
||||||
|
if (neg) MathOperator.Minus else MathOperator.Plus
|
||||||
|
}, c, v)
|
||||||
|
}
|
||||||
|
exprTypeAndVariable.map(x => compileConstant(ctx, value.quickSimplify, x._2)).getOrElse(Nil)
|
||||||
|
} else {
|
||||||
|
assertAllBytesForSum("Long addition not supported", ctx, params)
|
||||||
|
val calculate = BuiltIns.compileAddition(ctx, params, decimal = decimal)
|
||||||
|
val store = expressionStorageFromAX(ctx, exprTypeAndVariable, expr.position)
|
||||||
|
calculate ++ store
|
||||||
|
}
|
||||||
case SeparateBytesExpression(h, l) =>
|
case SeparateBytesExpression(h, l) =>
|
||||||
exprTypeAndVariable.fold {
|
exprTypeAndVariable.fold {
|
||||||
// TODO: order?
|
// TODO: order?
|
||||||
@@ -1367,7 +1380,10 @@ object MfCompiler {
|
|||||||
case IfStatement(c, t, e) => IfStatement(f(c), t.map(gx), e.map(gx))
|
case IfStatement(c, t, e) => IfStatement(f(c), t.map(gx), e.map(gx))
|
||||||
case s:AssemblyStatement => s.copy(expression = f(s.expression))
|
case s:AssemblyStatement => s.copy(expression = f(s.expression))
|
||||||
case Assignment(d,s) => Assignment(fx(d), f(s))
|
case Assignment(d,s) => Assignment(fx(d), f(s))
|
||||||
case _ => ???
|
case BlockStatement(s) => BlockStatement(s.map(gx))
|
||||||
|
case _ =>
|
||||||
|
println(stmt)
|
||||||
|
???
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1416,7 +1432,7 @@ object MfCompiler {
|
|||||||
} else {
|
} else {
|
||||||
params.zip(normalParams).foreach{
|
params.zip(normalParams).foreach{
|
||||||
case (v@VariableExpression(_), MemoryVariable(paramName, paramType, _)) =>
|
case (v@VariableExpression(_), MemoryVariable(paramName, paramType, _)) =>
|
||||||
actualCode = actualCode.map(stmt => replaceVariable(stmt, paramName, v).asInstanceOf[ExecutableStatement])
|
actualCode = actualCode.map(stmt => replaceVariable(stmt, paramName.stripPrefix(i.environment.prefix), v).asInstanceOf[ExecutableStatement])
|
||||||
case _ =>
|
case _ =>
|
||||||
ErrorReporting.error(s"Parameters to macro functions have to be variables", position)
|
ErrorReporting.error(s"Parameters to macro functions have to be variables", position)
|
||||||
}
|
}
|
||||||
|
28
src/main/scala/millfork/env/Constant.scala
vendored
28
src/main/scala/millfork/env/Constant.scala
vendored
@@ -182,6 +182,34 @@ case class CompoundConstant(operator: MathOperator.Value, lhs: Constant, rhs: Co
|
|||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
NumericConstant(value, size)
|
NumericConstant(value, size)
|
||||||
|
case (NumericConstant(0, 1), c) =>
|
||||||
|
operator match {
|
||||||
|
case MathOperator.Plus => c
|
||||||
|
case MathOperator.Minus => CompoundConstant(operator, l, r)
|
||||||
|
case MathOperator.Times => Constant.Zero
|
||||||
|
case MathOperator.Shl => Constant.Zero
|
||||||
|
case MathOperator.Shr => Constant.Zero
|
||||||
|
case MathOperator.Shl9 => Constant.Zero
|
||||||
|
case MathOperator.Shr9 => Constant.Zero
|
||||||
|
case MathOperator.Exor => c
|
||||||
|
case MathOperator.Or => c
|
||||||
|
case MathOperator.And => Constant.Zero
|
||||||
|
case _ => CompoundConstant(operator, l, r)
|
||||||
|
}
|
||||||
|
case (c, NumericConstant(0, 1)) =>
|
||||||
|
operator match {
|
||||||
|
case MathOperator.Plus => c
|
||||||
|
case MathOperator.Minus => c
|
||||||
|
case MathOperator.Times => Constant.Zero
|
||||||
|
case MathOperator.Shl => c
|
||||||
|
case MathOperator.Shr => c
|
||||||
|
case MathOperator.Shl9 => c
|
||||||
|
case MathOperator.Shr9 => c
|
||||||
|
case MathOperator.Exor => c
|
||||||
|
case MathOperator.Or => c
|
||||||
|
case MathOperator.And => Constant.Zero
|
||||||
|
case _ => CompoundConstant(operator, l, r)
|
||||||
|
}
|
||||||
case _ => CompoundConstant(operator, l, r)
|
case _ => CompoundConstant(operator, l, r)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
29
src/test/scala/millfork/test/MacroSuite.scala
Normal file
29
src/test/scala/millfork/test/MacroSuite.scala
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package millfork.test
|
||||||
|
|
||||||
|
import millfork.test.emu.EmuBenchmarkRun
|
||||||
|
import org.scalatest.{FunSuite, Matchers}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Karol Stasiak
|
||||||
|
*/
|
||||||
|
class MacroSuite extends FunSuite with Matchers {
|
||||||
|
|
||||||
|
test("Most basic test") {
|
||||||
|
EmuBenchmarkRun(
|
||||||
|
"""
|
||||||
|
| macro void run(byte x) {
|
||||||
|
| output = x
|
||||||
|
| }
|
||||||
|
|
|
||||||
|
| byte output @$c000
|
||||||
|
|
|
||||||
|
| void main () {
|
||||||
|
| byte a
|
||||||
|
| a = 7
|
||||||
|
| run(a)
|
||||||
|
| }
|
||||||
|
""".stripMargin) { m =>
|
||||||
|
m.readByte(0xc000) should equal(7)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Reference in New Issue
Block a user