瀏覽代碼

Improved performance of PreScript, real line counter for exceptions

Kajetan Johannes Hammerle 7 年之前
父節點
當前提交
82bb813b8b

二進制
.DS_Store


+ 144 - 154
src/me/hammerle/code/Code.java

@@ -5,11 +5,12 @@ import java.util.HashMap;
 import java.util.Map.Entry;
 import java.util.Map.Entry;
 import java.util.Stack;
 import java.util.Stack;
 import java.util.TreeSet;
 import java.util.TreeSet;
-import me.hammerle.exceptions.PrescriptException;
+import me.hammerle.exceptions.PreScriptException;
 import me.hammerle.exceptions.NoSuchMethodException;
 import me.hammerle.exceptions.NoSuchMethodException;
 
 
 public class Code implements Comparable<Code>
 public class Code implements Comparable<Code>
 {
 {
+    protected final int realLine;
     protected final int line;
     protected final int line;
     private int subline;
     private int subline;
     
     
@@ -20,7 +21,7 @@ public class Code implements Comparable<Code>
     private final Object value;
     private final Object value;
     private int jump;
     private int jump;
     
     
-    private Code(String function, int level, int pars, int line, int subline, Object value, int jump)
+    private Code(String function, int level, int pars, int line, int subline, Object value, int jump, int realLine)
     {
     {
         this.function = function;
         this.function = function;
         this.level = level;
         this.level = level;
@@ -29,16 +30,17 @@ public class Code implements Comparable<Code>
         this.subline = subline;
         this.subline = subline;
         this.value = value;
         this.value = value;
         this.jump = jump;
         this.jump = jump;
+        this.realLine = realLine;
     }
     }
     
     
-    public Code(String function, int level, int pars, int line, int subline)
+    public Code(String function, int level, int pars, int line, int subline, int realLine)
     {
     {
-        this(function.trim(), level, pars, line, subline, null, 0);
+        this(function.trim(), level, pars, line, subline, null, 0, realLine);
     }
     }
     
     
-    public Code(int level, int pars, int line, int subline, Object value)
+    public Code(int level, int pars, int line, int subline, Object value, int realLine)
     {
     {
-        this(null, level, pars, line, subline, value, 0);
+        this(null, level, pars, line, subline, value, 0, realLine);
     }
     }
     
     
     public void executeFunction(SnuviParser parser, Script sc, Stack<Object> stack)
     public void executeFunction(SnuviParser parser, Script sc, Stack<Object> stack)
@@ -159,30 +161,21 @@ public class Code implements Comparable<Code>
     private static SnuviParser parser = null;
     private static SnuviParser parser = null;
     private static String scriptName = null;
     private static String scriptName = null;
     private static int sublines = 0;
     private static int sublines = 0;
+    private static int realLines = 0;
+    private static HashMap<String, String> strings;
     
     
     private static int findEndOfLine(String code, int pos)
     private static int findEndOfLine(String code, int pos)
     {
     {
         int start = pos;
         int start = pos;
         int length = code.length();
         int length = code.length();
-        char c;
-        boolean text = false;
         while(pos < length)
         while(pos < length)
         {
         {
-            c = code.charAt(pos);
-            if(text && c != '"')
-            {
-                pos++;
-                continue;
-            }
-            switch(c)
+            switch(code.charAt(pos))
             {
             {
                 case ';':
                 case ';':
                 case '{':
                 case '{':
                 case '}':
                 case '}':
                     return pos;
                     return pos;
-                case '"':
-                    text = !text;
-                    break;
             }
             }
             pos++;
             pos++;
         }
         }
@@ -192,28 +185,20 @@ public class Code implements Comparable<Code>
     private static int findStartOfSyntax(StringBuilder code, int pos)
     private static int findStartOfSyntax(StringBuilder code, int pos)
     {
     {
         int bracketCounter = 0;
         int bracketCounter = 0;
-        char c;
-        boolean text = false;
         while(pos >= 0 && code.charAt(pos) == ' ')
         while(pos >= 0 && code.charAt(pos) == ' ')
         {
         {
             pos--;
             pos--;
         }
         }
         while(pos >= 0)
         while(pos >= 0)
         {
         {
-            c = code.charAt(pos);
-            if(text && c != '"')
-            {
-                pos--;
-                continue;
-            }
-            switch(c)
+            switch(code.charAt(pos))
             {
             {
                 case ';':
                 case ';':
                 case '{':
                 case '{':
                 case '}':
                 case '}':
                     if(bracketCounter != 0)
                     if(bracketCounter != 0)
                     {
                     {
-                        throw new PrescriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
+                        throw new PreScriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
                     }
                     }
                     return pos + 1;
                     return pos + 1;
                 case ' ':
                 case ' ':
@@ -236,9 +221,6 @@ public class Code implements Comparable<Code>
                         break;
                         break;
                     }
                     }
                     return pos + 1;
                     return pos + 1;
-                case '"':
-                    text = !text;
-                    break;
                 case ')':
                 case ')':
                     bracketCounter++;
                     bracketCounter++;
                     break;
                     break;
@@ -264,7 +246,6 @@ public class Code implements Comparable<Code>
     {
     {
         int bracketCounter = 0;
         int bracketCounter = 0;
         char c;
         char c;
-        boolean text = false;
         while(pos < code.length() && code.charAt(pos) == ' ')
         while(pos < code.length() && code.charAt(pos) == ' ')
         {
         {
             pos++;
             pos++;
@@ -272,11 +253,6 @@ public class Code implements Comparable<Code>
         while(pos < code.length())
         while(pos < code.length())
         {
         {
             c = code.charAt(pos);
             c = code.charAt(pos);
-            if(text && c != '"')
-            {
-                pos++;
-                continue;
-            }
             if(b && c == '\n')
             if(b && c == '\n')
             {
             {
                 if(bracketCounter != 0)
                 if(bracketCounter != 0)
@@ -293,7 +269,7 @@ public class Code implements Comparable<Code>
                 case '}':
                 case '}':
                     if(bracketCounter != 0)
                     if(bracketCounter != 0)
                     {
                     {
-                        throw new PrescriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
+                        throw new PreScriptException(scriptName, code.substring(pos - 1, Math.min(code.length(), pos + 20)), "unbalanced ()"); 
                     }
                     }
                     return pos;
                     return pos;
                 case ' ':
                 case ' ':
@@ -316,9 +292,6 @@ public class Code implements Comparable<Code>
                         break;
                         break;
                     }
                     }
                     return pos;
                     return pos;
-                case '"':
-                    text = !text;
-                    break;
                 case '(':
                 case '(':
                     bracketCounter++;
                     bracketCounter++;
                     break;
                     break;
@@ -335,9 +308,42 @@ public class Code implements Comparable<Code>
         return code.length();
         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)
     private static int findSyntax(String find, StringBuilder code, int pos)
     {
     {
         int length = code.length();
         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;
         char c;
         boolean text = false;
         boolean text = false;
         String s;
         String s;
@@ -355,7 +361,7 @@ public class Code implements Comparable<Code>
                 pos++;
                 pos++;
                 continue;
                 continue;
             }
             }
-            s = code.substring(pos);
+            s = code.substring(pos, Math.min(pos + add, length));
             // additionel check for e.g. difference between + and +=
             // additionel check for e.g. difference between + and +=
             if(s.startsWith(find) && !s.startsWith(find + "=") && code.charAt(pos - 1) != '=') 
             if(s.startsWith(find) && !s.startsWith(find + "=") && code.charAt(pos - 1) != '=') 
             {
             {
@@ -401,7 +407,7 @@ public class Code implements Comparable<Code>
             newSyntax.append(")");
             newSyntax.append(")");
             pos -= end - start - newSyntax.length();
             pos -= end - start - newSyntax.length();
             //System.out.println(sb.substring(start, end) + "   ===>    " + newSyntax);
             //System.out.println(sb.substring(start, end) + "   ===>    " + newSyntax);
-            sb.replace(start, end, newSyntax.toString());
+            sb.replace(start, end, newSyntax.toString());    
         }
         }
     }
     }
     
     
@@ -439,32 +445,22 @@ public class Code implements Comparable<Code>
     
     
     private static String replaceChar(char find, char replacement, String code)
     private static String replaceChar(char find, char replacement, String code)
     {
     {
-        char[] chars = code.toCharArray();
-        int length = code.length();
-        char c;
-        boolean text = false;
+        return code.replace(find, replacement);
+    }
+    
+    private static int countChar(char find, String code)
+    {
+        int counter = 0;
         int pos = 0;
         int pos = 0;
-        while(pos < length)
+        while(pos < code.length())
         {
         {
-            c = code.charAt(pos);
-            if(text && c != '"')
-            {
-                pos++;
-                continue;
-            }
-            if(c == '"')
-            {
-                text = !text;
-                pos++;
-                continue;
-            }
-            if(c == find)
+            if(code.charAt(pos) == find)
             {
             {
-                chars[pos] = replacement;
+                counter++;
             }
             }
             pos++;
             pos++;
         }
         }
-        return new String(chars);
+        return counter;
     }
     }
     
     
     private static void addKeyWordBrackets(String keyWord, StringBuilder sb)
     private static void addKeyWordBrackets(String keyWord, StringBuilder sb)
@@ -499,6 +495,9 @@ public class Code implements Comparable<Code>
     
     
     public static Code[] generate(SnuviParser parser, String scriptName, String code, HashMap<String, Integer> gotos)
     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.scriptName = scriptName;
         Code.parser = parser;
         Code.parser = parser;
         // comments
         // comments
@@ -507,41 +506,74 @@ public class Code implements Comparable<Code>
         StringBuilder sb = new StringBuilder(code);
         StringBuilder sb = new StringBuilder(code);
         while(true)
         while(true)
         {
         {
-            old = findSyntax("/*", sb, old);
+            old = findSyntaxIgnoreString("/*", sb, old);
             if(old == -1)
             if(old == -1)
             {
             {
                 break;
                 break;
             }
             }
-            pos = findSyntax("*/", sb, old);
+            pos = findSyntaxIgnoreString("*/", sb, old);
             if(pos == -1)
             if(pos == -1)
             {
             {
-                throw new PrescriptException(scriptName, sb.substring(old, Math.min(old + 20, sb.length())), "/* without */");
+                throw new PreScriptException(scriptName, sb.substring(old, Math.min(old + 20, sb.length())), "/* without */");
             }
             }
-            sb.replace(old, pos + 2, "");
+            sb.delete(old, pos + 2);
         }
         }
         old = 0;
         old = 0;
         while(true)
         while(true)
         {
         {
-            old = findSyntax("//", sb, old);
+            old = findSyntaxIgnoreString("//", sb, old);
             if(old == -1)
             if(old == -1)
             {
             {
                 break;
                 break;
             }
             }
-            pos = findSyntax("\n", sb, old);
+            pos = findSyntaxIgnoreString("\n", sb, old);
             if(pos == -1)
             if(pos == -1)
             {
             {
-                sb.replace(old, sb.length(), "");
+                sb.delete(old, sb.length());
                 break;
                 break;
             }
             }
-            sb.replace(old, pos + 1, "");
+            sb.delete(old, pos + 1);
         }
         }
         // end comments
         // 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 ;
         // allowing labels without ;
         old = 0;
         old = 0;
         while(true)
         while(true)
         {
         {
-            pos = findSyntax("@", sb, old);
+            pos = findChar('@', sb, old);
             if(pos == -1)
             if(pos == -1)
             {
             {
                 break;
                 break;
@@ -589,7 +621,7 @@ public class Code implements Comparable<Code>
         changeUnSyntax("/=", "div", sb);
         changeUnSyntax("/=", "div", sb);
         changeUnSyntax("*=", "mul", sb);
         changeUnSyntax("*=", "mul", sb);
 
 
-        changeBiSyntax("=", "setvar", sb, true);
+        changeBiSyntax("=", "setvar", sb, true); 
         
         
         // numbers like -5 turn to sub(,5) --> fixing
         // numbers like -5 turn to sub(,5) --> fixing
         pos = 0;
         pos = 0;
@@ -603,13 +635,16 @@ public class Code implements Comparable<Code>
             sb.insert(pos + 4, '0');
             sb.insert(pos + 4, '0');
             pos++;
             pos++;
         }
         }
-
+        
         code = sb.toString();
         code = sb.toString();
+
         //System.out.println(code);
         //System.out.println(code);
         // end of substitution
         // end of substitution
         // split code into lines
         // split code into lines
-        ArrayList<Code> list = new ArrayList<>();
+        // tree for sorting and inserting of code
+        TreeSet<Code> tree = new TreeSet();
         sublines = 0;
         sublines = 0;
+        realLines = 1;
         String actual;
         String actual;
         int length = code.length();
         int length = code.length();
         int level = 1;
         int level = 1;
@@ -619,13 +654,16 @@ public class Code implements Comparable<Code>
         {
         {
             old = pos;
             old = pos;
             pos = findEndOfLine(code, pos);
             pos = findEndOfLine(code, pos);
-            actual = code.substring(old, pos).trim();
+            actual = code.substring(old, pos);
+            //System.out.println(actual);
+            realLines += countChar('\n', actual);
+            actual = actual.trim();
             if(actual.startsWith("@"))
             if(actual.startsWith("@"))
             {
             {
                 // sets the right layer of the goto, the exact position is set later
                 // sets the right layer of the goto, the exact position is set later
                 if(gotos.put(actual.substring(1), line) != null)
                 if(gotos.put(actual.substring(1), line) != null)
                 {
                 {
-                    throw new PrescriptException(scriptName, code.substring(old, Math.min(code.length(), pos + 20)), "double goto");
+                    throw new PreScriptException(scriptName, realLines, code.substring(old, Math.min(code.length(), pos + 20)), "double goto");
                 }
                 }
                 pos++;
                 pos++;
                 continue;
                 continue;
@@ -634,69 +672,30 @@ public class Code implements Comparable<Code>
             {
             {
                 case '{':
                 case '{':
                     line++;
                     line++;
-                    splitFunctions(list, actual, level, line);
+                    splitFunctions(tree, actual, level, line);
                     level++;
                     level++;
                     break;
                     break;
                 case '}': 
                 case '}': 
                     level--;
                     level--;
+                    line++;
+                    sublines++;
+                    tree.add(new Code("gotoline", level, 0, line, sublines, realLines));
                     break;
                     break;
                 case ';': 
                 case ';': 
                     line++;
                     line++;
-                    splitFunctions(list, actual, level, line);
+                    splitFunctions(tree, actual, level, line);
                     break;
                     break;
             }
             }
             pos++;
             pos++;
         }
         }
         // end of code splitting
         // end of code splitting
 
 
-        // tree for sorting and inserting of code
-        TreeSet<Code> tree = new TreeSet(list);
         Code[] c = tree.toArray(new Code[tree.size()]);
         Code[] c = tree.toArray(new Code[tree.size()]);
 
 
-        // insert "gotoline" at while
+        // generating gotos of key words
         String function;
         String function;
         int baseLevel;
         int baseLevel;
-        boolean lastLineChecker;
-        for(int i = 0; i < c.length; i++)
-        {
-            function = c[i].function;
-            if(function == null || !function.equals("while"))
-            {
-                continue;
-            }
-            baseLevel = c[i].level;
-            // keeping sure "gotoline" is inserted at least at the end of the code
-            lastLineChecker = true;
-            for(int j = i + 1; j < c.length; j++)
-            {
-                if(c[j].level <= baseLevel)
-                {
-                    Code gotoLine = new Code("gotoline", c[i].level, 0, c[j].line, c[j].subline + 1);
-                    while(tree.contains(gotoLine)) // prevent whiles from overwriting other whiles
-                    {
-                        gotoLine.subline++;
-                    }
-                    tree.add(gotoLine);
-                    lastLineChecker = false;
-                    break;
-                }
-            }
-            if(lastLineChecker)
-            {
-                sublines++;
-                Code gotoLine = new Code("gotoline", c[i].level, 0, c[c.length - 1].line + 1, sublines);
-                while(tree.contains(gotoLine)) // prevent whiles from overwriting other whiles
-                {
-                    gotoLine.subline++;
-                }
-                tree.add(gotoLine);
-            }
-        }
-        // end of while handling
-        // generating gotos of key words
-        c = tree.toArray(new Code[tree.size()]);
-
-        boolean whileCheck = false;
+        boolean gotoLine = false;
         int lastLineChange = 0;
         int lastLineChange = 0;
         line = 0;
         line = 0;
         for(int i = 0; i < c.length; i++)
         for(int i = 0; i < c.length; i++)
@@ -719,7 +718,7 @@ public class Code implements Comparable<Code>
                 case "catch":
                 case "catch":
                     break;
                     break;
                 case "while":
                 case "while":
-                    whileCheck = true;
+                    gotoLine = true;
                     break;
                     break;
                 default:
                 default:
                     continue;
                     continue;
@@ -730,37 +729,22 @@ public class Code implements Comparable<Code>
                 if(c[j].level <= baseLevel)
                 if(c[j].level <= baseLevel)
                 {
                 {
                     c[i].jump = j - i; // key word pos - end pos = jump
                     c[i].jump = j - i; // key word pos - end pos = jump
-                    if(whileCheck)
+                    if(gotoLine)
                     {
                     {
-                        // setting right jump for gotoline of while
-                        whileCheck = false;
-                        c[j].jump = lastLineChange - j;
+                        // setting right jump for gotoline of loops
+                        gotoLine = false;
+                        c[j].jump = lastLineChange - j - 1;
                     }
                     }
                     break;
                     break;
                 }
                 }
             }
             }
-            if(c[i].jump == 0)
-            {
-               c[i].jump = tree.size() - i; 
-            }
         }
         }
         // end of key word jumps
         // end of key word jumps
-        // correct wrong gotos
-        for(Entry<String, Integer> i : gotos.entrySet())
-        {
-            int value = i.getValue() + 1;
-            for(int j = value - 1; j < c.length; j++)
-            {
-                if(c[j].line == value)
-                {
-                    i.setValue(j);
-                    break;
-                }
-            }
-        }
+
         // end
         // end
         //java.util.Arrays.stream(c).forEach(co -> System.out.println(co.toString()));
         //java.util.Arrays.stream(c).forEach(co -> System.out.println(co.toString()));
         //gotos.forEach((k, v) -> System.out.println(k + "   " + v));
         //gotos.forEach((k, v) -> System.out.println(k + "   " + v));
+        System.out.println("END GENERATE - " + (System.currentTimeMillis() - startTime));     
         //System.exit(0);
         //System.exit(0);
         return c;
         return c;
     } 
     } 
@@ -876,18 +860,20 @@ public class Code implements Comparable<Code>
         return list;
         return list;
     }
     }
     
     
-    private static void splitFunctions(ArrayList<Code> list, String f, int level, int line)
+    private static void splitFunctions(TreeSet<Code> tree, String f, int level, int line)
     {
     {
+        f = f.trim();
         sublines++;
         sublines++;
         int start = findOpenBracket(f, 0);
         int start = findOpenBracket(f, 0);
         int end = findClosingBracket(f, start);
         int end = findClosingBracket(f, start);
-        if((start != -1 || end != -1) && (((start == -1 || end == -1) && start != end) || end != f.length() - 1))
+        if((start != -1 || end != -1) && 
+                (((start == -1 || end == -1) && start != end) || end != f.length() - 1))
         {
         {
-            throw new PrescriptException(scriptName, f, "unbalanced ()");
+            throw new PreScriptException(scriptName, realLines, f, "unbalanced ()");
         }
         }
         if(start == -1)
         if(start == -1)
         {
         {
-            list.add(new Code(level, 0, line, sublines, convertInput(f, true)));
+            tree.add(new Code(level, 0, line, sublines, convertInput(f, true), realLines));
             return;
             return;
         }
         }
         else if(start >= end - 1)
         else if(start >= end - 1)
@@ -895,19 +881,19 @@ public class Code implements Comparable<Code>
             String functionName = f.substring(0, start).trim().toLowerCase();
             String functionName = f.substring(0, start).trim().toLowerCase();
             if(!parser.isRegisteredFunction(functionName))
             if(!parser.isRegisteredFunction(functionName))
             {
             {
-                throw new NoSuchMethodException(scriptName, f, functionName);
+                throw new NoSuchMethodException(scriptName, realLines, f, functionName);
             }
             }
-            list.add(new Code(functionName, level, 0, line, sublines));
+            tree.add(new Code(functionName, level, 0, line, sublines, realLines));
             return;
             return;
         }
         }
         ArrayList<String> splitted = splitComma(f.substring(start + 1, end));
         ArrayList<String> splitted = splitComma(f.substring(start + 1, end));
         String functionName = f.substring(0, start).trim().toLowerCase();
         String functionName = f.substring(0, start).trim().toLowerCase();
         if(!parser.isRegisteredFunction(functionName))
         if(!parser.isRegisteredFunction(functionName))
         {
         {
-            throw new NoSuchMethodException(scriptName, f, functionName);
+            throw new NoSuchMethodException(scriptName, realLines, f, functionName);
         }
         }
-        list.add(new Code(functionName, level, splitted.size(), line, sublines));
-        splitted.forEach(s -> splitFunctions(list, s, level, line));
+        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)
     public static Object convertInput(String s, boolean variable)
@@ -933,6 +919,10 @@ public class Code implements Comparable<Code>
             }
             }
             return s.substring(1, 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"))
         else if(s.equals("true"))
         {
         {
             return true;
             return true;

+ 9 - 10
src/me/hammerle/code/Script.java

@@ -4,7 +4,6 @@ import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Arrays;
 import java.util.HashMap;
 import java.util.HashMap;
 import java.util.HashSet;
 import java.util.HashSet;
-import java.util.List;
 import java.util.Stack;
 import java.util.Stack;
 import me.hammerle.exceptions.CodeTooLongException;
 import me.hammerle.exceptions.CodeTooLongException;
 import me.hammerle.exceptions.GotoLabelNotFoundException;
 import me.hammerle.exceptions.GotoLabelNotFoundException;
@@ -163,6 +162,11 @@ public class Script
         return code[position].line;
         return code[position].line;
     }
     }
     
     
+    public int getActiveRealCodeLine()
+    {
+        return code[position].realLine;
+    }
+    
     // -----------------------------------------------------------------------------------
     // -----------------------------------------------------------------------------------
     // Event-Handling
     // Event-Handling
     // -----------------------------------------------------------------------------------
     // -----------------------------------------------------------------------------------
@@ -274,13 +278,13 @@ public class Script
         }
         }
     }
     }
     
     
-    public void gotoLabel(String label)
+    public void gotoLabel(String label, boolean scheduled)
     {
     {
         try
         try
         {
         {
             int i = gotos.get(label);
             int i = gotos.get(label);
             incLoopCounter();
             incLoopCounter();
-            position = i - 1;
+            position = i - (scheduled ? 0 : 1);
         }
         }
         catch(NullPointerException ex)
         catch(NullPointerException ex)
         {
         {
@@ -296,7 +300,7 @@ public class Script
     public void gotoLabelWithReturn(String label)
     public void gotoLabelWithReturn(String label)
     {
     {
         returnStack.push(position);
         returnStack.push(position);
-        gotoLabel(label);
+        gotoLabel(label, false);
     }
     }
     
     
     public void doReturn()
     public void doReturn()
@@ -304,14 +308,9 @@ public class Script
         position = returnStack.pop(); 
         position = returnStack.pop(); 
     }
     }
     
     
-    public void gotoSpecialJumpLine(int i)
-    {
-        position += code[position].getJumpLine() + i;
-    }
-    
     public void gotoSpecialJumpLine()
     public void gotoSpecialJumpLine()
     {
     {
-        gotoSpecialJumpLine(-1);
+        position += code[position].getJumpLine();
     }
     }
     
     
     public void jumpNextIfElse()
     public void jumpNextIfElse()

+ 4 - 4
src/me/hammerle/code/ScriptUtils.java

@@ -8,7 +8,7 @@ import java.util.Arrays;
 import java.util.Collection;
 import java.util.Collection;
 import java.util.Random;
 import java.util.Random;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
-import me.hammerle.exceptions.PrescriptException;
+import me.hammerle.exceptions.PreScriptException;
 
 
 public class ScriptUtils
 public class ScriptUtils
 {
 {
@@ -83,14 +83,14 @@ public class ScriptUtils
             } 
             } 
             catch (MalformedInputException ex) 
             catch (MalformedInputException ex) 
             {
             {
-                throw new PrescriptException(filename, "", "file contains an illegal character, change file encoding");
+                throw new PreScriptException(filename, "", "file contains an illegal character, change file encoding");
             }
             }
             catch (IOException ex) 
             catch (IOException ex) 
             {
             {
-                throw new PrescriptException(filename, "", "file '" + filename + "' cannot be read");
+                throw new PreScriptException(filename, "", "file '" + filename + "' cannot be read");
             }
             }
         }
         }
-        throw new PrescriptException(filename, "", "file '" + filename + "' does not exist");
+        throw new PreScriptException(filename, "", "file '" + filename + "' does not exist");
     }
     }
     
     
     public static String readCode(String filename)
     public static String readCode(String filename)

