97 lines
3.2 KiB
Java
97 lines
3.2 KiB
Java
package io.gitlab.jfronny.muscript.ast.dynamic;
|
|
|
|
import io.gitlab.jfronny.muscript.ast.DynamicExpr;
|
|
import io.gitlab.jfronny.muscript.annotations.CanThrow;
|
|
import io.gitlab.jfronny.muscript.annotations.UncheckedDynamic;
|
|
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.data.dynamic.*;
|
|
import io.gitlab.jfronny.muscript.data.dynamic.additional.DFinal;
|
|
import io.gitlab.jfronny.muscript.error.LocationalException;
|
|
|
|
import java.io.IOException;
|
|
import java.util.*;
|
|
import java.util.stream.Stream;
|
|
|
|
@CanThrow
|
|
@UncheckedDynamic
|
|
public class Call extends DynamicExpr {
|
|
private final DynamicExpr left;
|
|
private final List<Arg> args;
|
|
|
|
public Call(int chStart, int chEnd, DynamicExpr left, List<Arg> args) {
|
|
super(Order.Call, chStart, chEnd);
|
|
this.left = left;
|
|
this.args = args;
|
|
}
|
|
|
|
@Override
|
|
public Dynamic<?> get(Scope dataRoot) {
|
|
try {
|
|
return left.get(dataRoot)
|
|
.asCallable()
|
|
.getValue()
|
|
.apply(DFinal.of(args.stream().flatMap(e -> e.get(dataRoot)).toArray(Dynamic[]::new)));
|
|
} catch (DynamicTypeConversionException e) {
|
|
throw e.locational(chStart, chEnd);
|
|
} catch (RuntimeException e) {
|
|
throw new LocationalException(chStart, chEnd, "Could not perform call successfully", e);
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public DynamicExpr optimize() {
|
|
List<Arg> args = new ArrayList<>();
|
|
DynamicExpr left = this.left.optimize();
|
|
if (left instanceof Bind bind) {
|
|
left = bind.callable;
|
|
args.add(new Arg(bind.parameter, false));
|
|
}
|
|
for (Arg arg : this.args) args.add(arg.optimize());
|
|
return new Call(chStart, chEnd, left, args);
|
|
}
|
|
|
|
@Override
|
|
public void decompile(ExprWriter writer) throws IOException {
|
|
parenthesize(left, writer, false);
|
|
if (args.size() > 3) {
|
|
writer.increaseIndent();
|
|
writer.append("(\n");
|
|
boolean first = true;
|
|
for (Arg arg : args) {
|
|
if (!first) writer.append(",\n");
|
|
first = false;
|
|
arg.expr.decompile(writer);
|
|
if (arg.variadic) writer.append("...");
|
|
}
|
|
writer.decreaseIndent();
|
|
writer.append("\n)");
|
|
} else {
|
|
writer.append("(");
|
|
boolean first = true;
|
|
for (Arg arg : args) {
|
|
if (!first) writer.append(", ");
|
|
first = false;
|
|
arg.expr.decompile(writer);
|
|
if (arg.variadic) writer.append("...");
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object obj) {
|
|
return obj instanceof Call call && left.equals(call.left) && args.equals(call.args);
|
|
}
|
|
|
|
public record Arg(DynamicExpr expr, boolean variadic) {
|
|
public Stream<Dynamic<?>> get(Scope dataRoot) {
|
|
return variadic ? expr.get(dataRoot).asList().getValue().stream() : Stream.of(expr.get(dataRoot));
|
|
}
|
|
|
|
public Arg optimize() {
|
|
return new Arg(expr.optimize(), variadic);
|
|
}
|
|
}
|
|
}
|