1
0
mirror of https://github.com/KarolS/millfork.git synced 2024-06-10 08:29:37 +00:00

Macro expansion fix, improved constant folding

This commit is contained in:
Karol Stasiak 2018-02-03 17:49:29 +01:00
parent 0ca1be0c00
commit 2665f18c77
4 changed files with 80 additions and 6 deletions

1
.gitignore vendored
View File

@ -5,6 +5,7 @@ project/target
project/project/target/
stuff
releases
src/test/scala/experiments/
# hidden files
*.~

View File

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

View File

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

View 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)
}
}
}