SnuviUtils.java 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. package me.hammerle.snuviscript.code;
  2. import java.io.File;
  3. import java.io.IOException;
  4. import java.lang.reflect.Array;
  5. import java.nio.charset.MalformedInputException;
  6. import java.nio.file.Files;
  7. import java.util.ArrayList;
  8. import java.util.HashMap;
  9. import java.util.LinkedList;
  10. import java.util.List;
  11. import java.util.Random;
  12. import java.util.regex.Pattern;
  13. import me.hammerle.snuviscript.exceptions.PreScriptException;
  14. public class SnuviUtils
  15. {
  16. private static final Random RANDOM = new Random();
  17. public static int randomInt(int min, int max)
  18. {
  19. return RANDOM.nextInt((max - min) + 1) + min;
  20. }
  21. // - in the number is handled somewhere else
  22. private static final Pattern NUMBER_PATTERN = Pattern.compile("^[-]{0,1}[0-9]*[.]{0,1}[0-9]*");
  23. public static boolean isNumber(String s)
  24. {
  25. return NUMBER_PATTERN.matcher(s).matches();
  26. }
  27. private static final Pattern FUNCTION_PATTERN = Pattern.compile("^[a-zA-Z.]*\\(.*\\)");
  28. public static boolean isFunction(String s)
  29. {
  30. return FUNCTION_PATTERN.matcher(s).matches();
  31. }
  32. private static final Pattern ARRAY_PATTERN = Pattern.compile("^[a-zA-Z][a-zA-Z0-9_]*\\[[^\\]]*\\]");
  33. public static boolean isArray(String s)
  34. {
  35. return ARRAY_PATTERN.matcher(s).matches();
  36. }
  37. public static String toString(double d)
  38. {
  39. if(d == (int) d)
  40. {
  41. return String.valueOf((int) d);
  42. }
  43. return String.valueOf(d);
  44. }
  45. // -------------------------------------------------------------------------
  46. // line splitter
  47. // -------------------------------------------------------------------------
  48. private static void addNonEmptyString(HashMap<String, String> strings, LinkedList<String> list, String s)
  49. {
  50. s = s.trim();
  51. if(!s.isEmpty())
  52. {
  53. if(s.startsWith("#"))
  54. {
  55. String text = strings.get(s);
  56. if(text != null)
  57. {
  58. list.add(text);
  59. return;
  60. }
  61. }
  62. list.add(s);
  63. }
  64. }
  65. private static int findNextClosingBracket(int pos, StringBuilder sb, int line)
  66. {
  67. int brackets = 0;
  68. int length = sb.length();
  69. while(pos < length)
  70. {
  71. switch(sb.charAt(pos))
  72. {
  73. case ')':
  74. brackets--;
  75. if(brackets == 0)
  76. {
  77. return pos;
  78. }
  79. else if(brackets < 0)
  80. {
  81. throw new PreScriptException(") without (", line);
  82. }
  83. break;
  84. case '(':
  85. brackets++;
  86. break;
  87. }
  88. pos++;
  89. }
  90. throw new PreScriptException("( without )", line);
  91. }
  92. private static int findNextClosingSBracket(int pos, StringBuilder sb, int line)
  93. {
  94. int brackets = 0;
  95. int length = sb.length();
  96. while(pos < length)
  97. {
  98. switch(sb.charAt(pos))
  99. {
  100. case ']':
  101. brackets--;
  102. if(brackets == 0)
  103. {
  104. return pos;
  105. }
  106. else if(brackets < 0)
  107. {
  108. throw new PreScriptException("] without [", line);
  109. }
  110. break;
  111. case '[':
  112. brackets++;
  113. break;
  114. }
  115. pos++;
  116. }
  117. throw new PreScriptException("[ without ]", line);
  118. }
  119. public static String[] split(HashMap<String, String> strings, String s, int line)
  120. {
  121. LinkedList<String> list = new LinkedList<>();
  122. int old = 0;
  123. int pos = 0;
  124. StringBuilder sb = new StringBuilder(s);
  125. int length = sb.length();
  126. char c;
  127. while(pos < length)
  128. {
  129. c = sb.charAt(pos);
  130. if(!Character.isLetterOrDigit(c))
  131. {
  132. switch(c)
  133. {
  134. case '_':
  135. case '.':
  136. case '#':
  137. case '$':
  138. case '@':
  139. break;
  140. case ')':
  141. throw new PreScriptException(") without (", line);
  142. case '(':
  143. pos = findNextClosingBracket(pos, sb, line) + 1;
  144. addNonEmptyString(strings, list, sb.substring(old, pos));
  145. old = pos;
  146. continue;
  147. case ']':
  148. throw new PreScriptException("] without [", line);
  149. case '[':
  150. pos = findNextClosingSBracket(pos, sb, line) + 1;
  151. addNonEmptyString(strings, list, sb.substring(old, pos));
  152. old = pos;
  153. continue;
  154. case '\t':
  155. case ' ':
  156. addNonEmptyString(strings, list, sb.substring(old, pos));
  157. old = pos + 1;
  158. pos = old;
  159. continue;
  160. case ',':
  161. addNonEmptyString(strings, list, sb.substring(old, pos));
  162. addNonEmptyString(strings, list, ",");
  163. old = pos + 1;
  164. pos = old;
  165. continue;
  166. default:
  167. addNonEmptyString(strings, list, sb.substring(old, pos));
  168. //System.out.println(old + " " + pos);
  169. old = pos;
  170. pos++;
  171. while(pos <= length && Syntax.getSyntax(sb.substring(old, pos)) != Syntax.UNKNOWN)
  172. {
  173. pos++;
  174. }
  175. pos--;
  176. if(old == pos)
  177. {
  178. throw new PreScriptException("unknown syntax '" + c + "'", line);
  179. }
  180. addNonEmptyString(strings, list, sb.substring(old, pos));
  181. old = pos;
  182. continue;
  183. }
  184. }
  185. pos++;
  186. }
  187. if(old < length)
  188. {
  189. addNonEmptyString(strings, list, sb.substring(old));
  190. }
  191. return list.toArray(new String[list.size()]);
  192. }
  193. public static String getArrayString(Object array)
  194. {
  195. StringBuilder sb = new StringBuilder("[");
  196. int length = Array.getLength(array) - 1;
  197. for(int i = 0; i < length; i++)
  198. {
  199. sb.append(Array.get(array, i));
  200. sb.append(", ");
  201. }
  202. if(length > 0)
  203. {
  204. sb.append(Array.get(array, length));
  205. }
  206. sb.append("]");
  207. return sb.toString();
  208. }
  209. // -------------------------------------------------------------------------
  210. // connectors
  211. // -------------------------------------------------------------------------
  212. public static String connect(Script sc, InputProvider[] c, int skip) throws Exception
  213. {
  214. StringBuilder sb = new StringBuilder();
  215. for(int i = skip; i < c.length; i++)
  216. {
  217. sb.append(c[i].getString(sc));
  218. }
  219. return sb.toString();
  220. }
  221. public static String connect(Script sc, InputProvider[] c, String s, int skip) throws Exception
  222. {
  223. StringBuilder sb = new StringBuilder();
  224. if(skip < c.length)
  225. {
  226. sb.append(c[skip].getString(sc));
  227. }
  228. for(int i = skip + 1; i < c.length; i++)
  229. {
  230. sb.append(s);
  231. sb.append(c[i].getString(sc));
  232. }
  233. return sb.toString();
  234. }
  235. // -------------------------------------------------------------------------
  236. // file stuff
  237. // -------------------------------------------------------------------------
  238. public static List<String> readCode(String ending, String... filenames)
  239. {
  240. LinkedList<List<String>> lists = new LinkedList<>();
  241. List<String> list;
  242. File script;
  243. int lines = 0;
  244. for(String filename : filenames)
  245. {
  246. script = new File("./" + filename + ending);
  247. if(script.exists())
  248. {
  249. try
  250. {
  251. list = Files.readAllLines(script.toPath());
  252. lines += list.size();
  253. lists.add(list);
  254. }
  255. catch (MalformedInputException ex)
  256. {
  257. throw new PreScriptException("'" + script.getPath() + "' contains an illegal character, change file encoding", 0);
  258. }
  259. catch (IOException ex)
  260. {
  261. throw new PreScriptException("file '" + script.getPath() + "' cannot be read", 0);
  262. }
  263. }
  264. else
  265. {
  266. throw new PreScriptException("file '" + script.getPath() + "' does not exist", 0);
  267. }
  268. }
  269. ArrayList<String> mergedList = new ArrayList<>(lines);
  270. lists.forEach(l -> mergedList.addAll(l));
  271. return mergedList;
  272. }
  273. public static List<String> readCode(String filename)
  274. {
  275. return readCode(filename, ".snuvi");
  276. }
  277. }