feat(muscript): implement extractSideEffects
ci/woodpecker/push/woodpecker Pipeline was successful Details

This commit is contained in:
Johannes Frohnmeyer 2024-04-05 18:15:15 +02:00
parent 9e6e337843
commit 95658555cf
Signed by: Johannes
GPG Key ID: E76429612C2929F4
1 changed files with 58 additions and 2 deletions

View File

@ -7,6 +7,7 @@ import io.gitlab.jfronny.muscript.ast.dynamic.*;
import io.gitlab.jfronny.muscript.ast.extensible.*;
import io.gitlab.jfronny.muscript.ast.number.*;
import io.gitlab.jfronny.muscript.ast.string.*;
import io.gitlab.jfronny.muscript.core.CodeLocation;
import io.gitlab.jfronny.muscript.data.additional.DFinal;
import io.gitlab.jfronny.muscript.data.dynamic.Dynamic;
@ -359,7 +360,62 @@ public class Optimizer {
}
public static Stream<Expr> extractSideEffects(Expr expr) {
//TODO actually implement
return Stream.of(expr);
return switch (expr) {
case NullLiteral e -> Stream.empty();
case BoolLiteral e -> Stream.empty();
case NumberLiteral e -> Stream.empty();
case StringLiteral e -> Stream.empty();
case DynamicLiteral e -> Stream.empty();
case Closure e -> Stream.empty();
case Variable e -> Stream.empty();
case This e -> Stream.empty();
case NumberUnpack(var inner) -> extractSideEffects(inner);
case StringUnpack(var inner) -> extractSideEffects(inner);
case BoolUnpack(var inner) -> extractSideEffects(inner);
case DynamicCoerce(var inner) -> extractSideEffects(inner);
case StringCoerce(var inner) -> extractSideEffects(inner);
case BoolAssign e -> Stream.of(e);
case NumberAssign e -> Stream.of(e);
case StringAssign e -> Stream.of(e);
case DynamicAssign e -> Stream.of(e);
case ExtensibleExpr e -> e.extractSideEffects();
case And(var location, var left, var right) -> Stream.concat(extractSideEffects(left), extractSideEffects(right));
case Or(var location, var left, var right) -> Stream.concat(extractSideEffects(left), extractSideEffects(right));
case Not(var location, var inner) -> extractSideEffects(inner);
case Equals(var location, var left, var right) -> Stream.concat(extractSideEffects(left), extractSideEffects(right));
case GreaterThan(var location, var left, var right) -> Stream.concat(extractSideEffects(left), extractSideEffects(right));
case BoolConditional(var location, var condition, var ifTrue, var ifFalse) -> extractConditionalSideEffects(location, condition, ifTrue, ifFalse);
case DynamicConditional(var location, var condition, var ifTrue, var ifFalse) -> extractConditionalSideEffects(location, condition, ifTrue, ifFalse);
case NumberConditional(var location, var condition, var ifTrue, var ifFalse) -> extractConditionalSideEffects(location, condition, ifTrue, ifFalse);
case StringConditional(var location, var condition, var ifTrue, var ifFalse) -> extractConditionalSideEffects(location, condition, ifTrue, ifFalse);
case Bind(var location, var callable, var parameter) -> Stream.concat(extractSideEffects(callable), extractSideEffects(parameter));
case Call e -> Stream.of(e);
case ExprGroup(var location, var steps, var finish, var packedArgs, var fork) -> fork
? Stream.of(expr)
: Stream.of(ExprGroup.of(location, steps.stream().flatMap(Optimizer::extractSideEffects).toList()));
case Get(var location, var left, var name) -> Stream.concat(extractSideEffects(left), extractSideEffects(name));
case ListLiteral(var location, var elements) -> elements.stream().flatMap(Optimizer::extractSideEffects);
case ObjectLiteral(var location, var content) -> content.values().stream().flatMap(Optimizer::extractSideEffects);
case Divide(var location, var dividend, var divisor) -> Stream.concat(extractSideEffects(dividend), extractSideEffects(divisor));
case Negate(var location, var inner) -> extractSideEffects(inner);
case Add(var location, var augend, var addend) -> Stream.concat(extractSideEffects(augend), extractSideEffects(addend));
case Subtract(var location, var minuend, var subtrahend) -> Stream.concat(extractSideEffects(minuend), extractSideEffects(subtrahend));
case Multiply(var location, var multiplier, var multiplicand) -> Stream.concat(extractSideEffects(multiplier), extractSideEffects(multiplicand));
case Modulo(var location, var dividend, var divisor) -> Stream.concat(extractSideEffects(dividend), extractSideEffects(divisor));
case Power(var location, var base, var exponent) -> Stream.concat(extractSideEffects(base), extractSideEffects(exponent));
case Concatenate(var location, var left, var right) -> Stream.concat(extractSideEffects(left), extractSideEffects(right));
};
}
private static Stream<Expr> extractConditionalSideEffects(CodeLocation location, BoolExpr condition, Expr ifTrue, Expr ifFalse) {
List<Expr> trueSE = extractSideEffects(ifTrue).toList();
List<Expr> falseSE = extractSideEffects(ifFalse).toList();
if (trueSE.isEmpty() && falseSE.isEmpty()) return extractSideEffects(condition);
return Stream.of(new DynamicConditional(
location,
condition,
asDynamic(ExprGroup.of(ifTrue.location(), trueSE, false)),
asDynamic(ExprGroup.of(ifFalse.location(), falseSE, false))
));
}
}