summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-17 00:10:30 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-17 00:10:30 +0000
commitea160abc678e9578b5e140121a6d7c59a3b9dd06 (patch)
tree0ae4d0ed1449f74d6cc361a5f8787892c0789168 /src/ast
parenta5d5a97818fb4fbd26c4fb25a5c410b1a60a1b18 (diff)
Improved struct pointer codegen, template instantiation and docs...
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast.c125
-rw-r--r--src/ast/ast.h2
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