New logic parser
This commit is contained in:
@@ -4,9 +4,7 @@ import arc.func.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import mindustry.logic.LStatements.*;
|
||||
|
||||
/** "Compiles" a sequence of statements into instructions. */
|
||||
public class LAssembler{
|
||||
@@ -37,10 +35,10 @@ public class LAssembler{
|
||||
putConst("@tick", 0);
|
||||
}
|
||||
|
||||
public static LAssembler assemble(String data, int maxInstructions){
|
||||
public static LAssembler assemble(String data){
|
||||
LAssembler asm = new LAssembler();
|
||||
|
||||
Seq<LStatement> st = read(data, maxInstructions);
|
||||
Seq<LStatement> st = read(data);
|
||||
|
||||
asm.instructions = st.map(l -> l.build(asm)).filter(l -> l != null).toArray(LInstruction.class);
|
||||
return asm;
|
||||
@@ -57,107 +55,7 @@ public class LAssembler{
|
||||
}
|
||||
|
||||
public static Seq<LStatement> read(String data){
|
||||
return read(data, LExecutor.maxInstructions);
|
||||
}
|
||||
|
||||
public static Seq<LStatement> read(String data, int max){
|
||||
//empty data check
|
||||
if(data == null || data.isEmpty()) return new Seq<>();
|
||||
|
||||
Seq<LStatement> statements = new Seq<>();
|
||||
String[] lines = data.split("\n");
|
||||
int index = 0;
|
||||
for(String line : lines){
|
||||
if(line.isEmpty()) continue;
|
||||
//remove trailing semicolons in case someone adds them in for no reason
|
||||
if(line.endsWith(";")) line = line.substring(0, line.length() - 1);
|
||||
|
||||
if(index++ > max) break;
|
||||
|
||||
line = line.replace("\t", "").trim();
|
||||
|
||||
try{
|
||||
String[] arr;
|
||||
if(line.startsWith("#")) continue;
|
||||
|
||||
//yes, I am aware that this can be split with regex, but that's slow and even more incomprehensible
|
||||
if(line.contains(" ")){
|
||||
Seq<String> tokens = new Seq<>();
|
||||
boolean inString = false;
|
||||
int lastIdx = 0;
|
||||
|
||||
for(int i = 0; i < line.length() + 1; i++){
|
||||
char c = i == line.length() ? ' ' : line.charAt(i);
|
||||
if(c == '#' && !inString){
|
||||
break;
|
||||
}else if(c == '"'){
|
||||
inString = !inString;
|
||||
}else if(c == ' ' && !inString){
|
||||
tokens.add(line.substring(lastIdx, Math.min(i, lastIdx + maxTokenLength)));
|
||||
lastIdx = i + 1;
|
||||
}
|
||||
}
|
||||
|
||||
arr = tokens.toArray(String.class);
|
||||
}else{
|
||||
arr = new String[]{line};
|
||||
}
|
||||
|
||||
//nothing found
|
||||
if(arr.length == 0) continue;
|
||||
|
||||
String type = arr[0];
|
||||
|
||||
//legacy stuff
|
||||
if(type.equals("bop")){
|
||||
arr[0] = "op";
|
||||
|
||||
//field order for bop used to be op a, b, result, but now it's op result a b
|
||||
String res = arr[4];
|
||||
arr[4] = arr[3];
|
||||
arr[3] = arr[2];
|
||||
arr[2] = res;
|
||||
}else if(type.equals("uop")){
|
||||
arr[0] = "op";
|
||||
|
||||
if(arr[1].equals("negate")){
|
||||
arr = new String[]{
|
||||
"op", "mul", arr[3], arr[2], "-1"
|
||||
};
|
||||
}else{
|
||||
//field order for uop used to be op a, result, but now it's op result a
|
||||
String res = arr[3];
|
||||
arr[3] = arr[2];
|
||||
arr[2] = res;
|
||||
}
|
||||
}
|
||||
|
||||
//fix up changed operaiton names
|
||||
if(type.equals("op")){
|
||||
arr[1] = opNameChanges.get(arr[1], arr[1]);
|
||||
}
|
||||
|
||||
LStatement st = LogicIO.read(arr);
|
||||
|
||||
if(st != null){
|
||||
statements.add(st);
|
||||
}else{
|
||||
//attempt parsing using custom parser if a match is found - this is for mods
|
||||
String first = arr[0];
|
||||
if(customParsers.containsKey(first)){
|
||||
statements.add(customParsers.get(first).get(arr));
|
||||
}else{
|
||||
//unparseable statement
|
||||
statements.add(new InvalidStatement());
|
||||
}
|
||||
}
|
||||
}catch(Exception parseFailed){
|
||||
parseFailed.printStackTrace();
|
||||
//when parsing fails, add a dummy invalid statement
|
||||
statements.add(new InvalidStatement());
|
||||
}
|
||||
}
|
||||
return statements;
|
||||
return LParser.parse(data);
|
||||
}
|
||||
|
||||
/** @return a variable ID by name.
|
||||
@@ -172,7 +70,7 @@ public class LAssembler{
|
||||
symbol = symbol.trim();
|
||||
|
||||
//string case
|
||||
if(symbol.startsWith("\"") && symbol.endsWith("\"")){
|
||||
if(!symbol.isEmpty() && symbol.charAt(0) == '\"' && symbol.charAt(symbol.length() - 1) == '\"'){
|
||||
return putConst("___" + symbol, symbol.substring(1, symbol.length() - 1).replace("\\n", "\n")).id;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user