|
@@ -2,10 +2,8 @@ package me.hammerle.code;
|
|
|
|
|
|
import java.util.ArrayList;
|
|
|
import java.util.HashMap;
|
|
|
-import java.util.LinkedList;
|
|
|
import java.util.Stack;
|
|
|
import me.hammerle.exceptions.PreScriptException;
|
|
|
-import me.hammerle.exceptions.NoSuchMethodException;
|
|
|
import me.hammerle.math.Fraction;
|
|
|
|
|
|
public class Code
|
|
@@ -13,24 +11,26 @@ public class Code
|
|
|
protected final int realLine;
|
|
|
protected final String function;
|
|
|
protected final int pars;
|
|
|
+ protected final byte layer;
|
|
|
protected Object value;
|
|
|
|
|
|
- private Code(String function, int pars, Object value, int realLine)
|
|
|
+ private Code(String function, int pars, Object value, int realLine, byte layer)
|
|
|
{
|
|
|
this.function = function;
|
|
|
this.pars = pars;
|
|
|
this.value = value;
|
|
|
this.realLine = realLine;
|
|
|
+ this.layer = layer;
|
|
|
}
|
|
|
|
|
|
- public Code(String function, int pars, int realLine)
|
|
|
+ public Code(String function, int pars, int realLine, byte layer)
|
|
|
{
|
|
|
- this(function, pars, null, realLine);
|
|
|
+ this(function, pars, null, realLine, layer);
|
|
|
}
|
|
|
|
|
|
- public Code(Object value, int realLine)
|
|
|
+ public Code(Object value, int realLine, byte layer)
|
|
|
{
|
|
|
- this(null, 0, value, realLine);
|
|
|
+ this(null, 0, value, realLine, layer);
|
|
|
}
|
|
|
|
|
|
public void executeFunction(SnuviParser parser, Script sc, Stack<Object> stack)
|
|
@@ -73,39 +73,40 @@ public class Code
|
|
|
@Override
|
|
|
public String toString()
|
|
|
{
|
|
|
- StringBuilder sb = new StringBuilder("(");
|
|
|
+ StringBuilder sb = new StringBuilder();
|
|
|
sb.append(realLine);
|
|
|
- sb.append(") ");
|
|
|
+ sb.append("| ");
|
|
|
+
|
|
|
+ for(int i = -1; i < layer; i++)
|
|
|
+ {
|
|
|
+ sb.append('>');
|
|
|
+ }
|
|
|
+ sb.append(' ');
|
|
|
|
|
|
if(function != null)
|
|
|
{
|
|
|
- sb.append("function '");
|
|
|
+ sb.append("call ");
|
|
|
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(' ');
|
|
|
+ sb.append(pars);
|
|
|
+
|
|
|
if(value != null)
|
|
|
{
|
|
|
- sb.append("(");
|
|
|
+ sb.append(" (");
|
|
|
sb.append(value);
|
|
|
sb.append(")");
|
|
|
}
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- sb.append("push '");
|
|
|
- sb.append(value);
|
|
|
- sb.append("' ");
|
|
|
+ sb.append("push ");
|
|
|
if(value != null)
|
|
|
{
|
|
|
sb.append(value.getClass().getSimpleName());
|
|
|
}
|
|
|
+ sb.append(" '");
|
|
|
+ sb.append(value);
|
|
|
+ sb.append("'");
|
|
|
return sb.toString();
|
|
|
}
|
|
|
return sb.toString();
|
|
@@ -122,7 +123,7 @@ public class Code
|
|
|
int length = code.length();
|
|
|
while(pos < length)
|
|
|
{
|
|
|
- if(!Character.isLetterOrDigit(code.charAt(pos)))
|
|
|
+ if(!Character.isLetterOrDigit(code.charAt(pos)) && code.charAt(pos) != '_')
|
|
|
{
|
|
|
return pos;
|
|
|
}
|
|
@@ -131,132 +132,6 @@ public class Code
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- 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, countChar('\n', pos, code), "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, countChar('\n', pos, code), "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();
|
|
@@ -271,22 +146,6 @@ public class Code
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- private static int findSyntax(String find, StringBuilder code, int pos)
|
|
|
- {
|
|
|
- int length = code.length();
|
|
|
- String s = code.toString();
|
|
|
- while(pos < length)
|
|
|
- {
|
|
|
- // additionel check for e.g. difference between + and +=
|
|
|
- if(s.startsWith(find, pos) && !s.startsWith(find + "=", pos) && (pos == 0 || code.charAt(pos - 1) != '='))
|
|
|
- {
|
|
|
- return pos;
|
|
|
- }
|
|
|
- pos++;
|
|
|
- }
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
private static int findSyntaxIgnoreString(String find, StringBuilder code, int pos)
|
|
|
{
|
|
|
int length = code.length();
|
|
@@ -315,77 +174,6 @@ public class Code
|
|
|
}
|
|
|
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());
|
|
|
- }
|
|
|
- }
|
|
|
|
|
|
public static int countChar(char find, int end, StringBuilder code)
|
|
|
{
|
|
@@ -403,32 +191,7 @@ public class Code
|
|
|
return counter;
|
|
|
}
|
|
|
|
|
|
- private static void addKeyWordBrackets(String keyWord, StringBuilder sb)
|
|
|
- {
|
|
|
- String with = keyWord + "()";
|
|
|
- int length = keyWord.length();
|
|
|
- int pos = 0;
|
|
|
- while(true)
|
|
|
- {
|
|
|
- pos = sb.indexOf(keyWord, pos);
|
|
|
- if(pos + length >= sb.length())
|
|
|
- {
|
|
|
- throw new PreScriptException(scriptName, countChar('\n', pos, sb), "unexpected keyword");
|
|
|
- }
|
|
|
- else if(pos == -1 ||
|
|
|
- (pos >= 1 && Character.isLetterOrDigit(sb.charAt(pos - 1))) ||
|
|
|
- (Character.isLetterOrDigit(sb.charAt(pos + length))))
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- else if(sb.charAt(pos + length) != '(')
|
|
|
- {
|
|
|
- sb.replace(pos, pos + length, with);
|
|
|
- }
|
|
|
- pos += length;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
+ @SuppressWarnings("")
|
|
|
private static String removeNonSyntax(String s)
|
|
|
{
|
|
|
StringBuilder sb = new StringBuilder(s);
|
|
@@ -448,21 +211,10 @@ public class Code
|
|
|
return sb.toString();
|
|
|
}
|
|
|
|
|
|
- public static Code[] generate(SnuviParser parser, String scriptName, String code, HashMap<String, Integer> gotos)
|
|
|
+ private static void removeComments(StringBuilder sb)
|
|
|
{
|
|
|
- System.out.println("START GENERATE");
|
|
|
- long startTime = System.currentTimeMillis();
|
|
|
-
|
|
|
- Code.scriptName = scriptName;
|
|
|
-
|
|
|
int old = 0;
|
|
|
int pos;
|
|
|
- StringBuilder sb = new StringBuilder(code);
|
|
|
-
|
|
|
- // ---------------------------------------------------------------------
|
|
|
- // comments
|
|
|
- // ---------------------------------------------------------------------
|
|
|
-
|
|
|
while(true)
|
|
|
{
|
|
|
old = findSyntaxIgnoreString("/*", sb, old);
|
|
@@ -493,12 +245,12 @@ public class Code
|
|
|
}
|
|
|
sb.delete(old, pos + 1);
|
|
|
}
|
|
|
-
|
|
|
- // ---------------------------------------------------------------------
|
|
|
- // replacing Strings with #... to get rid of "
|
|
|
- // ---------------------------------------------------------------------
|
|
|
-
|
|
|
- pos = 0;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static HashMap<String, String> replaceStrings(StringBuilder sb)
|
|
|
+ {
|
|
|
+ int old;
|
|
|
+ int pos = 0;
|
|
|
String replacement;
|
|
|
String text;
|
|
|
int stringIndex = 0;
|
|
@@ -527,12 +279,13 @@ public class Code
|
|
|
}
|
|
|
pos++;
|
|
|
}
|
|
|
-
|
|
|
- // ---------------------------------------------------------------------
|
|
|
- // allowing labels without ;
|
|
|
- // ---------------------------------------------------------------------
|
|
|
-
|
|
|
- old = 0;
|
|
|
+ return strings;
|
|
|
+ }
|
|
|
+
|
|
|
+ private static void formatLabels(StringBuilder sb)
|
|
|
+ {
|
|
|
+ int pos;
|
|
|
+ int old = 0;
|
|
|
while(true)
|
|
|
{
|
|
|
pos = findChar('@', sb, old);
|
|
@@ -552,58 +305,34 @@ public class Code
|
|
|
sb.insert(pos, ';');
|
|
|
}
|
|
|
}
|
|
|
+ }
|
|
|
+
|
|
|
+ public static Code[] generate(SnuviParser parser, String scriptName, String code, HashMap<String, Integer> gotos)
|
|
|
+ {
|
|
|
+ System.out.print("Starting '" + scriptName + "' ... ");
|
|
|
+ long startTime = System.currentTimeMillis();
|
|
|
+
|
|
|
+ Code.scriptName = scriptName;
|
|
|
+
|
|
|
+ StringBuilder sb = new StringBuilder(code);
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
- // allowing key words without ()
|
|
|
+ // comments
|
|
|
// ---------------------------------------------------------------------
|
|
|
-
|
|
|
- addKeyWordBrackets("else", sb);
|
|
|
- addKeyWordBrackets("try", sb);
|
|
|
- addKeyWordBrackets("catch", sb);
|
|
|
+
|
|
|
+ removeComments(sb);
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
- // replacing of function syntax
|
|
|
+ // replacing Strings with #... to get rid of "
|
|
|
// ---------------------------------------------------------------------
|
|
|
-
|
|
|
- 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);
|
|
|
+
|
|
|
+ HashMap<String, String> strings = replaceStrings(sb);
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
|
- // numbers like -5 turn to sub(,5) --> fixing
|
|
|
+ // allowing labels without ;
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
- pos = 0;
|
|
|
- while(true)
|
|
|
- {
|
|
|
- pos = findSyntax("sub(,", sb, pos);
|
|
|
- if(pos == -1)
|
|
|
- {
|
|
|
- break;
|
|
|
- }
|
|
|
- sb.insert(pos + 4, '0');
|
|
|
- pos++;
|
|
|
- }
|
|
|
+ formatLabels(sb);
|
|
|
|
|
|
code = sb.toString();
|
|
|
|
|
@@ -614,8 +343,8 @@ public class Code
|
|
|
ArrayList<String> lines = new ArrayList<>();
|
|
|
int lineCounter = 1;
|
|
|
ArrayList<Integer> realCodeLine = new ArrayList<>();
|
|
|
- old = 0;
|
|
|
- pos = 0;
|
|
|
+ int old = 0;
|
|
|
+ int pos = 0;
|
|
|
int length = code.length();
|
|
|
int counter = 0;
|
|
|
int bracketCounter = 0;
|
|
@@ -689,26 +418,34 @@ public class Code
|
|
|
// ---------------------------------------------------------------------
|
|
|
// generating byte code
|
|
|
// ---------------------------------------------------------------------
|
|
|
-
|
|
|
+
|
|
|
+ LineCompiler compiler = new LineCompiler(parser, scriptName);
|
|
|
ArrayList<Code> co = new ArrayList<>();
|
|
|
- Stack<Integer> parCounter = new Stack<>();
|
|
|
- char current;
|
|
|
- char previous;
|
|
|
- int layer = 0;
|
|
|
int line;
|
|
|
- boolean noFunction;
|
|
|
- LinkedList<Integer> whileStart = new LinkedList<>();
|
|
|
+ byte layer = 0;
|
|
|
String s;
|
|
|
for(int i = 0; i < lines.size(); i++)
|
|
|
{
|
|
|
s = lines.get(i);
|
|
|
- if(s.isEmpty())
|
|
|
+ //System.out.println(s);
|
|
|
+ if(s.isEmpty() || s.equals("{"))
|
|
|
{
|
|
|
continue;
|
|
|
}
|
|
|
- else if(s.startsWith("while"))
|
|
|
+ else if(lines.get(Math.min(i + 1, lines.size() - 1)).equals("{"))
|
|
|
+ {
|
|
|
+ layer++;
|
|
|
+ if(s.equals("try") || s.equals("catch") || s.equals("else"))
|
|
|
+ {
|
|
|
+ co.add(new Code(s, 0, realCodeLine.get(i), layer));
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else if(s.equals("}"))
|
|
|
{
|
|
|
- whileStart.push(co.size());
|
|
|
+ layer--;
|
|
|
+ co.add(new Code("gotoline", 0, realCodeLine.get(i), layer));
|
|
|
+ continue;
|
|
|
}
|
|
|
else if(s.charAt(0) == '@')
|
|
|
{
|
|
@@ -716,68 +453,8 @@ public class Code
|
|
|
continue;
|
|
|
}
|
|
|
line = realCodeLine.get(i);
|
|
|
- previous = ',';
|
|
|
- noFunction = true;
|
|
|
- pos = s.length() - 1;
|
|
|
- while(pos >= 0)
|
|
|
- {
|
|
|
- current = s.charAt(pos);
|
|
|
- switch(current)
|
|
|
- {
|
|
|
- case ')':
|
|
|
- parCounter.add(0);
|
|
|
- if(previous != ',' && previous != ')')
|
|
|
- {
|
|
|
- throw new PreScriptException(scriptName, line, "unexpected )");
|
|
|
- }
|
|
|
- old = pos;
|
|
|
- break;
|
|
|
- case '(':
|
|
|
- if(previous != ')')
|
|
|
- {
|
|
|
- parCounter.set(parCounter.size() - 1, parCounter.lastElement() + 1);
|
|
|
- if(noFunction)
|
|
|
- {
|
|
|
- co.add(new Code(Code.convertInput(strings, s.substring(pos + 1, old), true), line));
|
|
|
- }
|
|
|
- }
|
|
|
- old = pos;
|
|
|
- pos--;
|
|
|
- while(pos >= 0 && (Character.isLetterOrDigit(s.charAt(pos))
|
|
|
- || s.charAt(pos) == '_' || s.charAt(pos) == '.'))
|
|
|
- {
|
|
|
- pos--;
|
|
|
- }
|
|
|
- pos++;
|
|
|
- String functionName = s.substring(pos, old).toLowerCase();
|
|
|
- if(!parser.isRegisteredFunction(functionName))
|
|
|
- {
|
|
|
- throw new NoSuchMethodException(scriptName, line, functionName);
|
|
|
- }
|
|
|
- co.add(new Code(functionName, parCounter.pop(), line));
|
|
|
- noFunction = false;
|
|
|
- break;
|
|
|
- case ',':
|
|
|
- parCounter.set(parCounter.size() - 1, parCounter.lastElement() + 1);
|
|
|
- if(noFunction)
|
|
|
- {
|
|
|
- co.add(new Code(Code.convertInput(strings, s.substring(pos + 1, old), true), line));
|
|
|
- }
|
|
|
- old = pos;
|
|
|
- noFunction = true;
|
|
|
- break;
|
|
|
- case '{':
|
|
|
- layer++;
|
|
|
- co.add(new Code("goto", 0, layer, line));
|
|
|
- break;
|
|
|
- case '}':
|
|
|
- co.add(new Code("goto", 0, layer, line));
|
|
|
- layer--;
|
|
|
- break;
|
|
|
- }
|
|
|
- pos--;
|
|
|
- previous = current;
|
|
|
- }
|
|
|
+ compiler.reset(line, layer, s);
|
|
|
+ compiler.compile(co, strings);
|
|
|
}
|
|
|
|
|
|
// ---------------------------------------------------------------------
|
|
@@ -785,49 +462,74 @@ public class Code
|
|
|
// ---------------------------------------------------------------------
|
|
|
|
|
|
Code[] c = co.toArray(new Code[co.size()]);
|
|
|
+ //java.util.Arrays.stream(c).forEach(cod -> System.out.println(cod.toString()));
|
|
|
+
|
|
|
+ //System.exit(0);
|
|
|
+ int oldLayer = 0;
|
|
|
+ int newLayer;
|
|
|
for(int i = 0; i < c.length; i++)
|
|
|
{
|
|
|
- if("goto".equals(c[i].function) && c[i].value != null)
|
|
|
+ newLayer = c[i].layer;
|
|
|
+ if(oldLayer < newLayer)
|
|
|
{
|
|
|
- Object value = c[i].value;
|
|
|
- if((int) value <= 0)
|
|
|
+ int j = findKeyWord(i, c);
|
|
|
+ if(j == 0)
|
|
|
{
|
|
|
- continue;
|
|
|
+ //java.util.Arrays.stream(c).forEach(cod -> System.out.println(cod.toString()));
|
|
|
+ throw new PreScriptException(scriptName, c[i].realLine, "well, fuck this, this should never happen");
|
|
|
}
|
|
|
- for(int j = i + 1; j < c.length; j++)
|
|
|
+ boolean jumpBack = j < 0;
|
|
|
+ j = Math.abs(j);
|
|
|
+ int k;
|
|
|
+ for(k = j; k < c.length; k++)
|
|
|
{
|
|
|
- if(value.equals(c[j].value))
|
|
|
+ if(c[k].layer < newLayer)
|
|
|
{
|
|
|
- c[i].value = j - i;
|
|
|
- switch(c[i-1].function)
|
|
|
- {
|
|
|
- case "while":
|
|
|
- c[j].value = whileStart.pollLast() - j - 1;
|
|
|
- break;
|
|
|
- /*case "if":
|
|
|
- case "else":
|
|
|
- case "try":
|
|
|
- case "catch":
|
|
|
- c[j].value = 0;
|
|
|
- break;*/
|
|
|
- default:
|
|
|
- c[j].value = 0;
|
|
|
- break;
|
|
|
- }
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
- }
|
|
|
+ c[j].value = k - j;
|
|
|
+ if(jumpBack)
|
|
|
+ {
|
|
|
+ c[k].value = i - k - 1;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ c[k].value = 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ oldLayer = newLayer;
|
|
|
}
|
|
|
|
|
|
// end
|
|
|
- System.out.println("END GENERATE - " + (System.currentTimeMillis() - startTime));
|
|
|
+ System.out.println((System.currentTimeMillis() - startTime) + " ms");
|
|
|
//java.util.Arrays.stream(c).forEach(cod -> System.out.println(cod.toString()));
|
|
|
//gotos.forEach((k, v) -> System.out.println("Lable " + k + " " + v));
|
|
|
//System.exit(0);
|
|
|
return c;
|
|
|
}
|
|
|
|
|
|
+ private static int findKeyWord(int start, Code[] c)
|
|
|
+ {
|
|
|
+ for(int j = start; j < c.length; j++)
|
|
|
+ {
|
|
|
+ if(c[j].function != null)
|
|
|
+ {
|
|
|
+ switch(c[j].function)
|
|
|
+ {
|
|
|
+ case "while":
|
|
|
+ return -j;
|
|
|
+ case "if":
|
|
|
+ case "else":
|
|
|
+ case "try":
|
|
|
+ case "catch":
|
|
|
+ return j;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+
|
|
|
public static Object convertInput(HashMap<String, String> map, String s, boolean variable)
|
|
|
{
|
|
|
if(s == null)
|
|
@@ -895,3 +597,4 @@ public class Code
|
|
|
return convertInput(null, s, false);
|
|
|
}
|
|
|
}
|
|
|
+// 916
|