@@ -2184,17 +2184,30 @@ static ExecResult exec_stmt(Interpreter* interp, Stmt* stmt, Env* env, LabelMap*
21842184 // Clear interpreter error state
21852185 clear_error (interp );
21862186
2187- // If a catch block exists, bind the catch name (if any) and execute it
2187+ // If a catch block exists, execute it. For the parameterized
2188+ // form `CATCH(SYMBOL: name)` create a child environment so the
2189+ // binding is temporary and shadows any outer binding only for
2190+ // the duration of the catch block (per specification).
21882191 if (stmt -> as .try_stmt .catch_block ) {
2192+ Env * exec_env = env ; /* default: use existing env */
2193+ Env * child_env = NULL ;
21892194 if (stmt -> as .try_stmt .catch_name ) {
2190- env_define (env , stmt -> as .try_stmt .catch_name , TYPE_STR );
2191- if (!env_assign (env , stmt -> as .try_stmt .catch_name , value_str (msg ), TYPE_STR , true)) {
2195+ child_env = env_create (env );
2196+ exec_env = child_env ;
2197+ if (!env_define (exec_env , stmt -> as .try_stmt .catch_name , TYPE_STR )) {
21922198 free (msg );
2199+ env_free (child_env );
2200+ return make_error ("Cannot bind catch name (frozen or existing)" , stmt -> line , stmt -> column );
2201+ }
2202+ if (!env_assign (exec_env , stmt -> as .try_stmt .catch_name , value_str (msg ), TYPE_STR , true)) {
2203+ free (msg );
2204+ env_free (child_env );
21932205 return make_error ("Cannot bind catch name (frozen)" , stmt -> line , stmt -> column );
21942206 }
21952207 }
21962208 free (msg );
2197- ExecResult cres = exec_stmt (interp , stmt -> as .try_stmt .catch_block , env , labels );
2209+ ExecResult cres = exec_stmt (interp , stmt -> as .try_stmt .catch_block , exec_env , labels );
2210+ if (child_env ) env_free (child_env );
21982211 if (cres .status == EXEC_ERROR ) return cres ;
21992212 return cres ;
22002213 }
0 commit comments