@@ -188,6 +188,22 @@ static Expr* parse_expression(Parser* parser);
188188static Stmt * parse_statement (Parser * parser );
189189static Stmt * parse_block (Parser * parser );
190190
191+ static void append_parse_error_throw_stmt (Parser * parser , Stmt * block ) {
192+ if (!parser || !block || !parser -> error_msg ) return ;
193+
194+ char * msg_dup = strdup (parser -> error_msg );
195+ Expr * callee = expr_ident (strdup ("THROW" ), parser -> error_line , parser -> error_col );
196+ Expr * call = expr_call (callee , parser -> error_line , parser -> error_col );
197+ Expr * arg = expr_str (msg_dup , parser -> error_line , parser -> error_col );
198+ expr_list_add (& call -> as .call .args , arg );
199+ Stmt * err_stmt = stmt_expr (call , parser -> error_line , parser -> error_col );
200+ stmt_list_add (& block -> as .block , err_stmt );
201+ free (parser -> error_msg );
202+ parser -> error_msg = NULL ;
203+ parser -> had_error = false;
204+ parser -> panic_mode = false;
205+ }
206+
191207static bool is_type_token (PTokenType type ) {
192208 return type == TOKEN_IDENT || type == TOKEN_FUNC || type == TOKEN_THR ;
193209}
@@ -606,6 +622,20 @@ static Stmt* parse_block(Parser* parser) {
606622 stmt_set_src (stmt , line_text );
607623 free (line_text );
608624 stmt_list_add (& block -> as .block , stmt );
625+ skip_newlines (parser );
626+ continue ;
627+ }
628+
629+ if (!parser -> error_msg ) {
630+ break ;
631+ }
632+
633+ append_parse_error_throw_stmt (parser , block );
634+
635+ while (parser -> current_token .type != TOKEN_EOF &&
636+ parser -> current_token .type != TOKEN_NEWLINE &&
637+ parser -> current_token .type != TOKEN_RBRACE ) {
638+ advance (parser );
609639 }
610640 skip_newlines (parser );
611641 }
@@ -693,7 +723,14 @@ static Stmt* parse_try(Parser* parser) {
693723 Token tok = parser -> current_token ;
694724 consume (parser , TOKEN_TRY , "Expected 'TRY'" );
695725 Stmt * try_block = parse_block (parser );
696- consume (parser , TOKEN_CATCH , "Expected 'CATCH' after TRY" );
726+ if (parser -> current_token .type != TOKEN_CATCH ) {
727+ report_error (parser , "Expected 'CATCH' after TRY" );
728+ while (parser -> current_token .type != TOKEN_EOF && parser -> current_token .type != TOKEN_RBRACE ) {
729+ advance (parser );
730+ }
731+ return NULL ;
732+ }
733+ advance (parser );
697734 char * catch_name = NULL ;
698735 if (match (parser , TOKEN_LPAREN )) {
699736 if (parser -> current_token .type == TOKEN_IDENT ) {
@@ -1015,17 +1052,7 @@ Stmt* parser_parse(Parser* parser) {
10151052 state so callers (e.g. RUN/IMPORT) don't treat it as a fatal
10161053 top-level parse failure. */
10171054 if (parser -> error_msg ) {
1018- char * msg_dup = strdup (parser -> error_msg );
1019- Expr * callee = expr_ident (strdup ("THROW" ), parser -> error_line , parser -> error_col );
1020- Expr * call = expr_call (callee , parser -> error_line , parser -> error_col );
1021- Expr * arg = expr_str (msg_dup , parser -> error_line , parser -> error_col );
1022- expr_list_add (& call -> as .call .args , arg );
1023- Stmt * err_stmt = stmt_expr (call , parser -> error_line , parser -> error_col );
1024- stmt_list_add (& program -> as .block , err_stmt );
1025- free (parser -> error_msg );
1026- parser -> error_msg = NULL ;
1027- parser -> had_error = false;
1028- parser -> panic_mode = false;
1055+ append_parse_error_throw_stmt (parser , program );
10291056 }
10301057
10311058 /* Synchronize after an error: advance to next newline or EOF so the
0 commit comments