From 657889c2b33bb53375c37ea6433957776169b86b Mon Sep 17 00:00:00 2001 From: Ivar Fatland Date: Sat, 3 Oct 2026 17:13:04 +0200 Subject: [PATCH] some progress some progress --- cig.h | 11 +---- json.c | 126 ++++++++++++++++++++++++++++++++----------------- scanner.c | 8 ++-- test_scanner.c | 4 +- 4 files changed, 91 insertions(+), 58 deletions(-) diff --git a/cig.h b/cig.h index 10b44be..3668c9e 100644 --- a/cig.h +++ b/cig.h @@ -317,7 +317,7 @@ scan_result_t scan_value_func(scan_value_t value); scan_result_t scan_error_and_recover(scanner_t *s, char const *message); bool scan_eof(scanner_t *s); -bool scan_literal(scanner_t *s, char const *lit); +scan_result_t scan_literal(scanner_t *s, char const *lit); int scan_repeat_literal(scanner_t *s, char const *lit); bool scan_whitespace(scanner_t *s); scan_result_t scan_digit(scanner_t *s); @@ -389,14 +389,7 @@ typedef struct json_pair { json_value_t value; } json_pair_t; -bool json_as_array(json_value_t *value, json_array_t *array); -bool json_as_boolean(json_value_t *value, bool *out_bool); -bool json_as_null(json_value_t *value); -bool json_as_number(json_value_t *value, double *out_double); -bool json_as_object(json_value_t *value, json_object_t *out_object); -bool json_as_string(json_value_t *value, json_string_t *out_string); -bool json_obj_get(json_object_t *obj, json_string_t key, json_value_t *out_value); -json_value_t json_parse(scanner_t *scanner, allocator_t allocator); +bool json_parse(scanner_t *scanner, allocator_t allocator, json_value_t *out); // string builder ////////////////////////////////////////////////////////////// typedef struct string_builder_node { diff --git a/json.c b/json.c index 5835a44..f2ca2d5 100644 --- a/json.c +++ b/json.c @@ -1,66 +1,106 @@ #include "cig.h" #include -bool json_as_array(json_value_t *value, json_array_t *array) { -} - -bool json_as_boolean(json_value_t *value, bool *out_bool) { -} - -bool json_as_null(json_value_t *value) { -} - -bool json_as_number(json_value_t *value, double *out_double) { -} - -bool json_as_object(json_value_t *value, json_object_t *out_object) { -} - -bool json_as_string(json_value_t *value, json_string_t *out_string) { -} - -bool json_obj_get(json_object_t *obj, json_string_t key, json_value_t *out_value) { -} - -json_value_t json_parse(scanner_t *scanner, allocator_t allocator) { +bool json_parse(scanner_t *scanner, allocator_t allocator, json_value_t *out) { scan_whitespace(scanner); - if (scan_string_literal(scanner)) { - const char *buffer = scanner->value.string_literal; + + scan_result_t str_result = scan_string_literal(scanner); + if (str_result.ok) { + const char *buffer = str_result.value.string_literal; size_t length = strlen(buffer); char *buff_copy = allocator_alloc(allocator, length+1); strncpy(buff_copy, buffer, length+1); buff_copy[length] = '\0'; - return (json_value_t) { + *out = (json_value_t) { .type=json_type_string, .string=(json_string_t) { .length=length, .buffer=buff_copy } }; - } else if (scan_f64(scanner)) { - return (json_value_t) { + return true; + } + + scan_result_t f64_result = scan_f64(scanner); + if (f64_result.ok) { + *out = (json_value_t) { .type=json_type_number, - .number=scanner->value.f64 + .number=f64_result.value.f64 }; - } else if (scan_i64(scanner)) { - // TODO: is this needed? - return (json_value_t) { + return true; + } + + scan_result_t i64_result = scan_i64(scanner); + if (i64_result.ok) { + *out = (json_value_t) { .type=json_type_number, - .number=(double)scanner->value.i64 + .number=(double)i64_result.value.i64 }; - } else if (scan_literal(scanner, "true")) { - return (json_value_t) { + return true; + } + + scan_result_t true_result = scan_literal(scanner, "true"); + if (true_result.ok) { + *out = (json_value_t) { .type=json_type_boolean, .boolean=true }; - } else if (scan_literal(scanner, "false")) { - return (json_value_t) { + return true; + } + + scan_result_t false_result = scan_literal(scanner, "false"); + if (false_result.ok) { + *out = (json_value_t) { .type=json_type_boolean, .boolean=false }; - } else if (scan_literal(scanner, "null")) { - return (json_value_t) { - .type=json_type_null - }; - } else if (scan_literal(scanner, "[")) { - json_parse(scanner, allocator); - // TODO + return true; } + + scan_result_t null_result = scan_literal(scanner, "null"); + if (null_result.ok) { + *out = (json_value_t) { .type=json_type_null, }; + return true; + } + + scan_result_t arr_open_result = scan_literal(scanner, "["); + if (arr_open_result.ok) { + json_value_t *values = make_arr(json_value_t, allocator); + do { + scan_whitespace(scanner); + json_value_t val; + bool ok = json_parse(scanner, allocator, &val); + if (!ok) { + return false; + } + arr_append(values, val); + scan_whitespace(scanner); + } while(scan_literal(scanner, ",").ok); + + *out = (json_value_t) { + .type=json_type_array, + .array=(json_array_t){ + .values=values, + .length=arr_len(values), + }, + }; + + scan_result_t arr_close_result = scan_literal(scanner, "]"); + return arr_close_result.ok; + } + + // TODO: arrays and objects are allowed to contain nothing... + + scan_result_t obj_open_result = scan_literal(scanner, "{"); + if (obj_open_result.ok) { + json_pair_t *pairs = make_arr(json_pair_t, allocator); + // TODO: continue here + do { + scan_whitespace(scanner); + scan_result_t key_result = scan_string_literal(scanner); + } while(scan_literal(scanner, ",").ok); + } + +typedef struct json_pair { + json_string_t key; + json_value_t value; +} json_pair_t; + } diff --git a/scanner.c b/scanner.c index 0148760..bcaeaa8 100644 --- a/scanner.c +++ b/scanner.c @@ -60,22 +60,22 @@ bool scan_eof(scanner_t *s) { return *s->cur == '\0'; } -bool scan_literal(scanner_t *s, char const *lit) { +scan_result_t scan_literal(scanner_t *s, char const *lit) { char const *save = s->cur; while (*lit && *lit == *s->cur) { lit++; s->cur++; } if (*lit == '\0') { - return true; + return (scan_result_t) { .ok = true }; } s->cur = save; - return false; + return scan_error(s, "literal not present"); } int scan_repeat_literal(scanner_t *s, char const *lit) { int n_repeats = 0; - while (scan_literal(s, lit)) { + while (scan_literal(s, lit).ok) { n_repeats++; } return n_repeats; diff --git a/test_scanner.c b/test_scanner.c index 03c292d..d368009 100644 --- a/test_scanner.c +++ b/test_scanner.c @@ -26,9 +26,9 @@ Test(scanner, looks_like_float) { bool does_look_like_int = looks_like_int(&scanner); while (*scanner.cur++ != ' '); bool expect; - if (scan_literal(&scanner, "true")) { + if (scan_literal(&scanner, "true").ok) { expect = true; - } else if (scan_literal(&scanner, "false")) { + } else if (scan_literal(&scanner, "false").ok) { expect = false; } else { assert(false && "invalid expectation");