summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
authorsuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:43:23 -0500
committersuresh <sureshkrishnan.ai@gmail.com>2026-01-25 11:43:23 -0500
commit26a0b55ed5bce4ad0ba2af109cfc96da7be2e34c (patch)
tree35ba8d7742b8ac727bfc6c4c73ab8b70f6eedb53 /src/ast
parent0bb69cb67078dfa921b5b8a42275ef31dfbc9a56 (diff)
parent489336b2101bf16edeec7bfc4379408eb19b936e (diff)
Merge branch 'main' into JsonType
# Conflicts: # examples/data/json_config.zc
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast.c74
-rw-r--r--src/ast/ast.h1
2 files changed, 75 insertions, 0 deletions
diff --git a/src/ast/ast.c b/src/ast/ast.c
index b20d9c2..0799845 100644
--- a/src/ast/ast.c
+++ b/src/ast/ast.c
@@ -59,6 +59,8 @@ Type *type_new(TypeKind kind)
t->args = NULL;
t->arg_count = 0;
t->is_const = 0;
+ t->is_explicit_struct = 0;
+ t->is_raw = 0;
t->array_size = 0;
return t;
}
@@ -283,6 +285,36 @@ static char *type_to_string_impl(Type *t)
}
case TYPE_FUNCTION:
+ if (t->is_raw)
+ {
+ // fn*(Args)->Ret
+ char *ret = type_to_string(t->inner);
+ char *res = xmalloc(strlen(ret) + 64);
+ sprintf(res, "fn*(");
+
+ for (int i = 0; i < t->arg_count; i++)
+ {
+ if (i > 0)
+ {
+ char *tmp = xmalloc(strlen(res) + 3);
+ sprintf(tmp, "%s, ", res);
+ free(res);
+ res = tmp;
+ }
+ char *arg = type_to_string(t->args[i]);
+ char *tmp = xmalloc(strlen(res) + strlen(arg) + 1);
+ sprintf(tmp, "%s%s", res, arg);
+ free(res);
+ res = tmp;
+ free(arg);
+ }
+ char *tmp = xmalloc(strlen(res) + strlen(ret) + 5); // ) -> Ret
+ sprintf(tmp, "%s) -> %s", res, ret);
+ free(res);
+ res = tmp;
+ free(ret);
+ return res;
+ }
if (t->inner)
{
free(type_to_string(t->inner));
@@ -410,6 +442,19 @@ static char *type_to_c_string_impl(Type *t)
case TYPE_POINTER:
{
char *inner = type_to_c_string(t->inner);
+ char *ptr_token = strstr(inner, "(*");
+ if (ptr_token)
+ {
+ long prefix_len = ptr_token - inner + 2; // "void (*"
+ char *res = xmalloc(strlen(inner) + 2);
+ strncpy(res, inner, prefix_len);
+ res[prefix_len] = 0;
+ strcat(res, "*");
+ strcat(res, ptr_token + 2);
+ free(inner);
+ return res;
+ }
+
if (t->is_restrict)
{
char *res = xmalloc(strlen(inner) + 16);
@@ -441,6 +486,35 @@ static char *type_to_c_string_impl(Type *t)
}
case TYPE_FUNCTION:
+ if (t->is_raw)
+ {
+ char *ret = type_to_c_string(t->inner);
+ char *res = xmalloc(strlen(ret) + 64); // heuristic start buffer
+ sprintf(res, "%s (*)(", ret);
+
+ for (int i = 0; i < t->arg_count; i++)
+ {
+ if (i > 0)
+ {
+ char *tmp = xmalloc(strlen(res) + 3);
+ sprintf(tmp, "%s, ", res);
+ free(res);
+ res = tmp;
+ }
+ char *arg = type_to_c_string(t->args[i]);
+ char *tmp = xmalloc(strlen(res) + strlen(arg) + 1);
+ sprintf(tmp, "%s%s", res, arg);
+ free(res);
+ res = tmp;
+ free(arg);
+ }
+ char *tmp = xmalloc(strlen(res) + 2);
+ sprintf(tmp, "%s)", res);
+ free(res);
+ res = tmp;
+ free(ret);
+ return res;
+ }
if (t->inner)
{
free(type_to_c_string(t->inner));
diff --git a/src/ast/ast.h b/src/ast/ast.h
index 1614f3c..12d8f2b 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -64,6 +64,7 @@ typedef struct Type
int arg_count;
int is_const;
int is_explicit_struct; // for example, "struct Foo" vs "Foo"
+ int is_raw; // Raw function pointer (fn*)
union
{
int array_size; // For fixed-size arrays [T; N].