some progress
some progress some progress
This commit is contained in:
@@ -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);
|
scan_result_t scan_error_and_recover(scanner_t *s, char const *message);
|
||||||
bool scan_eof(scanner_t *s);
|
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);
|
int scan_repeat_literal(scanner_t *s, char const *lit);
|
||||||
bool scan_whitespace(scanner_t *s);
|
bool scan_whitespace(scanner_t *s);
|
||||||
scan_result_t scan_digit(scanner_t *s);
|
scan_result_t scan_digit(scanner_t *s);
|
||||||
@@ -389,14 +389,7 @@ typedef struct json_pair {
|
|||||||
json_value_t value;
|
json_value_t value;
|
||||||
} json_pair_t;
|
} json_pair_t;
|
||||||
|
|
||||||
bool json_as_array(json_value_t *value, json_array_t *array);
|
bool json_parse(scanner_t *scanner, allocator_t allocator, json_value_t *out);
|
||||||
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);
|
|
||||||
|
|
||||||
// string builder //////////////////////////////////////////////////////////////
|
// string builder //////////////////////////////////////////////////////////////
|
||||||
typedef struct string_builder_node {
|
typedef struct string_builder_node {
|
||||||
|
|||||||
@@ -1,66 +1,107 @@
|
|||||||
#include "cig.h"
|
#include "cig.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
bool json_as_array(json_value_t *value, json_array_t *array) {
|
bool json_parse(scanner_t *scanner, allocator_t allocator, json_value_t *out) {
|
||||||
}
|
|
||||||
|
|
||||||
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) {
|
|
||||||
scan_whitespace(scanner);
|
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);
|
size_t length = strlen(buffer);
|
||||||
char *buff_copy = allocator_alloc(allocator, length+1);
|
char *buff_copy = allocator_alloc(allocator, length+1);
|
||||||
strncpy(buff_copy, buffer, length+1);
|
strncpy(buff_copy, buffer, length+1);
|
||||||
buff_copy[length] = '\0';
|
buff_copy[length] = '\0';
|
||||||
return (json_value_t) {
|
*out = (json_value_t) {
|
||||||
.type=json_type_string,
|
.type=json_type_string,
|
||||||
.string=(json_string_t) { .length=length, .buffer=buff_copy }
|
.string=(json_string_t) { .length=length, .buffer=buff_copy }
|
||||||
};
|
};
|
||||||
} else if (scan_f64(scanner)) {
|
return true;
|
||||||
return (json_value_t) {
|
}
|
||||||
|
|
||||||
|
scan_result_t f64_result = scan_f64(scanner);
|
||||||
|
if (f64_result.ok) {
|
||||||
|
*out = (json_value_t) {
|
||||||
.type=json_type_number,
|
.type=json_type_number,
|
||||||
.number=scanner->value.f64
|
.number=f64_result.value.f64
|
||||||
};
|
};
|
||||||
} else if (scan_i64(scanner)) {
|
return true;
|
||||||
// TODO: is this needed?
|
}
|
||||||
return (json_value_t) {
|
|
||||||
|
scan_result_t i64_result = scan_i64(scanner);
|
||||||
|
if (i64_result.ok) {
|
||||||
|
*out = (json_value_t) {
|
||||||
.type=json_type_number,
|
.type=json_type_number,
|
||||||
.number=(double)scanner->value.i64
|
.number=(double)i64_result.value.i64
|
||||||
};
|
};
|
||||||
} else if (scan_literal(scanner, "true")) {
|
return true;
|
||||||
return (json_value_t) {
|
}
|
||||||
|
|
||||||
|
scan_result_t true_result = scan_literal(scanner, "true");
|
||||||
|
if (true_result.ok) {
|
||||||
|
*out = (json_value_t) {
|
||||||
.type=json_type_boolean,
|
.type=json_type_boolean,
|
||||||
.boolean=true
|
.boolean=true
|
||||||
};
|
};
|
||||||
} else if (scan_literal(scanner, "false")) {
|
return true;
|
||||||
return (json_value_t) {
|
}
|
||||||
|
|
||||||
|
scan_result_t false_result = scan_literal(scanner, "false");
|
||||||
|
if (false_result.ok) {
|
||||||
|
*out = (json_value_t) {
|
||||||
.type=json_type_boolean,
|
.type=json_type_boolean,
|
||||||
.boolean=false
|
.boolean=false
|
||||||
};
|
};
|
||||||
} else if (scan_literal(scanner, "null")) {
|
return true;
|
||||||
return (json_value_t) {
|
}
|
||||||
.type=json_type_null
|
|
||||||
|
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);
|
||||||
|
scan_result_t arr_close_result = scan_literal(scanner, "]");
|
||||||
|
if (arr_close_result.ok) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
json_value_t val;
|
||||||
|
bool ok = json_parse(scanner, allocator, &val);
|
||||||
|
if (!ok) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
arr_append(values, val);
|
||||||
|
} while(scan_literal(scanner, ",").ok); // Not quite correct, but oh well...
|
||||||
|
|
||||||
|
*out = (json_value_t) {
|
||||||
|
.type=json_type_array,
|
||||||
|
.array=(json_array_t){
|
||||||
|
.values=values,
|
||||||
|
.length=arr_len(values),
|
||||||
|
},
|
||||||
};
|
};
|
||||||
} else if (scan_literal(scanner, "[")) {
|
|
||||||
json_parse(scanner, allocator);
|
return arr_close_result.ok;
|
||||||
// TODO
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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);
|
||||||
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,22 +60,22 @@ bool scan_eof(scanner_t *s) {
|
|||||||
return *s->cur == '\0';
|
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;
|
char const *save = s->cur;
|
||||||
while (*lit && *lit == *s->cur) {
|
while (*lit && *lit == *s->cur) {
|
||||||
lit++;
|
lit++;
|
||||||
s->cur++;
|
s->cur++;
|
||||||
}
|
}
|
||||||
if (*lit == '\0') {
|
if (*lit == '\0') {
|
||||||
return true;
|
return (scan_result_t) { .ok = true };
|
||||||
}
|
}
|
||||||
s->cur = save;
|
s->cur = save;
|
||||||
return false;
|
return scan_error(s, "literal not present");
|
||||||
}
|
}
|
||||||
|
|
||||||
int scan_repeat_literal(scanner_t *s, char const *lit) {
|
int scan_repeat_literal(scanner_t *s, char const *lit) {
|
||||||
int n_repeats = 0;
|
int n_repeats = 0;
|
||||||
while (scan_literal(s, lit)) {
|
while (scan_literal(s, lit).ok) {
|
||||||
n_repeats++;
|
n_repeats++;
|
||||||
}
|
}
|
||||||
return n_repeats;
|
return n_repeats;
|
||||||
|
|||||||
+2
-2
@@ -26,9 +26,9 @@ Test(scanner, looks_like_float) {
|
|||||||
bool does_look_like_int = looks_like_int(&scanner);
|
bool does_look_like_int = looks_like_int(&scanner);
|
||||||
while (*scanner.cur++ != ' ');
|
while (*scanner.cur++ != ' ');
|
||||||
bool expect;
|
bool expect;
|
||||||
if (scan_literal(&scanner, "true")) {
|
if (scan_literal(&scanner, "true").ok) {
|
||||||
expect = true;
|
expect = true;
|
||||||
} else if (scan_literal(&scanner, "false")) {
|
} else if (scan_literal(&scanner, "false").ok) {
|
||||||
expect = false;
|
expect = false;
|
||||||
} else {
|
} else {
|
||||||
assert(false && "invalid expectation");
|
assert(false && "invalid expectation");
|
||||||
|
|||||||
Reference in New Issue
Block a user