FunctionRegistry.java 36 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. package me.hammerle.snuviscript.code;
  2. import me.hammerle.snuviscript.inputprovider.InputProvider;
  3. import java.io.File;
  4. import java.nio.charset.StandardCharsets;
  5. import java.lang.reflect.Array;
  6. import java.nio.file.Files;
  7. import java.nio.file.Paths;
  8. import java.time.ZonedDateTime;
  9. import java.util.List;
  10. import java.util.ArrayList;
  11. import java.util.Arrays;
  12. import java.util.Collections;
  13. import java.util.Calendar;
  14. import java.util.GregorianCalendar;
  15. import java.util.HashMap;
  16. import java.util.Map;
  17. import java.util.HashSet;
  18. import java.util.Iterator;
  19. import java.util.Objects;
  20. import java.util.Set;
  21. import java.util.stream.Collectors;
  22. import me.hammerle.snuviscript.config.SnuviConfig;
  23. public class FunctionRegistry
  24. {
  25. private static final HashMap<String, Object> GLOBAL_VARS = new HashMap<>();
  26. private static final HashMap<String, NamedFunction> FUNCTIONS = new HashMap<>();
  27. protected static void registerFunction(String name, String fname, ExceptionBiFunction<Script, InputProvider[], Object> f)
  28. {
  29. FUNCTIONS.put(name, new NamedFunction(fname, f));
  30. }
  31. protected static void registerFunction(String name, ExceptionBiFunction<Script, InputProvider[], Object> f)
  32. {
  33. registerFunction(name, name, f);
  34. }
  35. protected static void registerAlias(String original, String alias)
  36. {
  37. FUNCTIONS.put(alias, FUNCTIONS.get(original));
  38. }
  39. public static NamedFunction getFunction(String f)
  40. {
  41. final String function = f.toLowerCase();
  42. return FUNCTIONS.getOrDefault(function, new NamedFunction(function, (sc, in) ->
  43. {
  44. sc.handleFunction(function, in);
  45. return Void.TYPE;
  46. }));
  47. }
  48. static
  49. {
  50. // ---------------------------------------------------------------------
  51. // system stuff
  52. // ---------------------------------------------------------------------
  53. registerFunction("nothing", (sc, in) -> Void.TYPE);
  54. registerFunction("error", (sc, in) ->
  55. {
  56. sc.setStackTrace(in[0].getBoolean(sc));
  57. return Void.TYPE;
  58. });
  59. registerFunction("", (sc, in) -> in[0].get(sc));
  60. registerFunction("test", (sc, in) ->
  61. {
  62. //sc.getScriptManager().startScript(true, ".sbasic", "./test2");
  63. return Void.TYPE;
  64. });
  65. // ---------------------------------------------------------------------
  66. // event
  67. // ---------------------------------------------------------------------
  68. registerFunction("event.load", (sc, in) ->
  69. {
  70. String event = in[0].getString(sc);
  71. sc.loadEvent(event);
  72. sc.getScriptManager().loadEventSafe(event, sc);
  73. return Void.TYPE;
  74. });
  75. registerFunction("event.unload", (sc, in) ->
  76. {
  77. String event = in[0].getString(sc);
  78. sc.unloadEvent(in[0].getString(sc));
  79. sc.getScriptManager().unloadEventSafe(event, sc);
  80. return Void.TYPE;
  81. });
  82. registerFunction("event.isloaded", (sc, in) -> sc.isEventLoaded(in[0].getString(sc)));
  83. // ---------------------------------------------------------------------
  84. // script
  85. // ---------------------------------------------------------------------
  86. registerFunction("script.get", (sc, in) ->
  87. {
  88. String name = in[0].getString(sc);
  89. for(Script script : sc.getScriptManager().getScripts())
  90. {
  91. if(script.getName().equals(name))
  92. {
  93. return script;
  94. }
  95. }
  96. return null;
  97. });
  98. registerFunction("script.getall", (sc, in) ->
  99. {
  100. String name = in[0].getString(sc);
  101. return sc.getScriptManager().getScripts().stream()
  102. .filter(script -> script.getName().equals(name))
  103. .collect(Collectors.toList());
  104. });
  105. registerFunction("script.term", (sc, in) ->
  106. {
  107. Script other = (Script) in[0].get(sc);
  108. other.term();
  109. sc.getScriptManager().removeScriptSafe(other);
  110. return Void.TYPE;
  111. });
  112. // ---------------------------------------------------------------------
  113. // bit
  114. // ---------------------------------------------------------------------
  115. registerFunction(">>", (sc, in) -> (double) (in[0].getInt(sc) >> in[1].getInt(sc)));
  116. registerFunction("<<", (sc, in) -> (double) (in[0].getInt(sc) << in[1].getInt(sc)));
  117. registerFunction("&", (sc, in) -> (double) (in[0].getInt(sc) & in[1].getInt(sc)));
  118. registerFunction("|", (sc, in) -> (double) (in[0].getInt(sc) | in[1].getInt(sc)));
  119. registerFunction("^", (sc, in) -> (double) (in[0].getInt(sc) ^ in[1].getInt(sc)));
  120. registerFunction("~", (sc, in) -> (double) (~in[0].getInt(sc)));
  121. registerFunction("bit.set", (sc, in) -> (double) (in[0].getInt(sc) | (1 << (in[1].getInt(sc)))));
  122. registerFunction("bit.unset", (sc, in) -> (double) (in[0].getInt(sc) & (~(1 << (in[1].getInt(sc))))));
  123. registerFunction("bit.get", (sc, in) -> (in[0].getInt(sc) & (1 << (in[1].getInt(sc)))) != 0);
  124. // ---------------------------------------------------------------------
  125. // math
  126. // ---------------------------------------------------------------------
  127. registerFunction("%", (sc, in) -> (double) (in[0].getInt(sc) % in[1].getInt(sc)));
  128. registerAlias("%", "math.mod");
  129. registerFunction("math.abs", (sc, in) -> Math.abs(in[0].getDouble(sc)));
  130. registerFunction("math.pow", (sc, in) -> Math.pow(in[0].getDouble(sc), in[1].getDouble(sc)));
  131. registerFunction("math.root", (sc, in) -> Math.pow(in[0].getDouble(sc), 1.0 / in[1].getDouble(sc)));
  132. registerFunction("math.sqrt", (sc, in) -> Math.sqrt(in[0].getDouble(sc)));
  133. registerFunction("math.hypot", (sc, in) -> Math.hypot(in[0].getDouble(sc), in[1].getDouble(sc)));
  134. registerFunction("math.sin", (sc, in) -> Math.sin(in[0].getDouble(sc)));
  135. registerFunction("math.cos", (sc, in) -> Math.cos(in[0].getDouble(sc)));
  136. registerFunction("math.tan", (sc, in) -> Math.tan(in[0].getDouble(sc)));
  137. registerFunction("math.asin", (sc, in) -> Math.asin(in[0].getDouble(sc)));
  138. registerFunction("math.acos", (sc, in) -> Math.acos(in[0].getDouble(sc)));
  139. registerFunction("math.atan", (sc, in) -> Math.atan(in[0].getDouble(sc)));
  140. registerFunction("math.e", (sc, in) -> Math.E);
  141. registerFunction("math.pi", (sc, in) -> Math.PI);
  142. registerFunction("math.ln", (sc, in) -> Math.log(in[0].getDouble(sc)));
  143. registerFunction("math.log", (sc, in) -> Math.log10(in[0].getDouble(sc)));
  144. registerFunction("math.random", (sc, in) -> (double) SnuviUtils.randomInt(in[0].getInt(sc), in[1].getInt(sc)));
  145. registerFunction("math.round", (sc, in) -> (double) Math.round(in[0].getDouble(sc)));
  146. registerFunction("math.rounddown", (sc, in) -> Math.floor(in[0].getDouble(sc)));
  147. registerFunction("math.roundup", (sc, in) -> Math.ceil(in[0].getDouble(sc)));
  148. registerFunction("math.roundcomma", (sc, in) ->
  149. {
  150. double d = in[0].getDouble(sc);
  151. int factor = (int) Math.pow(10, in[1].getInt(sc));
  152. return (double) (((double) Math.round(d * factor)) / factor);
  153. });
  154. // ---------------------------------------------------------------------
  155. // lists
  156. // ---------------------------------------------------------------------
  157. registerFunction("list.new", (sc, in) ->
  158. {
  159. if(in.length == 0)
  160. {
  161. return new ArrayList<>();
  162. }
  163. in[0].set(sc, new ArrayList<>());
  164. return Void.TYPE;
  165. });
  166. registerFunction("list.exists", (sc, in) -> in[0].get(sc) instanceof List);
  167. registerFunction("list.add", (sc, in) -> ((List) in[0].get(sc)).add(in[1].get(sc)));
  168. registerFunction("list.addall", (sc, in) ->
  169. {
  170. List list = ((List) in[0].get(sc));
  171. for(int i = 1; i < in.length; i++)
  172. {
  173. list.add(in[i].get(sc));
  174. }
  175. return Void.TYPE;
  176. });
  177. registerFunction("list.remove", (sc, in) -> ((List) in[0].get(sc)).remove(in[1].get(sc)));
  178. registerFunction("list.removeindex", (sc, in) -> ((List) in[0].get(sc)).remove(in[1].getInt(sc)));
  179. registerFunction("list.contains", (sc, in) -> ((List) in[0].get(sc)).contains(in[1].get(sc)));
  180. registerFunction("list.getsize", (sc, in) -> (double) ((List) in[0].get(sc)).size());
  181. registerFunction("list.getindex", (sc, in) -> ((List) in[0].get(sc)).get(in[1].getInt(sc)));
  182. registerAlias("list.getindex", "list.get");
  183. registerFunction("list.setindex", (sc, in) -> ((List) in[0].get(sc)).set(in[1].getInt(sc), in[2].get(sc)));
  184. registerFunction("list.clear", (sc, in) ->
  185. {
  186. ((List) in[0].get(sc)).clear();
  187. return Void.TYPE;
  188. });
  189. registerFunction("list.getindexof", (sc, in) -> (double) ((List) in[0].get(sc)).indexOf(in[1].get(sc)));
  190. registerFunction("list.sort", (sc, in) ->
  191. {
  192. Collections.sort(((List<Object>) in[0].get(sc)), (Object o1, Object o2) -> ((Comparable) o1).compareTo(o2));
  193. return Void.TYPE;
  194. });
  195. registerFunction("list.reverse", (sc, in) ->
  196. {
  197. Collections.reverse((List<Object>) in[0].get(sc));
  198. return Void.TYPE;
  199. });
  200. registerFunction("list.shuffle", (sc, in) ->
  201. {
  202. Collections.shuffle((List<Object>) in[0].get(sc));
  203. return Void.TYPE;
  204. });
  205. registerFunction("list.iterator", (sc, in) -> ((List) in[0].get(sc)).iterator());
  206. // ---------------------------------------------------------------------
  207. // arrays
  208. // ---------------------------------------------------------------------
  209. registerFunction("array.new", (sc, in) ->
  210. {
  211. if(in.length == 0)
  212. {
  213. throw new ArrayIndexOutOfBoundsException("missing array dimension");
  214. }
  215. int[] dim = new int[in.length];
  216. for(int i = 0; i < in.length; i++)
  217. {
  218. dim[i] = in[i].getInt(sc);
  219. }
  220. return Array.newInstance(Object.class, dim);
  221. });
  222. registerFunction("array.getsize", (sc, in) -> (double) Array.getLength(in[0].get(sc)));
  223. registerAlias("array.getsize", "array.length");
  224. /*
  225. registerFunction("array.swap", (sc, in) ->
  226. {
  227. Object[] o = (Object[]) args[0];
  228. int first = ScriptUtils.getInt(args[1]);
  229. int sec = ScriptUtils.getInt(args[2]);
  230. Object helper = o[first];
  231. o[first] = o[sec];
  232. o[sec] = helper;
  233. });
  234. registerFunction("array.sort", (sc, in) ->
  235. {
  236. if(args.length <= 1)
  237. {
  238. Arrays.sort((Object[]) args[0]);
  239. }
  240. else
  241. {
  242. Arrays.sort((Object[]) args[0], ScriptUtils.getInt(args[1]), ScriptUtils.getInt(args[2]));
  243. }
  244. });
  245. registerFunction("array.copy", (sc, in) ->
  246. {
  247. int first = ScriptUtils.getInt(args[2]);
  248. System.arraycopy((Object[]) args[0], first, (Object[]) args[1],
  249. ScriptUtils.getInt(args[4]), ScriptUtils.getInt(args[3]) - first + 1);
  250. });
  251. registerFunction("array.rsort", (sc, in) ->
  252. {
  253. if(args.length <= 1)
  254. {
  255. Arrays.sort((Object[]) args[0], (Object o, Object o1) -> -((Comparable) o).compareTo(o));
  256. }
  257. else
  258. {
  259. Arrays.sort((Object[]) args[0], ScriptUtils.getInt(args[1]),
  260. ScriptUtils.getInt(args[2]), (Object o, Object o1) -> -((Comparable) o).compareTo(o));
  261. }
  262. });
  263. registerFunction("array.fill", (sc, in) ->
  264. {
  265. if(args.length <= 2)
  266. {
  267. Arrays.fill((Object[]) args[0], args[1]);
  268. }
  269. else
  270. {
  271. Arrays.fill((Object[]) args[0], ScriptUtils.getInt(args[2]), ScriptUtils.getInt(args[3]), args[1]);
  272. }
  273. });*/
  274. // ---------------------------------------------------------------------
  275. // maps
  276. // ---------------------------------------------------------------------
  277. registerFunction("map.new", (sc, in) ->
  278. {
  279. if(in.length == 0)
  280. {
  281. return new HashMap<>();
  282. }
  283. in[0].set(sc, new HashMap<>());
  284. return Void.TYPE;
  285. });
  286. registerFunction("map.exists", (sc, in) -> in[0].get(sc) instanceof Map);
  287. registerFunction("map.add", (sc, in) -> ((Map) in[0].get(sc)).put(in[1].get(sc), in[2].get(sc)));
  288. registerFunction("map.remove", (sc, in) -> ((Map) in[0].get(sc)).remove(in[1].get(sc)));
  289. registerFunction("map.contains", (sc, in) -> ((Map) in[0].get(sc)).containsKey(in[1].get(sc)));
  290. registerFunction("map.getsize", (sc, in) -> (double) ((Map) in[0].get(sc)).size());
  291. registerFunction("map.get", (sc, in) -> ((Map) in[0].get(sc)).get(in[1].get(sc)));
  292. registerFunction("map.getordefault", (sc, in) -> ((Map) in[0].get(sc)).getOrDefault(in[1].get(sc), in[2].get(sc)));
  293. registerFunction("map.clear", (sc, in) ->
  294. {
  295. ((Map) in[0].get(sc)).clear();
  296. return Void.TYPE;
  297. });
  298. registerFunction("map.iterator", (sc, in) -> ((Map) in[0].get(sc)).entrySet().iterator());
  299. registerFunction("map.getkey", (sc, in) -> ((Map.Entry) in[0].get(sc)).getKey());
  300. registerFunction("map.getvalue", (sc, in) -> ((Map.Entry) in[0].get(sc)).getValue());
  301. registerFunction("map.setvalue", (sc, in) -> ((Map.Entry) in[0].get(sc)).setValue(in[1].get(sc)));
  302. // ---------------------------------------------------------------------
  303. // sets
  304. // ---------------------------------------------------------------------
  305. registerFunction("set.new", (sc, in) ->
  306. {
  307. if(in.length == 0)
  308. {
  309. return new HashSet<>();
  310. }
  311. in[0].set(sc, new HashSet<>());
  312. return Void.TYPE;
  313. });
  314. registerFunction("set.exists", (sc, in) -> in[0].get(sc) instanceof Set);
  315. registerFunction("set.add", (sc, in) -> ((Set) in[0].get(sc)).add(in[1].get(sc)));
  316. registerFunction("set.addall", (sc, in) ->
  317. {
  318. Set set = ((Set) in[0].get(sc));
  319. for(int i = 1; i < in.length; i++)
  320. {
  321. set.add(in[i].get(sc));
  322. }
  323. return Void.TYPE;
  324. });
  325. registerFunction("set.remove", (sc, in) -> ((Set) in[0].get(sc)).remove(in[1].get(sc)));
  326. registerFunction("set.contains", (sc, in) -> ((Set) in[0].get(sc)).contains(in[1].get(sc)));
  327. registerFunction("set.getsize", (sc, in) -> (double) ((Set) in[0].get(sc)).size());
  328. registerFunction("set.clear", (sc, in) ->
  329. {
  330. ((Set) in[0].get(sc)).clear();
  331. return Void.TYPE;
  332. });
  333. registerFunction("set.iterator", (sc, in) -> ((Set) in[0].get(sc)).iterator());
  334. // ---------------------------------------------------------------------
  335. // time
  336. // ---------------------------------------------------------------------
  337. registerFunction("time.new", (sc, in) ->
  338. {
  339. if(in.length <= 1)
  340. {
  341. GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
  342. cal.setTimeInMillis(in[0].getLong(sc));
  343. return cal;
  344. }
  345. else
  346. {
  347. GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
  348. cal.setTimeInMillis(in[1].getLong(sc));
  349. in[0].set(sc, cal);
  350. return Void.TYPE;
  351. }
  352. });
  353. registerFunction("time.getmillis", (sc, in) -> (double) System.currentTimeMillis());
  354. registerFunction("time.getnanos", (sc, in) -> (double) System.nanoTime());
  355. registerFunction("time.from", (sc, in) -> (double) ((GregorianCalendar) in[0].get(sc)).getTimeInMillis());
  356. registerFunction("time.nextday", (sc, in) ->
  357. {
  358. GregorianCalendar cal = (GregorianCalendar) in[0].get(sc);
  359. cal.add(Calendar.DAY_OF_YEAR, 1);
  360. cal.set(Calendar.HOUR_OF_DAY, 0);
  361. cal.set(Calendar.SECOND, 0);
  362. cal.set(Calendar.MINUTE, 0);
  363. cal.set(Calendar.MILLISECOND, 0);
  364. return Void.TYPE;
  365. });
  366. registerFunction("time.getyear", (sc, in) -> (double) ((GregorianCalendar) in[0].get(sc)).get(Calendar.YEAR));
  367. registerFunction("time.getmonth", (sc, in) -> (double) (((GregorianCalendar) in[0].get(sc)).get(Calendar.MONTH) + 1));
  368. registerFunction("time.getday", (sc, in) -> (double) (((GregorianCalendar) in[0].get(sc)).get(Calendar.DAY_OF_MONTH)));
  369. registerFunction("time.gethour", (sc, in) -> (double) ((GregorianCalendar) in[0].get(sc)).get(Calendar.HOUR_OF_DAY));
  370. registerFunction("time.getminute", (sc, in) -> (double) ((GregorianCalendar) in[0].get(sc)).get(Calendar.MINUTE));
  371. registerFunction("time.getsecond", (sc, in) -> (double) ((GregorianCalendar) in[0].get(sc)).get(Calendar.SECOND));
  372. // ---------------------------------------------------------------------
  373. // text
  374. // ---------------------------------------------------------------------
  375. registerFunction("text.matches", (sc, in) -> in[0].getString(sc).matches(in[1].getString(sc)));
  376. registerFunction("text.number", (sc, in) -> SnuviUtils.toString(in[0].getDouble(sc)));
  377. registerFunction("text.class", (sc, in) -> in[0].get(sc).getClass().getSimpleName());
  378. registerFunction("text.tolowercase", (sc, in) -> SnuviUtils.connect(sc, in, 0).toLowerCase());
  379. registerAlias("text.tolowercase", "tolowercase");
  380. registerFunction("text.touppercase", (sc, in) -> SnuviUtils.connect(sc, in, 0).toUpperCase());
  381. registerAlias("text.touppercase", "touppercase");
  382. registerFunction("text.split", (sc, in) ->
  383. {
  384. if(in.length <= 2)
  385. {
  386. String[] parts = in[1].getString(sc).split(in[0].getString(sc));
  387. ArrayList<Object> list = new ArrayList<>();
  388. for(String part : parts)
  389. {
  390. list.add(SnuviUtils.convert(part));
  391. }
  392. return list;
  393. }
  394. else
  395. {
  396. String[] parts = in[2].getString(sc).split(in[1].getString(sc));
  397. ArrayList<Object> list = new ArrayList<>();
  398. for(String part : parts)
  399. {
  400. list.add(SnuviUtils.convert(part));
  401. }
  402. in[0].set(sc, list);
  403. return Void.TYPE;
  404. }
  405. });
  406. registerAlias("text.split", "split");
  407. registerFunction("text.concatlist", (sc, in) ->
  408. {
  409. StringBuilder sb = new StringBuilder();
  410. List<Object> list = (List<Object>) in[0].get(sc);
  411. String splitter = in[1].getString(sc);
  412. Iterator<Object> iter = list.iterator();
  413. int from = in[2].getInt(sc);
  414. int to = Math.min(in[3].getInt(sc), list.size() - 1);
  415. to -= from;
  416. while(iter.hasNext() && from > 0)
  417. {
  418. iter.next();
  419. from--;
  420. }
  421. while(iter.hasNext() && to > 0)
  422. {
  423. sb.append(iter.next());
  424. sb.append(splitter);
  425. to--;
  426. }
  427. if(iter.hasNext() && to == 0)
  428. {
  429. sb.append(iter.next());
  430. }
  431. return sb.toString();
  432. });
  433. registerAlias("text.concatlist", "concatlist");
  434. registerFunction("text.concat", (sc, in) -> SnuviUtils.connect(sc, in, 0));
  435. registerAlias("text.concat", "concat");
  436. registerFunction("text.concatspace", (sc, in) -> SnuviUtils.connect(sc, in, " ", 0));
  437. registerFunction("text", (sc, in) -> String.valueOf(in[0].get(sc)));
  438. registerFunction("text.substring", (sc, in) -> in[0].getString(sc).substring(in[1].getInt(sc), in[2].getInt(sc)));
  439. registerFunction("text.length", (sc, in) -> (double) in[0].getString(sc).length());
  440. registerFunction("text.startswith", (sc, in) -> in[0].getString(sc).startsWith(in[1].getString(sc), in[2].getInt(sc)));
  441. registerFunction("text.endswith", (sc, in) -> in[0].getString(sc).endsWith(in[1].getString(sc)));
  442. registerFunction("text.contains", (sc, in) -> in[0].getString(sc).contains(in[1].getString(sc)));
  443. registerFunction("text.indexof", (sc, in) -> (double) in[0].getString(sc).indexOf(in[1].getString(sc), in[2].getInt(sc)));
  444. registerFunction("text.lastindexof", (sc, in) -> (double) in[0].getString(sc).lastIndexOf(in[1].getString(sc), in[2].getInt(sc)));
  445. registerFunction("text.replace", (sc, in) -> in[0].getString(sc).replace(in[1].getString(sc), in[2].getString(sc)));
  446. registerFunction("text.trim", (sc, in) -> in[0].getString(sc).trim());
  447. registerFunction("text.charat", (sc, in) -> String.valueOf(in[0].getString(sc).charAt(in[1].getInt(sc))));
  448. registerFunction("text.charcode", (sc, in) -> (double) in[0].getString(sc).charAt(in[1].getInt(sc)));
  449. registerFunction("text.fromcode", (sc, in) -> String.valueOf((char) in[0].getInt(sc)));
  450. registerFunction("text.onlyletters", (sc, in) ->
  451. {
  452. for(char c : in[0].getString(sc).toCharArray())
  453. {
  454. if(!Character.isLetter(c))
  455. {
  456. return false;
  457. }
  458. }
  459. return true;
  460. });
  461. // -------------------------------------------------------------------------------
  462. // files
  463. // -------------------------------------------------------------------------------
  464. registerFunction("file.new", (sc, in) -> new File(in[0].getString(sc)));
  465. registerFunction("file.exists", (sc, in) -> ((File) in[0].get(sc)).exists());
  466. registerFunction("file.isfile", (sc, in) -> ((File) in[0].get(sc)).isFile());
  467. registerFunction("file.isdirectory", (sc, in) -> ((File) in[0].get(sc)).isDirectory());
  468. registerFunction("file.delete", (sc, in) -> ((File) in[0].get(sc)).delete());
  469. registerFunction("file.getname", (sc, in) -> ((File) in[0].get(sc)).getName());
  470. registerFunction("file.getlist", (sc, in) -> Arrays.asList(((File) in[0].get(sc)).listFiles()));
  471. registerFunction("file.read", (sc, in) -> Files.readAllLines(((File) in[0].get(sc)).toPath()));
  472. registerFunction("file.write", (sc, in) ->
  473. {
  474. File f = (File) in[0].get(sc);
  475. if(f.getParentFile() != null)
  476. {
  477. f.getParentFile().mkdirs();
  478. }
  479. if(!f.exists())
  480. {
  481. f.createNewFile();
  482. }
  483. Files.write(Paths.get(f.toURI()), ((List<Object>) in[1].get(sc))
  484. .stream().map(o -> String.valueOf(o)).collect(Collectors.toList()), StandardCharsets.UTF_8);
  485. return Void.TYPE;
  486. });
  487. // ---------------------------------------------------------------------
  488. // config
  489. // ---------------------------------------------------------------------
  490. registerFunction("config.new", (sc, in) -> new SnuviConfig(sc, in[0].getString(sc), in[1].getString(sc)));
  491. registerFunction("config.exists", (sc, in) -> ((SnuviConfig) in[0].get(sc)).exists());
  492. registerFunction("config.save", (sc, in) -> ((SnuviConfig) in[0].get(sc)).save());
  493. registerFunction("config.load", (sc, in) ->
  494. {
  495. ((SnuviConfig) in[0].get(sc)).load();
  496. return Void.TYPE;
  497. });
  498. registerFunction("config.delete", (sc, in) -> ((SnuviConfig) in[0].get(sc)).delete());
  499. registerFunction("config.set", (sc, in) ->
  500. {
  501. ((SnuviConfig) in[0].get(sc)).set(in[1].getString(sc), in[2].get(sc));
  502. return Void.TYPE;
  503. });
  504. registerFunction("config.getbool", (sc, in) -> ((SnuviConfig) in[0].get(sc)).getBoolean(in[1].getString(sc), in[2].getBoolean(sc)));
  505. registerFunction("config.getdouble", (sc, in) -> ((SnuviConfig) in[0].get(sc)).getDouble(in[1].getString(sc), in[2].getDouble(sc)));
  506. registerFunction("config.getstring", (sc, in) -> ((SnuviConfig) in[0].get(sc)).getString(in[1].getString(sc), in[2].getString(sc)));
  507. // ---------------------------------------------------------------------
  508. // read library
  509. // ---------------------------------------------------------------------
  510. registerFunction("read.number", (sc, in) -> Double.parseDouble(in[0].getString(sc)));
  511. // ---------------------------------------------------------------------
  512. // commands without library
  513. // ---------------------------------------------------------------------
  514. // elementary calculating
  515. registerFunction("+", (sc, in) -> in[0].getDouble(sc) + in[1].getDouble(sc));
  516. registerAlias("+", "add");
  517. registerFunction("-", (sc, in) -> in.length == 1 ? -in[0].getDouble(sc) : in[0].getDouble(sc) - in[1].getDouble(sc));
  518. registerAlias("-", "sub");
  519. registerFunction("*", (sc, in) -> in[0].getDouble(sc) * in[1].getDouble(sc));
  520. registerAlias("*", "mul");
  521. registerFunction("/", (sc, in) -> in[0].getDouble(sc) / in[1].getDouble(sc));
  522. registerAlias("/", "div");
  523. // var setter
  524. registerFunction("=", (sc, in) ->
  525. {
  526. Object o = in[1].get(sc);
  527. in[0].set(sc, o);
  528. return o;
  529. });
  530. registerFunction("+=", (sc, in) ->
  531. {
  532. Object o = in[0].getDouble(sc) + in[1].getDouble(sc);
  533. in[0].set(sc, o);
  534. return o;
  535. });
  536. registerFunction("p++", (sc, in) ->
  537. {
  538. double d = in[0].getDouble(sc);
  539. in[0].set(sc, d + 1.0);
  540. return d;
  541. });
  542. registerAlias("p++", "inc");
  543. registerFunction("++", (sc, in) ->
  544. {
  545. double d = in[0].getDouble(sc) + 1.0;
  546. in[0].set(sc, d);
  547. return d;
  548. });
  549. registerFunction("-=", (sc, in) ->
  550. {
  551. Object o = in[0].getDouble(sc) - in[1].getDouble(sc);
  552. in[0].set(sc, o);
  553. return o;
  554. });
  555. registerFunction("p--", (sc, in) ->
  556. {
  557. double d = in[0].getDouble(sc);
  558. in[0].set(sc, d - 1.0);
  559. return d;
  560. });
  561. registerAlias("p--", "dec");
  562. registerFunction("--", (sc, in) ->
  563. {
  564. double d = in[0].getDouble(sc) - 1.0;
  565. in[0].set(sc, d);
  566. return d;
  567. });
  568. registerFunction("*=", (sc, in) ->
  569. {
  570. Object o = in[0].getDouble(sc) * in[1].getDouble(sc);
  571. in[0].set(sc, o);
  572. return o;
  573. });
  574. registerFunction("/=", (sc, in) ->
  575. {
  576. Object o = in[0].getDouble(sc) / in[1].getDouble(sc);
  577. in[0].set(sc, o);
  578. return o;
  579. });
  580. registerFunction("%=", (sc, in) ->
  581. {
  582. Object o = (double) (in[0].getInt(sc) % in[1].getInt(sc));
  583. in[0].set(sc, o);
  584. return o;
  585. });
  586. registerFunction("<<=", (sc, in) ->
  587. {
  588. Object o = (double) (in[0].getInt(sc) << in[1].getInt(sc));
  589. in[0].set(sc, o);
  590. return o;
  591. });
  592. registerFunction(">>=", (sc, in) ->
  593. {
  594. Object o = (double) (in[0].getInt(sc) >> in[1].getInt(sc));
  595. in[0].set(sc, o);
  596. return o;
  597. });
  598. registerFunction("&=", (sc, in) ->
  599. {
  600. Object o = (double) (in[0].getInt(sc) & in[1].getInt(sc));
  601. in[0].set(sc, o);
  602. return o;
  603. });
  604. registerFunction("^=", (sc, in) ->
  605. {
  606. Object o = (double) (in[0].getInt(sc) ^ in[1].getInt(sc));
  607. in[0].set(sc, o);
  608. return o;
  609. });
  610. registerFunction("|=", (sc, in) ->
  611. {
  612. Object o = (double) (in[0].getInt(sc) | in[1].getInt(sc));
  613. in[0].set(sc, o);
  614. return o;
  615. });
  616. // var stuff
  617. registerFunction("getvar", (sc, in) -> sc.getVar(in[0].getString(sc)).get(sc));
  618. registerFunction("setvar", (sc, in) ->
  619. {
  620. sc.getVar(in[0].getString(sc)).set(sc, in[1].get(sc));
  621. return Void.TYPE;
  622. });
  623. registerFunction("removevar", (sc, in) ->
  624. {
  625. sc.getVar(in[0].getString(sc)).set(sc, null);
  626. return Void.TYPE;
  627. });
  628. registerFunction("wait", (sc, in) ->
  629. {
  630. sc.setWaiting();
  631. return Void.TYPE;
  632. });
  633. // branching
  634. registerFunction("goto", (sc, in) ->
  635. {
  636. sc.gotoLabel(in[0].getString(sc), true);
  637. return Void.TYPE;
  638. });
  639. registerFunction("ignoregoto", (sc, in) ->
  640. {
  641. sc.gotoLabel(in[0].getString(sc), false);
  642. return Void.TYPE;
  643. });
  644. registerAlias("ignoregoto", "igoto");
  645. registerFunction("sgoto", (sc, in) ->
  646. {
  647. int time = in[0].getInt(sc);
  648. if(time < 0)
  649. {
  650. throw new IllegalArgumentException("time units can't be negative");
  651. }
  652. String label = in[1].getString(sc);
  653. sc.getScriptManager().getScheduler().scheduleTask(() ->
  654. {
  655. if(sc.shouldTerm() || sc.isHolded())
  656. {
  657. return;
  658. }
  659. sc.gotoLabel(label, true, 1);
  660. sc.run();
  661. if(sc.shouldTerm())
  662. {
  663. sc.getScriptManager().removeScriptSafe(sc);
  664. }
  665. }, time);
  666. return Void.TYPE;
  667. });
  668. registerFunction("gosub", (sc, in) ->
  669. {
  670. sc.goSub(in[0].getString(sc));
  671. return Void.TYPE;
  672. });
  673. // comparing
  674. registerFunction("==", (sc, in) -> Objects.equals(in[0].get(sc), in[1].get(sc)));
  675. registerAlias("==", "equal");
  676. registerAlias("==", "equals");
  677. registerFunction("!=", (sc, in) -> !Objects.equals(in[0].get(sc), in[1].get(sc)));
  678. registerAlias("!=", "notequal");
  679. registerFunction("<", (sc, in) -> ((Comparable) in[0].get(sc)).compareTo(in[1].get(sc)) < 0);
  680. registerAlias("<", "less");
  681. registerFunction(">", (sc, in) -> ((Comparable) in[0].get(sc)).compareTo(in[1].get(sc)) > 0);
  682. registerAlias(">", "greater");
  683. registerFunction("<=", (sc, in) -> ((Comparable) in[0].get(sc)).compareTo(in[1].get(sc)) <= 0);
  684. registerAlias("<=", "lessequal");
  685. registerFunction(">=", (sc, in) -> ((Comparable) in[0].get(sc)).compareTo(in[1].get(sc)) >= 0);
  686. registerAlias(">=", "greaterequal");
  687. registerFunction("!", (sc, in) -> !in[0].getBoolean(sc));
  688. registerAlias("!", "invert");
  689. // logical stuff
  690. registerFunction("&&", (sc, in) ->
  691. {
  692. for(InputProvider i : in)
  693. {
  694. if(!i.getBoolean(sc))
  695. {
  696. return false;
  697. }
  698. }
  699. return true;
  700. });
  701. registerAlias("&&", "and");
  702. registerFunction("||", (sc, in) ->
  703. {
  704. for(InputProvider i : in)
  705. {
  706. if(i.getBoolean(sc))
  707. {
  708. return true;
  709. }
  710. }
  711. return false;
  712. });
  713. registerAlias( "||", "or");
  714. // non grouped stuff
  715. registerFunction("getscriptvar", (sc, in) -> GLOBAL_VARS.get(in[0].getString(sc)));
  716. registerFunction("setscriptvar", (sc, in) -> GLOBAL_VARS.put(in[0].getString(sc), in[1].get(sc)));
  717. registerFunction("delscriptvar", (sc, in) -> GLOBAL_VARS.remove(in[0].getString(sc)));
  718. registerFunction("hasnext", (sc, in) -> ((Iterator) in[0].get(sc)).hasNext());
  719. registerFunction("next", (sc, in) -> ((Iterator) in[0].get(sc)).next());
  720. registerFunction("swap", (sc, in) ->
  721. {
  722. Object o = in[0].get(sc);
  723. in[0].set(sc, in[1].get(sc));
  724. in[1].set(sc, o);
  725. return Void.TYPE;
  726. });
  727. registerFunction("print", (sc, in) ->
  728. {
  729. sc.getScriptManager().getLogger().print(SnuviUtils.connect(sc, in, 0), null, "print", sc.getName(), sc, sc.getActiveSourceLine());
  730. return Void.TYPE;
  731. });
  732. registerFunction("rprint", (sc, in) ->
  733. {
  734. System.out.println(SnuviUtils.connect(sc, in, 0));
  735. return Void.TYPE;
  736. });
  737. registerFunction("waitfor", (sc, in) ->
  738. {
  739. long l = in[0].getInt(sc);
  740. if(l < 0)
  741. {
  742. throw new IllegalArgumentException("time units can't be negative");
  743. }
  744. sc.setHolded(true);
  745. sc.setWaiting();
  746. sc.getScriptManager().getScheduler().scheduleTask(() ->
  747. {
  748. if(sc.shouldTerm())
  749. {
  750. return;
  751. }
  752. sc.setHolded(false);
  753. sc.run();
  754. if(sc.shouldTerm())
  755. {
  756. sc.getScriptManager().removeScriptSafe(sc);
  757. }
  758. }, l);
  759. return Void.TYPE;
  760. });
  761. registerFunction("term", (sc, in) ->
  762. {
  763. sc.term();
  764. sc.getScriptManager().removeScriptSafe(sc);
  765. return Void.TYPE;
  766. });
  767. registerFunction("isdouble", (sc, in) ->
  768. {
  769. return in[0].get(sc) instanceof Double;
  770. });
  771. registerFunction("islong", (sc, in) ->
  772. {
  773. Object o = in[0].get(sc);
  774. if(o instanceof Double)
  775. {
  776. double d = (Double) o;
  777. return d == (long) d;
  778. }
  779. return false;
  780. });
  781. registerFunction("assert", (sc, in) ->
  782. {
  783. if(!in[0].getBoolean(sc))
  784. {
  785. throw new IllegalArgumentException("assertion failed");
  786. }
  787. return Void.TYPE;
  788. });
  789. registerFunction("class", (sc, in) -> in[0].get(sc).getClass());
  790. registerFunction("usedmemory", (sc, in) ->
  791. {
  792. Runtime runtime = Runtime.getRuntime();
  793. double usedMemory = (runtime.totalMemory() - runtime.freeMemory()) / 1048576;
  794. return usedMemory;
  795. });
  796. registerFunction("allocatedmemory", (sc, in) -> Runtime.getRuntime().totalMemory() / 1048576.0);
  797. }
  798. }