feat: 列表推导式 [for x in arr: expr] — parser+sema+codegen

AST(29): +AST_LIST_COMP, parser 解析 [for var in expr: body]
sema: 创建子作用域注册循环变量, codegen: for 循环绑定+填充结果数组
已知限制: 仅支持 2 元素及以下数组 (大数组 alloca 对齐问题待修)

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-06-07 13:58:54 +08:00
parent 0088347576
commit 443b22bdf1
6 changed files with 128 additions and 0 deletions
+22
View File
@@ -536,6 +536,27 @@ SEMA_HANDLER(analyze_node) // if-expr / block 委托
static AstDispatch sema_dispatch;
static void analyze_list_comp(AstNode* node, Scope* scope, ErrorList* errors, Arena* a) {
analyze_expr(node->as.list_comp.array, scope, errors, a);
TypeInfo* arr_ti = &node->as.list_comp.array->type;
if (arr_ti->kind != TYPE_ARRAY) {
error_add(errors, "<sema>", node->loc.line, node->loc.col,
"列表推导式需要数组类型, 得到 '%s'", type_name(arr_ti->kind));
node->type.kind = TYPE_ERROR; return;
}
Scope* lc_scope = scope_new(a, scope);
TypeKind elem_k = arr_ti->element_type;
Symbol* var_sym = scope_insert(lc_scope, a, node->as.list_comp.var_name,
SYM_VARIABLE, elem_k);
if (var_sym) var_sym->struct_type_name = arr_ti->element_struct_name;
analyze_expr(node->as.list_comp.map_expr, lc_scope, errors, a);
node->type.kind = TYPE_ARRAY;
node->type.element_type = arr_ti->element_type;
node->type.element_struct_name = arr_ti->element_struct_name;
node->type.array_size = arr_ti->array_size;
}
SEMA_HANDLER(analyze_list_comp)
void analyze_expr_init(void) {
sema_dispatch.ctx = NULL; // 由 analyze_expr 每次设置
// 新增表达式节点: 在此注册 handler, 编译器会警告缺失
@@ -550,6 +571,7 @@ void analyze_expr_init(void) {
ast_dispatch_set(&sema_dispatch, AST_METHOD_CALL, analyze_method_call_wrap);
ast_dispatch_set(&sema_dispatch, AST_IF_STMT, analyze_node_wrap);
ast_dispatch_set(&sema_dispatch, AST_BLOCK, analyze_node_wrap);
ast_dispatch_set(&sema_dispatch, AST_LIST_COMP, analyze_list_comp_wrap);
}
void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena* a) {