summaryrefslogtreecommitdiff
path: root/src/codegen
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-20 12:51:23 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-20 12:51:23 +0000
commitb106fe19b55e9fe3348b3a5c9992c21dac27b02c (patch)
tree32663c9a791b7f45ce9bc61c5a87351d5dc2c782 /src/codegen
parente5d8c4219cfe5629a3ce4dbff01406a1817a788f (diff)
Working a bit on the LSP + fixed some bugs
Diffstat (limited to 'src/codegen')
-rw-r--r--src/codegen/codegen_main.c110
1 files changed, 89 insertions, 21 deletions
diff --git a/src/codegen/codegen_main.c b/src/codegen/codegen_main.c
index 7382827..97abfc7 100644
--- a/src/codegen/codegen_main.c
+++ b/src/codegen/codegen_main.c
@@ -14,33 +14,101 @@ static int struct_depends_on(ASTNode *s1, const char *target_name)
return 0;
}
- // Only structs have dependencies that matter for ordering.
- if (s1->type != NODE_STRUCT)
+ // Check structs
+ if (s1->type == NODE_STRUCT)
{
- return 0;
- }
+ ASTNode *field = s1->strct.fields;
+ while (field)
+ {
+ if (field->type == NODE_FIELD && field->field.type)
+ {
+ char *type_str = field->field.type;
- ASTNode *field = s1->strct.fields;
- while (field)
+ // Skip pointers - they don't create ordering dependency.
+ if (strchr(type_str, '*'))
+ {
+ field = field->next;
+ continue;
+ }
+
+ // Clean type string (remove struct/enum prefixes)
+ const char *clean = type_str;
+ if (strncmp(clean, "struct ", 7) == 0)
+ {
+ clean += 7;
+ }
+ else if (strncmp(clean, "enum ", 5) == 0)
+ {
+ clean += 5;
+ }
+ else if (strncmp(clean, "union ", 6) == 0)
+ {
+ clean += 6;
+ }
+
+ // Check for match
+ size_t len = strlen(target_name);
+ if (strncmp(clean, target_name, len) == 0)
+ {
+ char next = clean[len];
+ if (next == 0 || next == '[' || isspace(next))
+ {
+ return 1;
+ }
+ }
+ }
+ field = field->next;
+ }
+ }
+ // Check enums (ADTs)
+ else if (s1->type == NODE_ENUM)
{
- if (field->type == NODE_FIELD && field->field.type)
+ ASTNode *variant = s1->enm.variants;
+ while (variant)
{
- char *type_str = field->field.type;
- // Skip pointers - they don't create ordering dependency.
- if (strchr(type_str, '*'))
+ if (variant->type == NODE_ENUM_VARIANT && variant->variant.payload)
{
- field = field->next;
- continue;
- }
+ char *type_str = type_to_string(variant->variant.payload);
+ if (type_str)
+ {
+ if (strchr(type_str, '*'))
+ {
+ free(type_str);
+ variant = variant->next;
+ continue;
+ }
- // Check if this field's type matches target (struct or enum).
- if (strcmp(type_str, target_name) == 0)
- {
- return 1;
+ const char *clean = type_str;
+ if (strncmp(clean, "struct ", 7) == 0)
+ {
+ clean += 7;
+ }
+ else if (strncmp(clean, "enum ", 5) == 0)
+ {
+ clean += 5;
+ }
+ else if (strncmp(clean, "union ", 6) == 0)
+ {
+ clean += 6;
+ }
+
+ size_t len = strlen(target_name);
+ if (strncmp(clean, target_name, len) == 0)
+ {
+ char next = clean[len];
+ if (next == 0 || next == '[' || isspace(next))
+ {
+ free(type_str);
+ return 1;
+ }
+ }
+ free(type_str);
+ }
}
+ variant = variant->next;
}
- field = field->next;
}
+
return 0;
}
@@ -102,8 +170,8 @@ static ASTNode *topo_sort_structs(ASTNode *head)
continue;
}
- // Enums and traits have no dependencies, emit first.
- if (nodes[i]->type == NODE_ENUM || nodes[i]->type == NODE_TRAIT)
+ // Traits have no dependencies, emit first.
+ if (nodes[i]->type == NODE_TRAIT)
{
order[order_idx++] = i;
emitted[i] = 1;
@@ -111,7 +179,7 @@ static ASTNode *topo_sort_structs(ASTNode *head)
continue;
}
- // For structs, check if all dependencies are emitted.
+ // For structs/enums, check if all dependencies are emitted.
int can_emit = 1;
for (int j = 0; j < count; j++)
{