package io.gitlab.jfronny.muscript.ast.math; import io.gitlab.jfronny.muscript.compiler.ExprWriter; import io.gitlab.jfronny.muscript.compiler.Order; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.ast.Expr; import io.gitlab.jfronny.muscript.ast.NumberExpr; import io.gitlab.jfronny.muscript.ast.literal.NumberLiteral; import java.io.IOException; public class Power extends NumberExpr { private final NumberExpr base; private final NumberExpr exponent; public Power(int chStart, int chEnd, NumberExpr base, NumberExpr exponent) { super(Order.Exp, chStart, chEnd); this.base = base; this.exponent = exponent; } @Override public Double get(Scope dataRoot) { return Math.pow(base.get(dataRoot), exponent.get(dataRoot)); } @Override public NumberExpr optimize() { NumberExpr base = this.base.optimize(); NumberExpr exponent = this.exponent.optimize(); if (base instanceof NumberLiteral litB && exponent instanceof NumberLiteral litE) return Expr.literal(chStart, chEnd, Math.pow(litB.value, litE.value)); if (exponent instanceof NumberLiteral exp && base instanceof Multiply multiply) { if (multiply.multiplier instanceof NumberLiteral literal) return new Multiply(multiply.chStart, multiply.chEnd, Expr.literal(chStart, chEnd, Math.pow(literal.value, exp.value)), new Power(chStart, chEnd, multiply.multiplicand, exp)); if (multiply.multiplicand instanceof NumberLiteral literal) return new Multiply(multiply.chStart, multiply.chEnd, Expr.literal(chStart, chEnd, Math.pow(literal.value, exp.value)), new Power(chStart, chEnd, multiply.multiplier, exp)); } return new Power(chStart, chEnd, base, exponent); } @Override public void decompile(ExprWriter writer) throws IOException { parenthesize(base, writer, false); writer.append(" ^ "); parenthesize(exponent, writer, true); } @Override public boolean equals(Object obj) { return obj instanceof Power power && base.equals(power.base) && exponent.equals(power.exponent); } }