summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-19 22:18:33 +0000
committerZuhaitz Méndez Fernández de Aránguiz <zuhaitz@debian>2026-01-19 22:18:33 +0000
commit3af5dcf34d705cc52c1ffe5b85c2a90b5104e4c9 (patch)
tree8ad5b61b2818baf1af80c0a725622cda2c3fa1b8 /src
parent959a27fd763e2e960ef31adf891118a261bad1c7 (diff)
Improve 'std/cuda.zc' and 'std/vec.zc' + iteration...
Diffstat (limited to 'src')
-rw-r--r--src/parser/parser_stmt.c26
-rw-r--r--src/parser/parser_utils.c37
2 files changed, 59 insertions, 4 deletions
diff --git a/src/parser/parser_stmt.c b/src/parser/parser_stmt.c
index 699b9fc..db47d16 100644
--- a/src/parser/parser_stmt.c
+++ b/src/parser/parser_stmt.c
@@ -1665,17 +1665,26 @@ ASTNode *parse_for(ParserContext *ctx, Lexer *l)
var_name[var.len] = 0;
ASTNode *obj_expr = start_expr;
+ char *iter_method = "iterator";
+
+ // Check for reference iteration: for x in &vec
+ if (obj_expr->type == NODE_EXPR_UNARY &&
+ obj_expr->unary.op && strcmp(obj_expr->unary.op, "&") == 0)
+ {
+ obj_expr = obj_expr->unary.operand;
+ iter_method = "iter_ref";
+ }
// var __it = obj.iterator();
ASTNode *it_decl = ast_create(NODE_VAR_DECL);
it_decl->var_decl.name = xstrdup("__it");
it_decl->var_decl.type_str = NULL; // inferred
- // obj.iterator()
+ // obj.iterator() or obj.iter_ref()
ASTNode *call_iter = ast_create(NODE_EXPR_CALL);
ASTNode *memb_iter = ast_create(NODE_EXPR_MEMBER);
memb_iter->member.target = obj_expr;
- memb_iter->member.field = xstrdup("iterator");
+ memb_iter->member.field = xstrdup(iter_method);
call_iter->call.callee = memb_iter;
call_iter->call.args = NULL;
call_iter->call.arg_count = 0;
@@ -3391,6 +3400,19 @@ ASTNode *parse_impl(ParserContext *ctx, Lexer *l)
n->impl_trait.target_type = name2;
n->impl_trait.methods = h;
add_to_impl_list(ctx, n);
+
+ // If target struct is generic, register this impl as a template
+ ASTNode *def = find_struct_def(ctx, name2);
+ if (def && ((def->type == NODE_STRUCT && def->strct.is_template) ||
+ (def->type == NODE_ENUM && def->enm.is_template)))
+ {
+ const char *gp = "T";
+ if (def->type == NODE_STRUCT && def->strct.generic_param_count > 0)
+ gp = def->strct.generic_params[0];
+ // TODO: Enum generic params support if needed
+ register_impl_template(ctx, name2, gp, n);
+ }
+
return n;
}
else
diff --git a/src/parser/parser_utils.c b/src/parser/parser_utils.c
index 1f881b7..f96ed24 100644
--- a/src/parser/parser_utils.c
+++ b/src/parser/parser_utils.c
@@ -1518,6 +1518,11 @@ ASTNode *copy_ast_replacing(ASTNode *n, const char *p, const char *c, const char
new_node->impl.struct_name = replace_type_str(n->impl.struct_name, p, c, os, ns);
new_node->impl.methods = copy_ast_replacing(n->impl.methods, p, c, os, ns);
break;
+ case NODE_IMPL_TRAIT:
+ new_node->impl_trait.trait_name = xstrdup(n->impl_trait.trait_name);
+ new_node->impl_trait.target_type = replace_type_str(n->impl_trait.target_type, p, c, os, ns);
+ new_node->impl_trait.methods = copy_ast_replacing(n->impl_trait.methods, p, c, os, ns);
+ break;
default:
break;
}
@@ -1879,8 +1884,17 @@ void instantiate_methods(ParserContext *ctx, GenericImplTemplate *it,
it->struct_name, mangled_struct_name);
it->impl_node->next = backup_next; // Restore
- new_impl->impl.struct_name = xstrdup(mangled_struct_name);
- ASTNode *meth = new_impl->impl.methods;
+
+ ASTNode *meth = NULL;
+
+ if (new_impl->type == NODE_IMPL) {
+ new_impl->impl.struct_name = xstrdup(mangled_struct_name);
+ meth = new_impl->impl.methods;
+ } else if (new_impl->type == NODE_IMPL_TRAIT) {
+ new_impl->impl_trait.target_type = xstrdup(mangled_struct_name);
+ meth = new_impl->impl_trait.methods;
+ }
+
while (meth)
{
char *suffix = meth->func.name + strlen(it->struct_name);
@@ -1995,6 +2009,16 @@ void instantiate_generic(ParserContext *ctx, const char *tpl, const char *arg,
ASTNode *i = ast_create(NODE_STRUCT);
i->strct.name = xstrdup(m);
i->strct.is_template = 0;
+
+ // Copy type attributes (e.g. has_drop)
+ i->type_info = type_new(TYPE_STRUCT);
+ i->type_info->name = xstrdup(m);
+ if (t->struct_node->type_info)
+ {
+ i->type_info->traits = t->struct_node->type_info->traits;
+ i->type_info->is_restrict = t->struct_node->type_info->is_restrict;
+ }
+
// Use first generic param for substitution (single-param backward compat)
const char *gp = (t->struct_node->strct.generic_param_count > 0)
? t->struct_node->strct.generic_params[0]
@@ -2009,6 +2033,15 @@ void instantiate_generic(ParserContext *ctx, const char *tpl, const char *arg,
ASTNode *i = ast_create(NODE_ENUM);
i->enm.name = xstrdup(m);
i->enm.is_template = 0;
+
+ // Copy type attributes (e.g. has_drop)
+ i->type_info = type_new(TYPE_ENUM);
+ i->type_info->name = xstrdup(m);
+ if (t->struct_node->type_info)
+ {
+ i->type_info->traits = t->struct_node->type_info->traits;
+ }
+
ASTNode *h = 0, *tl = 0;
ASTNode *v = t->struct_node->enm.variants;
while (v)