Logic progress
This commit is contained in:
@@ -2,8 +2,11 @@ package mindustry.logic;
|
||||
|
||||
import arc.func.*;
|
||||
import arc.struct.*;
|
||||
import arc.util.ArcAnnotate.*;
|
||||
import mindustry.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
/** "Compiles" a sequence of statements into instructions. */
|
||||
public class LAssembler{
|
||||
@@ -16,10 +19,23 @@ public class LAssembler{
|
||||
LInstruction[] instructions;
|
||||
|
||||
public LAssembler(){
|
||||
putVar("@counter");
|
||||
putConst("@time", 0);
|
||||
|
||||
//add default constants
|
||||
putConst("false", 0);
|
||||
putConst("true", 1);
|
||||
putConst("null", null);
|
||||
|
||||
//store base content (TODO hacky?)
|
||||
|
||||
for(Item item : Vars.content.items()){
|
||||
putConst("@" + item.name, item);
|
||||
}
|
||||
|
||||
for(Liquid liquid : Vars.content.liquids()){
|
||||
putConst("@" + liquid.name, liquid);
|
||||
}
|
||||
}
|
||||
|
||||
public static LAssembler assemble(String data){
|
||||
@@ -84,7 +100,7 @@ public class LAssembler{
|
||||
}
|
||||
|
||||
/** Adds a constant value by name. */
|
||||
BVar putConst(String name, Object value){
|
||||
public BVar putConst(String name, Object value){
|
||||
BVar var = putVar(name);
|
||||
var.constant = true;
|
||||
var.value = value;
|
||||
@@ -92,7 +108,7 @@ public class LAssembler{
|
||||
}
|
||||
|
||||
/** Registers a variable name mapping. */
|
||||
BVar putVar(String name){
|
||||
public BVar putVar(String name){
|
||||
if(vars.containsKey(name)){
|
||||
return vars.get(name);
|
||||
}else{
|
||||
@@ -102,7 +118,11 @@ public class LAssembler{
|
||||
}
|
||||
}
|
||||
|
||||
/** A saved variable. */
|
||||
public @Nullable BVar getVar(String name){
|
||||
return vars.get(name);
|
||||
}
|
||||
|
||||
/** A variable "builder". */
|
||||
public static class BVar{
|
||||
public int id;
|
||||
public boolean constant;
|
||||
@@ -113,5 +133,14 @@ public class LAssembler{
|
||||
}
|
||||
|
||||
BVar(){}
|
||||
|
||||
@Override
|
||||
public String toString(){
|
||||
return "BVar{" +
|
||||
"id=" + id +
|
||||
", constant=" + constant +
|
||||
", value=" + value +
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,8 @@ import mindustry.graphics.*;
|
||||
public enum LCategory{
|
||||
blocks(Pal.accentBack),
|
||||
control(Color.cyan.cpy().shiftSaturation(-0.6f).mul(0.7f)),
|
||||
operations(Pal.place.cpy().shiftSaturation(-0.5f).mul(0.7f));
|
||||
operations(Pal.place.cpy().shiftSaturation(-0.5f).mul(0.7f)),
|
||||
io(Pal.remove.cpy().shiftSaturation(-0.5f).mul(0.7f));;
|
||||
|
||||
public final Color color;
|
||||
|
||||
|
||||
@@ -4,59 +4,56 @@ import arc.util.ArcAnnotate.*;
|
||||
import arc.util.*;
|
||||
import mindustry.*;
|
||||
import mindustry.gen.*;
|
||||
import mindustry.type.*;
|
||||
|
||||
public class LExecutor{
|
||||
LInstruction[] instructions;
|
||||
int counter;
|
||||
//special variables
|
||||
public static final int
|
||||
varCounter = 0,
|
||||
varTime = 1;
|
||||
|
||||
//values of all the variables
|
||||
Var[] vars;
|
||||
public double[] memory = {};
|
||||
public LInstruction[] instructions = {};
|
||||
public Var[] vars = {};
|
||||
|
||||
public boolean initialized(){
|
||||
return instructions != null && vars != null && instructions.length > 0;
|
||||
}
|
||||
|
||||
/** Runs all the instructions at once. Debugging only! */
|
||||
public void runAll(){
|
||||
counter = 0;
|
||||
|
||||
while(counter < instructions.length){
|
||||
instructions[counter++].run(this);
|
||||
}
|
||||
}
|
||||
|
||||
/** Runs a single instruction. */
|
||||
public void runOnce(){
|
||||
//reset to start
|
||||
if(counter >= instructions.length) counter = 0;
|
||||
//set time
|
||||
vars[varTime].numval = Time.millis();
|
||||
|
||||
if(counter < instructions.length){
|
||||
instructions[counter++].run(this);
|
||||
//reset to start
|
||||
if(vars[varCounter].numval >= instructions.length) vars[varCounter].numval = 0;
|
||||
|
||||
if(vars[varCounter].numval < instructions.length){
|
||||
instructions[(int)(vars[varCounter].numval++)].run(this);
|
||||
}
|
||||
}
|
||||
|
||||
public void load(Object context, String data){
|
||||
load(context,LAssembler.assemble(data));
|
||||
public void load(String data){
|
||||
load(LAssembler.assemble(data));
|
||||
}
|
||||
|
||||
public void load(Object context, LAssembler builder){
|
||||
builder.putConst("this", context);
|
||||
|
||||
/** Loads with a specified assembler. Resets all variables. */
|
||||
public void load(LAssembler builder){
|
||||
vars = new Var[builder.vars.size];
|
||||
instructions = builder.instructions;
|
||||
counter = 0;
|
||||
|
||||
builder.vars.each((name, var) -> {
|
||||
Var v = new Var();
|
||||
vars[var.id] = v;
|
||||
Var dest = new Var(name);
|
||||
vars[var.id] = dest;
|
||||
|
||||
if(var.constant){
|
||||
v.constant = true;
|
||||
if(var.value instanceof Number){
|
||||
v.numval = ((Number)var.value).doubleValue();
|
||||
}else{
|
||||
v.isobj = true;
|
||||
v.objval = var.value;
|
||||
}
|
||||
dest.constant = var.constant;
|
||||
|
||||
if(var.value instanceof Number){
|
||||
dest.isobj = false;
|
||||
dest.numval = ((Number)var.value).doubleValue();
|
||||
}else{
|
||||
dest.isobj = true;
|
||||
dest.objval = var.value;
|
||||
}
|
||||
});
|
||||
}
|
||||
@@ -65,12 +62,17 @@ public class LExecutor{
|
||||
|
||||
@Nullable Building building(int index){
|
||||
Object o = vars[index].objval;
|
||||
return o == null && o instanceof Building ? (Building)o : null;
|
||||
return vars[index].isobj && o instanceof Building ? (Building)o : null;
|
||||
}
|
||||
|
||||
@Nullable Object obj(int index){
|
||||
Object o = vars[index].objval;
|
||||
return vars[index].isobj ? o : null;
|
||||
}
|
||||
|
||||
boolean bool(int index){
|
||||
Var v = vars[index];
|
||||
return v.isobj ? v.objval != null : Math.abs(v.numval) < 0.0001;
|
||||
return v.isobj ? v.objval != null : Math.abs(v.numval) >= 0.00001;
|
||||
}
|
||||
|
||||
double num(int index){
|
||||
@@ -78,11 +80,6 @@ public class LExecutor{
|
||||
return v.isobj ? 0 : v.numval;
|
||||
}
|
||||
|
||||
String str(int index){
|
||||
Var v = vars[index];
|
||||
return v.isobj ? String.valueOf(v.objval) : String.valueOf(v.numval);
|
||||
}
|
||||
|
||||
int numi(int index){
|
||||
return (int)num(index);
|
||||
}
|
||||
@@ -104,11 +101,17 @@ public class LExecutor{
|
||||
|
||||
//endregion
|
||||
|
||||
static class Var{
|
||||
boolean isobj, constant;
|
||||
public static class Var{
|
||||
public final String name;
|
||||
|
||||
Object objval;
|
||||
double numval;
|
||||
public boolean isobj, constant;
|
||||
|
||||
public Object objval;
|
||||
public double numval;
|
||||
|
||||
public Var(String name){
|
||||
this.name = name;
|
||||
}
|
||||
}
|
||||
|
||||
//region instruction types
|
||||
@@ -135,11 +138,74 @@ public class LExecutor{
|
||||
}
|
||||
}
|
||||
|
||||
public static class SenseI implements LInstruction{
|
||||
public static class ReadI implements LInstruction{
|
||||
public int from, to;
|
||||
|
||||
public ReadI(int from, int to){
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public ReadI(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
int address = exec.numi(from);
|
||||
|
||||
exec.setnum(to,address < 0 || address >= exec.memory.length ? 0 : exec.memory[address]);
|
||||
}
|
||||
}
|
||||
|
||||
public static class WriteI implements LInstruction{
|
||||
public int from, to;
|
||||
|
||||
public WriteI(int from, int to){
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
}
|
||||
|
||||
public WriteI(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
int address = exec.numi(to);
|
||||
|
||||
if(address >= 0 && address < exec.memory.length){
|
||||
exec.memory[address] = exec.num(from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class SenseI implements LInstruction{
|
||||
public int from, to, type;
|
||||
|
||||
public SenseI(int from, int to, int type){
|
||||
this.from = from;
|
||||
this.to = to;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public SenseI(){
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Building build = exec.building(from);
|
||||
Object sense = exec.obj(type);
|
||||
|
||||
double output = 0;
|
||||
|
||||
if(build != null){
|
||||
if(sense instanceof Item && build.items != null){
|
||||
output = build.items.get((Item)sense);
|
||||
}else if(sense instanceof Liquid && build.liquids != null){
|
||||
output = build.liquids.get((Liquid)sense);
|
||||
}
|
||||
}
|
||||
|
||||
exec.setnum(to, output);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -195,22 +261,48 @@ public class LExecutor{
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
exec.counter = exec.instructions.length;
|
||||
exec.vars[varCounter].numval = exec.instructions.length;
|
||||
}
|
||||
}
|
||||
|
||||
public static class PrintI implements LInstruction{
|
||||
public int value;
|
||||
private static final StringBuilder out = new StringBuilder();
|
||||
|
||||
public PrintI(int value){
|
||||
public int value, target;
|
||||
|
||||
public PrintI(int value, int target){
|
||||
this.value = value;
|
||||
this.target = target;
|
||||
}
|
||||
|
||||
PrintI(){}
|
||||
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
Log.info(exec.str(value));
|
||||
Building b = exec.building(target);
|
||||
|
||||
if(b == null) return;
|
||||
|
||||
//this should avoid any garbage allocation
|
||||
Var v = exec.vars[value];
|
||||
if(v.isobj){
|
||||
if(v.objval instanceof String){
|
||||
b.handleString(v.objval);
|
||||
}else if(v.objval == null){
|
||||
b.handleString("null");
|
||||
}else{
|
||||
b.handleString("[object]");
|
||||
}
|
||||
}else{
|
||||
out.setLength(0);
|
||||
//display integer version when possible
|
||||
if(Math.abs(v.numval - (int)v.numval) < 0.000001){
|
||||
out.append((int)v.numval);
|
||||
}else{
|
||||
out.append(v.numval);
|
||||
}
|
||||
b.handleString(out);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -227,7 +319,7 @@ public class LExecutor{
|
||||
@Override
|
||||
public void run(LExecutor exec){
|
||||
if(to != -1 && exec.bool(cond)){
|
||||
exec.counter = to;
|
||||
exec.vars[varCounter].numval = to;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,13 +3,102 @@ package mindustry.logic;
|
||||
import arc.graphics.*;
|
||||
import arc.scene.ui.*;
|
||||
import arc.scene.ui.layout.*;
|
||||
import arc.util.*;
|
||||
import mindustry.annotations.Annotations.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import mindustry.logic.LCanvas.*;
|
||||
import mindustry.logic.LExecutor.*;
|
||||
import mindustry.ui.*;
|
||||
|
||||
public class LStatements{
|
||||
|
||||
@RegisterStatement("write")
|
||||
public static class WriteStatement extends LStatement{
|
||||
public String to = "0";
|
||||
public String from = "result";
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
Log.info("mem:: ");
|
||||
|
||||
table.field(to, Styles.nodeField, str -> to = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
|
||||
table.add(" = ");
|
||||
|
||||
table.field(from, Styles.nodeField, str -> from = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LCategory category(){
|
||||
return LCategory.io;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LInstruction build(LAssembler builder){
|
||||
return new WriteI(builder.var(from), builder.var(to));
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterStatement("read")
|
||||
public static class ReadStatement extends LStatement{
|
||||
public String to = "result";
|
||||
public String from = "0";
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
table.field(to, Styles.nodeField, str -> to = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
|
||||
table.add(" = mem:: ");
|
||||
|
||||
table.field(from, Styles.nodeField, str -> from = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LCategory category(){
|
||||
return LCategory.io;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LInstruction build(LAssembler builder){
|
||||
return new ReadI(builder.var(from), builder.var(to));
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterStatement("sensor")
|
||||
public static class SensorStatement extends LStatement{
|
||||
public String to = "result";
|
||||
public String from = "@0", type = "@copper";
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
table.field(to, Styles.nodeField, str -> to = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
|
||||
table.add(" = ");
|
||||
|
||||
table.field(type, Styles.nodeField, str -> type = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
|
||||
table.add(" in ");
|
||||
|
||||
table.field(from, Styles.nodeField, str -> from = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LCategory category(){
|
||||
return LCategory.operations;
|
||||
}
|
||||
|
||||
@Override
|
||||
public LInstruction build(LAssembler builder){
|
||||
return new SenseI(builder.var(from), builder.var(to), builder.var(type));
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterStatement("set")
|
||||
public static class SetStatement extends LStatement{
|
||||
public String to = "result";
|
||||
@@ -122,16 +211,22 @@ public class LStatements{
|
||||
@RegisterStatement("print")
|
||||
public static class PrintStatement extends LStatement{
|
||||
public String value = "\"frog\"";
|
||||
public String target = "result";
|
||||
|
||||
@Override
|
||||
public void build(Table table){
|
||||
table.field(value, Styles.nodeField, str -> value = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
|
||||
table.add(" to ");
|
||||
|
||||
table.field(target, Styles.nodeField, str -> target = str)
|
||||
.size(100f, 40f).pad(2f).color(table.color);
|
||||
}
|
||||
|
||||
@Override
|
||||
public LInstruction build(LAssembler builder){
|
||||
return new PrintI(builder.var(value));
|
||||
return new PrintI(builder.var(value), builder.var(target));
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -182,6 +277,8 @@ public class LStatements{
|
||||
}
|
||||
}
|
||||
|
||||
//disabled until further notice - bypasses the network
|
||||
/*
|
||||
@RegisterStatement("getbuild")
|
||||
public static class getBuildStatement extends LStatement{
|
||||
public String x = "0", y = "0", dest = "result";
|
||||
@@ -211,5 +308,5 @@ public class LStatements{
|
||||
public LCategory category(){
|
||||
return LCategory.blocks;
|
||||
}
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user