mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-09 00:58:16 +00:00
Separate check_stmt code into separate procedures
This commit is contained in:
+65
-48
@@ -1912,27 +1912,22 @@ gb_internal void check_value_decl_stmt(CheckerContext *ctx, Ast *node, u32 mod_f
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
gb_internal void check_expr_stmt(CheckerContext *ctx, Ast *node) {
|
||||||
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
ast_node(es, ExprStmt, node);
|
||||||
switch (node->kind) {
|
|
||||||
case_ast_node(_, EmptyStmt, node); case_end;
|
|
||||||
case_ast_node(_, BadStmt, node); case_end;
|
|
||||||
case_ast_node(_, BadDecl, node); case_end;
|
|
||||||
|
|
||||||
case_ast_node(es, ExprStmt, node)
|
|
||||||
Operand operand = {Addressing_Invalid};
|
Operand operand = {Addressing_Invalid};
|
||||||
ExprKind kind = check_expr_base(ctx, &operand, es->expr, nullptr);
|
ExprKind kind = check_expr_base(ctx, &operand, es->expr, nullptr);
|
||||||
switch (operand.mode) {
|
switch (operand.mode) {
|
||||||
case Addressing_Type: {
|
case Addressing_Type:
|
||||||
|
{
|
||||||
gbString str = type_to_string(operand.type);
|
gbString str = type_to_string(operand.type);
|
||||||
error(node, "'%s' is not an expression", str);
|
error(node, "'%s' is not an expression", str);
|
||||||
gb_string_free(str);
|
gb_string_free(str);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case Addressing_NoValue:
|
case Addressing_NoValue:
|
||||||
return;
|
return;
|
||||||
default: {
|
}
|
||||||
if (kind == Expr_Stmt) {
|
if (kind == Expr_Stmt) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1988,7 +1983,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
if (operand.expr->kind == Ast_BinaryExpr) {
|
if (operand.expr->kind == Ast_BinaryExpr) {
|
||||||
ast_node(be, BinaryExpr, operand.expr);
|
ast_node(be, BinaryExpr, operand.expr);
|
||||||
if (be->op.kind != Token_CmpEq) {
|
if (be->op.kind != Token_CmpEq) {
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (be->left->tav.mode) {
|
switch (be->left->tav.mode) {
|
||||||
@@ -2007,15 +2002,12 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
||||||
}
|
ast_node(as, AssignStmt, node);
|
||||||
}
|
|
||||||
case_end;
|
|
||||||
|
|
||||||
case_ast_node(as, AssignStmt, node);
|
if (as->op.kind == Token_Eq) {
|
||||||
switch (as->op.kind) {
|
|
||||||
case Token_Eq: {
|
|
||||||
// a, b, c = 1, 2, 3; // Multisided
|
// a, b, c = 1, 2, 3; // Multisided
|
||||||
|
|
||||||
isize lhs_count = as->lhs.count;
|
isize lhs_count = as->lhs.count;
|
||||||
@@ -2058,10 +2050,8 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
if (lhs_count != rhs_count) {
|
if (lhs_count != rhs_count) {
|
||||||
error(as->lhs[0], "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
|
error(as->lhs[0], "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
|
||||||
}
|
}
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
default: {
|
} else {
|
||||||
// a += 1; // Single-sided
|
// a += 1; // Single-sided
|
||||||
Token op = as->op;
|
Token op = as->op;
|
||||||
if (as->lhs.count != 1 || as->rhs.count != 1) {
|
if (as->lhs.count != 1 || as->rhs.count != 1) {
|
||||||
@@ -2084,27 +2074,15 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
|
|
||||||
check_expr(ctx, &lhs, as->lhs[0]);
|
check_expr(ctx, &lhs, as->lhs[0]);
|
||||||
check_binary_expr(ctx, &rhs, binary_expr, nullptr, true);
|
check_binary_expr(ctx, &rhs, binary_expr, nullptr, true);
|
||||||
if (rhs.mode == Addressing_Invalid) {
|
if (rhs.mode != Addressing_Invalid) {
|
||||||
return;
|
|
||||||
}
|
|
||||||
// NOTE(bill): Only use the first one will be used
|
// NOTE(bill): Only use the first one will be used
|
||||||
check_assignment_variable(ctx, &lhs, &rhs);
|
check_assignment_variable(ctx, &lhs, &rhs);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case_end;
|
}
|
||||||
|
|
||||||
case_ast_node(bs, BlockStmt, node);
|
gb_internal void check_if_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||||
check_open_scope(ctx, node);
|
ast_node(is, IfStmt, node);
|
||||||
check_label(ctx, bs->label, node);
|
|
||||||
|
|
||||||
check_stmt_list(ctx, bs->stmts, flags);
|
|
||||||
check_block_stmt_for_errors(ctx, node);
|
|
||||||
check_close_scope(ctx);
|
|
||||||
case_end;
|
|
||||||
|
|
||||||
case_ast_node(is, IfStmt, node);
|
|
||||||
check_open_scope(ctx, node);
|
check_open_scope(ctx, node);
|
||||||
|
|
||||||
check_label(ctx, is->label, node);
|
check_label(ctx, is->label, node);
|
||||||
@@ -2134,18 +2112,16 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
}
|
}
|
||||||
|
|
||||||
check_close_scope(ctx);
|
check_close_scope(ctx);
|
||||||
case_end;
|
}
|
||||||
|
|
||||||
case_ast_node(ws, WhenStmt, node);
|
gb_internal void check_return_stmt(CheckerContext *ctx, Ast *node) {
|
||||||
check_when_stmt(ctx, ws, flags);
|
ast_node(rs, ReturnStmt, node);
|
||||||
case_end;
|
|
||||||
|
|
||||||
case_ast_node(rs, ReturnStmt, node);
|
|
||||||
GB_ASSERT(ctx->curr_proc_sig != nullptr);
|
GB_ASSERT(ctx->curr_proc_sig != nullptr);
|
||||||
|
|
||||||
if (ctx->in_defer) {
|
if (ctx->in_defer) {
|
||||||
error(rs->token, "'return' cannot be used within a defer statement");
|
error(rs->token, "'return' cannot be used within a defer statement");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *proc_type = ctx->curr_proc_sig;
|
Type *proc_type = ctx->curr_proc_sig;
|
||||||
@@ -2155,7 +2131,7 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
TypeProc *pt = &proc_type->Proc;
|
TypeProc *pt = &proc_type->Proc;
|
||||||
if (pt->diverging) {
|
if (pt->diverging) {
|
||||||
error(rs->token, "Diverging procedures may not return");
|
error(rs->token, "Diverging procedures may not return");
|
||||||
break;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Entity **result_entities = nullptr;
|
Entity **result_entities = nullptr;
|
||||||
@@ -2213,10 +2189,11 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case_end;
|
}
|
||||||
|
|
||||||
case_ast_node(fs, ForStmt, node);
|
gb_internal void check_for_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags) {
|
||||||
u32 new_flags = mod_flags | Stmt_BreakAllowed | Stmt_ContinueAllowed;
|
ast_node(fs, ForStmt, node);
|
||||||
|
mod_flags |= Stmt_BreakAllowed | Stmt_ContinueAllowed;
|
||||||
|
|
||||||
check_open_scope(ctx, node);
|
check_open_scope(ctx, node);
|
||||||
check_label(ctx, fs->label, node); // TODO(bill): What should the label's "scope" be?
|
check_label(ctx, fs->label, node); // TODO(bill): What should the label's "scope" be?
|
||||||
@@ -2238,11 +2215,51 @@ gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags)
|
|||||||
error(fs->post, "'for' statement post statement must be a simple statement");
|
error(fs->post, "'for' statement post statement must be a simple statement");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
check_stmt(ctx, fs->body, new_flags);
|
check_stmt(ctx, fs->body, mod_flags);
|
||||||
|
|
||||||
|
check_close_scope(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
gb_internal void check_stmt_internal(CheckerContext *ctx, Ast *node, u32 flags) {
|
||||||
|
u32 mod_flags = flags & (~Stmt_FallthroughAllowed);
|
||||||
|
switch (node->kind) {
|
||||||
|
case_ast_node(_, EmptyStmt, node); case_end;
|
||||||
|
case_ast_node(_, BadStmt, node); case_end;
|
||||||
|
case_ast_node(_, BadDecl, node); case_end;
|
||||||
|
|
||||||
|
case_ast_node(es, ExprStmt, node)
|
||||||
|
check_expr_stmt(ctx, node);
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(as, AssignStmt, node);
|
||||||
|
check_assign_stmt(ctx, node);
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(bs, BlockStmt, node);
|
||||||
|
check_open_scope(ctx, node);
|
||||||
|
check_label(ctx, bs->label, node);
|
||||||
|
|
||||||
|
check_stmt_list(ctx, bs->stmts, flags);
|
||||||
|
check_block_stmt_for_errors(ctx, node);
|
||||||
check_close_scope(ctx);
|
check_close_scope(ctx);
|
||||||
case_end;
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(is, IfStmt, node);
|
||||||
|
check_if_stmt(ctx, node, mod_flags);
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(ws, WhenStmt, node);
|
||||||
|
check_when_stmt(ctx, ws, flags);
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(rs, ReturnStmt, node);
|
||||||
|
check_return_stmt(ctx, node);
|
||||||
|
case_end;
|
||||||
|
|
||||||
|
case_ast_node(fs, ForStmt, node);
|
||||||
|
check_for_stmt(ctx, node, mod_flags);
|
||||||
|
case_end;
|
||||||
|
|
||||||
case_ast_node(rs, RangeStmt, node);
|
case_ast_node(rs, RangeStmt, node);
|
||||||
check_range_stmt(ctx, node, mod_flags);
|
check_range_stmt(ctx, node, mod_flags);
|
||||||
|
|||||||
Reference in New Issue
Block a user