+ 12 - 12
src/me/hammerle/code/SnuviParser.java

@@ -20,7 +20,7 @@ import java.util.function.BiFunction;
 import java.util.function.BiConsumer;
 import java.util.function.BiConsumer;
 import java.util.function.Consumer;
 import java.util.function.Consumer;
 import java.util.stream.Collectors;
 import java.util.stream.Collectors;
-import me.hammerle.exceptions.PrescriptException;
+import me.hammerle.exceptions.PreScriptException;
 import me.hammerle.exceptions.SnuviException;
 import me.hammerle.exceptions.SnuviException;
 
 
 public class SnuviParser 
 public class SnuviParser 
@@ -286,7 +286,7 @@ public class SnuviParser
         registerConsumer("wait", (args, sc) -> 
         registerConsumer("wait", (args, sc) -> 
                 { sc.resetLoopCounter(); throw new HoldCodeException(); });
                 { sc.resetLoopCounter(); throw new HoldCodeException(); });
         registerConsumer("goto", (args, sc) -> 
         registerConsumer("goto", (args, sc) -> 
-                sc.gotoLabel(args[0].toString()));
+                sc.gotoLabel(args[0].toString(), false));
         registerConsumer("gotoline", (args, sc) -> 
         registerConsumer("gotoline", (args, sc) -> 
                 { sc.gotoSpecialJumpLine(); sc.incLoopCounter(); });
                 { sc.gotoSpecialJumpLine(); sc.incLoopCounter(); });
         registerConsumer("sgoto", (args, sc) -> 
         registerConsumer("sgoto", (args, sc) -> 
@@ -432,7 +432,7 @@ public class SnuviParser
             term();
             term();
             return script;
             return script;
         }
         }
