feat: 表达式作为值 — if/else 和 block 可产生值
This commit is contained in:
@@ -423,6 +423,8 @@ static void analyze_expr(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
case AST_ENUM_VARIANT: analyze_enum_variant(node, scope, errors, a); break;
|
||||
case AST_INDEX_EXPR: analyze_index_expr(node, scope, errors, a); break;
|
||||
case AST_METHOD_CALL: analyze_method_call(node, scope, errors, a); break;
|
||||
case AST_IF_STMT: analyze_node(node, scope, errors, a); break;
|
||||
case AST_BLOCK: analyze_node(node, scope, errors, a); break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
@@ -602,6 +604,17 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
for (size_t i = 0; i < node->as.block.stmt_count; i++) {
|
||||
analyze_node(node->as.block.stmts[i], scope, errors, a);
|
||||
}
|
||||
// 表达式作为值: 块类型 = 最后一条表达式语句的类型
|
||||
if (node->as.block.stmt_count > 0) {
|
||||
AstNode* last = node->as.block.stmts[node->as.block.stmt_count - 1];
|
||||
if (last->kind == AST_EXPR_STMT) {
|
||||
TypeKind ek = last->as.expr_stmt.expr->type.kind;
|
||||
if (ek != TYPE_ERROR && ek != TYPE_VOID) {
|
||||
node->type.kind = ek;
|
||||
node->type.struct_name = last->as.expr_stmt.expr->type.struct_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AST_LET_STMT: {
|
||||
@@ -773,6 +786,19 @@ static void analyze_node(AstNode* node, Scope* scope, ErrorList* errors, Arena*
|
||||
if (node->as.if_stmt.else_block) {
|
||||
analyze_node(node->as.if_stmt.else_block, scope, errors, a);
|
||||
}
|
||||
// 表达式作为值: if 类型 = 两个分支的共同非 void 类型
|
||||
{
|
||||
AstNode* tb = node->as.if_stmt.then_block;
|
||||
AstNode* eb = node->as.if_stmt.else_block;
|
||||
if (tb && eb) {
|
||||
TypeKind tt = tb->type.kind, et = eb->type.kind;
|
||||
if (tt == et && tt != TYPE_VOID && tt != TYPE_ERROR) {
|
||||
node->type.kind = tt;
|
||||
if (tt == TYPE_STRUCT && tb->type.struct_name)
|
||||
node->type.struct_name = tb->type.struct_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case AST_WHILE_STMT:
|
||||
|
||||
Reference in New Issue
Block a user