|
@@ -1,14 +1,14 @@
|
|
|
package me.hammerle.code;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
-import java.util.Collections;
|
|
|
import java.util.HashMap;
|
|
|
import java.util.Stack;
|
|
|
+import java.util.TreeSet;
|
|
|
|
|
|
public class Code implements Comparable<Code>
|
|
|
{
|
|
|
private final int line;
|
|
|
- private final int subline;
|
|
|
+ private int subline;
|
|
|
|
|
|
private final String function;
|
|
|
private final int level;
|
|
@@ -32,7 +32,7 @@ public class Code implements Comparable<Code>
|
|
|
this.line = line;
|
|
|
this.subline = subline;
|
|
|
this.value = value;
|
|
|
- this.jump = 0;
|
|
|
+ this.jump = jump;
|
|
|
}
|
|
|
|
|
|
public Code(String function, int level, int pars, int line, int subline)
|
|
@@ -93,6 +93,8 @@ public class Code implements Comparable<Code>
|
|
|
}
|
|
|
sb.append(" (");
|
|
|
sb.append(line);
|
|
|
+ sb.append(",");
|
|
|
+ sb.append(subline);
|
|
|
sb.append(") ");
|
|
|
|
|
|
if(value != null)
|
|
@@ -177,15 +179,283 @@ public class Code implements Comparable<Code>
|
|
|
return start;
|
|
|
}
|
|
|
|
|
|
+ private static int findStartOfSyntax(String code, int pos)
|
|
|
+ {
|
|
|
+ int bracketCounter = 0;
|
|
|
+ char c;
|
|
|
+ boolean text = false;
|
|
|
+ while(code.charAt(pos) == ' ')
|
|
|
+ {
|
|
|
+ pos--;
|
|
|
+ }
|
|
|
+ while(pos >= 0)
|
|
|
+ {
|
|
|
+ c = code.charAt(pos);
|
|
|
+ if(text && c != '"')
|
|
|
+ {
|
|
|
+ pos--;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ switch(c)
|
|
|
+ {
|
|
|
+ case ';':
|
|
|
+ case '{':
|
|
|
+ case '}':
|
|
|
+ case ' ':
|
|
|
+ case '+':
|
|
|
+ case '-':
|
|
|
+ case '*':
|
|
|
+ case '/':
|
|
|
+ case '^':
|
|
|
+ case '=':
|
|
|
+ if(bracketCounter != 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return pos + 1;
|
|
|
+ case '"':
|
|
|
+ text = !text;
|
|
|
+ break;
|
|
|
+ case ')':
|
|
|
+ bracketCounter++;
|
|
|
+ break;
|
|
|
+ case '(':
|
|
|
+ if(bracketCounter == 0)
|
|
|
+ {
|
|
|
+ return pos + 1;
|
|
|
+ }
|
|
|
+ bracketCounter--;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pos--;
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int findEndOfSyntax(String code, int pos)
|
|
|
+ {
|
|
|
+ int bracketCounter = 0;
|
|
|
+ char c;
|
|
|
+ boolean text = false;
|
|
|
+ while(code.charAt(pos) == ' ')
|
|
|
+ {
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ while(pos < code.length())
|
|
|
+ {
|
|
|
+ c = code.charAt(pos);
|
|
|
+ if(text && c != '"')
|
|
|
+ {
|
|
|
+ pos++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ switch(c)
|
|
|
+ {
|
|
|
+ case ';':
|
|
|
+ case '{':
|
|
|
+ case '}':
|
|
|
+ case ' ':
|
|
|
+ case '+':
|
|
|
+ case '-':
|
|
|
+ case '*':
|
|
|
+ case '/':
|
|
|
+ case '^':
|
|
|
+ case '=':
|
|
|
+ case '%':
|
|
|
+ if(bracketCounter != 0)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ return pos;
|
|
|
+ case '"':
|
|
|
+ text = !text;
|
|
|
+ break;
|
|
|
+ case '(':
|
|
|
+ bracketCounter++;
|
|
|
+ break;
|
|
|
+ case ')':
|
|
|
+ if(bracketCounter == 0)
|
|
|
+ {
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
+ bracketCounter--;
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ return code.length();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static int findSyntax(String find, String code, int pos)
|
|
|
+ {
|
|
|
+ int length = code.length();
|
|
|
+ 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);
|
|
|
+ if(s.startsWith(find) && !s.startsWith(find + "=") && code.charAt(pos - 1) != '=')
|
|
|
+ {
|
|
|
+ return pos;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ return -1;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String changeBiSyntax(String syntax, String f, String code, boolean b)
|
|
|
+ {
|
|
|
+ int pos = -1;
|
|
|
+ int end;
|
|
|
+ int start;
|
|
|
+ int slength = syntax.length();
|
|
|
+ StringBuilder sb = new StringBuilder(code);
|
|
|
+ StringBuilder newSyntax;
|
|
|
+ while(pos < sb.length())
|
|
|
+ {
|
|
|
+ pos = findSyntax(syntax, sb.toString(), pos + 1);
|
|
|
+ if(pos == -1)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start = findStartOfSyntax(sb.toString(), pos - 1);
|
|
|
+ end = findEndOfSyntax(sb.toString(), 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(")");
|
|
|
+ sb.replace(start, end, newSyntax.toString());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String changeUnSyntax(String syntax, String f, String code)
|
|
|
+ {
|
|
|
+ int pos = -1;
|
|
|
+ int end;
|
|
|
+ int start;
|
|
|
+ int slength = syntax.length();
|
|
|
+ String first;
|
|
|
+ StringBuilder sb = new StringBuilder(code);
|
|
|
+ StringBuilder newSyntax;
|
|
|
+ while(pos < sb.length())
|
|
|
+ {
|
|
|
+ pos = findSyntax(syntax, sb.toString(), pos + 1);
|
|
|
+ if(pos == -1)
|
|
|
+ {
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ start = findStartOfSyntax(sb.toString(), pos - 1);
|
|
|
+ end = findEndOfSyntax(sb.toString(), 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("))");
|
|
|
+ sb.replace(start, end, newSyntax.toString());
|
|
|
+ }
|
|
|
+ return sb.toString();
|
|
|
+ }
|
|
|
+
|
|
|
+ private static String replaceChar(char find, char replacement, String code)
|
|
|
+ {
|
|
|
+ char[] chars = code.toCharArray();
|
|
|
+ int length = code.length();
|
|
|
+ char c;
|
|
|
+ boolean text = false;
|
|
|
+ int pos = 0;
|
|
|
+ while(pos < length)
|
|
|
+ {
|
|
|
+ c = code.charAt(pos);
|
|
|
+ if(text && c != '"')
|
|
|
+ {
|
|
|
+ pos++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(c == '"')
|
|
|
+ {
|
|
|
+ text = !text;
|
|
|
+ pos++;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ if(c == find)
|
|
|
+ {
|
|
|
+ chars[pos] = replacement;
|
|
|
+ }
|
|
|
+ pos++;
|
|
|
+ }
|
|
|
+ return new String(chars);
|
|
|
+ }
|
|
|
+
|
|
|
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 pos = 0;
|
|
|
int old;
|
|
|
+ int pos = 0;
|
|
|
int line = 0;
|
|
|
while(pos < length)
|
|
|
{
|
|
@@ -215,13 +485,53 @@ public class Code implements Comparable<Code>
|
|
|
}
|
|
|
pos++;
|
|
|
}
|
|
|
- Collections.sort(list);
|
|
|
+ // 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 < list.size(); i++)
|
|
|
+ for(int i = 0; i < helper.length; i++)
|
|
|
{
|
|
|
- function = list.get(i).function;
|
|
|
+ function = helper[i].function;
|
|
|
+ if(function == null || !function.equals("while"))
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ baseLevel = helper[i].level;
|
|
|
+ for(int j = i + 1; j < helper.length; j++)
|
|
|
+ {
|
|
|
+ if(helper[j].level <= baseLevel)
|
|
|
+ {
|
|
|
+ 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;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ // 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;
|
|
@@ -230,32 +540,40 @@ public class Code implements Comparable<Code>
|
|
|
{
|
|
|
case "if":
|
|
|
case "else":
|
|
|
- case "while":
|
|
|
case "try":
|
|
|
case "catch":
|
|
|
break;
|
|
|
+ case "while":
|
|
|
+ whileCheck = true;
|
|
|
+ break;
|
|
|
default:
|
|
|
continue;
|
|
|
}
|
|
|
- baseLevel = list.get(i).level;
|
|
|
- for(int j = i + 1; j < list.size(); j++)
|
|
|
+ baseLevel = helper[i].level;
|
|
|
+ for(int j = i + 1; j < helper.length; j++)
|
|
|
{
|
|
|
- if(list.get(j).level == baseLevel)
|
|
|
+ if(helper[j].level <= baseLevel)
|
|
|
{
|
|
|
- list.get(i).jump = j - i;
|
|
|
+ helper[i].jump = j - i;
|
|
|
+ if(whileCheck)
|
|
|
+ {
|
|
|
+ whileCheck = false;
|
|
|
+ helper[j].jump = lastLineChange - j;
|
|
|
+ }
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- if(list.get(i).jump == 0)
|
|
|
+ if(helper[i].jump == 0)
|
|
|
{
|
|
|
- list.get(i).jump = list.size() - i;
|
|
|
+ helper[i].jump = list.size() - i;
|
|
|
}
|
|
|
}
|
|
|
+ // Ende
|
|
|
|
|
|
- //list.forEach(c -> System.out.println(c.toString()));
|
|
|
+ //tree.stream().forEach(c -> System.out.println(c.toString()));
|
|
|
//gotos.forEach((k, v) -> System.out.println(k + " " + v));
|
|
|
//System.exit(0);
|
|
|
- return list.toArray(new Code[list.size()]);
|
|
|
+ return tree.toArray(new Code[list.size()]);
|
|
|
}
|
|
|
|
|
|
private static int findOpenBracket(String code, int pos)
|
|
@@ -391,7 +709,7 @@ public class Code implements Comparable<Code>
|
|
|
}
|
|
|
splitted.forEach(s -> splitFunctions(list, s, level, line));
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
public static Object convertInput(String s)
|
|
|
{
|
|
|
if(s == null)
|