Skip to content

Commit d785acb

Browse files
committed
JSON updates
1 parent 37400e9 commit d785acb

File tree

2 files changed

+54
-5
lines changed

2 files changed

+54
-5
lines changed

convex-core/src/main/java/convex/core/json/JSONReader.java

Lines changed: 40 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
import java.io.IOException;
44
import java.io.InputStream;
55
import java.util.ArrayList;
6+
import java.util.NoSuchElementException;
67

78
import org.antlr.v4.runtime.CharStream;
89
import org.antlr.v4.runtime.CharStreams;
910
import org.antlr.v4.runtime.CommonTokenStream;
1011
import org.antlr.v4.runtime.atn.PredictionMode;
1112

1213
import convex.core.data.ACell;
14+
import convex.core.data.AMap;
15+
import convex.core.data.AString;
1316
import convex.core.data.Cells;
1417
import convex.core.data.Maps;
1518
import convex.core.data.Vectors;
@@ -23,6 +26,7 @@
2326
import convex.core.json.reader.antlr.JSONParser.*;
2427
import convex.core.lang.reader.ConvexErrorListener;
2528
import convex.core.util.JSONUtils;
29+
import convex.core.util.Utils;
2630

2731
/**
2832
* Reader implementation for pure JSON
@@ -42,23 +46,33 @@ public JSONListener() {
4246
*/
4347
protected void push(ACell a) {
4448
ArrayList<ACell> top=stack.getLast();
49+
// System.err.println("pushed "+a);
4550
top.add(a);
4651
}
4752

4853
@SuppressWarnings("unchecked")
4954
protected <R extends ACell> R pop() {
5055
ArrayList<ACell> top=stack.getLast();
5156
ACell cell=top.removeLast();
57+
// System.err.println("popped "+cell);
5258
return (R) cell;
5359
}
5460

5561
protected void pushList() {
62+
// System.err.println(stack);
5663
stack.add(new ArrayList<>());
64+
// System.err.println("pushed new list to make "+stack);
5765
}
5866

5967
protected ArrayList<ACell> popList() {
60-
ArrayList<ACell> top=stack.removeLast();
61-
return top;
68+
try {
69+
// System.err.println(stack);
70+
ArrayList<ACell> top=stack.removeLast();
71+
// System.err.println("popped list "+top+ "to make "+stack);
72+
return top;
73+
} catch (NoSuchElementException e) {
74+
throw new ParseException("Fatal parsing error, no elements on stack");
75+
}
6276
}
6377

6478
@Override
@@ -100,7 +114,7 @@ public void exitNumber(NumberContext ctx) {
100114
return;
101115
}
102116
} catch (Exception e) {
103-
117+
// fall through to exception
104118
}
105119
throw new ParseException("Can't parse as number: "+num);
106120
}
@@ -136,13 +150,34 @@ public static ACell read(java.io.Reader r) throws IOException {
136150
public static ACell read(InputStream is) throws IOException {
137151
return read(CharStreams.fromStream(is));
138152
}
139-
140153

154+
public static AMap<AString,ACell> readObject(String s) {
155+
return readObject(CharStreams.fromString(s));
156+
}
157+
158+
public static AMap<AString,ACell> readObject(java.io.Reader r) throws IOException {
159+
return readObject(CharStreams.fromReader(r));
160+
}
161+
162+
public static AMap<AString,ACell> readObject(InputStream is) throws IOException {
163+
return readObject(CharStreams.fromStream(is));
164+
}
165+
166+
@SuppressWarnings("unchecked")
167+
private static AMap<AString,ACell> readObject(CharStream fromStream) {
168+
ACell a=read(fromStream);
169+
if (a instanceof AMap object) {
170+
return object;
171+
}
172+
throw new ParseException("Not a JSON object, got: "+Utils.getClassName(a));
173+
}
174+
175+
141176
private static final ConvexErrorListener ERROR_LISTENER=new ConvexErrorListener();
142177

143178

144179
static JSONParser getParser(CharStream cs, JSONListener listener) {
145-
// Create lexer and paser for the CharStream
180+
// Create lexer and parser for the CharStream
146181
JSONLexer lexer=new JSONLexer(cs);
147182
lexer.removeErrorListeners();
148183
lexer.addErrorListener(ERROR_LISTENER);

convex-core/src/test/java/convex/core/utils/JSONUtilsTest.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
import convex.core.data.prim.CVMDouble;
3333
import convex.core.data.prim.CVMLong;
3434
import convex.core.exceptions.ParseException;
35+
import convex.core.json.JSONReader;
3536
import convex.core.lang.RT;
3637
import convex.core.util.JSONUtils;
3738

@@ -146,6 +147,18 @@ public void testJSON() {
146147
assertEquals(Maps.of("[\"\" 3]",4), RT.cvm(JSONUtils.json(Maps.of(Vectors.of("",3),4))));
147148
}
148149

150+
@Test
151+
public void testJSONObjects() {
152+
assertEquals(Maps.of("1",2), JSONReader.read("{\"1\" : 2}"));
153+
assertEquals(CVMLong.ONE,JSONReader.read("1"));
154+
assertNull(JSONReader.read(" null"));
155+
assertEquals(Strings.COLON,JSONReader.read("\":\""));
156+
assertEquals(Vectors.of(1,2),JSONReader.read("[1,2]"));
157+
158+
assertThrows(ParseException.class,()->JSONReader.readObject("[]")); // not an object
159+
160+
}
161+
149162
@Test
150163
public void testJSONComments() {
151164
assertEquals(Vectors.of(true,null),JSONUtils.parseJSON5("[true, /* \n */ null]"));
@@ -248,6 +261,7 @@ private void doJSONRoundTrip(Object o, ACell c) {
248261
// Written JSON should be parseable as strict JSON
249262
assertEquals(c,JSONUtils.parse(js1),()->"JSON="+js1);
250263
assertEquals(c,JSONUtils.parse(js2));
264+
assertEquals(c,JSONReader.read(js2));
251265
}
252266

253267
}

0 commit comments

Comments
 (0)