Files
tokenizer/json.c
2025-11-14 07:30:20 +01:00

132 lines
2.4 KiB
C

#include <stdlib.h>
#include <stddef.h>
#include <stdbool.h>
#include <stdio.h>
#include "s8slice.h"
struct json {
struct json_value* root;
struct json_value** ctx;
S8Slice pending_key;
bool has_pending_key;
};
struct json_value {
S8Slice key;
struct json_value* next;
enum {
JSON_OBJECT,
JSON_ARRAY,
JSON_NUMBER,
JSON_STRING,
JSON_BOOL,
JSON_NULL,
} kind;
union {
double number;
S8Slice string;
bool boolean;
struct json_value* object_head;
struct json_value* array_head;
};
};
static struct json_value* new_value(struct json* j)
{
struct json_value* new = calloc(1, sizeof(struct json_value));
if (!new) {
perror("calloc");
abort();
}
return new;
}
void json_init(struct json* j)
{
j->ctx = &j->root;
}
void json_add_key(struct json* j, S8Slice key)
{
j->has_pending_key = true;
j->pending_key = key;
}
void json_add_value(struct json* j, struct json_value* new)
{
*j->ctx = new;
j->ctx = &new->next;
/*
if (j->has_pending_key) {
new->key = j->pending_key;
j->has_pending_key = false;
}
*/
}
void json_add_object(struct json* j)
{
struct json_value* new = new_value(j);
new->kind = JSON_OBJECT;
json_add_value(j, new);
j->ctx = &new->object_head;
}
void json_add_number(struct json* j, double n)
{
struct json_value* new = new_value(j);
new->kind = JSON_NUMBER;
new->number = n;
json_add_value(j, new);
}
void json_print_value(struct json_value* val, int depth)
{
if (!val) {
return;
}
for (int i = 0; i < depth; i++) {
printf(" ");
}
switch (val->kind) {
case JSON_NUMBER: {
printf("%lf,\n", val->number);
json_print_value(val->next, depth);
} break;
case JSON_OBJECT: {
json_print_value(val->object_head, depth+1);
} break;
default: {
fprintf(stderr, "not implemented");
abort();
} break;
}
}
void json_print(struct json* j)
{
json_print_value(j->root, 0);
}
int main()
{
struct json j = {0};
json_init(&j);
json_add_number(&j, 53);
json_add_object(&j);
json_add_number(&j, 12);
json_print(&j);
return EXIT_SUCCESS;
}