diff --git a/src/core/core_log.h b/src/core/core_log.h index 042fb22..a3d4ba1 100644 --- a/src/core/core_log.h +++ b/src/core/core_log.h @@ -67,6 +67,7 @@ fn void default_log_proc(log_event_t ev); #define not_implemented assert(!"not implemented!") #define invalid_codepath assert(!"invalid code path!") #define default_is_invalid default: assert(!"invalid default case") +#define else_is_invalid else { assert(!"else was not expected to be executed!"); } diff --git a/src/core/core_string.h b/src/core/core_string.h index f18dd90..64d023e 100644 --- a/src/core/core_string.h +++ b/src/core/core_string.h @@ -71,7 +71,8 @@ fn f64 f64_from_s8(s8_t string); // // string8 constructors #define s8(str,len) (s8_t){str, len} -#define s8_nil() (s8_t){0} +#define s8_null (s8_t){0} +#define s8_invalid s8_lit("") #define s8_lit(string) (s8_t){(char *)string, sizeof(string) - 1} #define s8_const_lit(string) { string, sizeof(string) - 1 } fn s8_t s8_from_range(char *begin, char *end); diff --git a/src/core/core_type_info.c b/src/core/core_type_info.c index c52a2f3..f23c2e3 100644 --- a/src/core/core_type_info.c +++ b/src/core/core_type_info.c @@ -20,6 +20,38 @@ fn i64 ti_enum_name_to_value(s8_t name, type_t *type) { return -1; } +fn i64 ti_enum_read_value(void *p, type_t *type) { + assert(type->kind == type_kind_enum); + i64 value = 0; + if (type->size == 1) { + value = *(i8 *)p; + } else if (type->size == 2) { + value = *(i16 *)p; + } else if (type->size == 4) { + value = *(i32 *)p; + } else if (type->size == 8) { + value = *(i64 *)p; + } else { + fatalf("invalid size of enum: %d", type->size); + } + return value; +} + +fn void ti_enum_write_value(void *p, i64 value, type_t *type) { + assert(type->kind == type_kind_enum); + if (type->size == 1) { + *(i8 *)p = (i8)value; + } else if (type->size == 2) { + *(i16 *)p = (i16)value; + } else if (type->size == 4) { + *(i32 *)p = (i32)value; + } else if (type->size == 8) { + *(i64 *)p = (i64)value; + } else { + fatalf("invalid size of enum: %d", type->size); + } +} + fn type_member_t *ti_get_member(s8_t name, type_t *type) { for (i32 i = 0; i < type->count; i += 1) { type_member_t *it = type->members + i; @@ -30,6 +62,20 @@ fn type_member_t *ti_get_member(s8_t name, type_t *type) { return NULL; } +fn void *ti_extract_member(void *p, type_member_t *tm) { + u8 *p8 = (u8 *)p; + u8 *result = p8 + tm->offset; + return result; +} + +fn void *ti_extract_array_idx(void *p, type_t *type, i32 idx) { + assert(idx < type->count); + + u8 *p8 = (u8 *)p; + u8 *result = p8 + type->base->size * idx; + return result; +} + fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) { assert(type->kind != type_kind_invalid); @@ -139,33 +185,19 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) { } if (type->kind == type_kind_enum) { - i64 value = 0; - if (type->size == 1) { - value = *(i8 *)p; - } else if (type->size == 2) { - value = *(i16 *)p; - } else if (type->size == 4) { - value = *(i32 *)p; - } else if (type->size == 8) { - value = *(i64 *)p; - } else { - fatalf("invalid size of enum: %d", type->size); - } + i64 value = ti_enum_read_value(p, type); s8_t s = ti_enum_value_to_name(value, type); sb8_append(sb, s); return; } if (type->kind == type_kind_array) { - u8 *p8 = (u8 *)p; sb8_printf(sb, "{"); sb->indent += 1; for (i32 i = 0; i < type->count; i += 1) { - type_t *base = type->base; - u8 *mem_p = p8 + base->size * i; - + void *mem_p = ti_extract_array_idx(p, type, i); sb8_indent(sb); - ti__serial_data_ex(sb, mem_p, base); + ti__serial_data_ex(sb, mem_p, type->base); sb8_printf(sb, ","); } sb->indent -= 1; @@ -174,13 +206,11 @@ fn void ti__serial_data_ex(sb8_t *sb, void *p, type_t *type) { } if (type->kind == type_kind_struct) { - u8 *p8 = (u8 *)p; - sb8_printf(sb, "{"); sb->indent += 1; for (i32 i = 0; i < type->count; i += 1) { type_member_t *mem = type->members + i; - u8 *mem_p = p8 + mem->offset; + void *mem_p = ti_extract_member(p, mem); sb8_indent(sb); sb8_printf(sb, "%S: ", mem->name); ti__serial_data_ex(sb, mem_p, mem->type); @@ -325,23 +355,12 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * if (value == -1) { fatalf("invalid enum value: %S", token->string); } - if (type->size == 1) { - *(i8 *)p = (i8)value; - } else if (type->size == 2) { - *(i16 *)p = (i16)value; - } else if (type->size == 4) { - *(i32 *)p = (i32)value; - } else if (type->size == 8) { - *(i64 *)p = (i64)value; - } else { - fatalf("invalid size of enum: %d", type->size); - } + + ti_enum_write_value(p, value, type); return; } if (type->kind == type_kind_struct) { - u8 *p8 = (u8 *)p; - #if 0 parser_expect(par, lex_kind_open_brace); while (!parser_match(par, lex_kind_close_brace)) { @@ -364,14 +383,14 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * parser_expect(par, lex_kind_open_brace); for (i32 i = 0; i < type->count; i += 1) { type_member_t *mem = type->members + i; - u8 *mem_p = p8 + mem->offset; + void *memp = ti_extract_member(p, mem); lex_t *ident = parser_expect(par, lex_kind_ident); parser_expect(par, lex_kind_colon); expect (s8_equal(ident->string, mem->name)) fatalf("expected identifier: %S, got instead %S", mem->name, ident->string); - ti__deserial_data_ex(arena, par, mem_p, mem->type); + ti__deserial_data_ex(arena, par, memp, mem->type); parser_expect(par, lex_kind_comma); } parser_expect(par, lex_kind_close_brace); @@ -379,13 +398,10 @@ fn void ti__deserial_data_ex(ma_arena_t *arena, parser_t *par, void *p, type_t * } if (type->kind == type_kind_array) { - u8 *p8 = (u8 *)p; parser_expect(par, lex_kind_open_brace); for (i32 i = 0; i < type->count; i += 1) { - type_t *base = type->base; - u8 *mem_p = p8 + base->size * i; - - ti__deserial_data_ex(arena, par, mem_p, base); + void *memp = ti_extract_array_idx(p, type, i); + ti__deserial_data_ex(arena, par, memp, type->base); parser_expect(par, lex_kind_comma); } parser_expect(par, lex_kind_close_brace); @@ -400,4 +416,27 @@ fn void *ti__deserial_data(ma_arena_t *arena, s8_t data, type_t *type) { ti__deserial_data_ex(arena, par, p, type); ma_end_scratch(scratch); return p; +} + +fn b32 ti_is_basic(type_t *type) { + b32 result = type->kind >= type_kind_first_basic && type->kind <= type_kind_last_basic; + return result; +} + +fn b32 ti_has_type_name(type_t *type) { + b32 result = ti_is_basic(type) || type->kind == type_kind_struct || type->kind == type_kind_enum || type->kind == type_kind_union; + return result; +} + +fn s8_t ti_serial_type(ma_arena_t *arena, type_t *type) { + if (ti_has_type_name(type)) { + return type->name; + } else if (type->kind == type_kind_pointer) { + s8_t name = ti_serial_type(arena, type->base); + return s8_printf(arena, "%S*", name); + } else if (type->kind == type_kind_array) { + s8_t name = ti_serial_type(arena, type->base); + return s8_printf(arena, "%S[%d]", name, type->count); + } else_is_invalid; + return s8_invalid; } \ No newline at end of file diff --git a/todo.txt b/todo.txt index 5d94b24..dcd501c 100644 --- a/todo.txt +++ b/todo.txt @@ -24,7 +24,9 @@ [ ] meta [x] search for python snippets and execute meta.py script on that file [ ] somehow index properly the meta files and ignore generated files + [ ] extract declarations from c files meta(introspect) + [ ] extract all globals from c files [ ] new simple format with tags [x] revisit api [ ] s8_bin - + [ ] hash table