From ea09838b46061bc599babe410b89931647a16665 Mon Sep 17 00:00:00 2001 From: Abdelrahman Date: Sun, 7 Sep 2025 19:22:49 +0100 Subject: [PATCH] Implement stringifying functions and headers --- ccodegen/datatypes.c | 188 ++++++++++++++++++++++++++++++++++++++----- ccodegen/datatypes.h | 29 +++++++ 2 files changed, 199 insertions(+), 18 deletions(-) diff --git a/ccodegen/datatypes.c b/ccodegen/datatypes.c index 3b56529..5a4df90 100644 --- a/ccodegen/datatypes.c +++ b/ccodegen/datatypes.c @@ -6,6 +6,9 @@ #include "wapp_core.h" #define ERR_MSG "Not enough capacity in dst buffer" +#define CFILE_DISCLAIMER "/**\n" \ + " * THIS FILE IS AUTOMATICALLY GENERATED. ANY MODIFICATIONS TO IT WILL BE OVERWRITTEN.\n" \ + " */\n\n" void cobject_to_string(Str8 *dst, const CObject *object) { wapp_debug_assert(dst != NULL && object != NULL, "`allocator`, `dst` and `object` should not be NULL"); @@ -45,6 +48,7 @@ void cobject_to_string(Str8 *dst, const CObject *object) { carg_to_string(dst, &(object->object.c_arg)); break; case COBJECT_CFUNC: + cfunc_to_string(dst, &(object->object.c_func)); break; case COBJECT_CINCULDE: cinclude_to_string(dst, &(object->object.c_include)); @@ -87,7 +91,7 @@ void cpointer_to_string(Str8 *dst, const CPointer *cpointer) { void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval) { wapp_debug_assert(dst != NULL && cenumval != NULL, "`dst` and `cenumval` should not be NULL"); - Str8 tmp = wapp_str8_buf(32); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_TINY); u64 tmp_size = 0; if (cenumval->value != NULL) { wapp_str8_format(&tmp, " = %d", *(cenumval->value)); @@ -105,10 +109,10 @@ void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval) { void cenum_to_string(Str8 *dst, const CEnum *cenum) { wapp_debug_assert(dst != NULL && cenum != NULL, "`dst` and `cenum` should not be NULL"); - Str8 header = wapp_str8_buf(4096); - Str8 values = wapp_str8_buf(8192); - Str8 footer = wapp_str8_buf(4096); - Str8 tmp = wapp_str8_buf(4096); + Str8 header = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 values = wapp_str8_buf(CCGEN_BUF_MAX); + Str8 footer = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_LARGE); if (cenum->add_typedef) { wapp_str8_copy_cstr_capped(&header, "typedef enum {\n"); @@ -152,8 +156,8 @@ void cmacro_to_string(Str8 *dst, const CMacro *cmacro) { void cstruct_to_string(Str8 *dst, const CStruct *cstruct) { wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL"); - Str8 declaration = wapp_str8_buf(4096); - Str8 definition = wapp_str8_buf(8192); + Str8 declaration = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 definition = wapp_str8_buf(CCGEN_BUF_MAX); declare_cstruct(&declaration, cstruct); define_cstruct(&definition, cstruct); @@ -167,7 +171,7 @@ void cstruct_to_string(Str8 *dst, const CStruct *cstruct) { void declare_cstruct(Str8 *dst, const CStruct *cstruct) { wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL"); - Str8 tmp = wapp_str8_buf(8192); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX); wapp_str8_format(&tmp, "typedef struct " WAPP_STR8_SPEC " " WAPP_STR8_SPEC ";\n", wapp_str8_varg(cstruct->name), @@ -180,10 +184,10 @@ void declare_cstruct(Str8 *dst, const CStruct *cstruct) { void define_cstruct(Str8 *dst, const CStruct *cstruct) { wapp_debug_assert(dst != NULL && cstruct != NULL, "`dst` and `cstruct` should not be NULL"); - Str8 definition = wapp_str8_buf(4096); - Str8 args = wapp_str8_buf(8192); + Str8 definition = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 args = wapp_str8_buf(CCGEN_BUF_MAX); Str8 footer = wapp_str8_lit_ro("};\n"); - Str8 tmp = wapp_str8_buf(1024); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MEDIUM); wapp_str8_format(&definition, "struct " WAPP_STR8_SPEC " {\n", wapp_str8_varg(cstruct->name)); @@ -242,10 +246,10 @@ void cdatatype_to_string(Str8 *dst, const CDataType *cdatatype) { void carg_to_string(Str8 *dst, const CArg *carg) { wapp_debug_assert(dst != NULL && carg != NULL, "`dst` and `carg` should not be NULL"); - Str8 qualifier = wapp_str8_buf(1024); - Str8 type = wapp_str8_buf(4096); - Str8 pointer = wapp_str8_buf(1024); - Str8 array = wapp_str8_buf(1024); + Str8 qualifier = wapp_str8_buf(CCGEN_BUF_MEDIUM); + Str8 type = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 pointer = wapp_str8_buf(CCGEN_BUF_MEDIUM); + Str8 array = wapp_str8_buf(CCGEN_BUF_MEDIUM); cqualifier_to_string(&qualifier, carg->qualifier); cdatatype_to_string(&type, &(carg->type)); @@ -260,15 +264,82 @@ void carg_to_string(Str8 *dst, const CArg *carg) { wapp_str8_varg(carg->name), wapp_str8_varg(array)); } +void cfunc_to_string(Str8 *dst, const CFunc *cfunc) { + wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL"); + + Str8 qualifiers = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 args = wapp_str8_buf(CCGEN_BUF_LARGE); + Str8 ret_type = wapp_str8_buf(CCGEN_BUF_SMALL); + Str8 pointer = wapp_str8_buf(CCGEN_BUF_SMALL); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MEDIUM); + CQualifier *qf = NULL; + CArg *arg = NULL; + + for (u64 i = 0; i < cfunc->qualifiers.node_count; ++i) { + qf = wapp_cqualifier_list_get(&(cfunc->qualifiers), i)->item; + if (*qf == CQUALIFIER_NONE) { continue; } + + cqualifier_to_string(&tmp, *qf); + + wapp_runtime_assert(tmp.size + 1 <= qualifiers.capacity - qualifiers.size, ERR_MSG); + if (qualifiers.size > 0) { wapp_str8_concat_capped(&qualifiers, &wapp_str8_lit_ro(" ")); } + + wapp_str8_concat_capped(&qualifiers, &tmp); + } + + for (u64 i = 0; i < cfunc->args.node_count; ++i) { + arg = wapp_carg_list_get(&(cfunc->args), i)->item; + carg_to_string(&tmp, arg); + + wapp_runtime_assert(tmp.size + 2 <= args.capacity - args.size, ERR_MSG); + wapp_str8_concat_capped(&args, &tmp); + if (i + 1 < cfunc->args.node_count) { wapp_str8_concat_capped(&args, &wapp_str8_lit_ro(", ")); } + } + + cdatatype_to_string(&ret_type, &(cfunc->ret_type)); + cpointer_to_string(&pointer, &(cfunc->pointer)); + + u64 total_size = cfunc->name.size + qualifiers.size + args.size + ret_type.size + pointer.size + 4; + wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG); + wapp_str8_format(dst, + WAPP_STR8_SPEC WAPP_STR8_SPEC " " WAPP_STR8_SPEC WAPP_STR8_SPEC "(" WAPP_STR8_SPEC ")", + wapp_str8_varg(qualifiers), + wapp_str8_varg(ret_type), + wapp_str8_varg(pointer), + wapp_str8_varg(cfunc->name), + wapp_str8_varg(args)); +} + +void declare_cfunc(Str8 *dst, const CFunc *cfunc) { + wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL"); + + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX); + cfunc_to_string(&tmp, cfunc); + + wapp_runtime_assert(tmp.size + 2 <= dst->capacity, ERR_MSG); + wapp_str8_format(dst, WAPP_STR8_SPEC ";\n", wapp_str8_varg(tmp)); +} + +void define_cfunc(Str8 *dst, const CFunc *cfunc) { + wapp_debug_assert(dst != NULL && cfunc != NULL, "`dst` and `cfunc` should not be NULL"); + + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX); + cfunc_to_string(&tmp, cfunc); + + wapp_runtime_assert(tmp.size + cfunc->body.size + 8 <= dst->capacity, ERR_MSG); + wapp_str8_format(dst, WAPP_STR8_SPEC " {\n" WAPP_STR8_SPEC "\n}\n\n", + wapp_str8_varg(tmp), wapp_str8_varg(cfunc->body)); +} + void cinclude_to_string(Str8 *dst, const CInclude *cinclude) { wapp_debug_assert(dst != NULL && cinclude != NULL, "`dst` and `cinclude` should not be NULL"); - Str8 header_str = wapp_str8_buf(4096); + Str8 header_str = wapp_str8_buf(CCGEN_BUF_LARGE); if (!cheaderinclude_to_string(&header_str, &(cinclude->header))) { return; } Str8 inc = wapp_str8_lit("#include "); - Str8 open_symbol = wapp_str8_buf(16); - Str8 close_symbol = wapp_str8_buf(16); + Str8 open_symbol = wapp_str8_buf(CCGEN_BUF_MIN); + Str8 close_symbol = wapp_str8_buf(CCGEN_BUF_MIN); if (cinclude->is_local) { wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("\"")); @@ -289,6 +360,87 @@ void cinclude_to_string(Str8 *dst, const CInclude *cinclude) { wapp_str8_varg(close_symbol)); } +void cheader_to_string(Str8 *dst, const CHeader *cheader) { + wapp_debug_assert(dst != NULL && cheader != NULL, "`dst` and `cheader` should not be NULL"); + + Allocator arena = wapp_mem_arena_allocator_init(MB(64)); + Str8 *output = wapp_str8_alloc_buf(&arena, KB(32)); + wapp_runtime_assert(output != NULL, "Failed to allocate buffer"); + + Str8 header_guard_name = wapp_str8_buf(CCGEN_BUF_SMALL); + Str8 tmp = wapp_str8_buf(CCGEN_BUF_MAX); + + // ADD HEADER GUARD AND START C LINKAGE + wapp_str8_to_upper(&header_guard_name, &(cheader->name)); + wapp_str8_concat_capped(&header_guard_name, &wapp_str8_lit_ro("_H")); + wapp_str8_format(&tmp, "#ifndef " WAPP_STR8_SPEC "\n#define " WAPP_STR8_SPEC "\n\n" + "#ifdef WAPP_PLATFORM_CPP\nBEGIN_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n", + wapp_str8_varg(header_guard_name), wapp_str8_varg(header_guard_name)); + wapp_str8_alloc_concat(&arena, output, &tmp); + + for (u64 i = 0; i < cheader->includes.node_count; ++i) { + cinclude_to_string(&tmp, wapp_cinclude_list_get(&(cheader->includes), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + if (cheader->includes.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); } + + for (u64 i = 0; i < cheader->macros.node_count; ++i) { + cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->macros), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + if (cheader->macros.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); } + + if (cheader->cpp_macros.node_count > 0) { + wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#ifdef WAPP_PLATFORM_CPP\n")); + + for (u64 i = 0; i < cheader->cpp_macros.node_count; ++i) { + cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->cpp_macros), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + + wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#else\n")); + + for (u64 i = 0; i < cheader->c_macros.node_count; ++i) { + cmacro_to_string(&tmp, wapp_cmacro_list_get(&(cheader->c_macros), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + + wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("#endif // !WAPP_PLATFORM_CPP\n\n")); + } + + for (u64 i = 0; i < cheader->decl_types.node_count; ++i) { + declare_cstruct(&tmp, wapp_cstruct_list_get(&(cheader->decl_types), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + if (cheader->decl_types.node_count > 0) { wapp_str8_alloc_concat(&arena, output, &wapp_str8_lit_ro("\n")); } + + for (u64 i = 0; i < cheader->types.node_count; ++i) { + cusertype_to_string(&tmp, wapp_cusertype_list_get(&(cheader->types), i)->item); + wapp_str8_concat_capped(&tmp, &wapp_str8_lit_ro("\n")); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + + for (u64 i = 0; i < cheader->funcs.node_count; ++i) { + declare_cfunc(&tmp, wapp_cfunc_list_get(&(cheader->funcs), i)->item); + wapp_str8_alloc_concat(&arena, output, &tmp); + } + + // END C LINKAGE AND CLOSE HEADER GUARD + wapp_str8_format(&tmp, "\n#ifdef WAPP_PLATFORM_CPP\nEND_C_LINKAGE\n#endif // !WAPP_PLATFORM_CPP\n\n" + "#endif // !" WAPP_STR8_SPEC "\n", wapp_str8_varg(header_guard_name)); + wapp_str8_alloc_concat(&arena, output, &tmp); + + wapp_runtime_assert(output->size <= dst->capacity, ERR_MSG); + wapp_str8_copy_str8_capped(dst, output); + + wapp_mem_arena_allocator_destroy(&arena); +} + +void csource_to_string(Str8 *dst, const CSource *csource) { + (void)dst; + (void)csource; +} + b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude) { wapp_debug_assert(dst != NULL && cheaderinclude != NULL, "`dst` and `cheaderinclude` should not be NULL"); diff --git a/ccodegen/datatypes.h b/ccodegen/datatypes.h index 8ac5e20..8b89a9d 100644 --- a/ccodegen/datatypes.h +++ b/ccodegen/datatypes.h @@ -7,6 +7,30 @@ #include "dbl_list.h" #include "type_enums.h" +#ifndef CCGEN_BUF_MIN +#define CCGEN_BUF_MIN 16 +#endif // !CCGEN_BUF_MIN + +#ifndef CCGEN_BUF_TINY +#define CCGEN_BUF_TINY 32 +#endif // !CCGEN_BUF_TINY + +#ifndef CCGEN_BUF_SMALL +#define CCGEN_BUF_SMALL 512 +#endif // !CCGEN_BUF_SMALL + +#ifndef CCGEN_BUF_MEDIUM +#define CCGEN_BUF_MEDIUM 1024 +#endif // !CCGEN_BUF_MEDIUM + +#ifndef CCGEN_BUF_LARGE +#define CCGEN_BUF_LARGE 4096 +#endif // !CCGEN_BUF_LARGE + +#ifndef CCGEN_BUF_MAX +#define CCGEN_BUF_MAX 8192 +#endif // !CCGEN_BUF_MAX + #define CENUM(NAME, VALUES, TYPEDEF) ((CEnum){ .name = (NAME), .values = (VALUES), .add_typedef = (TYPEDEF) }) #define CSTRUCT(NAME, ARGS, TYPEDEF_NAME_PTR) ((CStruct){ .name = (NAME), .args = (ARGS), .typedef_name = (TYPEDEF_NAME_PTR) }) @@ -245,7 +269,12 @@ void define_cstruct(Str8 *dst, const CStruct *cstruct); void cusertype_to_string(Str8 *dst, const CUserType *cusertype); void cdatatype_to_string(Str8 *dst, const CDataType *cdatatype); void carg_to_string(Str8 *dst, const CArg *carg); +void cfunc_to_string(Str8 *dst, const CFunc *cfunc); +void declare_cfunc(Str8 *dst, const CFunc *cfunc); +void define_cfunc(Str8 *dst, const CFunc *cfunc); void cinclude_to_string(Str8 *dst, const CInclude *cinclude); +void cheader_to_string(Str8 *dst, const CHeader *cheader); +void csource_to_string(Str8 *dst, const CSource *csource); b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude); #endif // !DATATYPES_H