diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2025-01-31 08:02:09 +0100 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2025-01-31 08:02:09 +0100 |
| commit | 8a9e6b1bd3be1041792311a86d8aac68b659e891 (patch) | |
| tree | 2a62729da17b2e6669c3d71a162525ff37e42c6a /json.c | |
feat: First version, failing json parse string
Diffstat (limited to 'json.c')
| -rw-r--r-- | json.c | 113 |
1 files changed, 113 insertions, 0 deletions
@@ -0,0 +1,113 @@ +#include "json.h" + +#include <assert.h> +#include <ctype.h> +#include <math.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> + +#include "string.h" + +typedef struct { + int value; + uintptr_t pos; +} parse_integer_result; + +parse_integer_result parse_integer(Arena *a, Str src, uintptr_t pos) { + int *ints = new (a, int, 16); // TODO: reuse in parsing + int i = 0; + while (isdigit(src.data[pos + i])) { + int val = (src.data[pos + i] - '0'); + ints[i] = val; + i++; + } + int result = 0; + for (int j = 0; j < i; j++) { + result += ints[j] * pow(10, (i - j - 1)); + } + printf("json.parse_integer: parsed int=%d at pos=%lu\n", result, pos); + return (parse_integer_result){result, pos + i}; +} + +uintptr_t absorb_whitespaces(Str src, uintptr_t pos) { + int i = 0; + while (isspace(src.data[pos + i])) { + i++; + } + return pos + i; +} + +typedef struct { + Vec *items; + uintptr_t pos; +} parse_array_result; + +parse_array_result parse_array(Arena *a, Str src, uintptr_t start_pos) { + printf("json.parse_array: parsing array %s\n", src.data + start_pos); + assert(src.data[start_pos] == '['); + uintptr_t pos = start_pos + 1; + Vec *items = Vec_new(a, JSON, 0); + for (;;) { + pos = absorb_whitespaces(src, pos); + parse_integer_result result = parse_integer(a, src, pos); + assert(result.pos > pos); + items = Vec_push(a, items, &result.value); + pos = result.pos; + pos = absorb_whitespaces(src, pos); + if (src.data[pos] == ',') { + pos++; + } else { + break; + } + }; + assert(src.data[pos] == ']'); + + return (parse_array_result){items, pos + 1}; +} + +typedef struct { + Str string; + uintptr_t pos; +} parse_string_result; + +parse_string_result parse_string(Arena *a, Str src, uintptr_t pos) { + printf("json.parse_string: %s", src.data + pos); + assert(src.data[pos] == '"'); + int i = 1; + + while (src.data[pos + i] != '"' && src.data[pos + i - 1] != '\\') { + i++; + assert(i + pos <= src.len); + } + assert(src.data[pos + i]); + char *s; + memcpy(s, src.data + pos + 1, i - 1); + + printf("%s", s); + + return (parse_string_result){Str_copy(a, src.data + pos + 1, i - 1), pos + i}; +} + +JSON JSON_parse(Arena *a, Str src) { + JSON json = {0}; + int pos = 0; + // printf("json.parse: src=%s", src.data); + if (isdigit(src.data[pos])) { + parse_integer_result result = parse_integer(a, src, 0); + json.integer = &result.value; + pos = result.pos; + } + if (src.data[pos] == '[') { + parse_array_result result = parse_array(a, src, pos); + json.array = result.items; + pos = result.pos; + } + if (src.data[pos] == '"') { + parse_string_result result = parse_string(a, src, pos); + json.string = &result.string; + pos = result.pos; + } + + return json; +} |
