Skip to content

Commit bc3c1d7

Browse files
committed
First usable version
1 parent 673b286 commit bc3c1d7

File tree

5 files changed

+116
-49
lines changed

5 files changed

+116
-49
lines changed

assets/bundles/bundle.properties

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,4 @@
11
lcategory.asserts = Runtime checks
2-
lcategory.asserts.description = Instructions for verifying invariants using assertions
2+
lcategory.asserts.description = Instructions for verifying invariants using assertions
3+
4+
lst.assert = Halt execution of this processor if the assertion is not met.

src/cardillan/mlogassertions/logic/AssertLStatements.java

Lines changed: 33 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55
import arc.scene.ui.layout.Table;
66
import arc.struct.Seq;
77
import mindustry.gen.LogicIO;
8-
import mindustry.logic.ConditionOp;
98
import mindustry.logic.LAssembler;
109
import mindustry.logic.LCategory;
1110
import mindustry.logic.LExecutor;
1211
import mindustry.logic.LStatement;
13-
import mindustry.logic.LVar;
1412
import mindustry.ui.Styles;
1513

1614
public class AssertLStatements {
@@ -32,14 +30,13 @@ public static void register() {
3230
}
3331

3432
private static class AssertStatement extends LStatement {
35-
private static final ConditionOp[] conditions = {ConditionOp.lessThan, ConditionOp.lessThanEq};
36-
33+
public TypeAssertion type = TypeAssertion.integer;
3734
public String min = "0";
38-
public ConditionOp opMin = ConditionOp.lessThanEq;
35+
public AssertOp opMin = AssertOp.lessThanEq;
3936
public String value = "index";
40-
public ConditionOp opMax = ConditionOp.lessThanEq;
41-
public String max = "length";
42-
public String message = "\"Array index '%s' out of bounds (%d to %d)\"";
37+
public AssertOp opMax = AssertOp.lessThanEq;
38+
public String max = "10";
39+
public String message = "\"Array index out of bounds (0 to 10).\"";
4340

4441
@Override
4542
public LCategory category() {
@@ -53,22 +50,35 @@ public void build(Table t) {
5350
t.add("invariant: ").padLeft(6);
5451
t.table(table -> {
5552
table.color.set(category().color);
56-
field(table, min, str -> min = str).left();
53+
table.add("type ");
54+
table.button(b -> {
55+
b.label(() -> type.name());
56+
b.clicked(() -> showSelect(b, TypeAssertion.all, type, o -> {
57+
type = o;
58+
build(t);
59+
}, 2, cell -> cell.size(110, 50)));
60+
}, Styles.logict, () -> {}).size(110, 40).left().pad(4f).color(table.color);
61+
table.add("bounds ");
62+
numField(table, min, str -> min = str);
5763
opButton(t, table, opMin, o -> opMin = o);
58-
field(table, value, str -> value = str).left();
64+
numField(table, value, str -> value = str);
5965
opButton(t, table, opMax, o -> opMax = o);
60-
field(table, max, str -> max = str).left();
66+
numField(table, max, str -> max = str);
6167
table.add("").growX();
6268
});
6369
t.row();
6470
t.add("message: ").padLeft(6);
6571
field(t, message, str -> message = str).width(0f).growX().padRight(3);
6672
}
6773

68-
void opButton(Table parent, Table table, ConditionOp op, Cons<ConditionOp> getter) {
74+
void numField(Table table, String num, Cons<String> getter) {
75+
field(table, num, getter).width(120).left();
76+
}
77+
78+
void opButton(Table parent, Table table, AssertOp op, Cons<AssertOp> getter) {
6979
table.button(b -> {
7080
b.label(() -> op.symbol);
71-
b.clicked(() -> showSelect(b, conditions, op, o -> {
81+
b.clicked(() -> showSelect(b, AssertOp.all, op, o -> {
7282
getter.get(o);
7383
build(parent);
7484
}));
@@ -78,14 +88,15 @@ void opButton(Table parent, Table table, ConditionOp op, Cons<ConditionOp> gette
7888

7989
@Override
8090
public LExecutor.LInstruction build(LAssembler builder) {
81-
return new AssertsLInstructions.AssertI(builder.var(min), opMin, builder.var(value),
91+
return new AssertsLInstructions.AssertI(type, builder.var(min), opMin, builder.var(value),
8292
opMax, builder.var(max), builder.var(message));
8393
}
8494

8595
@Override
8696
public final void write(StringBuilder builder) {
8797
writer.start(builder);
8898
writer.write(opcode);
99+
writer.write(type.name());
89100
writer.write(min);
90101
writer.write(opMin.name());
91102
writer.write(value);
@@ -96,12 +107,14 @@ public final void write(StringBuilder builder) {
96107
}
97108

98109
public LStatement read(String[] tokens) {
99-
if (tokens.length > 1) min = tokens[1];
100-
if (tokens.length > 2) opMin = mindustry.logic.ConditionOp.valueOf(tokens[2]);
101-
if (tokens.length > 3) value = tokens[3];
102-
if (tokens.length > 4) opMax = mindustry.logic.ConditionOp.valueOf(tokens[4]);
103-
if (tokens.length > 5) max = tokens[5];
104-
if (tokens.length > 6) message = tokens[6];
110+
int i = 1;
111+
if (tokens.length > i) type = TypeAssertion.valueOf(tokens[i++]);
112+
if (tokens.length > i) min = tokens[i++];
113+
if (tokens.length > i) opMin = AssertOp.valueOf(tokens[i++]);
114+
if (tokens.length > i) value = tokens[i++];
115+
if (tokens.length > i) opMax = AssertOp.valueOf(tokens[i++]);
116+
if (tokens.length > i) max = tokens[i++];
117+
if (tokens.length > i) message = tokens[i++];
105118
return this;
106119
}
107120

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package cardillan.mlogassertions.logic;
2+
3+
public enum AssertOp {
4+
lessThan("<", (a, b) -> a < b),
5+
lessThanEq("<=", (a, b) -> a <= b),
6+
;
7+
8+
public static final AssertOp[] all = values();
9+
10+
public final AssertOpLambda function;
11+
public final String symbol;
12+
13+
AssertOp(String symbol, AssertOpLambda function){
14+
this.symbol = symbol;
15+
this.function = function;
16+
}
17+
18+
@Override
19+
public String toString(){
20+
return symbol;
21+
}
22+
23+
public interface AssertOpLambda {
24+
boolean get(double a, double b);
25+
}
26+
}
Lines changed: 13 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,21 @@
11
package cardillan.mlogassertions.logic;
22

3-
import mindustry.ctype.Content;
4-
import mindustry.ctype.MappableContent;
5-
import mindustry.game.Team;
6-
import mindustry.gen.Building;
7-
import mindustry.gen.Unit;
8-
import mindustry.logic.ConditionOp;
93
import mindustry.logic.LExecutor;
104
import mindustry.logic.LVar;
115

126
public class AssertsLInstructions {
137

148
public static class AssertI implements LExecutor.LInstruction {
9+
public TypeAssertion type;
1510
public LVar min;
16-
public ConditionOp opMin = ConditionOp.lessThanEq;
11+
public AssertOp opMin;
1712
public LVar value;
18-
public ConditionOp opMax = ConditionOp.lessThanEq;
13+
public AssertOp opMax;
1914
public LVar max;
2015
public LVar message;
2116

22-
public AssertI(LVar min, ConditionOp opMin, LVar value, ConditionOp opMax, LVar max, LVar message) {
17+
public AssertI(TypeAssertion type, LVar min, AssertOp opMin, LVar value, AssertOp opMax, LVar max, LVar message) {
18+
this.type = type;
2319
this.min = min;
2420
this.opMin = opMin;
2521
this.value = value;
@@ -30,27 +26,16 @@ public AssertI(LVar min, ConditionOp opMin, LVar value, ConditionOp opMax, LVar
3026

3127
@Override
3228
public final void run(LExecutor exec) {
33-
if (exec.textBuffer.length() >= LExecutor.maxTextBuffer) return;
29+
boolean typeAssert = value.isobj ? type.objFunction.get(value.objval) : type.function.get(value.numval);
30+
boolean minAssert = opMin.function.get(min.num(), value.num());
31+
boolean maxAssert = opMax.function.get(value.num(), max.num());
3432

35-
if (value.isobj) {
36-
String strValue = toString(value.objval);
37-
exec.textBuffer.append(strValue);
38-
} else {
39-
exec.textBuffer.append(value.numval);
33+
if (!typeAssert || !minAssert || !maxAssert) {
34+
//skip back to self.
35+
// TODO enter broken assertion state
36+
exec.counter.numval--;
37+
exec.yield = true;
4038
}
4139
}
42-
43-
public static String toString(Object obj) {
44-
return
45-
obj == null ? "null" :
46-
obj instanceof String s ? s :
47-
obj instanceof MappableContent content ? content.name :
48-
obj instanceof Content ? "[content]" :
49-
obj instanceof Building build ? build.block.name :
50-
obj instanceof Unit unit ? unit.type.name :
51-
obj instanceof Enum<?> e ? e.name() :
52-
obj instanceof Team team ? team.name :
53-
"[object]";
54-
}
5540
}
5641
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package cardillan.mlogassertions.logic;
2+
3+
import mindustry.logic.ConditionOp;
4+
5+
import java.util.Objects;
6+
7+
public enum TypeAssertion {
8+
any(num -> true, obj -> true),
9+
notNull(num -> true, Objects::nonNull),
10+
decimal(num -> true),
11+
integer(num -> num == (long) num),
12+
even(num -> num == (long) num && num % 2 == 0),
13+
odd(num -> num == (long) num && num % 2 != 0),
14+
;
15+
16+
public static final TypeAssertion[] all = values();
17+
public final TypeAssertionObjLambda objFunction;
18+
public final TypeAssertionLambda function;
19+
20+
TypeAssertion(TypeAssertionLambda function) {
21+
this(function, obj -> false);
22+
}
23+
24+
TypeAssertion(TypeAssertionLambda function, TypeAssertionObjLambda objFunction) {
25+
this.function = function;
26+
this.objFunction = objFunction;
27+
}
28+
29+
@Override
30+
public String toString() {
31+
return super.toString();
32+
}
33+
34+
public interface TypeAssertionObjLambda {
35+
boolean get(Object obj);
36+
}
37+
38+
public interface TypeAssertionLambda {
39+
boolean get(double val);
40+
}
41+
}

0 commit comments

Comments
 (0)