aboutsummaryrefslogtreecommitdiff
path: root/core/encoding/json/parser.odin
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2019-01-14 15:51:52 +0000
committergingerBill <bill@gingerbill.org>2019-01-14 15:51:52 +0000
commite047d9eb5ef1c8bee1d437dac9837fd774a17315 (patch)
treed91040989f5e3e7ca9b9df9f3c632de6fa950933 /core/encoding/json/parser.odin
parent3113e8c892412259d3111f697ce47c14dd43d556 (diff)
Update `package json` parser to store the end position on the values
Diffstat (limited to 'core/encoding/json/parser.odin')
-rw-r--r--core/encoding/json/parser.odin16
1 files changed, 14 insertions, 2 deletions
diff --git a/core/encoding/json/parser.odin b/core/encoding/json/parser.odin
index 374f8589f..688a98a49 100644
--- a/core/encoding/json/parser.odin
+++ b/core/encoding/json/parser.odin
@@ -6,6 +6,7 @@ import "core:strconv"
Parser :: struct {
tok: Tokenizer,
+ prev_token: Token,
curr_token: Token,
spec: Specification,
allocator: mem.Allocator,
@@ -31,11 +32,17 @@ parse :: proc(data: []byte, spec := Specification.JSON, allocator := context.all
return parse_object(&p);
}
+token_end_pos :: proc(tok: Token) -> Pos {
+ end := tok.pos;
+ end.offset += len(tok.text);
+ return end;
+}
+
advance_token :: proc(p: ^Parser) -> (Token, Error) {
err: Error;
- prev := p.curr_token;
+ p.prev_token := p.curr_token;
p.curr_token, err = get_token(&p.tok);
- return prev, err;
+ return p.prev_token, err;
}
@@ -60,6 +67,8 @@ expect_token :: proc(p: ^Parser, kind: Kind) -> Error {
parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
value.pos = p.curr_token.pos;
+ defer value.end = token_end_pos(p.prev_token);
+
token := p.curr_token;
switch token.kind {
case Kind.Null:
@@ -124,6 +133,7 @@ parse_value :: proc(p: ^Parser) -> (value: Value, err: Error) {
parse_array :: proc(p: ^Parser) -> (value: Value, err: Error) {
value.pos = p.curr_token.pos;
+ defer value.end = token_end_pos(p.prev_token);
if err = expect_token(p, Kind.Open_Bracket); err != Error.None {
return;
}
@@ -192,6 +202,8 @@ parse_object_key :: proc(p: ^Parser) -> (key: string, err: Error) {
parse_object :: proc(p: ^Parser) -> (value: Value, err: Error) {
value.pos = p.curr_token.pos;
+ defer value.end = token_end_pos(p.prev_token);
+
if err = expect_token(p, Kind.Open_Brace); err != Error.None {
value.pos = p.curr_token.pos;
return;