Skip to content

Commit 0e276f3

Browse files
committed
Add SimplifiedExpression
1 parent 80bd106 commit 0e276f3

7 files changed

Lines changed: 157 additions & 3 deletions

File tree

liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/Expression.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,9 @@ public boolean isLiteral() {
8282
* @return true if it is a boolean expression, false otherwise
8383
*/
8484
public boolean isBooleanExpression() {
85+
if (this instanceof SimplifiedExpression node) {
86+
return node.getSimplifiedExpression().isBooleanExpression();
87+
}
8588
if (this instanceof LiteralBoolean || this instanceof Ite || this instanceof AliasInvocation
8689
|| this instanceof FunctionInvocation) {
8790
return true;
@@ -99,6 +102,8 @@ public boolean isBooleanExpression() {
99102
}
100103

101104
public List<Expression> getConjuncts() {
105+
if (this instanceof SimplifiedExpression node)
106+
return node.getSimplifiedExpression().getConjuncts();
102107
if (this instanceof BinaryExpression binaryExpression && "&&".equals(binaryExpression.getOperator())) {
103108
List<Expression> conjuncts = new ArrayList<>();
104109
conjuncts.addAll(binaryExpression.getFirstOperand().getConjuncts());
Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
package liquidjava.rj_language.ast;
2+
3+
import java.util.ArrayList;
4+
import java.util.List;
5+
import java.util.Objects;
6+
7+
import liquidjava.diagnostics.errors.LJError;
8+
import liquidjava.rj_language.visitors.ExpressionVisitor;
9+
import spoon.reflect.reference.CtTypeReference;
10+
11+
public class SimplifiedExpression extends Expression {
12+
13+
private final Expression origin;
14+
private final List<Binder> binders;
15+
16+
public SimplifiedExpression(Expression simplified, Expression origin) {
17+
this(simplified, origin, List.of());
18+
}
19+
20+
public SimplifiedExpression(Expression simplified, Expression origin, List<Binder> binders) {
21+
addChild(simplified);
22+
this.origin = origin;
23+
this.binders = new ArrayList<>(binders);
24+
}
25+
26+
public Expression getSimplifiedExpression() {
27+
return children.get(0);
28+
}
29+
30+
public Expression getOrigin() {
31+
return origin;
32+
}
33+
34+
public List<Binder> getBinders() {
35+
return binders;
36+
}
37+
38+
@Override
39+
public <T> T accept(ExpressionVisitor<T> visitor) throws LJError {
40+
return visitor.visitSimplifiedNode(this);
41+
}
42+
43+
@Override
44+
public void getVariableNames(List<String> toAdd) {
45+
getSimplifiedExpression().getVariableNames(toAdd);
46+
}
47+
48+
@Override
49+
public void getStateInvocations(List<String> toAdd, List<String> all) {
50+
getSimplifiedExpression().getStateInvocations(toAdd, all);
51+
}
52+
53+
@Override
54+
public boolean isBooleanTrue() {
55+
return getSimplifiedExpression().isBooleanTrue();
56+
}
57+
58+
@Override
59+
public Expression clone() {
60+
return new SimplifiedExpression(getSimplifiedExpression().clone(), origin.clone(), binders);
61+
}
62+
63+
@Override
64+
public String toString() {
65+
return getSimplifiedExpression().toString();
66+
}
67+
68+
@Override
69+
public int hashCode() {
70+
return Objects.hash(getSimplifiedExpression(), origin, binders);
71+
}
72+
73+
@Override
74+
public boolean equals(Object obj) {
75+
if (this == obj)
76+
return true;
77+
if (obj == null)
78+
return false;
79+
if (getClass() != obj.getClass())
80+
return false;
81+
SimplifiedExpression other = (SimplifiedExpression) obj;
82+
return getSimplifiedExpression().equals(other.getSimplifiedExpression()) && origin.equals(other.origin)
83+
&& binders.equals(other.binders);
84+
}
85+
86+
public static class Binder {
87+
private final String name;
88+
private final String type;
89+
90+
public Binder(String name, String type) {
91+
this.name = name;
92+
this.type = type;
93+
}
94+
95+
public Binder(String name, CtTypeReference<?> type) {
96+
this(name, type.getQualifiedName());
97+
}
98+
99+
public String getName() {
100+
return name;
101+
}
102+
103+
public String getType() {
104+
return type;
105+
}
106+
107+
@Override
108+
public int hashCode() {
109+
return Objects.hash(name, type);
110+
}
111+
112+
@Override
113+
public boolean equals(Object obj) {
114+
if (this == obj)
115+
return true;
116+
if (obj == null)
117+
return false;
118+
if (getClass() != obj.getClass())
119+
return false;
120+
Binder other = (Binder) obj;
121+
return name.equals(other.name) && type.equals(other.type);
122+
}
123+
}
124+
}

liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/formatter/ExpressionFormatter.java

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
import liquidjava.rj_language.ast.LiteralReal;
1818
import liquidjava.rj_language.ast.LiteralString;
1919
import liquidjava.rj_language.ast.Enum;
20+
import liquidjava.rj_language.ast.SimplifiedExpression;
2021
import liquidjava.rj_language.ast.UnaryExpression;
2122
import liquidjava.rj_language.ast.Var;
2223
import liquidjava.rj_language.visitors.ExpressionVisitor;
@@ -61,8 +62,12 @@ private String formatArguments(List<Expression> args) {
6162
}
6263

6364
private Expression unwrapGroup(Expression expression) {
64-
while (expression instanceof GroupExpression group)
65-
expression = group.getExpression();
65+
while (expression instanceof GroupExpression || expression instanceof SimplifiedExpression) {
66+
if (expression instanceof GroupExpression group)
67+
expression = group.getExpression();
68+
else if (expression instanceof SimplifiedExpression node)
69+
expression = node.getSimplifiedExpression();
70+
}
6671
return expression;
6772
}
6873

@@ -161,6 +166,11 @@ public String visitLiteralString(LiteralString lit) {
161166
return lit.toString();
162167
}
163168

169+
@Override
170+
public String visitSimplifiedNode(SimplifiedExpression node) {
171+
return formatExpression(node.getSimplifiedExpression());
172+
}
173+
164174
@Override
165175
public String visitUnaryExpression(UnaryExpression exp) {
166176
return exp.getOp() + formatOperand(exp, exp.getExpression(), true);

liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/formatter/ExpressionPrecedence.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import liquidjava.rj_language.ast.Expression;
55
import liquidjava.rj_language.ast.GroupExpression;
66
import liquidjava.rj_language.ast.Ite;
7+
import liquidjava.rj_language.ast.SimplifiedExpression;
78
import liquidjava.rj_language.ast.UnaryExpression;
89

910
public enum ExpressionPrecedence {
@@ -16,6 +17,8 @@ public boolean isLowerThan(ExpressionPrecedence other) {
1617
public static ExpressionPrecedence of(Expression expression) {
1718
if (expression instanceof GroupExpression group)
1819
return of(group.getExpression());
20+
if (expression instanceof SimplifiedExpression node)
21+
return of(node.getSimplifiedExpression());
1922
if (expression instanceof Ite)
2023
return TERNARY;
2124
if (expression instanceof UnaryExpression)

liquidjava-verifier/src/main/java/liquidjava/rj_language/ast/typing/TypeInfer.java

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import liquidjava.rj_language.ast.LiteralLong;
1616
import liquidjava.rj_language.ast.LiteralReal;
1717
import liquidjava.rj_language.ast.LiteralString;
18+
import liquidjava.rj_language.ast.SimplifiedExpression;
1819
import liquidjava.rj_language.ast.UnaryExpression;
1920
import liquidjava.rj_language.ast.Var;
2021
import liquidjava.utils.Utils;
@@ -57,6 +58,8 @@ else if (e instanceof FunctionInvocation)
5758
return functionType(ctx, (FunctionInvocation) e);
5859
else if (e instanceof AliasInvocation)
5960
return boolType(factory);
61+
else if (e instanceof SimplifiedExpression)
62+
return getType(ctx, factory, ((SimplifiedExpression) e).getSimplifiedExpression());
6063

6164
return Optional.empty();
6265
}

liquidjava-verifier/src/main/java/liquidjava/rj_language/visitors/ExpressionVisitor.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
import liquidjava.rj_language.ast.LiteralLong;
1414
import liquidjava.rj_language.ast.LiteralReal;
1515
import liquidjava.rj_language.ast.LiteralString;
16+
import liquidjava.rj_language.ast.SimplifiedExpression;
1617
import liquidjava.rj_language.ast.UnaryExpression;
1718
import liquidjava.rj_language.ast.Var;
1819

@@ -39,9 +40,11 @@ public interface ExpressionVisitor<T> {
3940

4041
T visitLiteralString(LiteralString lit) throws LJError;
4142

43+
T visitSimplifiedNode(SimplifiedExpression node) throws LJError;
44+
4245
T visitUnaryExpression(UnaryExpression exp) throws LJError;
4346

4447
T visitEnum(Enum en) throws LJError;
4548

4649
T visitVar(Var var) throws LJError;
47-
}
50+
}

liquidjava-verifier/src/main/java/liquidjava/smt/ExpressionToZ3Visitor.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import liquidjava.rj_language.ast.LiteralLong;
1616
import liquidjava.rj_language.ast.LiteralReal;
1717
import liquidjava.rj_language.ast.LiteralString;
18+
import liquidjava.rj_language.ast.SimplifiedExpression;
1819
import liquidjava.rj_language.ast.UnaryExpression;
1920
import liquidjava.rj_language.ast.Var;
2021
import liquidjava.rj_language.visitors.ExpressionVisitor;
@@ -113,6 +114,11 @@ public Expr<?> visitLiteralString(LiteralString lit) {
113114
return ctx.makeString(lit.toString());
114115
}
115116

117+
@Override
118+
public Expr<?> visitSimplifiedNode(SimplifiedExpression node) throws LJError {
119+
return node.getSimplifiedExpression().accept(this);
120+
}
121+
116122
@Override
117123
public Expr<?> visitUnaryExpression(UnaryExpression exp) throws LJError {
118124
return switch (exp.getOp()) {

0 commit comments

Comments
 (0)