SnuviUtils.java 9.4 KB

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