FunctionRegistry.java 35 KB

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