Browse Source

Added option to parse number as integer, disabled by default

jockus 4 years ago
parent
commit
195dbd658d

+ 5 - 4
core/encoding/json/parser.odin

@@ -11,11 +11,12 @@ Parser :: struct {
 	spec:           Specification,
 	allocator:      mem.Allocator,
 	unmarshal_data: any,
+	parse_integers: bool,
 }
 
-make_parser :: proc(data: []byte, spec := Specification.JSON, allocator := context.allocator) -> Parser {
+make_parser :: proc(data: []byte, spec := Specification.JSON, parse_integers := false, allocator := context.allocator) -> Parser {
 	p: Parser;
-	p.tok = make_tokenizer(data, spec);
+	p.tok = make_tokenizer(data, spec, parse_integers);
 	p.spec = spec;
 	p.allocator = allocator;
 	assert(p.allocator.procedure != nil);
@@ -23,9 +24,9 @@ make_parser :: proc(data: []byte, spec := Specification.JSON, allocator := conte
 	return p;
 }
 
-parse :: proc(data: []byte, spec := Specification.JSON, allocator := context.allocator) -> (Value, Error) {
+parse :: proc(data: []byte, spec := Specification.JSON, parse_integers := false, allocator := context.allocator) -> (Value, Error) {
 	context.allocator = allocator;
-	p := make_parser(data, spec, allocator);
+	p := make_parser(data, spec, parse_integers, allocator);
 
 	if p.spec == Specification.JSON5 {
 		return parse_value(&p);

+ 4 - 3
core/encoding/json/tokenizer.odin

@@ -42,12 +42,13 @@ Tokenizer :: struct {
 	w:                int,  // current rune width in bytes
 	curr_line_offset: int,
 	spec:             Specification,
+	parse_integers:   bool,
 }
 
 
 
-make_tokenizer :: proc(data: []byte, spec := Specification.JSON) -> Tokenizer {
-	t := Tokenizer{pos = {line=1}, data = data, spec = spec};
+make_tokenizer :: proc(data: []byte, spec := Specification.JSON, parse_integers := false) -> Tokenizer {
+	t := Tokenizer{pos = {line=1}, data = data, spec = spec, parse_integers = parse_integers};
 	next_rune(&t);
 	if t.r == utf8.RUNE_BOM {
 		next_rune(&t);
@@ -217,7 +218,7 @@ get_token :: proc(t: ^Tokenizer) -> (token: Token, err: Error) {
 		fallthrough;
 
 	case '0'..'9':
-		token.kind = .Integer;
+		token.kind = t.parse_integers ? .Integer : .Float;
 		if t.spec == .JSON5 { // Hexadecimal Numbers
 			if curr_rune == '0' && (t.r == 'x' || t.r == 'X') {
 				next_rune(t);

+ 1 - 1
core/encoding/json/validator.odin

@@ -4,7 +4,7 @@ import "core:mem"
 
 // NOTE(bill): is_valid will not check for duplicate keys
 is_valid :: proc(data: []byte, spec := Specification.JSON) -> bool {
-	p := make_parser(data, spec, mem.nil_allocator());
+	p := make_parser(data, spec, false, mem.nil_allocator());
 	if p.spec == Specification.JSON5 {
 		return validate_value(&p);
 	}