New logic parser

This commit is contained in:
Anuken
2021-03-09 15:47:19 -05:00
parent 4f37f29ae8
commit ae2736d393
5 changed files with 158 additions and 126 deletions

View File

@@ -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;
}