java-commons/muscript/src/main/java/io/gitlab/jfronny/muscript/ast/dynamic/Call.java

66 lines
2.1 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.data.Scope;
import io.gitlab.jfronny.muscript.data.dynamic.*;
import io.gitlab.jfronny.muscript.error.LocationalException;
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(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 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);
}
}
}