type_info improvements

This commit is contained in:
Krzosa Karol
2025-01-06 12:17:57 +01:00
parent 773eeb1cbf
commit a059eec8ea
4 changed files with 85 additions and 42 deletions

View File

@@ -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!"); }

View File

@@ -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("<INVALID>")
#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);

View File

@@ -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;
}

View File

@@ -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