authorgravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-05-03 19:26:24+12:00
committergravatar for marc@tiehu.isMarc Tiehuis <marc@tiehu.is> 2018-05-04 17:56:20+12:00
logef3111be236fc389a696562d31bccd3a9b6d1c56
tree4c9b57104193fce77f41e317f6c81f77ba0069f2
parentf17472635ee8bb2fbce8a1105059cd919e1b6d5b

Use allocator backed array for json value decoder


1 files changed, 39 insertions(+), 43 deletions(-)

std/json.zig+39-43
...@@ -1017,9 +1017,7 @@ const JsonParser = struct {...@@ -1017,9 +1017,7 @@ const JsonParser = struct {
1017 state: State,1017 state: State,
1018 copy_strings: bool,1018 copy_strings: bool,
1019 // Stores parent nodes and un-combined Values.1019 // Stores parent nodes and un-combined Values.
1020 // Worst case scenario we have nested key, values and so need two times the stack size.1020 stack: ArrayList(Value),
1021 stack: [2 * StreamingJsonParser.max_stack_size]Value,
1022 stack_used: u16,
10231021
1024 const State = enum {1022 const State = enum {
1025 ObjectKey,1023 ObjectKey,
...@@ -1033,14 +1031,17 @@ const JsonParser = struct {...@@ -1033,14 +1031,17 @@ const JsonParser = struct {
1033 .allocator = allocator,1031 .allocator = allocator,
1034 .state = State.Simple,1032 .state = State.Simple,
1035 .copy_strings = copy_strings,1033 .copy_strings = copy_strings,
1036 .stack = undefined,1034 .stack = ArrayList(Value).init(allocator),
1037 .stack_used = 0,
1038 };1035 };
1039 }1036 }
10401037
1038 pub fn deinit(p: &JsonParser) void {
1039 p.stack.deinit();
1040 }
1041
1041 pub fn reset(p: &JsonParser) void {1042 pub fn reset(p: &JsonParser) void {
1042 p.state = State.Simple;1043 p.state = State.Simple;
1043 p.stack_used = 0;1044 p.stack.shrink(0);
1044 }1045 }
10451046
1046 pub fn parse(p: &JsonParser, input: []const u8) !ValueTree {1047 pub fn parse(p: &JsonParser, input: []const u8) !ValueTree {
...@@ -1079,11 +1080,11 @@ const JsonParser = struct {...@@ -1079,11 +1080,11 @@ const JsonParser = struct {
1079 return error.IncompleteJsonInput;1080 return error.IncompleteJsonInput;
1080 }1081 }
10811082
1082 std.debug.assert(p.stack_used == 1);1083 std.debug.assert(p.stack.len == 1);
10831084
1084 return ValueTree {1085 return ValueTree {
1085 .arena = arena,1086 .arena = arena,
1086 .root = p.stack[0],1087 .root = p.stack.at(0),
1087 };1088 };
1088 }1089 }
10891090
...@@ -1093,16 +1094,15 @@ const JsonParser = struct {...@@ -1093,16 +1094,15 @@ const JsonParser = struct {
1093 switch (p.state) {1094 switch (p.state) {
1094 State.ObjectKey => switch (token.id) {1095 State.ObjectKey => switch (token.id) {
1095 Token.Id.ObjectEnd => {1096 Token.Id.ObjectEnd => {
1096 if (p.stack_used == 1) {1097 if (p.stack.len == 1) {
1097 return;1098 return;
1098 }1099 }
10991100
1100 var value = p.stack[p.stack_used - 1];1101 var value = p.stack.pop();
1101 p.stack_used -= 1;
1102 try p.pushToParent(value);1102 try p.pushToParent(value);
1103 },1103 },
1104 Token.Id.String => {1104 Token.Id.String => {
1105 p.pushStack(try p.parseString(allocator, token, input, i));1105 try p.stack.append(try p.parseString(allocator, token, input, i));
1106 p.state = State.ObjectValue;1106 p.state = State.ObjectValue;
1107 },1107 },
1108 else => {1108 else => {
...@@ -1110,41 +1110,41 @@ const JsonParser = struct {...@@ -1110,41 +1110,41 @@ const JsonParser = struct {
1110 },1110 },
1111 },1111 },
1112 State.ObjectValue => {1112 State.ObjectValue => {
1113 var object = &p.stack[p.stack_used - 2].Object;1113 var object = &p.stack.items[p.stack.len - 2].Object;
1114 var key = p.stack[p.stack_used - 1].String;1114 var key = p.stack.items[p.stack.len - 1].String;
11151115
1116 switch (token.id) {1116 switch (token.id) {
1117 Token.Id.ObjectBegin => {1117 Token.Id.ObjectBegin => {
1118 p.pushStack(Value { .Object = ObjectMap.init(allocator) });1118 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1119 p.state = State.ObjectKey;1119 p.state = State.ObjectKey;
1120 },1120 },
1121 Token.Id.ArrayBegin => {1121 Token.Id.ArrayBegin => {
1122 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });1122 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1123 p.state = State.ArrayValue;1123 p.state = State.ArrayValue;
1124 },1124 },
1125 Token.Id.String => {1125 Token.Id.String => {
1126 _ = try object.put(key, try p.parseString(allocator, token, input, i));1126 _ = try object.put(key, try p.parseString(allocator, token, input, i));
1127 p.stack_used -= 1;1127 _ = p.stack.pop();
1128 p.state = State.ObjectKey;1128 p.state = State.ObjectKey;
1129 },1129 },
1130 Token.Id.Number => {1130 Token.Id.Number => {
1131 _ = try object.put(key, try p.parseNumber(token, input, i));1131 _ = try object.put(key, try p.parseNumber(token, input, i));
1132 p.stack_used -= 1;1132 _ = p.stack.pop();
1133 p.state = State.ObjectKey;1133 p.state = State.ObjectKey;
1134 },1134 },
1135 Token.Id.True => {1135 Token.Id.True => {
1136 _ = try object.put(key, Value { .Bool = true });1136 _ = try object.put(key, Value { .Bool = true });
1137 p.stack_used -= 1;1137 _ = p.stack.pop();
1138 p.state = State.ObjectKey;1138 p.state = State.ObjectKey;
1139 },1139 },
1140 Token.Id.False => {1140 Token.Id.False => {
1141 _ = try object.put(key, Value { .Bool = false });1141 _ = try object.put(key, Value { .Bool = false });
1142 p.stack_used -= 1;1142 _ = p.stack.pop();
1143 p.state = State.ObjectKey;1143 p.state = State.ObjectKey;
1144 },1144 },
1145 Token.Id.Null => {1145 Token.Id.Null => {
1146 _ = try object.put(key, Value.Null);1146 _ = try object.put(key, Value.Null);
1147 p.stack_used -= 1;1147 _ = p.stack.pop();
1148 p.state = State.ObjectKey;1148 p.state = State.ObjectKey;
1149 },1149 },
1150 else => {1150 else => {
...@@ -1153,24 +1153,23 @@ const JsonParser = struct {...@@ -1153,24 +1153,23 @@ const JsonParser = struct {
1153 }1153 }
1154 },1154 },
1155 State.ArrayValue => {1155 State.ArrayValue => {
1156 var array = &p.stack[p.stack_used - 1].Array;1156 var array = &p.stack.items[p.stack.len - 1].Array;
11571157
1158 switch (token.id) {1158 switch (token.id) {
1159 Token.Id.ArrayEnd => {1159 Token.Id.ArrayEnd => {
1160 if (p.stack_used == 1) {1160 if (p.stack.len == 1) {
1161 return;1161 return;
1162 }1162 }
11631163
1164 var value = p.stack[p.stack_used - 1];1164 var value = p.stack.pop();
1165 p.stack_used -= 1;
1166 try p.pushToParent(value);1165 try p.pushToParent(value);
1167 },1166 },
1168 Token.Id.ObjectBegin => {1167 Token.Id.ObjectBegin => {
1169 p.pushStack(Value { .Object = ObjectMap.init(allocator) });1168 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1170 p.state = State.ObjectKey;1169 p.state = State.ObjectKey;
1171 },1170 },
1172 Token.Id.ArrayBegin => {1171 Token.Id.ArrayBegin => {
1173 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });1172 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1174 p.state = State.ArrayValue;1173 p.state = State.ArrayValue;
1175 },1174 },
1176 Token.Id.String => {1175 Token.Id.String => {
...@@ -1195,27 +1194,27 @@ const JsonParser = struct {...@@ -1195,27 +1194,27 @@ const JsonParser = struct {
1195 },1194 },
1196 State.Simple => switch (token.id) {1195 State.Simple => switch (token.id) {
1197 Token.Id.ObjectBegin => {1196 Token.Id.ObjectBegin => {
1198 p.pushStack(Value { .Object = ObjectMap.init(allocator) });1197 try p.stack.append(Value { .Object = ObjectMap.init(allocator) });
1199 p.state = State.ObjectKey;1198 p.state = State.ObjectKey;
1200 },1199 },
1201 Token.Id.ArrayBegin => {1200 Token.Id.ArrayBegin => {
1202 p.pushStack(Value { .Array = ArrayList(Value).init(allocator) });1201 try p.stack.append(Value { .Array = ArrayList(Value).init(allocator) });
1203 p.state = State.ArrayValue;1202 p.state = State.ArrayValue;
1204 },1203 },
1205 Token.Id.String => {1204 Token.Id.String => {
1206 p.pushStack(try p.parseString(allocator, token, input, i));1205 try p.stack.append(try p.parseString(allocator, token, input, i));
1207 },1206 },
1208 Token.Id.Number => {1207 Token.Id.Number => {
1209 p.pushStack(try p.parseNumber(token, input, i));1208 try p.stack.append(try p.parseNumber(token, input, i));
1210 },1209 },
1211 Token.Id.True => {1210 Token.Id.True => {
1212 p.pushStack(Value { .Bool = true });1211 try p.stack.append(Value { .Bool = true });
1213 },1212 },
1214 Token.Id.False => {1213 Token.Id.False => {
1215 p.pushStack(Value { .Bool = false });1214 try p.stack.append(Value { .Bool = false });
1216 },1215 },
1217 Token.Id.Null => {1216 Token.Id.Null => {
1218 p.pushStack(Value.Null);1217 try p.stack.append(Value.Null);
1219 },1218 },
1220 Token.Id.ObjectEnd, Token.Id.ArrayEnd => {1219 Token.Id.ObjectEnd, Token.Id.ArrayEnd => {
1221 unreachable;1220 unreachable;
...@@ -1225,12 +1224,12 @@ const JsonParser = struct {...@@ -1225,12 +1224,12 @@ const JsonParser = struct {
1225 }1224 }
12261225
1227 fn pushToParent(p: &JsonParser, value: &const Value) !void {1226 fn pushToParent(p: &JsonParser, value: &const Value) !void {
1228 switch (p.stack[p.stack_used - 1]) {1227 switch (p.stack.at(p.stack.len - 1)) {
1229 // Object Parent -> [ ..., object, <key>, value ]1228 // Object Parent -> [ ..., object, <key>, value ]
1230 Value.String => |key| {1229 Value.String => |key| {
1231 p.stack_used -= 1;1230 _ = p.stack.pop();
12321231
1233 var object = &p.stack[p.stack_used - 1].Object;1232 var object = &p.stack.items[p.stack.len - 1].Object;
1234 _ = try object.put(key, value);1233 _ = try object.put(key, value);
1235 p.state = State.ObjectKey;1234 p.state = State.ObjectKey;
1236 },1235 },
...@@ -1245,11 +1244,6 @@ const JsonParser = struct {...@@ -1245,11 +1244,6 @@ const JsonParser = struct {
1245 }1244 }
1246 }1245 }
12471246
1248 fn pushStack(p: &JsonParser, value: &const Value) void {
1249 p.stack[p.stack_used] = *value;
1250 p.stack_used += 1;
1251 }
1252
1253 fn parseString(p: &JsonParser, allocator: &Allocator, token: &const Token, input: []const u8, i: usize) !Value {1247 fn parseString(p: &JsonParser, allocator: &Allocator, token: &const Token, input: []const u8, i: usize) !Value {
1254 // TODO: We don't strictly have to copy values which do not contain any escape1248 // TODO: We don't strictly have to copy values which do not contain any escape
1255 // characters if flagged with the option.1249 // characters if flagged with the option.
...@@ -1270,6 +1264,7 @@ const debug = std.debug;...@@ -1270,6 +1264,7 @@ const debug = std.debug;
12701264
1271test "json parser dynamic" {1265test "json parser dynamic" {
1272 var p = JsonParser.init(std.debug.global_allocator, false);1266 var p = JsonParser.init(std.debug.global_allocator, false);
1267 defer p.deinit();
12731268
1274 const s =1269 const s =
1275 \\{1270 \\{
...@@ -1289,7 +1284,8 @@ test "json parser dynamic" {...@@ -1289,7 +1284,8 @@ test "json parser dynamic" {
1289 ;1284 ;
12901285
1291 var tree = try p.parse(s);1286 var tree = try p.parse(s);
1292 tree.deinit();1287 defer tree.deinit();
1288
1293 var root = tree.root;1289 var root = tree.root;
12941290
1295 var image = (??root.Object.get("Image")).value;1291 var image = (??root.Object.get("Image")).value;