style(muscript): clean up Optimizer

This commit is contained in:
Johannes Frohnmeyer 2024-04-07 15:35:51 +02:00
parent a171edf20f
commit f1e51f98e3
Signed by: Johannes
GPG Key ID: E76429612C2929F4
1 changed files with 55 additions and 50 deletions

View File

@ -3,6 +3,7 @@ package io.gitlab.jfronny.muscript.optimizer;
import io.gitlab.jfronny.commons.StringFormatter;
import io.gitlab.jfronny.muscript.ast.*;
import io.gitlab.jfronny.muscript.ast.bool.*;
import io.gitlab.jfronny.muscript.ast.context.Script;
import io.gitlab.jfronny.muscript.ast.dynamic.*;
import io.gitlab.jfronny.muscript.ast.extensible.*;
import io.gitlab.jfronny.muscript.ast.number.*;
@ -21,6 +22,10 @@ import static io.gitlab.jfronny.muscript.ast.Expr.literal;
import static io.gitlab.jfronny.muscript.ast.context.ExprUtils.*;
public class Optimizer {
public static Script optimize(Script script) {
return new Script(optimize(script.content()));
}
public static Expr optimize(Expr expr) {
return switch (unpack(expr)) {
case null -> throw new NullPointerException();
@ -111,6 +116,47 @@ public class Optimizer {
yield optimize(new Subtract(location, augend, innerAddend));
yield new Add(location, augend, addend);
}
case Subtract e -> {
var location = e.location();
var minuend = optimize(e.minuend());
var subtrahend = optimize(e.subtrahend());
if (minuend instanceof NumberLiteral(var location1, var minuendValue)
&& subtrahend instanceof NumberLiteral(var location2, var subtrahendValue))
yield literal(location, minuendValue - subtrahendValue);
if (minuend instanceof Subtract(var location1, var minuend1, var subtrahend1))
yield optimize(new Subtract(location, minuend1, new Add(minuend.location(), subtrahend1, subtrahend)));
if (subtrahend instanceof Subtract(var location1, var minuend1, var subtrahend1))
yield new Subtract(location, new Add(subtrahend.location(), minuend, subtrahend1), minuend1);
if (subtrahend instanceof Negate(var location1, var inner)) {
if (minuend instanceof Negate(var location2, var inner2))
yield new Subtract(location, inner, inner2);
yield optimize(new Add(location, minuend, inner));
}
if (minuend instanceof Negate(var location1, var inner)) {
yield optimize(new Negate(location, new Add(location, inner, subtrahend)));
}
yield new Subtract(location, minuend, subtrahend);
}
case Negate e -> {
var location = e.location();
var inner = optimize(e.inner());
if (inner instanceof Negate(var location1, var innerInner))
yield innerInner;
if (inner instanceof NumberLiteral(var location1, var value))
yield literal(location, -value);
if (inner instanceof Subtract(var location1, var minuend, var subtrahend))
yield optimize(new Subtract(location, subtrahend, minuend));
yield new Negate(location, inner);
}
case Multiply e -> {
var location = e.location();
var multiplier = optimize(e.multiplier());
var multiplicand = optimize(e.multiplicand());
if (multiplier instanceof NumberLiteral(var location1, var multiplierValue)
&& multiplicand instanceof NumberLiteral(var location2, var multiplicandValue))
yield literal(location, multiplierValue * multiplicandValue);
yield new Multiply(location, multiplicand, multiplier);
}
case Divide e -> {
var location = e.location();
var dividend = optimize(e.dividend());
@ -133,26 +179,6 @@ public class Optimizer {
yield literal(location, dividendValue % divisorValue);
yield new Modulo(location, dividend, divisor);
}
case Multiply e -> {
var location = e.location();
var multiplier = optimize(e.multiplier());
var multiplicand = optimize(e.multiplicand());
if (multiplier instanceof NumberLiteral(var location1, var multiplierValue)
&& multiplicand instanceof NumberLiteral(var location2, var multiplicandValue))
yield literal(location, multiplierValue * multiplicandValue);
yield new Multiply(location, multiplicand, multiplier);
}
case Negate e -> {
var location = e.location();
var inner = optimize(e.inner());
if (inner instanceof Negate(var location1, var innerInner))
yield innerInner;
if (inner instanceof NumberLiteral(var location1, var value))
yield literal(location, -value);
if (inner instanceof Subtract(var location1, var minuend, var subtrahend))
yield optimize(new Subtract(location, subtrahend, minuend));
yield new Negate(location, inner);
}
case Power e -> {
var location = e.location();
var base = optimize(e.base());
@ -173,27 +199,6 @@ public class Optimizer {
}
yield new Power(location, base, exponent);
}
case Subtract e -> {
var location = e.location();
var minuend = optimize(e.minuend());
var subtrahend = optimize(e.subtrahend());
if (minuend instanceof NumberLiteral(var location1, var minuendValue)
&& subtrahend instanceof NumberLiteral(var location2, var subtrahendValue))
yield literal(location, minuendValue - subtrahendValue);
if (minuend instanceof Subtract(var location1, var minuend1, var subtrahend1))
yield optimize(new Subtract(location, minuend1, new Add(minuend.location(), subtrahend1, subtrahend)));
if (subtrahend instanceof Subtract(var location1, var minuend1, var subtrahend1))
yield new Subtract(location, new Add(subtrahend.location(), minuend, subtrahend1), minuend1);
if (subtrahend instanceof Negate(var location1, var inner)) {
if (minuend instanceof Negate(var location2, var inner2))
yield new Subtract(location, inner, inner2);
yield optimize(new Add(location, minuend, inner));
}
if (minuend instanceof Negate(var location1, var inner)) {
yield optimize(new Negate(location, new Add(location, inner, subtrahend)));
}
yield new Subtract(location, minuend, subtrahend);
}
};
}
@ -225,15 +230,6 @@ public class Optimizer {
yield rightValue ? left : literal(location, false);
yield new And(location, left, right);
}
case Not e -> {
var location = e.location();
var inner = optimize(e.inner());
if (inner instanceof BoolLiteral(var location1, var value))
yield literal(location, !value);
if (inner instanceof Not(var location1, var innerInner))
yield innerInner;
yield new Not(location, inner);
}
case Or e -> {
var location = e.location();
var left = optimize(e.left());
@ -244,6 +240,15 @@ public class Optimizer {
yield rightValue ? literal(location, true) : left;
yield new Or(location, left, right);
}
case Not e -> {
var location = e.location();
var inner = optimize(e.inner());
if (inner instanceof BoolLiteral(var location1, var value))
yield literal(location, !value);
if (inner instanceof Not(var location1, var innerInner))
yield innerInner;
yield new Not(location, inner);
}
case Equals e -> {
var location = e.location();
var left = optimize(e.left());