-        catch(PrescriptException ex)
+        catch(PreScriptException ex)
         {
         {
             logger.printException(ex);
             logger.printException(ex);
             return null;
             return null;
@@ -542,7 +542,7 @@ public class SnuviParser
     {
     {
         if(Arrays.stream(args).anyMatch(s -> !((boolean) s)))
         if(Arrays.stream(args).anyMatch(s -> !((boolean) s)))
         {
         {
-            sc.gotoSpecialJumpLine(0);
+            sc.gotoSpecialJumpLine();
         }
         }
     } 
     } 
                   
                   
@@ -562,7 +562,7 @@ public class SnuviParser
             }
             }
             try
             try
             {
             {
-                sc.gotoLabel(args[1].toString());
+                sc.gotoLabel(args[1].toString(), true);
                 sc.setHalt(false);
                 sc.setHalt(false);
                 sc.runCode();
                 sc.runCode();
             }
             }
@@ -653,7 +653,7 @@ public class SnuviParser
     private long getNextDay(Object[] args)       
     private long getNextDay(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         cal.add(Calendar.DAY_OF_YEAR, 1);
         cal.add(Calendar.DAY_OF_YEAR, 1);
         cal.set(Calendar.HOUR, 0);
         cal.set(Calendar.HOUR, 0);
         cal.set(Calendar.SECOND, 0);
         cal.set(Calendar.SECOND, 0);
@@ -665,42 +665,42 @@ public class SnuviParser
     private int getYear(Object[] args)       
     private int getYear(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.YEAR);   
         return cal.get(Calendar.YEAR);   
     }
     }
     
     
     private int getMonth(Object[] args)       
     private int getMonth(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.MONTH) + 1;   
         return cal.get(Calendar.MONTH) + 1;   
     }
     }
     
     
     private int getDay(Object[] args)       
     private int getDay(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.DAY_OF_MONTH);   
         return cal.get(Calendar.DAY_OF_MONTH);   
     }
     }
     
     
     private int getHour(Object[] args)       
     private int getHour(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.HOUR_OF_DAY);   
         return cal.get(Calendar.HOUR_OF_DAY);   
     }
     }
     
     
     private int getMinute(Object[] args)       
     private int getMinute(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.MINUTE);   
         return cal.get(Calendar.MINUTE);   
     }
     }
     
     
     private int getSecond(Object[] args)       
     private int getSecond(Object[] args)       
     {
     {
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
         GregorianCalendar cal = GregorianCalendar.from(ZonedDateTime.now());
-        cal.setTimeInMillis((long) args[0]);
+        cal.setTimeInMillis(getLong(args[0]));
         return cal.get(Calendar.SECOND);   
         return cal.get(Calendar.SECOND);   
     }
     }
 }
 }

