Răsfoiți Sursa

Minor clean up of `is_terminating` code

This does not fix all known issues with it
gingerBill 1 an în urmă
părinte
comite
4eab735b13
1 a modificat fișierele cu 19 adăugiri și 8 ștergeri
  1. 19 8
      src/check_stmt.cpp

+ 19 - 8
src/check_stmt.cpp

@@ -254,6 +254,13 @@ gb_internal bool check_has_break(Ast *stmt, String const &label, bool implicit)
 }
 
 
+String label_from_node(Ast *node, String default_label) {
+	if (node != nullptr && node->kind == Ast_Ident) {
+		return node->Ident.token.string;
+	}
+	return default_label;
+}
+
 
 // NOTE(bill): The last expression has to be a 'return' statement
 // TODO(bill): This is a mild hack and should be probably handled properly
@@ -264,7 +271,7 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
 	case_end;
 
 	case_ast_node(bs, BlockStmt, node);
-		return check_is_terminating_list(bs->stmts, label);
+		return check_is_terminating_list(bs->stmts, label_from_node(bs->label, label));
 	case_end;
 
 	case_ast_node(es, ExprStmt, node);
@@ -285,9 +292,10 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
 	case_end;
 
 	case_ast_node(is, IfStmt, node);
+		String new_label = label_from_node(is->label, label);
 		if (is->else_stmt != nullptr) {
-			if (check_is_terminating(is->body, label) &&
-			    check_is_terminating(is->else_stmt, label)) {
+			if (check_is_terminating(is->body, new_label) &&
+			    check_is_terminating(is->else_stmt, new_label)) {
 			    return true;
 		    }
 		}
@@ -320,7 +328,8 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
 	case_end;
 
 	case_ast_node(fs, ForStmt, node);
-		if (fs->cond == nullptr && !check_has_break(fs->body, label, true)) {
+		String new_label = label_from_node(fs->label, label);
+		if (fs->cond == nullptr && !check_has_break(fs->body, new_label, true)) {
 			return true;
 		}
 	case_end;
@@ -335,14 +344,15 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
 
 	case_ast_node(ss, SwitchStmt, node);
 		bool has_default = false;
+		String new_label = label_from_node(ss->label, label);
 		for_array(i, ss->body->BlockStmt.stmts) {
 			Ast *clause = ss->body->BlockStmt.stmts[i];
 			ast_node(cc, CaseClause, clause);
 			if (cc->list.count == 0) {
 				has_default = true;
 			}
-			if (!check_is_terminating_list(cc->stmts, label) ||
-			    check_has_break_list(cc->stmts, label, true)) {
+			if (!check_is_terminating_list(cc->stmts, new_label) ||
+			    check_has_break_list(cc->stmts, new_label, true)) {
 				return false;
 			}
 		}
@@ -351,14 +361,15 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
 
 	case_ast_node(ss, TypeSwitchStmt, node);
 		bool has_default = false;
+		String new_label = label_from_node(ss->label, label);
 		for_array(i, ss->body->BlockStmt.stmts) {
 			Ast *clause = ss->body->BlockStmt.stmts[i];
 			ast_node(cc, CaseClause, clause);
 			if (cc->list.count == 0) {
 				has_default = true;
 			}
-			if (!check_is_terminating_list(cc->stmts, label) ||
-			    check_has_break_list(cc->stmts, label, true)) {
+			if (!check_is_terminating_list(cc->stmts, new_label) ||
+			    check_has_break_list(cc->stmts, new_label, true)) {
 				return false;
 			}
 		}