mirror of
https://github.com/KarolS/millfork.git
synced 2025-01-01 06:29:53 +00:00
Macro expansion fix, improved constant folding
This commit is contained in:
parent
0ca1be0c00
commit
2665f18c77
1
.gitignore
vendored
1
.gitignore
vendored
@ -5,6 +5,7 @@ project/target
|
||||
project/project/target/
|
||||
stuff
|
||||
releases
|
||||
src/test/scala/experiments/
|
||||
|
||||
# hidden files
|
||||
*.~
|
||||
|
@ -771,10 +771,23 @@ object MfCompiler {
|
||||
}
|
||||
}
|
||||
case SumExpression(params, decimal) =>
|
||||
assertAllBytesForSum("Long addition not supported", ctx, params)
|
||||
val calculate = BuiltIns.compileAddition(ctx, params, decimal = decimal)
|
||||
val store = expressionStorageFromAX(ctx, exprTypeAndVariable, expr.position)
|
||||
calculate ++ store
|
||||
val a = params.map{case (n, p) => env.eval(p).map(n -> _)}
|
||||
if (a.forall(_.isDefined)) {
|
||||
val value = a.foldLeft(Constant.Zero){(c, pair) =>
|
||||
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) =>
|
||||
exprTypeAndVariable.fold {
|
||||
// TODO: order?
|
||||
@ -1367,7 +1380,10 @@ object MfCompiler {
|
||||
case IfStatement(c, t, e) => IfStatement(f(c), t.map(gx), e.map(gx))
|
||||
case s:AssemblyStatement => s.copy(expression = f(s.expression))
|
||||
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 {
|
||||
params.zip(normalParams).foreach{
|
||||
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 _ =>
|
||||
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 _ =>
|
||||
}
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
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)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user