+ 3 - 3
src/me/hammerle/exceptions/NoSuchMethodException.java

@@ -1,9 +1,9 @@
 package me.hammerle.exceptions;
 package me.hammerle.exceptions;
 
 
-public class NoSuchMethodException extends PrescriptException
+public class NoSuchMethodException extends PreScriptException
 {
 {
-    public NoSuchMethodException(String scriptName, String code, String error) 
+    public NoSuchMethodException(String scriptName, int line, String code, String error) 
     {
     {
-        super(scriptName, code, error);
+        super(scriptName, line, code, error);
     }
     }
 }
 }

+ 22 - 0
src/me/hammerle/exceptions/PreScriptException.java

@@ -0,0 +1,22 @@
+package me.hammerle.exceptions;
+
+public class PreScriptException extends SnuviException
+{
+    private final String error;
+    
+    public PreScriptException(String scriptName, int line, String code, String error) 
+    {
+        super(null, scriptName, line, code);
+        this.error = error;
+    }
+    
+    public PreScriptException(String scriptName, String code, String error) 
+    {
+        this(scriptName, -1, code, error);
+    }
+    
+    public String getException()
+    {
+        return error;
+    }
+}

+ 0 - 17
src/me/hammerle/exceptions/PrescriptException.java

@@ -1,17 +0,0 @@
-package me.hammerle.exceptions;
-
-public class PrescriptException extends SnuviException
-{
-    private final String error;
-    
-    public PrescriptException(String scriptName, String code, String error) 
-    {
-        super(null, scriptName, code);
-        this.error = error;
-    }
-    
-    public String getException()
-    {
-        return error;
-    }
-}

