expect_token :: (use parser: ^Parser, kind: Token.Kind) -> (Token, Error) {
previous := current_token;
consume_token(parser);
- if previous.kind == kind do return previous, .None;
- else do return previous, .Unexpected_Token;
+ error := Error.{ .None, previous.position };
+ if previous.kind != kind do error.kind = .Unexpected_Token;
+ return previous, error;
}
#private
case .Open_Bracket {
value, err := parse_array(parser);
- if err != .None do return value, err;
+ if err.kind != .None do return value, err;
return_value = value;
}
case .Open_Brace {
value, err := parse_object(parser);
- if err != .None do return value, err;
+ if err.kind != .None do return value, err;
return_value = value;
}
case #default {
consume_token(parser);
- return return_value, .Unexpected_Token;
+ return return_value, .{ .Unexpected_Token, current.position };
}
}
- return return_value, .None;
+ return return_value, .{ .None };
}
#private_file
value := new(Value_Array, allocator);
_, err := expect_token(parser, .Open_Bracket);
- if err != .None do return value, err;
+ if err.kind != .None do return value, err;
// This uses the context allocators because the array resizing needs to happen in a general purpose heap allocator
arr := array.make(#type ^Value, allocator=context.allocator);
- defer if err != .None {
+ defer if err.kind != .None {
for elem: arr {
free(elem, allocator);
}
while current_token.kind != .Close_Bracket {
elem, elem_err := parse_value(parser);
- if elem_err != .None {
+ if elem_err.kind != .None {
err = elem_err;
return value, err;
}
}
_, close_err := expect_token(parser, .Close_Bracket);
- if close_err != .None {
+ if close_err.kind != .None {
err = close_err;
return value, err;
}
value := new(Value_Object, allocator);
_, err := expect_token(parser, .Open_Brace);
- if err != .None do return value, err;
+ if err.kind != .None do return value, err;
// This uses the context allocators because the array resizing needs to happen in a general purpose heap allocator
array.init(^value.object_, allocator=context.allocator);
- defer if err != .None {
+ defer if err.kind != .None {
free(value, allocator);
}
while current_token.kind != .Close_Brace {
key_token, key_err := expect_token(parser, .String);
- if key_err != .None {
+ if key_err.kind != .None {
err = key_err;
return value, err;
}
key := unescape_string(key_token, allocator);
_, colon_err := expect_token(parser, .Colon);
- if colon_err != .None {
+ if colon_err.kind != .None {
err = colon_err;
return value, err;
}
elem, elem_err := parse_value(parser);
- if elem_err != .None {
+ if elem_err.kind != .None {
err = elem_err;
return value, err;
}
#if false {
for elem: value.object_ {
if elem.key == key {
- err = .Duplicate_Keys;
+ err.kind = .Duplicate_Keys;
+ err.pos = key_token.pos;
string.free(key, allocator);
return value, err;
}
}
_, close_err := expect_token(parser, .Close_Brace);
- if close_err != .None {
+ if close_err.kind != .None {
err = close_err;
return value, err;
}
buffer.count = buffer_write;
return buffer;
-}
\ No newline at end of file
+}
#private
token_get :: (use tkn: ^Tokenizer) -> (Token, Error) {
- err := Error.None;
+ err := Error.{};
skip_whitespace(tkn);
token := Token.{};
curr_char := data[offset];
next_char, has_next := next_character(tkn);
- if !has_next do return .{}, .EOF;
+ if !has_next do return .{}, .{ .EOF, token.position };
switch curr_char {
case #char "{" do token.kind = .Open_Brace;
}
case #char "-" {
- next_character(tkn);
switch data[offset] {
case #char "0" .. #char "9" ---
case #default {
- err = .Illegal_Character;
+ err.kind = .Illegal_Character;
+ err.pos = token.position;
break break;
}
}
while offset < data.count {
ch := data[offset];
if ch == #char "\n" {
- err = .String_Unterminated;
+ err.kind = .String_Unterminated;
+ err.pos = token.position;
break break;
}
token.text = data.data[token.offset .. offset];
- if token.kind == .Invalid do err = .Illegal_Character;
+ if token.kind == .Invalid do err.kind = .Illegal_Character;
return token, err;
}
retval := data[offset];
offset += 1;
- column += offset;
+ column += 1;
return retval, true;
}
next_character(tkn);
}
}
-}
\ No newline at end of file
+}