Add select operation (#10798)
This commit is contained in:
@@ -28,6 +28,17 @@ public enum ConditionOp{
|
|||||||
this.objFunction = objFunction;
|
this.objFunction = objFunction;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean test(LVar va, LVar vb){
|
||||||
|
if(this == ConditionOp.strictEqual){
|
||||||
|
return va.isobj == vb.isobj && ((va.isobj && va.objval == vb.objval) || (!va.isobj && va.numval == vb.numval));
|
||||||
|
}
|
||||||
|
if(objFunction != null && va.isobj && vb.isobj){
|
||||||
|
//use object function if both are objects
|
||||||
|
return objFunction.get(va.obj(), vb.obj());
|
||||||
|
}
|
||||||
|
return function.get(va.num(), vb.num());
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString(){
|
public String toString(){
|
||||||
return symbol;
|
return symbol;
|
||||||
|
|||||||
@@ -785,15 +785,7 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
if(!to.constant){
|
if(!to.constant) to.set(from);
|
||||||
if(from.isobj){
|
|
||||||
to.objval = from.objval;
|
|
||||||
to.isobj = true;
|
|
||||||
}else{
|
|
||||||
to.numval = LVar.invalid(from.numval) ? 0 : from.numval;
|
|
||||||
to.isobj = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -829,6 +821,28 @@ public class LExecutor{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class SelectI implements LInstruction{
|
||||||
|
public ConditionOp op = ConditionOp.notEqual;
|
||||||
|
public LVar result, comp0, comp1, a, b;
|
||||||
|
|
||||||
|
public SelectI(ConditionOp op, LVar result, LVar comp0, LVar comp1, LVar a, LVar b){
|
||||||
|
this.op = op;
|
||||||
|
this.result = result;
|
||||||
|
this.comp0 = comp0;
|
||||||
|
this.comp1 = comp1;
|
||||||
|
this.a = a;
|
||||||
|
this.b = b;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SelectI(){}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run(LExecutor exec){
|
||||||
|
if(result.constant) return;
|
||||||
|
result.set(op.test(comp0, comp1) ? a : b);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static class EndI implements LInstruction{
|
public static class EndI implements LInstruction{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -1134,26 +1148,11 @@ public class LExecutor{
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void run(LExecutor exec){
|
public void run(LExecutor exec){
|
||||||
if(address != -1){
|
if(address != -1 && op.test(value, compare)){
|
||||||
LVar va = value;
|
|
||||||
LVar vb = compare;
|
|
||||||
boolean cmp;
|
|
||||||
|
|
||||||
if(op == ConditionOp.strictEqual){
|
|
||||||
cmp = va.isobj == vb.isobj && ((va.isobj && va.objval == vb.objval) || (!va.isobj && va.numval == vb.numval));
|
|
||||||
}else if(op.objFunction != null && va.isobj && vb.isobj){
|
|
||||||
//use object function if both are objects
|
|
||||||
cmp = op.objFunction.get(value.obj(), compare.obj());
|
|
||||||
}else{
|
|
||||||
cmp = op.function.get(value.num(), compare.num());
|
|
||||||
}
|
|
||||||
|
|
||||||
if(cmp){
|
|
||||||
exec.counter.numval = address;
|
exec.counter.numval = address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public static class WaitI implements LInstruction{
|
public static class WaitI implements LInstruction{
|
||||||
public LVar value;
|
public LVar value;
|
||||||
|
|||||||
@@ -793,6 +793,55 @@ public class LStatements{
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@RegisterStatement("select")
|
||||||
|
public static class SelectStatement extends LStatement{
|
||||||
|
public String result = "result";
|
||||||
|
public ConditionOp op = ConditionOp.notEqual;
|
||||||
|
public String comp0 = "x", comp1 = "false", a = "a", b = "b";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void build(Table table){
|
||||||
|
rebuild(table);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void rebuild(Table table){
|
||||||
|
table.clearChildren();
|
||||||
|
table.left();
|
||||||
|
|
||||||
|
table.table(t -> {
|
||||||
|
t.setColor(table.color);
|
||||||
|
|
||||||
|
field(t, result, str -> result = str);
|
||||||
|
t.add(" = if ");
|
||||||
|
|
||||||
|
JumpStatement.addOp(this, t, op, o -> {
|
||||||
|
op = o;
|
||||||
|
rebuild(table);
|
||||||
|
}, comp0, str -> comp0 = str, comp1, str -> comp1 = str);
|
||||||
|
}).left();
|
||||||
|
|
||||||
|
table.row();
|
||||||
|
table.table(t -> {
|
||||||
|
t.setColor(table.color);
|
||||||
|
|
||||||
|
t.add("then ");
|
||||||
|
field(t, a, str -> a = str);
|
||||||
|
t.add(" else ");
|
||||||
|
field(t, b, str -> b = str);
|
||||||
|
}).left();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LInstruction build(LAssembler builder){
|
||||||
|
return new SelectI(op, builder.var(result), builder.var(comp0), builder.var(comp1), builder.var(a), builder.var(b));
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public LCategory category(){
|
||||||
|
return LCategory.operation;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@RegisterStatement("wait")
|
@RegisterStatement("wait")
|
||||||
public static class WaitStatement extends LStatement{
|
public static class WaitStatement extends LStatement{
|
||||||
public String value = "0.5";
|
public String value = "0.5";
|
||||||
@@ -984,17 +1033,22 @@ public class LStatements{
|
|||||||
table.clearChildren();
|
table.clearChildren();
|
||||||
table.setColor(last);
|
table.setColor(last);
|
||||||
|
|
||||||
if(op != ConditionOp.always) field(table, value, str -> value = str);
|
addOp(this, table, op, o -> {
|
||||||
|
|
||||||
table.button(b -> {
|
|
||||||
b.label(() -> op.symbol);
|
|
||||||
b.clicked(() -> showSelect(b, ConditionOp.all, op, o -> {
|
|
||||||
op = o;
|
op = o;
|
||||||
rebuild(table);
|
rebuild(table);
|
||||||
}));
|
}, value, str -> value = str, compare, str -> compare = str);
|
||||||
}, Styles.logict, () -> {}).size(op == ConditionOp.always ? 80f : 48f, 40f).pad(4f).color(table.color);
|
}
|
||||||
|
|
||||||
if(op != ConditionOp.always) field(table, compare, str -> compare = str);
|
public static void addOp(LStatement st, Table t, ConditionOp op, Cons<ConditionOp> getter, String comp0, Cons<String> set0, String comp1, Cons<String> set2){
|
||||||
|
if(op != ConditionOp.always) st.field(t, comp0, set0);
|
||||||
|
|
||||||
|
t.button(b -> {
|
||||||
|
b.add(op.symbol);
|
||||||
|
b.clicked(() -> st.showSelect(b, ConditionOp.all, op, getter));
|
||||||
|
}, Styles.logict, () -> {
|
||||||
|
}).size(op == ConditionOp.always ? 80f : 48f, 40f).pad(4f).color(t.color);
|
||||||
|
|
||||||
|
if(op != ConditionOp.always) st.field(t, comp1, set2);
|
||||||
}
|
}
|
||||||
|
|
||||||
//elements need separate conversion logic
|
//elements need separate conversion logic
|
||||||
|
|||||||
@@ -101,6 +101,12 @@ public class LVar{
|
|||||||
isobj = true;
|
isobj = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void set(LVar other){
|
||||||
|
isobj = other.isobj;
|
||||||
|
objval = other.objval;
|
||||||
|
numval = other.numval;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean invalid(double d){
|
public static boolean invalid(double d){
|
||||||
return Double.isNaN(d) || Double.isInfinite(d);
|
return Double.isNaN(d) || Double.isInfinite(d);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -386,9 +386,7 @@ public class LogicBlock extends Block{
|
|||||||
if(!var.constant){
|
if(!var.constant){
|
||||||
LVar dest = asm.getVar(var.name);
|
LVar dest = asm.getVar(var.name);
|
||||||
if(dest != null && !dest.constant){
|
if(dest != null && !dest.constant){
|
||||||
dest.isobj = var.isobj;
|
dest.set(var);
|
||||||
dest.objval = var.objval;
|
|
||||||
dest.numval = var.numval;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user