+ 2 - 2
src/me/hammerle/exceptions/SnuviException.java

@@ -40,11 +40,11 @@ public class SnuviException extends RuntimeException
     
     
     public SnuviException(Exception ex, Script sc)
     public SnuviException(Exception ex, Script sc)
     {
     {
-        this(ex, sc.getName(), sc.getActiveCodeLine());
+        this(ex, sc.getName(), sc.getActiveRealCodeLine());
         int i = sc.getActiveCodeLine();
         int i = sc.getActiveCodeLine();
         if(i != -1)
         if(i != -1)
         {
         {
-            for(Code c : sc.getCode(line))
+            for(Code c : sc.getCode(i))
             {
             {
                 this.code.add(c.toString());
                 this.code.add(c.toString());
             }
             }

+ 41 - 3
src/me/hammerle/snuviscript/SnuviScript.java

@@ -4,7 +4,7 @@ import me.hammerle.code.Script;
 import me.hammerle.code.SnuviParser;
 import me.hammerle.code.SnuviParser;
 import me.hammerle.exceptions.SnuviException;
 import me.hammerle.exceptions.SnuviException;
 import me.hammerle.code.ISnuviScheduler;
 import me.hammerle.code.ISnuviScheduler;
-import me.hammerle.code.ScriptUtils;
+import me.hammerle.exceptions.PreScriptException;
 
 
 public class SnuviScript 
 public class SnuviScript 
 {
 {
@@ -15,6 +15,10 @@ public class SnuviScript
             System.out.println("Exception " + ex);
             System.out.println("Exception " + ex);
             System.out.println(ex.getOriginalException());
             System.out.println(ex.getOriginalException());
             System.out.println(ex.getCode());
             System.out.println(ex.getCode());
+            if(ex instanceof PreScriptException)
+            {
+                System.out.println(((PreScriptException) ex).getException());
+            }
             System.out.println(ex.getLine());
             System.out.println(ex.getLine());
             System.out.println(ex.getScriptName());
             System.out.println(ex.getScriptName());
         }, new ISnuviScheduler() 
         }, new ISnuviScheduler() 
@@ -36,7 +40,41 @@ public class SnuviScript
         parser.registerConsumer("debug", (o, sc) -> System.out.println(o[0]));
         parser.registerConsumer("debug", (o, sc) -> System.out.println(o[0]));
         parser.registerFunction("ggv", (o, sc) -> o[0]);
         parser.registerFunction("ggv", (o, sc) -> o[0]);
         
         
-        parser.startScript(Script.class, "test", 
-                "debug(equal(2, null));", true);
+        StringBuilder sb = new StringBuilder("wusi = 1;\n");
+        int counter = 0;
+        for(int i = 0; i < 1000; i++)
+        {
+            switch(counter)
+            {
+                case 0: sb.append("wusi += 1;\n"); break;
+                case 1: sb.append("wusi *= 2;\n"); break;
+                case 2: sb.append("wusi = wusi - 1;\n"); break;
+                case 3: sb.append("wusi /= 2;\n"); break;
+                case 4: sb.append("wusi += 1;\n"); break;
+            }
+            counter++;
+            if(counter >= 5)
+            {
+                counter = 0;
+            }
+        }
+        sb.append("debug(wusi);");
+        
+        /*String s = "i = 3;\n" +
+"while(i < 10)\n" +
+"{\n" +
+"    j = 5;\n" +
+"    debug(i);\n" +
+"    while(j < 10)\n" +
+"    {\n" +
+"        debug(j);\n" +
+"        j += 1;\n" +
+"    }\n" +
+"    i += 1;\n" +
+"}";*/
+        //System.out.println(s);
+        //System.out.println("___________");
+        parser.startScript(Script.class, "test", sb.toString(), true);
+        //parser.startScript(Script.class, "test", s, true);
     }   
     }   
 }
 }