Skip to content

Commit 96ea969

Browse files
committed
Add Support for Char Literals
1 parent 375418d commit 96ea969

File tree

8 files changed

+88
-2
lines changed

8 files changed

+88
-2
lines changed

liquidjava-verifier/src/main/java/liquidjava/processor/refinement_checker/object_checkers/AuxStateHandler.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ public static void setDefaultState(RefinedFunction f, TypeChecker tc) {
9494
String retType = sg.getReturnType().toString();
9595
Predicate typePredicate = switch (retType) {
9696
case "int" -> Predicate.createLit("0", Types.INT);
97+
case "char" -> Predicate.createLit("\u0000", Types.CHAR);
9798
case "boolean" -> Predicate.createLit("false", Types.BOOLEAN);
9899
case "double" -> Predicate.createLit("0.0", Types.DOUBLE);
99100
default -> throw new RuntimeException("Ghost not implemented for type " + retType);

liquidjava-verifier/src/main/java/liquidjava/rj_language/Predicate.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
import liquidjava.rj_language.ast.GroupExpression;
2121
import liquidjava.rj_language.ast.Ite;
2222
import liquidjava.rj_language.ast.LiteralBoolean;
23+
import liquidjava.rj_language.ast.LiteralChar;
2324
import liquidjava.rj_language.ast.LiteralInt;
2425
import liquidjava.rj_language.ast.LiteralLong;
2526
import liquidjava.rj_language.ast.LiteralReal;
@@ -236,6 +237,7 @@ public static Predicate createLit(String value, String type) {
236237
case Types.INT, Types.SHORT -> new LiteralInt(value);
237238
case Types.LONG -> new LiteralLong(value);
238239
case Types.DOUBLE, Types.FLOAT -> new LiteralReal(value);
240+
case Types.CHAR -> new LiteralChar(value);
239241
default -> throw new IllegalArgumentException("Unsupported literal type: " + type);
240242
};
241243
return new Predicate(exp);

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ public void setChild(int index, Expression element) {
5656

5757
public boolean isLiteral() {
5858
return this instanceof LiteralInt || this instanceof LiteralLong || this instanceof LiteralReal
59-
|| this instanceof LiteralBoolean;
59+
|| this instanceof LiteralBoolean || this instanceof LiteralChar;
6060
}
6161

6262
/**
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
package liquidjava.rj_language.ast;
2+
3+
import java.util.List;
4+
5+
import liquidjava.diagnostics.errors.LJError;
6+
import liquidjava.rj_language.visitors.ExpressionVisitor;
7+
8+
public class LiteralChar extends Expression {
9+
10+
private final char value;
11+
12+
public LiteralChar(char value) {
13+
this.value = value;
14+
}
15+
16+
public LiteralChar(String value) {
17+
this.value = value.charAt(0);
18+
}
19+
20+
@Override
21+
public <T> T accept(ExpressionVisitor<T> visitor) throws LJError {
22+
return visitor.visitLiteralChar(this);
23+
}
24+
25+
public char getValue() {
26+
return value;
27+
}
28+
29+
@Override
30+
public String toString() {
31+
return "'" + value + "'";
32+
}
33+
34+
@Override
35+
public void getVariableNames(List<String> toAdd) {
36+
// end leaf
37+
}
38+
39+
@Override
40+
public void getStateInvocations(List<String> toAdd, List<String> all) {
41+
// end leaf
42+
}
43+
44+
@Override
45+
public Expression clone() {
46+
return new LiteralChar(value);
47+
}
48+
49+
@Override
50+
public boolean isBooleanTrue() {
51+
return false;
52+
}
53+
54+
@Override
55+
public int hashCode() {
56+
return Character.hashCode(value);
57+
}
58+
59+
@Override
60+
public boolean equals(Object obj) {
61+
if (this == obj)
62+
return true;
63+
if (obj == null)
64+
return false;
65+
if (getClass() != obj.getClass())
66+
return false;
67+
LiteralChar other = (LiteralChar) obj;
68+
return value == other.value;
69+
}
70+
}

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
@@ -10,6 +10,7 @@
1010
import liquidjava.rj_language.ast.GroupExpression;
1111
import liquidjava.rj_language.ast.Ite;
1212
import liquidjava.rj_language.ast.LiteralBoolean;
13+
import liquidjava.rj_language.ast.LiteralChar;
1314
import liquidjava.rj_language.ast.LiteralInt;
1415
import liquidjava.rj_language.ast.LiteralLong;
1516
import liquidjava.rj_language.ast.LiteralReal;
@@ -40,6 +41,8 @@ else if (e instanceof LiteralReal)
4041
return Optional.of(Utils.getType("double", factory));
4142
else if (e instanceof LiteralBoolean)
4243
return boolType(factory);
44+
else if (e instanceof LiteralChar)
45+
return Optional.of(Utils.getType("char", factory));
4346
else if (e instanceof Var)
4447
return varType(ctx, (Var) e);
4548
else if (e instanceof UnaryExpression)

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import liquidjava.rj_language.ast.GroupExpression;
88
import liquidjava.rj_language.ast.Ite;
99
import liquidjava.rj_language.ast.LiteralBoolean;
10+
import liquidjava.rj_language.ast.LiteralChar;
1011
import liquidjava.rj_language.ast.LiteralInt;
1112
import liquidjava.rj_language.ast.LiteralLong;
1213
import liquidjava.rj_language.ast.LiteralReal;
@@ -31,6 +32,8 @@ public interface ExpressionVisitor<T> {
3132

3233
T visitLiteralBoolean(LiteralBoolean lit) throws LJError;
3334

35+
T visitLiteralChar(LiteralChar lit) throws LJError;
36+
3437
T visitLiteralReal(LiteralReal lit) throws LJError;
3538

3639
T visitLiteralString(LiteralString lit) throws LJError;

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import liquidjava.rj_language.ast.GroupExpression;
1010
import liquidjava.rj_language.ast.Ite;
1111
import liquidjava.rj_language.ast.LiteralBoolean;
12+
import liquidjava.rj_language.ast.LiteralChar;
1213
import liquidjava.rj_language.ast.LiteralInt;
1314
import liquidjava.rj_language.ast.LiteralLong;
1415
import liquidjava.rj_language.ast.LiteralReal;
@@ -96,6 +97,11 @@ public Expr<?> visitLiteralBoolean(LiteralBoolean lit) {
9697
return ctx.makeBooleanLiteral(lit.isBooleanTrue());
9798
}
9899

100+
@Override
101+
public Expr<?> visitLiteralChar(LiteralChar lit) {
102+
return ctx.makeIntegerLiteral(lit.getValue());
103+
}
104+
99105
@Override
100106
public Expr<?> visitLiteralReal(LiteralReal lit) {
101107
return ctx.makeDoubleLiteral(lit.getValue());

liquidjava-verifier/src/main/java/liquidjava/utils/constants/Types.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ public class Types {
1010
public static final String SHORT = "short";
1111
public static final String LONG = "long";
1212
public static final String FLOAT = "float";
13+
public static final String CHAR = "char";
1314
public static final String NULL = "<nulltype>";
14-
public static final String[] IMPLEMENTED = { "boolean", "int", "short", "long", "float", "double" };
15+
public static final String[] IMPLEMENTED = { "boolean", "int", "short", "long", "float", "double", "char" };
1516
}

0 commit comments

Comments
 (0)