| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951 | 
							- package me.hammerle.code;
 
- import java.util.ArrayList;
 
- import java.util.HashMap;
 
- import java.util.Map.Entry;
 
- import java.util.Stack;
 
- import java.util.TreeSet;
 
- import me.hammerle.exceptions.PreScriptException;
 
- import me.hammerle.exceptions.NoSuchMethodException;
 
- public class Code implements Comparable<Code>
 
- {
 
-     protected final int realLine;
 
-     protected final int line;
 
-     private int subline;
 
-     
 
-     private final String function;
 
-     private final int level;
 
-     private final int pars;
 
-     
 
-     private final Object value;
 
-     private int jump;
 
-     
 
-     private Code(String function, int level, int pars, int line, int subline, Object value, int jump, int realLine)
 
-     {
 
-         this.function = function;
 
-         this.level = level;
 
-         this.pars = pars;
 
-         this.line = line;
 
-         this.subline = subline;
 
-         this.value = value;
 
-         this.jump = jump;
 
-         this.realLine = realLine;
 
-     }
 
-     
 
-     public Code(String function, int level, int pars, int line, int subline, int realLine)
 
-     {
 
-         this(function.trim(), level, pars, line, subline, null, 0, realLine);
 
-     }
 
-     
 
-     public Code(int level, int pars, int line, int subline, Object value, int realLine)
 
-     {
 
-         this(null, level, pars, line, subline, value, 0, realLine);
 
-     }
 
-     
 
-     public void executeFunction(SnuviParser parser, Script sc, Stack<Object> stack)
 
-     {
 
-         //System.out.println("Executing: " + this.toString());
 
-         if(value != null)
 
-         {
 
-             if(value.getClass() == Variable.class)
 
-             {
 
-                 stack.push(sc.getVar(((Variable) value).getName()));
 
-                 return;
 
-             }
 
-             stack.push(value);
 
-             return;
 
-         }
 
-         else if(value == null && function == null)
 
-         {
 
-             stack.push(value);
 
-             return;
 
-         }
 
-         Object[] input;
 
-         if(pars > 0)
 
-         {
 
-             input = new Object[pars];
 
-             for(int i = 0; i < pars; i++)
 
-             {
 
-                 input[i] = stack.pop();
 
-             }
 
-         }
 
-         else
 
-         {
 
-             input = new Object[0];
 
-         }
 
-         Object output = parser.parseFunction(sc, function, input);
 
-         if(output != Void.TYPE)
 
-         {
 
-             stack.push(output);
 
-         }
 
-     }
 
-     
 
-     public String getFunction()
 
-     {
 
-         return function;
 
-     }
 
-     @Override
 
-     public String toString() 
 
-     {
 
-         StringBuilder sb = new StringBuilder(">");
 
-         for(int i = 1; i < level; i++)
 
-         {
 
-             sb.append(">");
 
-         }
 
-         sb.append(" (");
 
-         sb.append(line);
 
-         sb.append(",");
 
-         sb.append(subline);
 
-         sb.append(") ");
 
-         
 
-         if(value != null)
 
-         {
 
-             sb.append("push ");
 
-             sb.append(value.getClass().getSimpleName());
 
-             sb.append(" '");
 
-             sb.append(value);
 
-             sb.append("'");
 
-             return sb.toString();
 
-         }
 
-         else if(value == null && function == null)
 
-         {
 
-             sb.append("push Null '");
 
-             sb.append(value);
 
-             sb.append("'");
 
-             return sb.toString();
 
-         }
 
-         
 
-         sb.append("function ");
 
-         sb.append(function);
 
-         sb.append(" (");
 
-         for(int i = 0; i < pars; i++)
 
-         {
 
-             sb.append("X,");
 
-         }
 
-         if(pars > 0)
 
-         {
 
-             sb.deleteCharAt(sb.length() - 1);
 
-         }
 
-         sb.append(")");
 
-         if(jump != 0)
 
-         {
 
-             sb.append(" (");
 
-             sb.append(jump);
 
-             sb.append(")");
 
-         }
 
-         return sb.toString();
 
-     }
 
-     
 
-     @Override
 
-     public int compareTo(Code o) 
 
-     {
 
-         int i = Integer.compare(line, o.line);
 
-         if(i == 0)
 
-         {
 
-             return Integer.compare(o.subline, subline);
 
-         }
 
-         return i;
 
-     }
 
-     
 
-     public int getJumpLine()
 
-     {
 
-         return jump;
 
-     }
 
-     
 
-     // -----------------------------------------------------------------------------------
 
-     // code builder
 
-     // -----------------------------------------------------------------------------------
 
-     
 
-     private static SnuviParser parser = null;
 
-     private static String scriptName = null;
 
-     private static int sublines = 0;
 
-     private static int realLines = 0;
 
-     private static HashMap<String, String> strings;
 
-     
 
-     private static int findEndOfLine(String code, int pos)
 
-     {
 
-         int start = pos;
 
-         int length = code.length();
 
-         while(pos < length)
 
-         {
 
-             switch(code.charAt(pos))
 
-             {
 
-                 case ';':
 
-                 case '{':
 
-                 case '}':
 
-                     return pos;
 
-             }
 
-             pos++;
 
-         }
 
-         return start;
 
-     }
 
-     
 
-     private static int findStartOfSyntax(StringBuilder code, int pos)
 
-     {
 
-         int bracketCounter = 0;
 
-         while(pos >= 0 && code.charAt(pos) == ' ')
 
-         {
 
-             pos--;
 
-         }
 
-         while(pos >= 0)
 
-         {
 
-             switch(code.charAt(pos))
 
-             {
 
-                 case ';':
 
-                 case '{':
 
-                 case '}':
 
-                     if(bracketCounter != 0)
 
-                     {
 
-                         throw new PreScriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
 
-                     }
 
-                     return pos + 1;
 
-                 case ' ':
 
-                 case '+':
 
-                 case '-':
 
-                 case '*':
 
-                 case '/':
 
-                 case '^':
 
-                 case '@':
 
-                 case '=':
 
-                 case '>':
 
-                 case '<':
 
-                 case '!':
 
-                 case '%':
 
-                 case ',':
 
-                 case '&':
 
-                 case '|':
 
-                     if(bracketCounter != 0)
 
-                     {
 
-                         break;
 
-                     }
 
-                     return pos + 1;
 
-                 case ')':
 
-                     bracketCounter++;
 
-                     break;
 
-                 case '(':
 
-                     if(bracketCounter == 0)
 
-                     {
 
-                         return pos + 1;
 
-                     }
 
-                     bracketCounter--;
 
-                     break;
 
-             }
 
-             pos--;
 
-         }
 
-         return 0;
 
-     }
 
-     
 
-     private static int findEndOfSyntax(StringBuilder code, int pos)
 
-     {
 
-         return findEndOfSyntax(code, pos, false);
 
-     }
 
-     
 
-     private static int findEndOfSyntax(StringBuilder code, int pos, boolean b)
 
-     {
 
-         int bracketCounter = 0;
 
-         char c;
 
-         while(pos < code.length() && code.charAt(pos) == ' ')
 
-         {
 
-             pos++;
 
-         }
 
-         while(pos < code.length())
 
-         {
 
-             c = code.charAt(pos);
 
-             if(b && c == '\n')
 
-             {
 
-                 if(bracketCounter != 0)
 
-                 {
 
-                     pos++;
 
-                     continue;
 
-                 }
 
-                 return pos;
 
-             }
 
-             switch(c)
 
-             {
 
-                 case ';':
 
-                 case '{':
 
-                 case '}':
 
-                     if(bracketCounter != 0)
 
-                     {
 
-                         throw new PreScriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
 
-                     }
 
-                     return pos;
 
-                 case ' ':
 
-                 case '+':
 
-                 case '-':
 
-                 case '*':
 
-                 case '/':
 
-                 case '^':
 
-                 case '@':
 
-                 case '=':
 
-                 case '>':
 
-                 case '<':
 
-                 case '!':
 
-                 case '%':
 
-                 case ',':
 
-                 case '&':
 
-                 case '|':
 
-                     if(bracketCounter != 0)
 
-                     {
 
-                         break;
 
-                     }
 
-                     return pos;
 
-                 case '(':
 
-                     bracketCounter++;
 
-                     break;
 
-                 case ')':
 
-                     if(bracketCounter == 0)
 
-                     {
 
-                         return pos;
 
-                     }
 
-                     bracketCounter--;
 
-                     break;
 
-             }
 
-             pos++;
 
-         }
 
-         return code.length();
 
-     }
 
-     
 
-     private static int findChar(char c, StringBuilder code, int pos)
 
-     {
 
-         int length = code.length();
 
-         while(pos < length)
 
-         {
 
-             if(code.charAt(pos) == c) 
 
-             {
 
-                 return pos;
 
-             }
 
-             pos++;
 
-         }
 
-         return -1;
 
-     }
 
-     
 
-     private static int findSyntax(String find, StringBuilder code, int pos)
 
-     {
 
-         int length = code.length();
 
-         int add = find.length() + 1;
 
-         String s;
 
-         while(pos < length)
 
-         {
 
-             s = code.substring(pos, Math.min(pos + add, length));
 
-             // additionel check for e.g. difference between + and +=
 
-             if(s.startsWith(find) && !s.startsWith(find + "=") && code.charAt(pos - 1) != '=') 
 
-             {
 
-                 return pos;
 
-             }
 
-             pos++;
 
-         }
 
-         return -1;
 
-     }
 
-     
 
-     private static int findSyntaxIgnoreString(String find, StringBuilder code, int pos)
 
-     {
 
-         int length = code.length();
 
-         int add = find.length() + 1;
 
-         char c;
 
-         boolean text = false;
 
-         String s;
 
-         while(pos < length)
 
-         {
 
-             c = code.charAt(pos);
 
-             if(text && c != '"')
 
-             {
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             if(c == '"')
 
-             {
 
-                 text = !text;
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             s = code.substring(pos, Math.min(pos + add, length));
 
-             // additionel check for e.g. difference between + and +=
 
-             if(s.startsWith(find) && !s.startsWith(find + "=") && code.charAt(pos - 1) != '=') 
 
-             {
 
-                 return pos;
 
-             }
 
-             pos++;
 
-         }
 
-         return -1;
 
-     }
 
-     
 
-     private static void changeBiSyntax(String syntax, String f, StringBuilder sb, boolean b)
 
-     {
 
-         int pos = -1;
 
-         int end;
 
-         int start;
 
-         int slength = syntax.length();
 
-         StringBuilder newSyntax;
 
-         while(pos < sb.length())
 
-         {
 
-             pos = findSyntax(syntax, sb, pos + 1);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             start = findStartOfSyntax(sb, pos - 1);
 
-             end = findEndOfSyntax(sb, pos + slength);
 
-             newSyntax = new StringBuilder(f);
 
-             newSyntax.append("(");
 
-             if(b)
 
-             {
 
-                 newSyntax.append("\"");
 
-             }
 
-             newSyntax.append(sb.substring(start, pos).trim());
 
-             if(b)
 
-             {
 
-                 newSyntax.append("\"");
 
-             }
 
-             if(end > pos)
 
-             {
 
-                 newSyntax.append(",");
 
-                 newSyntax.append(sb.substring(pos + slength, end).trim());
 
-             }
 
-             newSyntax.append(")");
 
-             pos -= end - start - newSyntax.length();
 
-             //System.out.println(sb.substring(start, end) + "   ===>    " + newSyntax);
 
-             sb.replace(start, end, newSyntax.toString());    
 
-         }
 
-     }
 
-     
 
-     private static void changeUnSyntax(String syntax, String f, StringBuilder sb)
 
-     {
 
-         int pos = -1;
 
-         int end;
 
-         int start;
 
-         int slength = syntax.length();
 
-         String first;
 
-         StringBuilder newSyntax;
 
-         while(pos < sb.length())
 
-         {
 
-             pos = findSyntax(syntax, sb, pos + 1);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             start = findStartOfSyntax(sb, pos - 1);
 
-             end = findEndOfSyntax(sb, pos + slength);
 
-             newSyntax = new StringBuilder("setvar(\"");
 
-             first = sb.substring(start, pos).trim();
 
-             newSyntax.append(first);
 
-             newSyntax.append("\",");
 
-             newSyntax.append(f);
 
-             newSyntax.append("(");
 
-             newSyntax.append(first);
 
-             newSyntax.append(",");
 
-             newSyntax.append(sb.substring(pos + slength, end).trim());
 
-             newSyntax.append("))");
 
-             pos -= end - start - newSyntax.length();
 
-             sb.replace(start, end, newSyntax.toString());
 
-         }
 
-     }
 
-     
 
-     private static String replaceChar(char find, char replacement, String code)
 
-     {
 
-         return code.replace(find, replacement);
 
-     }
 
-     
 
-     private static int countChar(char find, String code)
 
-     {
 
-         int counter = 0;
 
-         int pos = 0;
 
-         while(pos < code.length())
 
-         {
 
-             if(code.charAt(pos) == find)
 
-             {
 
-                 counter++;
 
-             }
 
-             pos++;
 
-         }
 
-         return counter;
 
-     }
 
-     
 
-     private static void addKeyWordBrackets(String keyWord, StringBuilder sb)
 
-     {
 
-         String with = keyWord + "()";
 
-         int length = keyWord.length();
 
-         int pos = 0;
 
-         while(true)
 
-         {
 
-             pos = findSyntax(keyWord, sb, pos);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             if(pos >= 1 && Character.isLetter(sb.charAt(pos - 1)))
 
-             {
 
-                 pos += length;
 
-                 continue;
 
-             }
 
-             if(pos + length < sb.length() && Character.isLetter(sb.charAt(pos + length)))
 
-             {
 
-                 pos += length;
 
-                 continue;
 
-             }
 
-             if(!sb.substring(pos).startsWith(with))
 
-             {
 
-                 sb.replace(pos, pos + length, with);
 
-             }
 
-             pos += length;
 
-         }
 
-     }
 
-     
 
-     public static Code[] generate(SnuviParser parser, String scriptName, String code, HashMap<String, Integer> gotos)
 
-     {
 
-         System.out.println("START GENERATE");
 
-         long startTime = System.currentTimeMillis();
 
-         
 
-         Code.scriptName = scriptName;
 
-         Code.parser = parser;
 
-         // comments
 
-         int old = 0;
 
-         int pos;
 
-         StringBuilder sb = new StringBuilder(code);
 
-         while(true)
 
-         {
 
-             old = findSyntaxIgnoreString("/*", sb, old);
 
-             if(old == -1)
 
-             {
 
-                 break;
 
-             }
 
-             pos = findSyntaxIgnoreString("*/", sb, old);
 
-             if(pos == -1)
 
-             {
 
-                 throw new PreScriptException(scriptName, sb.substring(old, Math.min(old + 20, sb.length())), "/* without */");
 
-             }
 
-             sb.delete(old, pos + 2);
 
-         }
 
-         old = 0;
 
-         while(true)
 
-         {
 
-             old = findSyntaxIgnoreString("//", sb, old);
 
-             if(old == -1)
 
-             {
 
-                 break;
 
-             }
 
-             pos = findSyntaxIgnoreString("\n", sb, old);
 
-             if(pos == -1)
 
-             {
 
-                 sb.delete(old, sb.length());
 
-                 break;
 
-             }
 
-             sb.delete(old, pos + 1);
 
-         }
 
-         // end comments
 
-         // replacing Strings with #... to get rid of "
 
-         pos = 0;
 
-         String text;
 
-         String replacement;
 
-         int stringIndex = 0;
 
-         strings = new HashMap<>();
 
-         while(pos < sb.length())
 
-         {
 
-             if(sb.charAt(pos) == '"')
 
-             {
 
-                 old = pos;
 
-                 pos++;
 
-                 while(sb.charAt(pos) != '"')
 
-                 {
 
-                     if(pos >= sb.length())
 
-                     {
 
-                         throw new PreScriptException(scriptName, sb.substring(old, Math.min(old + 20, sb.length())), "\" without another");
 
-                     }
 
-                     pos++;
 
-                 }
 
-                 pos++;
 
-                 text = sb.substring(old, pos);
 
-                 //System.out.println("Found String: " + text);
 
-                 replacement = "#" + stringIndex;
 
-                 sb.replace(old, pos, replacement);
 
-                 strings.put(replacement, text);
 
-                 stringIndex++;
 
-                 pos -= (pos - old) - replacement.length();
 
-             }
 
-             pos++;
 
-         }
 
-         // end of string replacing
 
-         
 
-         // allowing labels without ;
 
-         old = 0;
 
-         while(true)
 
-         {
 
-             pos = findChar('@', sb, old);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             pos++;
 
-             old = pos;
 
-             pos = findEndOfSyntax(sb, pos, true);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             if(sb.charAt(pos) != ';')
 
-             {
 
-                 sb.insert(pos, ';');
 
-             }
 
-         }
 
-         // key words without ()
 
-         addKeyWordBrackets("else", sb);        
 
-         addKeyWordBrackets("try", sb);   
 
-         addKeyWordBrackets("catch", sb);   
 
-         //System.out.println(sb);
 
-         // end key words
 
-         // replacing of function syntax
 
-         changeBiSyntax("^", "math.pow", sb, false);
 
-         changeBiSyntax("/", "div", sb, false);
 
-         changeBiSyntax("%", "math.mod", sb, false);
 
-         changeBiSyntax("*", "mul", sb, false);
 
-         changeBiSyntax("-", "sub", sb, false);
 
-         changeBiSyntax("+", "add", sb, false);
 
-         changeBiSyntax("==", "equal", sb, false);
 
-         changeBiSyntax("!=", "notequal", sb, false);
 
-         changeBiSyntax("<", "less", sb, false);
 
-         changeBiSyntax(">", "greater", sb, false);
 
-         changeBiSyntax(">=", "greaterequal", sb, false);
 
-         changeBiSyntax("<=", "lessequal", sb, false);
 
-         changeBiSyntax("||", "or", sb, false);
 
-         changeBiSyntax("&&", "and", sb, false);
 
-         changeUnSyntax("+=", "add", sb);
 
-         changeUnSyntax("-=", "sub", sb);
 
-         changeUnSyntax("/=", "div", sb);
 
-         changeUnSyntax("*=", "mul", sb);
 
-         changeBiSyntax("=", "setvar", sb, true); 
 
-         
 
-         // numbers like -5 turn to sub(,5) --> fixing
 
-         pos = 0;
 
-         while(true)
 
-         {
 
-             pos = findSyntax("sub(,", sb, pos);
 
-             if(pos == -1)
 
-             {
 
-                 break;
 
-             }
 
-             sb.insert(pos + 4, '0');
 
-             pos++;
 
-         }
 
-         
 
-         code = sb.toString();
 
-         //System.out.println(code);
 
-         // end of substitution
 
-         // split code into lines
 
-         // tree for sorting and inserting of code
 
-         TreeSet<Code> tree = new TreeSet();
 
-         sublines = 0;
 
-         realLines = 1;
 
-         String actual;
 
-         int length = code.length();
 
-         int level = 1;
 
-         pos = 0;
 
-         int line = 0;
 
-         while(pos < length)
 
-         {
 
-             old = pos;
 
-             pos = findEndOfLine(code, pos);
 
-             actual = code.substring(old, pos);
 
-             //System.out.println(actual);
 
-             realLines += countChar('\n', actual);
 
-             actual = actual.trim();
 
-             if(actual.startsWith("@"))
 
-             {
 
-                 // sets the right layer of the goto, the exact position is set later
 
-                 if(gotos.put(actual.substring(1), line) != null)
 
-                 {
 
-                     throw new PreScriptException(scriptName, realLines, code.substring(old, Math.min(code.length(), pos + 20)), "double goto");
 
-                 }
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             switch(code.charAt(pos))
 
-             {
 
-                 case '{':
 
-                     line++;
 
-                     splitFunctions(tree, actual, level, line);
 
-                     level++;
 
-                     break;
 
-                 case '}': 
 
-                     level--;
 
-                     line++;
 
-                     sublines++;
 
-                     tree.add(new Code("gotoline", level, 0, line, sublines, realLines));
 
-                     break;
 
-                 case ';': 
 
-                     line++;
 
-                     splitFunctions(tree, actual, level, line);
 
-                     break;
 
-             }
 
-             pos++;
 
-         }
 
-         // end of code splitting
 
-         Code[] c = tree.toArray(new Code[tree.size()]);
 
-         // generating gotos of key words
 
-         String function;
 
-         int baseLevel;
 
-         boolean gotoLine = false;
 
-         int lastLineChange = 0;
 
-         line = 0;
 
-         for(int i = 0; i < c.length; i++)
 
-         {
 
-             function = c[i].function;
 
-             if(c[i].line != line)
 
-             {
 
-                 line = c[i].line;
 
-                 lastLineChange = i;
 
-             }
 
-             if(function == null)
 
-             {
 
-                 continue;
 
-             }
 
-             switch(function)
 
-             {
 
-                 case "if":
 
-                 case "else":
 
-                 case "try":
 
-                 case "catch":
 
-                     break;
 
-                 case "while":
 
-                     gotoLine = true;
 
-                     break;
 
-                 default:
 
-                     continue;
 
-             }
 
-             baseLevel = c[i].level;
 
-             for(int j = i + 1; j < c.length; j++)
 
-             {
 
-                 if(c[j].level <= baseLevel)
 
-                 {
 
-                     c[i].jump = j - i; // key word pos - end pos = jump
 
-                     if(gotoLine)
 
-                     {
 
-                         // setting right jump for gotoline of loops
 
-                         gotoLine = false;
 
-                         c[j].jump = lastLineChange - j - 1;
 
-                     }
 
-                     break;
 
-                 }
 
-             }
 
-         }
 
-         // end of key word jumps
 
-         // end
 
-         //java.util.Arrays.stream(c).forEach(co -> System.out.println(co.toString()));
 
-         //gotos.forEach((k, v) -> System.out.println(k + "   " + v));
 
-         System.out.println("END GENERATE - " + (System.currentTimeMillis() - startTime));     
 
-         //System.exit(0);
 
-         return c;
 
-     } 
 
-     
 
-     private static int findOpenBracket(String code, int pos)
 
-     {
 
-         int length = code.length();
 
-         char c;
 
-         boolean text = false;
 
-         while(pos < length)
 
-         {
 
-             c = code.charAt(pos);
 
-             if(text && c != '"')
 
-             {
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             switch(c)
 
-             {
 
-                 case '(':
 
-                     return pos;
 
-                 case '"':
 
-                     text = !text;
 
-                     break;
 
-             }
 
-             pos++;
 
-         }
 
-         return -1;
 
-     }
 
-     
 
-     private static int findClosingBracket(String code, int pos)
 
-     {
 
-         if(pos == -1)
 
-         {
 
-            pos++;
 
-         }
 
-         int length = code.length();
 
-         char c;
 
-         boolean text = false;
 
-         int brackets = 0;
 
-         while(pos < length)
 
-         {
 
-             c = code.charAt(pos);
 
-             if(text && c != '"')
 
-             {
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             switch(c)
 
-             {
 
-                 case '(':
 
-                     brackets++;
 
-                     break;
 
-                 case ')':
 
-                     brackets--;
 
-                     if(brackets == 0)
 
-                     {
 
-                         return pos;
 
-                     }
 
-                     break;
 
-                 case '"':
 
-                     text = !text;
 
-                     break;
 
-             }
 
-             pos++;
 
-         }
 
-         return -1;
 
-     }
 
-     
 
-     private static ArrayList<String> splitComma(String code)
 
-     {
 
-         ArrayList<String> list = new ArrayList<>();
 
-         int length = code.length();
 
-         int pos = 0;
 
-         int old = 0;
 
-         int brackets = 0;
 
-         char c;
 
-         boolean text = false;
 
-         while(pos < length)
 
-         {
 
-             c = code.charAt(pos);
 
-             if(text && c != '"')
 
-             {
 
-                 pos++;
 
-                 continue;
 
-             }
 
-             
 
-             switch(c)
 
-             {
 
-                 case '"':
 
-                     text = !text;
 
-                     break;
 
-                 case '(':
 
-                     brackets++;
 
-                     break;
 
-                 case ')':
 
-                     brackets--;
 
-                     break;
 
-                 case ',':
 
-                     if(brackets == 0)
 
-                     {
 
-                         list.add(code.substring(old, pos));
 
-                         old = pos + 1;
 
-                     }
 
-                     break;
 
-             }
 
-             pos++;
 
-         }
 
-         if(old < pos)
 
-         {
 
-             list.add(code.substring(old, pos));
 
-         }
 
-         return list;
 
-     }
 
-     
 
-     private static void splitFunctions(TreeSet<Code> tree, String f, int level, int line)
 
-     {
 
-         f = f.trim();
 
-         sublines++;
 
-         int start = findOpenBracket(f, 0);
 
-         int end = findClosingBracket(f, start);
 
-         if((start != -1 || end != -1) && 
 
-                 (((start == -1 || end == -1) && start != end) || end != f.length() - 1))
 
-         {
 
-             throw new PreScriptException(scriptName, realLines, f, "unbalanced ()");
 
-         }
 
-         if(start == -1)
 
-         {
 
-             tree.add(new Code(level, 0, line, sublines, convertInput(f, true), realLines));
 
-             return;
 
-         }
 
-         else if(start >= end - 1)
 
-         {
 
-             String functionName = f.substring(0, start).trim().toLowerCase();
 
-             if(!parser.isRegisteredFunction(functionName))
 
-             {
 
-                 throw new NoSuchMethodException(scriptName, realLines, f, functionName);
 
-             }
 
-             tree.add(new Code(functionName, level, 0, line, sublines, realLines));
 
-             return;
 
-         }
 
-         ArrayList<String> splitted = splitComma(f.substring(start + 1, end));
 
-         String functionName = f.substring(0, start).trim().toLowerCase();
 
-         if(!parser.isRegisteredFunction(functionName))
 
-         {
 
-             throw new NoSuchMethodException(scriptName, realLines, f, functionName);
 
-         }
 
-         tree.add(new Code(functionName, level, splitted.size(), line, sublines, realLines));
 
-         splitted.forEach(s -> splitFunctions(tree, s, level, line));
 
-     }
 
-     
 
-     public static Object convertInput(String s, boolean variable)
 
-     {
 
-         if(s == null)
 
-         {
 
-             return null;
 
-         }
 
-         s = s.trim();
 
-         if(s.length() == 0)
 
-         {
 
-             return "";
 
-         }  
 
-         if(s.charAt(0) == '"' && s.charAt(s.length() - 1) == '"')
 
-         {
 
-             if(s.length() == 1)
 
-             {
 
-                 return "\"";
 
-             }
 
-             else if(s.charAt(1) == '$')
 
-             {
 
-                 return s.substring(2, s.length() - 1);
 
-             }
 
-             return s.substring(1, s.length() - 1);
 
-         }
 
-         else if(s.startsWith("#"))
 
-         {
 
-             return convertInput(strings.get(s), variable);
 
-         }
 
-         else if(s.equals("true"))
 
-         {
 
-             return true;
 
-         }
 
-         else if(s.equals("false"))
 
-         {
 
-             return false;
 
-         }
 
-         else if(s.equals("null"))
 
-         {
 
-             return null;
 
-         }
 
-         try
 
-         {
 
-             return Double.parseDouble(s);
 
-         }
 
-         catch(NumberFormatException ex)
 
-         {
 
-             if(variable)
 
-             {
 
-                 return new Variable(s);
 
-             }
 
-             return s;
 
-         }
 
-     }
 
- }
 
 
  |