aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/token.c
diff options
context:
space:
mode:
authornsfisis <nsfisis@gmail.com>2025-08-29 21:25:03 +0900
committernsfisis <nsfisis@gmail.com>2025-08-29 21:49:56 +0900
commitb678465c11517a5342b1ec5aa4fe21570f13a3ed (patch)
tree6ef19e02b1cf18f5ac451e6104f6e20b475a6f52 /src/token.c
parent8f352553faec69a6f29854898b93be47604aff28 (diff)
downloadducc-b678465c11517a5342b1ec5aa4fe21570f13a3ed.tar.gz
ducc-b678465c11517a5342b1ec5aa4fe21570f13a3ed.tar.zst
ducc-b678465c11517a5342b1ec5aa4fe21570f13a3ed.zip
feat: add utility function to dump any internal object as JSON
Diffstat (limited to 'src/token.c')
-rw-r--r--src/token.c57
1 files changed, 50 insertions, 7 deletions
diff --git a/src/token.c b/src/token.c
index 70e4a41..74105f3 100644
--- a/src/token.c
+++ b/src/token.c
@@ -1,5 +1,6 @@
#include "token.h"
#include "common.h"
+#include "json.h"
const char* token_kind_stringify(TokenKind k) {
if (k == TokenKind_eof)
@@ -283,28 +284,53 @@ BOOL is_pp_directive(TokenKind k) {
k == TokenKind_pp_directive_warning;
}
-const char* token_stringify(Token* t) {
- TokenKind k = t->kind;
+const char* token_stringify(Token* tok) {
+ TokenKind k = tok->kind;
if (k == TokenKind_pp_directive_non_directive) {
- char* buf = calloc(strlen(t->value.string) + 1 + 1, sizeof(char));
- sprintf(buf, "#%s", t->value.string);
+ char* buf = calloc(strlen(tok->value.string) + 1 + 1, sizeof(char));
+ sprintf(buf, "#%s", tok->value.string);
return buf;
} else if (k == TokenKind_literal_int) {
const char* kind_str = token_kind_stringify(k);
char* buf = calloc(10 + strlen(kind_str) + 3 + 1, sizeof(char));
- sprintf(buf, "%d (%s)", t->value.integer, kind_str);
+ sprintf(buf, "%d (%s)", tok->value.integer, kind_str);
return buf;
} else if (k == TokenKind_other || k == TokenKind_character_constant || k == TokenKind_ident ||
k == TokenKind_literal_str) {
const char* kind_str = token_kind_stringify(k);
- char* buf = calloc(strlen(t->value.string) + strlen(kind_str) + 3 + 1, sizeof(char));
- sprintf(buf, "%s (%s)", t->value.string, kind_str);
+ char* buf = calloc(strlen(tok->value.string) + strlen(kind_str) + 3 + 1, sizeof(char));
+ sprintf(buf, "%s (%s)", tok->value.string, kind_str);
return buf;
} else {
return token_kind_stringify(k);
}
}
+void token_build_json(JsonBuilder* builder, Token* tok) {
+ jsonbuilder_object_start(builder);
+ jsonbuilder_object_member_start(builder, "kind");
+ jsonbuilder_string(builder, token_kind_stringify(tok->kind));
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_member_start(builder, "value");
+ if (tok->kind == TokenKind_pp_directive_non_directive) {
+ char* buf = calloc(strlen(tok->value.string) + 1 + 1, sizeof(char));
+ sprintf(buf, "#%s", tok->value.string);
+ jsonbuilder_string(builder, buf);
+ } else if (tok->kind == TokenKind_literal_int) {
+ jsonbuilder_integer(builder, tok->value.integer);
+ } else if (tok->kind == TokenKind_other || tok->kind == TokenKind_character_constant ||
+ tok->kind == TokenKind_ident || tok->kind == TokenKind_literal_str) {
+ jsonbuilder_string(builder, tok->value.string);
+ } else {
+ jsonbuilder_null(builder);
+ }
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_member_start(builder, "loc");
+ sourcelocation_build_json(builder, &tok->loc);
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_end(builder);
+}
+
void tokens_init(TokenArray* tokens, size_t capacity) {
tokens->len = 0;
tokens->capacity = capacity;
@@ -330,3 +356,20 @@ Token* tokens_pop(TokenArray* tokens) {
if (tokens->len != 0)
tokens->len--;
}
+
+void tokens_build_json(JsonBuilder* builder, TokenArray* tokens) {
+ jsonbuilder_object_start(builder);
+ jsonbuilder_object_member_start(builder, "len");
+ jsonbuilder_integer(builder, tokens->len);
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_member_start(builder, "data");
+ jsonbuilder_array_start(builder);
+ for (int i = 0; i < tokens->len; ++i) {
+ jsonbuilder_array_element_start(builder);
+ token_build_json(builder, &tokens->data[i]);
+ jsonbuilder_array_element_end(builder);
+ }
+ jsonbuilder_array_end(builder);
+ jsonbuilder_object_member_end(builder);
+ jsonbuilder_object_end(builder);
+}