|
@@ -4,6 +4,7 @@ import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Stack;
|
|
|
import java.util.TreeSet;
|
|
|
+import me.hammerle.exceptions.PrescriptException;
|
|
|
|
|
|
public class Code implements Comparable<Code>
|
|
|
{
|
|
@@ -201,6 +202,11 @@ public class Code implements Comparable<Code>
|
|
|
case ';':
|
|
|
case '{':
|
|
|
case '}':
|
|
|
+ if(bracketCounter != 0)
|
|
|
+ {
|
|
|
+ throw new PrescriptException("unbalanced ()", code.substring(pos - 1, Math.min(code.length(), pos + 10)));
|
|
|
+ }
|
|
|
+ return pos + 1;
|
|
|
case ' ':
|
|
|
case '+':
|
|
|
case '-':
|
|
@@ -208,6 +214,10 @@ public class Code implements Comparable<Code>
|
|
|
case '/':
|
|
|
case '^':
|
|
|
case '=':
|
|
|
+ case '>':
|
|
|
+ case '<':
|
|
|
+ case '!':
|
|
|
+ case '%':
|
|
|
if(bracketCounter != 0)
|
|
|
{
|
|
|
break;
|
|
@@ -254,6 +264,11 @@ public class Code implements Comparable<Code>
|
|
|
case ';':
|
|
|
case '{':
|
|
|
case '}':
|
|
|
+ if(bracketCounter != 0)
|
|
|
+ {
|
|
|
+ throw new PrescriptException("unbalanced ()", code.substring(pos - 1, Math.min(code.length(), pos + 10)));
|
|
|
+ }
|
|
|
+ return pos;
|
|
|
case ' ':
|
|
|
case '+':
|
|
|
case '-':
|
|
@@ -261,7 +276,10 @@ public class Code implements Comparable<Code>
|
|
|
case '/':
|
|
|
case '^':
|
|
|
case '=':
|
|
|
- case '%':
|
|
|
+ case '>':
|
|
|
+ case '<':
|
|
|
+ case '!':
|
|
|
+ case '%':
|
|
|
if(bracketCounter != 0)
|
|
|
{
|
|
|
break;
|
|
@@ -350,6 +368,7 @@ public class Code implements Comparable<Code>
|
|
|
newSyntax.append(sb.substring(pos + slength, end).trim());
|
|
|
}
|
|
|
newSyntax.append(")");
|
|
|
+ pos -= end - start - newSyntax.length();
|
|
|
sb.replace(start, end, newSyntax.toString());
|
|
|
}
|
|
|
return sb.toString();
|
|
@@ -383,6 +402,7 @@ public class Code implements Comparable<Code>
|
|
|
newSyntax.append(",");
|
|
|
newSyntax.append(sb.substring(pos + slength, end).trim());
|
|
|
newSyntax.append("))");
|
|
|
+ pos -= end - start - newSyntax.length();
|
|
|
sb.replace(start, end, newSyntax.toString());
|
|
|
}
|
|
|
return sb.toString();
|
|
@@ -420,160 +440,184 @@ public class Code implements Comparable<Code>
|
|
|
|
|
|
public static Code[] generate(String code, HashMap<String, Integer> gotos)
|
|
|
{
|
|
|
- // Anfängliches Austauschen mit Functionssyntax
|
|
|
- code = changeBiSyntax("^", "math.pow", code, false);
|
|
|
- code = changeBiSyntax("/", "div", code, false);
|
|
|
- code = changeBiSyntax("%", "math.mod", code, false);
|
|
|
- code = changeBiSyntax("*", "mul", code, false);
|
|
|
- code = changeBiSyntax("-", "sub", code, false);
|
|
|
- code = changeBiSyntax("+", "add", code, false);
|
|
|
-
|
|
|
- code = changeBiSyntax("==", "equal", code, false);
|
|
|
- code = changeBiSyntax("!=", "notequal", code, false);
|
|
|
- code = changeBiSyntax("<", "less", code, false);
|
|
|
- code = changeBiSyntax(">", "greater", code, false);
|
|
|
- code = changeBiSyntax(">=", "greaterequal", code, false);
|
|
|
- code = changeBiSyntax("<=", "lessequal", code, false);
|
|
|
-
|
|
|
- code = changeUnSyntax("+=", "add", code);
|
|
|
- code = changeUnSyntax("-=", "add", code);
|
|
|
- code = changeUnSyntax("/=", "add", code);
|
|
|
- code = changeUnSyntax("*=", "add", code);
|
|
|
-
|
|
|
- code = changeBiSyntax("=", "setvar", code, true);
|
|
|
-
|
|
|
- //code = replaceChar('[', '(', code);
|
|
|
- //code = replaceChar(']', ')', code);
|
|
|
-
|
|
|
- System.out.println(code);
|
|
|
- //System.exit(0);
|
|
|
- // Ende des Austauschen
|
|
|
- // Zerlegen des Codes in Zeilen
|
|
|
- ArrayList<Code> list = new ArrayList<>();
|
|
|
- sublines = 0;
|
|
|
- String actual;
|
|
|
- int length = code.length();
|
|
|
- int level = 1;
|
|
|
- int old;
|
|
|
- int pos = 0;
|
|
|
- int line = 0;
|
|
|
- while(pos < length)
|
|
|
+ try
|
|
|
{
|
|
|
- old = pos;
|
|
|
- pos = findEndOfLine(code, pos);
|
|
|
- actual = code.substring(old, pos).trim();
|
|
|
- if(actual.startsWith("@"))
|
|
|
- {
|
|
|
- gotos.put(actual.substring(1), line);
|
|
|
+ // Anfängliches Austauschen mit Functionssyntax
|
|
|
+ code = changeBiSyntax("^", "math.pow", code, false);
|
|
|
+ code = changeBiSyntax("/", "div", code, false);
|
|
|
+ code = changeBiSyntax("%", "math.mod", code, false);
|
|
|
+ code = changeBiSyntax("*", "mul", code, false);
|
|
|
+ code = changeBiSyntax("-", "sub", code, false);
|
|
|
+ code = changeBiSyntax("+", "add", code, false);
|
|
|
+
|
|
|
+ code = changeBiSyntax("==", "equal", code, false);
|
|
|
+ code = changeBiSyntax("!=", "notequal", code, false);
|
|
|
+ code = changeBiSyntax("<", "less", code, false);
|
|
|
+ code = changeBiSyntax(">", "greater", code, false);
|
|
|
+ code = changeBiSyntax(">=", "greaterequal", code, false);
|
|
|
+ code = changeBiSyntax("<=", "lessequal", code, false);
|
|
|
+
|
|
|
+ code = changeUnSyntax("+=", "add", code);
|
|
|
+ code = changeUnSyntax("-=", "sub", code);
|
|
|
+ code = changeUnSyntax("/=", "div", code);
|
|
|
+ code = changeUnSyntax("*=", "mul", code);
|
|
|
+
|
|
|
+ code = changeBiSyntax("=", "setvar", code, true);
|
|
|
+
|
|
|
+ //code = replaceChar('[', '(', code);
|
|
|
+ //code = replaceChar(']', ')', code);
|
|
|
+
|
|
|
+ //System.out.println(code);
|
|
|
+ //System.exit(0);
|
|
|
+ // Ende des Austauschen
|
|
|
+ // Zerlegen des Codes in Zeilen
|
|
|
+ ArrayList<Code> list = new ArrayList<>();
|
|
|
+ sublines = 0;
|
|
|
+ String actual;
|
|
|
+ int length = code.length();
|
|
|
+ int level = 1;
|
|
|
+ int old;
|
|
|
+ int pos = 0;
|
|
|
+ int line = 0;
|
|
|
+ while(pos < length)
|
|
|
+ {
|
|
|
+ old = pos;
|
|
|
+ pos = findEndOfLine(code, pos);
|
|
|
+ actual = code.substring(old, pos).trim();
|
|
|
+ //System.out.println("WUSI: " + actual);
|
|
|
+ if(actual.startsWith("@"))
|
|
|
+ {
|
|
|
+ gotos.put(actual.substring(1), line);
|
|
|
+ pos++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ switch(code.charAt(pos))
|
|
|
+ {
|
|
|
+ case '{':
|
|
|
+ line++;
|
|
|
+ splitFunctions(list, actual, level, line);
|
|
|
+ level++;
|
|
|
+ break;
|
|
|
+ case '}':
|
|
|
+ level--;
|
|
|
+ break;
|
|
|
+ case ';':
|
|
|
+ line++;
|
|
|
+ splitFunctions(list, actual, level, line);
|
|
|
+ break;
|
|
|
+ }
|
|
|
pos++;
|
|
|
- continue;
|
|
|
- }
|
|
|
- switch(code.charAt(pos))
|
|
|
- {
|
|
|
- case '{':
|
|
|
- line++;
|
|
|
- splitFunctions(list, actual, level, line);
|
|
|
- level++;
|
|
|
- break;
|
|
|
- case '}':
|
|
|
- level--;
|
|
|
- break;
|
|
|
- case ';':
|
|
|
- line++;
|
|
|
- splitFunctions(list, actual, level, line);
|
|
|
- break;
|
|
|
}
|
|
|
- pos++;
|
|
|
- }
|
|
|
- // Ende der Zeilenzerlegung
|
|
|
-
|
|
|
- // Anlegen eines Trees zum sortieren und einfügen von Code
|
|
|
- TreeSet<Code> tree = new TreeSet(list);
|
|
|
- Code[] helper = tree.toArray(new Code[tree.size()]);
|
|
|
-
|
|
|
- // Einfügen von "gotoline" bei while-Schleifen
|
|
|
- String function;
|
|
|
- int baseLevel;
|
|
|
- for(int i = 0; i < helper.length; i++)
|
|
|
- {
|
|
|
- function = helper[i].function;
|
|
|
- if(function == null || !function.equals("while"))
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- baseLevel = helper[i].level;
|
|
|
- for(int j = i + 1; j < helper.length; j++)
|
|
|
+ // Ende der Zeilenzerlegung
|
|
|
+
|
|
|
+ // Anlegen eines Trees zum sortieren und einfügen von Code
|
|
|
+ TreeSet<Code> tree = new TreeSet(list);
|
|
|
+ Code[] helper = tree.toArray(new Code[tree.size()]);
|
|
|
+
|
|
|
+ // Einfügen von "gotoline" bei while-Schleifen
|
|
|
+ String function;
|
|
|
+ int baseLevel;
|
|
|
+ for(int i = 0; i < helper.length; i++)
|
|
|
{
|
|
|
- if(helper[j].level <= baseLevel)
|
|
|
+ function = helper[i].function;
|
|
|
+ if(function == null || !function.equals("while"))
|
|
|
{
|
|
|
- helper[i].jump = j - i + 1;
|
|
|
- Code c = new Code("gotoline", helper[i].level, 0, helper[j].line, helper[j].subline + 1);
|
|
|
- while(tree.contains(c)) // Damit keine Whiles, die gleich enden, sich überschreiben
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ baseLevel = helper[i].level;
|
|
|
+ for(int j = i + 1; j < helper.length; j++)
|
|
|
+ {
|
|
|
+ if(helper[j].level <= baseLevel)
|
|
|
{
|
|
|
- c.subline++;
|
|
|
+ helper[i].jump = j - i + 1;
|
|
|
+ Code c = new Code("gotoline", helper[i].level, 0, helper[j].line, helper[j].subline + 1);
|
|
|
+ while(tree.contains(c)) // Damit keine Whiles, die gleich enden, sich überschreiben
|
|
|
+ {
|
|
|
+ c.subline++;
|
|
|
+ }
|
|
|
+ tree.add(c);
|
|
|
+ break;
|
|
|
}
|
|
|
- tree.add(c);
|
|
|
- break;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
- // Ende des While-Handlings
|
|
|
- // Erstellen der Sprungmarken der Schlüsselwörter
|
|
|
- helper = tree.toArray(new Code[tree.size()]);
|
|
|
-
|
|
|
- boolean whileCheck = false;
|
|
|
- int lastLineChange = 0;
|
|
|
- line = 0;
|
|
|
- for(int i = 0; i < helper.length; i++)
|
|
|
- {
|
|
|
- function = helper[i].function;
|
|
|
- if(helper[i].line != line)
|
|
|
- {
|
|
|
- line = helper[i].line;
|
|
|
- lastLineChange = i;
|
|
|
- }
|
|
|
- if(function == null)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- switch(function)
|
|
|
+ // Ende des While-Handlings
|
|
|
+ // Erstellen der Sprungmarken der Schlüsselwörter
|
|
|
+ helper = tree.toArray(new Code[tree.size()]);
|
|
|
+
|
|
|
+ boolean whileCheck = false;
|
|
|
+ int lastLineChange = 0;
|
|
|
+ line = 0;
|
|
|
+ for(int i = 0; i < helper.length; i++)
|
|
|
{
|
|
|
- case "if":
|
|
|
- case "else":
|
|
|
- case "try":
|
|
|
- case "catch":
|
|
|
- break;
|
|
|
- case "while":
|
|
|
- whileCheck = true;
|
|
|
- break;
|
|
|
- default:
|
|
|
+ function = helper[i].function;
|
|
|
+ if(helper[i].line != line)
|
|
|
+ {
|
|
|
+ line = helper[i].line;
|
|
|
+ lastLineChange = i;
|
|
|
+ }
|
|
|
+ if(function == null)
|
|
|
+ {
|
|
|
continue;
|
|
|
- }
|
|
|
- baseLevel = helper[i].level;
|
|
|
- for(int j = i + 1; j < helper.length; j++)
|
|
|
- {
|
|
|
- if(helper[j].level <= baseLevel)
|
|
|
+ }
|
|
|
+ switch(function)
|
|
|
{
|
|
|
- helper[i].jump = j - i;
|
|
|
- if(whileCheck)
|
|
|
+ case "if":
|
|
|
+ case "else":
|
|
|
+ case "try":
|
|
|
+ case "catch":
|
|
|
+ break;
|
|
|
+ case "while":
|
|
|
+ whileCheck = true;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ baseLevel = helper[i].level;
|
|
|
+ for(int j = i + 1; j < helper.length; j++)
|
|
|
+ {
|
|
|
+ if(helper[j].level <= baseLevel)
|
|
|
{
|
|
|
- whileCheck = false;
|
|
|
- helper[j].jump = lastLineChange - j;
|
|
|
+ helper[i].jump = j - i;
|
|
|
+ if(whileCheck)
|
|
|
+ {
|
|
|
+ whileCheck = false;
|
|
|
+ helper[j].jump = lastLineChange - j;
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
- break;
|
|
|
+ }
|
|
|
+ if(helper[i].jump == 0)
|
|
|
+ {
|
|
|
+ helper[i].jump = list.size() - i;
|
|
|
}
|
|
|
}
|
|
|
- if(helper[i].jump == 0)
|
|
|
+ // Ende der Srungmarken
|
|
|
+ // Korrektur der Gotos;
|
|
|
+ Code[] c = tree.toArray(new Code[list.size()]);
|
|
|
+ gotos.entrySet().forEach((i) ->
|
|
|
{
|
|
|
- helper[i].jump = list.size() - i;
|
|
|
- }
|
|
|
+ int value = i.getValue() + 1;
|
|
|
+ for(int j = value; j < c.length; j++)
|
|
|
+ {
|
|
|
+ if(c[j].line == value)
|
|
|
+ {
|
|
|
+ i.setValue(j);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ });
|
|
|
+ // Ende
|
|
|
+ //java.util.Arrays.stream(c).forEach(co -> System.out.println(co.toString()));
|
|
|
+ //gotos.forEach((k, v) -> System.out.println(k + " " + v));
|
|
|
+ //System.exit(0);
|
|
|
+ return c;
|
|
|
+ }
|
|
|
+ catch(PrescriptException ex)
|
|
|
+ {
|
|
|
+ ScriptUtils.printError("PrescriptException");
|
|
|
+ ScriptUtils.printError(ex.getBadString() + " - " + ex.getException());
|
|
|
+ return null;
|
|
|
}
|
|
|
- // Ende
|
|
|
-
|
|
|
- //tree.stream().forEach(c -> System.out.println(c.toString()));
|
|
|
- //gotos.forEach((k, v) -> System.out.println(k + " " + v));
|
|
|
- //System.exit(0);
|
|
|
- return tree.toArray(new Code[list.size()]);
|
|
|
}
|
|
|
|
|
|
private static int findOpenBracket(String code, int pos)
|
|
@@ -599,11 +643,15 @@ public class Code implements Comparable<Code>
|
|
|
}
|
|
|
pos++;
|
|
|
}
|
|
|
- return length;
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
private static int findClosingBracket(String code, int pos)
|
|
|
{
|
|
|
+ if(pos == -1)
|
|
|
+ {
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
int length = code.length();
|
|
|
char c;
|
|
|
boolean text = false;
|
|
@@ -623,18 +671,18 @@ public class Code implements Comparable<Code>
|
|
|
break;
|
|
|
case ')':
|
|
|
brackets--;
|
|
|
+ if(brackets == 0)
|
|
|
+ {
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
break;
|
|
|
case '"':
|
|
|
text = !text;
|
|
|
break;
|
|
|
}
|
|
|
- if(brackets == 0)
|
|
|
- {
|
|
|
- return pos;
|
|
|
- }
|
|
|
pos++;
|
|
|
}
|
|
|
- return code.length() - 1;
|
|
|
+ return -1;
|
|
|
}
|
|
|
|
|
|
private static ArrayList<String> splitComma(String code)
|
|
@@ -688,25 +736,22 @@ public class Code implements Comparable<Code>
|
|
|
sublines++;
|
|
|
int start = findOpenBracket(f, 0);
|
|
|
int end = findClosingBracket(f, start);
|
|
|
- if(start >= end - 1)
|
|
|
+ if((start != -1 || end != -1) && (((start == -1 || end == -1) && start != end) || end != f.length() - 1))
|
|
|
{
|
|
|
- if(start == f.length())
|
|
|
- {
|
|
|
- list.add(new Code(level, 0, line, sublines, convertInput(f.substring(0, start))));
|
|
|
- return;
|
|
|
- }
|
|
|
- list.add(new Code(f.substring(0, start), level, 0, line, sublines));
|
|
|
- return;
|
|
|
+ throw new PrescriptException("unbalanced ()", f);
|
|
|
}
|
|
|
- ArrayList<String> splitted = splitComma(f.substring(start + 1, end));
|
|
|
- if(start == f.length())
|
|
|
+ if(start == -1)
|
|
|
{
|
|
|
- list.add(new Code(level, 0, line, sublines, convertInput(f.substring(0, start))));
|
|
|
+ list.add(new Code(level, 0, line, sublines, convertInput(f)));
|
|
|
+ return;
|
|
|
}
|
|
|
- else
|
|
|
+ else if(start >= end - 1)
|
|
|
{
|
|
|
- list.add(new Code(f.substring(0, start), level, splitted.size(), line, sublines));
|
|
|
+ list.add(new Code(f.substring(0, start), level, 0, line, sublines));
|
|
|
+ return;
|
|
|
}
|
|
|
+ ArrayList<String> splitted = splitComma(f.substring(start + 1, end));
|
|
|
+ list.add(new Code(f.substring(0, start), level, splitted.size(), line, sublines));
|
|
|
splitted.forEach(s -> splitFunctions(list, s, level, line));
|
|
|
}
|
|
|
|