diff options
Diffstat (limited to 'src/ast')
| -rw-r--r-- | src/ast/ast.c | 125 | ||||
| -rw-r--r-- | src/ast/ast.h | 2 |
2 files changed, 127 insertions, 0 deletions
diff --git a/src/ast/ast.c b/src/ast/ast.c index 4a34c7c..dee2eed 100644 --- a/src/ast/ast.c +++ b/src/ast/ast.c @@ -288,3 +288,128 @@ char *type_to_string(Type *t) return xstrdup("unknown"); } } + +// C-compatible type stringifier. +// Strictly uses 'struct T' for explicit structs to support external types. +// Does NOT mangle pointers to 'Ptr'. +char *type_to_c_string(Type *t) +{ + if (!t) + { + return xstrdup("void"); + } + + switch (t->kind) + { + case TYPE_VOID: + return xstrdup("void"); + case TYPE_STRUCT: + { + // Only prepend 'struct' if explicitly requested (e.g. "struct Foo") + // otherwise assume it's a typedef/alias (e.g. "Foo"). + if (t->is_explicit_struct) + { + char *res = xmalloc(strlen(t->name) + 8); + sprintf(res, "struct %s", t->name); + return res; + } + else + { + return xstrdup(t->name); + } + } + case TYPE_BOOL: + return xstrdup("bool"); + case TYPE_STRING: + return xstrdup("string"); + case TYPE_CHAR: + return xstrdup("char"); + case TYPE_I8: + return xstrdup("int8_t"); + case TYPE_U8: + return xstrdup("uint8_t"); + case TYPE_I16: + return xstrdup("int16_t"); + case TYPE_U16: + return xstrdup("uint16_t"); + case TYPE_I32: + return xstrdup("int32_t"); + case TYPE_U32: + return xstrdup("uint32_t"); + case TYPE_I64: + return xstrdup("int64_t"); + case TYPE_U64: + return xstrdup("uint64_t"); + case TYPE_F32: + return xstrdup("float"); + case TYPE_F64: + return xstrdup("double"); + case TYPE_USIZE: + return xstrdup("size_t"); + case TYPE_ISIZE: + return xstrdup("ptrdiff_t"); + case TYPE_BYTE: + return xstrdup("uint8_t"); + case TYPE_I128: + return xstrdup("__int128"); + case TYPE_U128: + return xstrdup("unsigned __int128"); + case TYPE_RUNE: + return xstrdup("int32_t"); + case TYPE_UINT: + return xstrdup("unsigned int"); + case TYPE_INT: + return xstrdup("int"); + case TYPE_FLOAT: + return xstrdup("float"); + + case TYPE_POINTER: + { + char *inner = type_to_c_string(t->inner); + if (t->is_restrict) + { + char *res = xmalloc(strlen(inner) + 16); + sprintf(res, "%s* __restrict", inner); + return res; + } + else + { + char *res = xmalloc(strlen(inner) + 2); + sprintf(res, "%s*", inner); + return res; + } + } + + case TYPE_ARRAY: + { + char *inner = type_to_c_string(t->inner); + + if (t->array_size > 0) + { + char *res = xmalloc(strlen(inner) + 20); + sprintf(res, "%s[%d]", inner, t->array_size); + return res; + } + + char *res = xmalloc(strlen(inner) + 7); + sprintf(res, "Slice_%s", inner); + return res; + } + + case TYPE_FUNCTION: + if (t->inner) + { + free(type_to_c_string(t->inner)); + } + return xstrdup("z_closure_T"); + + case TYPE_GENERIC: + return xstrdup(t->name); + + case TYPE_ENUM: + return xstrdup(t->name); + + default: + return xstrdup("unknown"); + } +} diff --git a/src/ast/ast.h b/src/ast/ast.h index 1b83a91..e9270c8 100644 --- a/src/ast/ast.h +++ b/src/ast/ast.h @@ -54,6 +54,7 @@ typedef struct Type struct Type **args; // For GENERIC args. int arg_count; int is_const; + int is_explicit_struct; // e.g. "struct Foo" vs "Foo" union { int array_size; // For fixed-size arrays [T; N]. @@ -548,5 +549,6 @@ Type *type_new_ptr(Type *inner); int type_eq(Type *a, Type *b); int is_integer_type(Type *t); char *type_to_string(Type *t); +char *type_to_c_string(Type *t); #endif |
