package io.gitlab.jfronny.muscript; import io.gitlab.jfronny.muscript.data.Scope; import io.gitlab.jfronny.muscript.data.dynamic.*; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Random; import static io.gitlab.jfronny.muscript.data.dynamic.DFinal.of; public class StandardLib { private static final Random rnd = new Random(); public static final SimpleDateFormat timeFormat = new SimpleDateFormat("HH:mm"); public static final SimpleDateFormat dateFormat = new SimpleDateFormat("dd. MM. yyyy"); public static Scope createScope() { return addTo(new Scope()); } public static Scope addTo(Scope scope) { return scope .set("PI", Math.PI) .set("time", timeFormat.format(new Date())) .set("date", dateFormat.format(new Date())) .set("round", StandardLib::round) .set("floor", StandardLib::floor) .set("ceil", StandardLib::ceil) .set("abs", StandardLib::abs) .set("random", StandardLib::random) .set("toUpper", StandardLib::toUpper) .set("toLower", StandardLib::toLower) .set("contains", StandardLib::contains) .set("replace", StandardLib::replace) .set("listOf", StandardLib::listOf) .set("len", StandardLib::len) .set("isEmpty", StandardLib::isEmpty) .set("concat", StandardLib::concat) .set("filter", StandardLib::filter) .set("map", StandardLib::map) .set("flatMap", StandardLib::flatMap) .set("fold", StandardLib::fold) .set("forEach", StandardLib::forEach); } // Numbers public static DNumber round(DList args) { if (args.size() == 1) { return of(Math.round(args.get(0).asNumber().getValue())); } else if (args.size() == 2) { double x = Math.pow(10, (int) (double) args.get(1).asNumber().getValue()); return of(Math.round(args.get(0).asNumber().getValue() * x) / x); } else { throw new IllegalArgumentException("Invalid number of arguments for round: expected 1 or 2 but got " + args.size()); } } public static DNumber floor(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for floor: expected 1 but got " + args.size()); return of(Math.floor(args.get(0).asNumber().getValue())); } public static DNumber ceil(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for ceil: expected 1 but got " + args.size()); return of(Math.ceil(args.get(0).asNumber().getValue())); } public static DNumber abs(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for abs: expected 1 but got " + args.size()); return of(Math.abs(args.get(0).asNumber().getValue())); } public static DNumber random(DList args) { if (args.size() == 0) return of(rnd.nextDouble()); else if (args.size() == 2) { double min = args.get(0).asNumber().getValue(); double max = args.get(1).asNumber().getValue(); return of(min + (max - min) * rnd.nextDouble()); } throw new IllegalArgumentException("Invalid number of arguments for random: expected 0 or 2 but got " + args.size()); } // Strings public static DString toUpper(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for toUpper: expected 1 but got " + args.size()); return of(args.get(0).asString().getValue().toUpperCase()); } public static DString toLower(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for toLower: expected 1 but got " + args.size()); return of(args.get(0).asString().getValue().toLowerCase()); } public static DBool contains(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for contains: expected 2 but got " + args.size()); return of(args.get(0).asString().getValue().contains(args.get(1).asString().getValue())); } public static DString replace(DList args) { if (args.size() != 3) throw new IllegalArgumentException("Invalid number of arguments for replace: expected 3 but got " + args.size()); return of(args.get(0).asString().getValue().replace(args.get(1).asString().getValue(), args.get(2).asString().getValue())); } // Lists public static DList listOf(DList args) { return args; } public static DNumber len(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for len: expected 1 but got " + args.size()); return of(args.get(0).asList().size()); } public static DBool isEmpty(DList args) { if (args.size() != 1) throw new IllegalArgumentException("Invalid number of arguments for isEmpty: expected 1 but got " + args.size()); return of(args.get(0).asList().isEmpty()); } public static DList concat(DList args) { return of(args.getValue().stream().flatMap(s -> s.asList().getValue().stream()).toList()); } public static DList filter(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for filter: expected at least 2 but got " + args.size()); DCallable dc = args.get(1).asCallable(); return of(args.get(0).asList().getValue().stream().filter(a -> dc.call(a).asBool().getValue()).toList()); } public static DList map(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for map: expected at least 2 but got " + args.size()); return of(args.get(0).asList().getValue().stream().>map(args.get(1).asCallable()::call).toList()); } public static DList flatMap(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for flatMap: expected at least 2 but got " + args.size()); DCallable dc = args.get(1).asCallable(); return of(args.get(0).asList().getValue().stream().flatMap(a -> dc.call(a).asList().getValue().stream()).toList()); } public static Dynamic fold(DList args) { if (args.size() != 3) throw new IllegalArgumentException("Invalid number of arguments for fold: expected at least 3 but got " + args.size()); return args.get(0).asList().getValue().stream().reduce(args.get(1), args.get(2).asCallable()::call); } public static Dynamic forEach(DList args) { if (args.size() != 2) throw new IllegalArgumentException("Invalid number of arguments for forEach: expected at least 2 but got " + args.size()); Dynamic result = new DNull(); DCallable dc = args.get(1).asCallable(); for (Dynamic dynamic : args.get(0).asList().getValue()) { result = dc.call(dynamic); } return result; } }