Add enum, struct, usertype, datatype and arg stringify functions
This commit is contained in:
		@@ -1,24 +1,14 @@
 | 
			
		||||
// vim:fileencoding=utf-8:foldmethod=marker
 | 
			
		||||
 | 
			
		||||
#include "datatypes.h"
 | 
			
		||||
#include "dbl_list.h"
 | 
			
		||||
#include "type_enums.h"
 | 
			
		||||
#include "wapp_core.h"
 | 
			
		||||
 | 
			
		||||
#define ERR_MSG "Not enough capacity in dst buffer"
 | 
			
		||||
 | 
			
		||||
internal inline void ctype_to_string(Str8 *dst, CType ctype);
 | 
			
		||||
internal inline void cqualifier_to_string(Str8 *dst, CQualifier cqualifier);
 | 
			
		||||
internal inline void cpointertype_to_string(Str8 *dst, CPointerType cpointertype);
 | 
			
		||||
internal inline void cpointer_to_string(Str8 *dst, const CPointer *cpointer);
 | 
			
		||||
internal inline void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval);
 | 
			
		||||
internal inline void cmacro_to_string(Str8 *dst, const CMacro *cmacro);
 | 
			
		||||
 | 
			
		||||
void cobject_to_string(Str8 *dst, const CObject *object) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL object != NULL, "`allocator`, `dst` and `object` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  if (object->kind >= COUNT_COBJECTKIND) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  wapp_debug_assert(dst != NULL && object != NULL, "`allocator`, `dst` and `object` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  switch (object->kind) {
 | 
			
		||||
    case COBJECT_CTYPE:
 | 
			
		||||
@@ -37,21 +27,27 @@ void cobject_to_string(Str8 *dst, const CObject *object) {
 | 
			
		||||
      cenumval_to_string(dst, &(object->object.c_enumval));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CENUM:
 | 
			
		||||
      cenum_to_string(dst, &(object->object.c_enum));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CMACRO:
 | 
			
		||||
      cmacro_to_string(dst, &(object->object.c_macro));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CSTRUCT:
 | 
			
		||||
      cstruct_to_string(dst, &(object->object.c_struct));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CUSERTYPE:
 | 
			
		||||
      cusertype_to_string(dst, &(object->object.c_usertype));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CDATATYPE:
 | 
			
		||||
      cdatatype_to_string(dst, &(object->object.c_datatype));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CARG:
 | 
			
		||||
      carg_to_string(dst, &(object->object.c_arg));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CFUNC:
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CINCULDE:
 | 
			
		||||
      cinclude_to_string(dst, &(object->object.c_include));
 | 
			
		||||
      break;
 | 
			
		||||
    case COBJECT_CHEADER:
 | 
			
		||||
      break;
 | 
			
		||||
@@ -62,22 +58,22 @@ void cobject_to_string(Str8 *dst, const CObject *object) {
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void ctype_to_string(Str8 *dst, CType ctype) {
 | 
			
		||||
void ctype_to_string(Str8 *dst, CType ctype) {
 | 
			
		||||
  wapp_runtime_assert(ctypes[ctype].size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_copy_str8_capped(dst, &ctypes[ctype]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void cqualifier_to_string(Str8 *dst, CQualifier cqualifier) {
 | 
			
		||||
void cqualifier_to_string(Str8 *dst, CQualifier cqualifier) {
 | 
			
		||||
  wapp_runtime_assert(cqualifiers[cqualifier].size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_copy_str8_capped(dst, &cqualifiers[cqualifier]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void cpointertype_to_string(Str8 *dst, CPointerType cpointertype) {
 | 
			
		||||
void cpointertype_to_string(Str8 *dst, CPointerType cpointertype) {
 | 
			
		||||
  wapp_runtime_assert(cpointertypes[cpointertype].size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_copy_str8_capped(dst, &cpointertypes[cpointertype]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void cpointer_to_string(Str8 *dst, const CPointer *cpointer) {
 | 
			
		||||
void cpointer_to_string(Str8 *dst, const CPointer *cpointer) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cpointer != NULL, "`dst` and `cpointer` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  u64 total_size = cpointertypes[cpointer->type].size + cqualifiers[cpointer->qualifier].size;
 | 
			
		||||
@@ -88,7 +84,7 @@ internal inline void cpointer_to_string(Str8 *dst, const CPointer *cpointer) {
 | 
			
		||||
                   wapp_str8_varg(cqualifiers[cpointer->qualifier]));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval) {
 | 
			
		||||
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);
 | 
			
		||||
@@ -106,8 +102,42 @@ internal inline void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval) {
 | 
			
		||||
                   wapp_str8_varg(tmp));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
internal inline void cmacro_to_string(Str8 *dst, const CMacro *cmacro) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cenumval != NULL, "`dst` and `cmacro` should not be NULL");
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  if (cenum->add_typedef) {
 | 
			
		||||
    wapp_str8_copy_cstr_capped(&header, "typedef enum {\n");
 | 
			
		||||
    wapp_str8_format(&footer, "} " WAPP_STR8_SPEC ";\n", wapp_str8_varg(cenum->name));
 | 
			
		||||
  } else {
 | 
			
		||||
    wapp_str8_format(&header, "enum " WAPP_STR8_SPEC " {\n", wapp_str8_varg(cenum->name));
 | 
			
		||||
    wapp_str8_copy_cstr_capped(&footer, "};\n");
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (u64 i = 0; i < cenum->values.node_count; ++i) {
 | 
			
		||||
    cenumval_to_string(&tmp, wapp_cenumval_list_get(&(cenum->values), i)->item);
 | 
			
		||||
    // Add 4 for extra characters
 | 
			
		||||
    wapp_runtime_assert(tmp.size + 4 <= values.capacity - values.size, ERR_MSG);
 | 
			
		||||
    wapp_str8_concat_capped(&values, &wapp_str8_lit_ro("  "));
 | 
			
		||||
    wapp_str8_concat_capped(&values, &tmp);
 | 
			
		||||
    wapp_str8_concat_capped(&values, &wapp_str8_lit_ro(",\n"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  u64 total_size = header.size + values.size + footer.size;
 | 
			
		||||
  wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_format(dst,
 | 
			
		||||
                   WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC,
 | 
			
		||||
                   wapp_str8_varg(header),
 | 
			
		||||
                   wapp_str8_varg(values),
 | 
			
		||||
                   wapp_str8_varg(footer));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cmacro_to_string(Str8 *dst, const CMacro *cmacro) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cmacro != NULL, "`dst` and `cmacro` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  Str8 def       = wapp_str8_lit("#define ");
 | 
			
		||||
  u64 total_size = def.size + cmacro->name.size + cmacro->value.size + 1; // Add 1 for newline
 | 
			
		||||
@@ -118,3 +148,168 @@ internal inline void cmacro_to_string(Str8 *dst, const CMacro *cmacro) {
 | 
			
		||||
                   wapp_str8_varg(cmacro->name),
 | 
			
		||||
                   wapp_str8_varg(cmacro->value));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  declare_cstruct(&declaration, cstruct);
 | 
			
		||||
  define_cstruct(&definition, cstruct);
 | 
			
		||||
 | 
			
		||||
  u64 total_size = declaration.size + definition.size;
 | 
			
		||||
  wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_format(dst, WAPP_STR8_SPEC WAPP_STR8_SPEC,
 | 
			
		||||
                   wapp_str8_varg(declaration), wapp_str8_varg(definition));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
  wapp_str8_format(&tmp,
 | 
			
		||||
                   "typedef struct " WAPP_STR8_SPEC " " WAPP_STR8_SPEC ";\n",
 | 
			
		||||
                   wapp_str8_varg(cstruct->name),
 | 
			
		||||
                   wapp_str8_varg(cstruct->typedef_name.size > 0 ? cstruct->typedef_name : cstruct->name));
 | 
			
		||||
 | 
			
		||||
  wapp_runtime_assert(tmp.size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_copy_str8_capped(dst, &tmp);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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 footer     = wapp_str8_lit_ro("};\n");
 | 
			
		||||
  Str8 tmp        = wapp_str8_buf(1024);
 | 
			
		||||
 | 
			
		||||
  wapp_str8_format(&definition, "struct " WAPP_STR8_SPEC " {\n", wapp_str8_varg(cstruct->name));
 | 
			
		||||
 | 
			
		||||
  for (u64 i = 0; i < cstruct->args.node_count; ++i) {
 | 
			
		||||
    carg_to_string(&tmp, wapp_carg_list_get(&(cstruct->args), i)->item);
 | 
			
		||||
    // Add 4 for extra characters
 | 
			
		||||
    wapp_runtime_assert(tmp.size + 4 <= args.capacity - args.size, ERR_MSG);
 | 
			
		||||
    wapp_str8_concat_capped(&args, &wapp_str8_lit_ro("  "));
 | 
			
		||||
    wapp_str8_concat_capped(&args, &tmp);
 | 
			
		||||
    wapp_str8_concat_capped(&args, &wapp_str8_lit_ro(";\n"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  u64 total_size = definition.size + args.size + footer.size;
 | 
			
		||||
  wapp_runtime_assert(total_size <= dst->capacity, ERR_MSG);
 | 
			
		||||
  wapp_str8_format(dst,
 | 
			
		||||
                   WAPP_STR8_SPEC WAPP_STR8_SPEC WAPP_STR8_SPEC,
 | 
			
		||||
                   wapp_str8_varg(definition),
 | 
			
		||||
                   wapp_str8_varg(args),
 | 
			
		||||
                   wapp_str8_varg(footer));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cusertype_to_string(Str8 *dst, const CUserType *cusertype) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cusertype != NULL, "`dst` and `cusertype` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  switch (cusertype->kind) {
 | 
			
		||||
    case CUSERTYPE_CENUM:
 | 
			
		||||
      cenum_to_string(dst, &(cusertype->type.c_enum));
 | 
			
		||||
      break;
 | 
			
		||||
    case CUSERTYPE_CSTRUCT:
 | 
			
		||||
      cstruct_to_string(dst, &(cusertype->type.c_struct));
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void cdatatype_to_string(Str8 *dst, const CDataType *cdatatype) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cdatatype != NULL, "`dst` and `cdatatype` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  switch (cdatatype->kind) {
 | 
			
		||||
    case CDATATYPE_CTYPE:
 | 
			
		||||
      ctype_to_string(dst, cdatatype->type.c_type);
 | 
			
		||||
      break;
 | 
			
		||||
    case CDATATYPE_CUSERTYPE:
 | 
			
		||||
      cusertype_to_string(dst, &(cdatatype->type.c_usertype));
 | 
			
		||||
      break;
 | 
			
		||||
    case CDATATYPE_STR:
 | 
			
		||||
      wapp_runtime_assert(cdatatype->type.str.size <= dst->capacity, ERR_MSG);
 | 
			
		||||
      wapp_str8_copy_str8_capped(dst, &(cdatatype->type.str));
 | 
			
		||||
      break;
 | 
			
		||||
    default:
 | 
			
		||||
      break;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
 | 
			
		||||
  cqualifier_to_string(&qualifier, carg->qualifier);
 | 
			
		||||
  cdatatype_to_string(&type, &(carg->type));
 | 
			
		||||
  wapp_str8_concat_capped(&type, &wapp_str8_lit_ro(" "));
 | 
			
		||||
  cpointer_to_string(&pointer, &(carg->pointer));
 | 
			
		||||
  if (carg->is_array) { wapp_str8_copy_cstr_capped(&array, "[]"); }
 | 
			
		||||
 | 
			
		||||
  u64 total_size = qualifier.size + type.size + pointer.size + array.size + carg->name.size;
 | 
			
		||||
  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(qualifier), wapp_str8_varg(type), wapp_str8_varg(pointer),
 | 
			
		||||
                   wapp_str8_varg(carg->name), wapp_str8_varg(array));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
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);
 | 
			
		||||
  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);
 | 
			
		||||
 | 
			
		||||
  if (cinclude->is_local) {
 | 
			
		||||
    wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("\""));
 | 
			
		||||
    wapp_str8_concat_capped(&close_symbol, &wapp_str8_lit_ro("\""));
 | 
			
		||||
    if (cinclude->same_dir) { wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("./")); }
 | 
			
		||||
  } else {
 | 
			
		||||
    wapp_str8_concat_capped(&open_symbol, &wapp_str8_lit_ro("<"));
 | 
			
		||||
    wapp_str8_concat_capped(&close_symbol, &wapp_str8_lit_ro(">"));
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  u64 total_size = header_str.size + inc.size + open_symbol.size + close_symbol.size;
 | 
			
		||||
  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 "\n",
 | 
			
		||||
                   wapp_str8_varg(inc),
 | 
			
		||||
                   wapp_str8_varg(open_symbol),
 | 
			
		||||
                   wapp_str8_varg(header_str),
 | 
			
		||||
                   wapp_str8_varg(close_symbol));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude) {
 | 
			
		||||
  wapp_debug_assert(dst != NULL && cheaderinclude != NULL, "`dst` and `cheaderinclude` should not be NULL");
 | 
			
		||||
 | 
			
		||||
  switch (cheaderinclude->kind) {
 | 
			
		||||
    case C_HEADER_INCLUDE_STR:
 | 
			
		||||
      wapp_runtime_assert(cheaderinclude->header.name.size <= dst->capacity, ERR_MSG);
 | 
			
		||||
      wapp_str8_format(dst, WAPP_STR8_SPEC, wapp_str8_varg(cheaderinclude->header.name));
 | 
			
		||||
      return true;
 | 
			
		||||
    case C_HEADER_INCLUDE_HEADER:
 | 
			
		||||
      // Take extension into account
 | 
			
		||||
      wapp_runtime_assert(cheaderinclude->header.header.name.size + 2 <= dst->capacity, ERR_MSG);
 | 
			
		||||
      wapp_str8_format(
 | 
			
		||||
        dst,
 | 
			
		||||
        WAPP_STR8_SPEC ".%s",
 | 
			
		||||
        wapp_str8_varg(cheaderinclude->header.header.name),
 | 
			
		||||
        cheaderinclude->header.header.extension == CFILE_EXT_H ? "h" : "c"
 | 
			
		||||
      );
 | 
			
		||||
      return true;
 | 
			
		||||
    default:
 | 
			
		||||
      return false;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  return false;
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -139,7 +139,7 @@ struct cmacro {
 | 
			
		||||
struct cstruct {
 | 
			
		||||
  Str8 name;
 | 
			
		||||
  CArgList args;
 | 
			
		||||
  Str8 *typedef_name;
 | 
			
		||||
  Str8 typedef_name;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
struct cusertype {
 | 
			
		||||
@@ -232,5 +232,20 @@ struct cobject {
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
void cobject_to_string(Str8 *dst, const CObject *object);
 | 
			
		||||
void ctype_to_string(Str8 *dst, CType ctype);
 | 
			
		||||
void cqualifier_to_string(Str8 *dst, CQualifier cqualifier);
 | 
			
		||||
void cpointertype_to_string(Str8 *dst, CPointerType cpointertype);
 | 
			
		||||
void cpointer_to_string(Str8 *dst, const CPointer *cpointer);
 | 
			
		||||
void cenumval_to_string(Str8 *dst, const CEnumVal *cenumval);
 | 
			
		||||
void cenum_to_string(Str8 *dst, const CEnum *cenum);
 | 
			
		||||
void cmacro_to_string(Str8 *dst, const CMacro *cmacro);
 | 
			
		||||
void cstruct_to_string(Str8 *dst, const CStruct *cstruct);
 | 
			
		||||
void declare_cstruct(Str8 *dst, const CStruct *cstruct);
 | 
			
		||||
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 cinclude_to_string(Str8 *dst, const CInclude *cinclude);
 | 
			
		||||
b32 cheaderinclude_to_string(Str8 *dst, const CHeaderInclude *cheaderinclude);
 | 
			
		||||
 | 
			
		||||
#endif // !DATATYPES_H
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user