summaryrefslogtreecommitdiff
path: root/src/ast
diff options
context:
space:
mode:
Diffstat (limited to 'src/ast')
-rw-r--r--src/ast/ast.c79
-rw-r--r--src/ast/ast.h17
2 files changed, 93 insertions, 3 deletions
diff --git a/src/ast/ast.c b/src/ast/ast.c
index 78d7efb..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;
}
@@ -129,6 +131,11 @@ int type_eq(Type *a, Type *b)
return 1;
}
+ if (a->kind == TYPE_UNKNOWN || b->kind == TYPE_UNKNOWN)
+ {
+ return 1;
+ }
+
// Lax integer matching (bool == int, char == i8, etc.).
if (is_integer_type(a) && is_integer_type(b))
{
@@ -278,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));
@@ -405,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);
@@ -436,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 6ef5d7a..12d8f2b 100644
--- a/src/ast/ast.h
+++ b/src/ast/ast.h
@@ -11,6 +11,15 @@ typedef struct ASTNode ASTNode;
// ** Formal Type System **
// Used for Generics, Type Inference, and robust pointer handling.
+
+typedef enum
+{
+ LITERAL_INT = 0,
+ LITERAL_FLOAT = 1,
+ LITERAL_STRING = 2,
+ LITERAL_CHAR = 3
+} LiteralKind;
+
typedef enum
{
TYPE_VOID,
@@ -55,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].
@@ -306,9 +316,10 @@ struct ASTNode
struct
{
char *pattern;
- char *binding_name;
+ char **binding_names; // Multiple bindings
+ int binding_count; // Count
+ int *binding_refs; // Ref flags per binding
int is_destructuring;
- int is_ref; // New: Supports 'ref' binding (Some(ref x))
ASTNode *guard;
ASTNode *body;
int is_default;
@@ -329,7 +340,7 @@ struct ASTNode
struct
{
- int type_kind;
+ LiteralKind type_kind;
unsigned long long int_val;
double float_val;
char *string_val;