From d23d03829e5baf947d347f49cc1d7807be6c070b Mon Sep 17 00:00:00 2001 From: Kimplul Date: Sun, 11 Aug 2024 23:23:12 +0300 Subject: initial generics for structs + Likely still very much full of bugs --- src/scope.c | 112 +++++++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 85 insertions(+), 27 deletions(-) (limited to 'src/scope.c') diff --git a/src/scope.c b/src/scope.c index 4316a40..5cd7075 100644 --- a/src/scope.c +++ b/src/scope.c @@ -32,13 +32,22 @@ struct scope *create_scope() return scope; } -void destroy_visible(struct visible *visible) +static void destroy_visible(struct visible *visible) { struct visible *prev = visible, *cur; if (prev) do { cur = prev->next; - /* destroy AST nodes globally somewhere? */ + free(prev); + } while ((prev = cur)); +} + +static void destroy_expanded(struct expanded *expanded) +{ + struct expanded *prev = expanded, *cur; + if (prev) + do { + cur = prev->next; free(prev); } while ((prev = cur)); } @@ -57,6 +66,8 @@ void destroy_scope(struct scope *scope) destroy_visible(scope->macros); destroy_visible(scope->types); + destroy_expanded(scope->expanded); + struct scope *prev = scope->children, *cur; if (prev) do { @@ -82,6 +93,9 @@ unsigned scope_flags(struct scope *scope, enum scope_flags flags) static struct visible *create_visible(char *id, struct ast *node) { struct visible *visible = calloc(1, sizeof(struct visible)); + if (!visible) + return NULL; + visible->id = id; visible->node = node; return visible; @@ -99,6 +113,22 @@ struct visible *create_type(struct scope *scope, char *id, struct ast *type) return n; } +struct expanded *create_expanded(struct scope *scope, struct ast *def, struct type *types, struct ast *expd) +{ + struct expanded *n = calloc(1, sizeof(struct expanded)); + if (!n) + return NULL; + + n->node = def; + n->types = types; + n->expd = expd; + + n->next = scope->expanded; + scope->expanded = n; + + return n; +} + struct visible *create_var(struct scope *scope, char *id, struct ast *var) { struct visible *n = create_visible(id, var); @@ -227,6 +257,19 @@ int scope_add_trait(struct scope *scope, struct ast *trait) return 0; } +int scope_add_expd_struct(struct scope *scope, struct ast *def, struct type *types, struct ast *expd) +{ + assert(def->k == AST_STRUCT_DEF); + assert(file_scope_find_expd_struct(scope, def, types) == NULL); + + create_expanded(scope, def, types, expd); + if (scope->parent && + scope_flags(scope, SCOPE_FILE) && ast_flags(def, AST_FLAG_PUBLIC)) + return scope_add_expd_struct(scope->parent, def, types, expd); + + return 0; +} + static struct ast *scope_find_visible(struct visible *v, char *id) { if (!v) @@ -241,6 +284,22 @@ static struct ast *scope_find_visible(struct visible *v, char *id) return NULL; } +static struct ast *scope_find_expanded(struct expanded *e, struct ast *def, struct type *types) +{ + if (!e) + return NULL; + + foreach_expanded(n, e) { + if (n->node != def) + continue; + + if (type_lists_match(n->types, types)) + return n->expd; + } + + return NULL; +} + struct ast *scope_find_type(struct scope *scope, char *id) { return scope_find_visible(scope->types, id); @@ -352,13 +411,36 @@ struct ast *file_scope_find_var(struct scope *scope, char *id) return NULL; } +struct ast *scope_find_expd_struct(struct scope *scope, struct ast *def, struct type *types) +{ + assert(def->k == AST_STRUCT_DEF); + struct ast *exists = scope_find_expanded(scope->expanded, def, types); + if (!exists) + return NULL; + + assert(exists->k == AST_STRUCT_DEF); + return exists; +} + +struct ast *file_scope_find_expd_struct(struct scope *scope, struct ast *def, struct type *types) +{ + assert(def->k == AST_STRUCT_DEF); + struct ast *found = scope_find_expd_struct(scope, def, types); + if (found) + return found; + + if (!scope_flags(scope, SCOPE_FILE)) + return file_scope_find_expd_struct(scope->parent, def, types); + + return NULL; +} + void scope_add_scope(struct scope *parent, struct scope *child) { assert(parent); assert(child); if (!scope_flags(child, SCOPE_FILE)) { - child->actuals = parent->actuals; child->fctx = parent->fctx; } @@ -366,27 +448,3 @@ void scope_add_scope(struct scope *parent, struct scope *child) child->next = parent->children; parent->children = child; } - -static int add_actual(struct actual *actuals, struct ast *node) -{ - if (!actuals->node) { - /* fill empty first element */ - actuals->node = node; - return 0; - } - - /* TODO: check that there isn't already an actual like ours */ - struct actual *actual = calloc(1, sizeof(struct actual)); - if (!actual) - return -1; - - actual->next = actuals->next; - actual->node = node; - actuals->next = actual; - return 0; -} - -int scope_add_actual(struct scope *scope, struct ast *node) -{ - return add_actual(scope->actuals, node); -} -- cgit v1.3