@@ -1881,6 +1881,123 @@ let lsp_phase_d_tests = [
18811881 Alcotest. test_case " pipeline: broken source → diag" `Quick test_lsp_pipeline_invalid;
18821882]
18831883
1884+ (* ============================================================================
1885+ Section 21: Try / Catch / Finally Tests
1886+ ============================================================================
1887+
1888+ These tests verify that the try/catch/finally construct type-checks and
1889+ survives the full pipeline through both the Julia and interpreter backends.
1890+
1891+ WASM 1.0 tests only verify that the pipeline raises a clean
1892+ UnsupportedFeature error when catch arms are present; body-only and
1893+ finally-only variants must succeed.
1894+ *)
1895+
1896+ let test_try_typecheck_body_only () =
1897+ match run_frontend (fixture " try_body_only.affine" ) with
1898+ | Error msg -> Alcotest. fail msg
1899+ | Ok _ -> ()
1900+
1901+ let test_try_typecheck_finally () =
1902+ match run_frontend (fixture " try_finally.affine" ) with
1903+ | Error msg -> Alcotest. fail msg
1904+ | Ok _ -> ()
1905+
1906+ let test_try_typecheck_catch_wildcard () =
1907+ match run_frontend (fixture " try_catch_wildcard.affine" ) with
1908+ | Error msg -> Alcotest. fail msg
1909+ | Ok _ -> ()
1910+
1911+ let test_try_typecheck_catch_var () =
1912+ match run_frontend (fixture " try_catch_var.affine" ) with
1913+ | Error msg -> Alcotest. fail msg
1914+ | Ok _ -> ()
1915+
1916+ let test_try_typecheck_full () =
1917+ match run_frontend (fixture " try_catch_finally.affine" ) with
1918+ | Error msg -> Alcotest. fail msg
1919+ | Ok _ -> ()
1920+
1921+ (* * Body-only and finally-only variants must compile to WASM without error. *)
1922+ let test_try_wasm_body_only () =
1923+ match run_wasm_pipeline (fixture " try_body_only.affine" ) with
1924+ | Error msg -> Alcotest. fail msg
1925+ | Ok _ -> ()
1926+
1927+ let test_try_wasm_finally () =
1928+ match run_wasm_pipeline (fixture " try_finally.affine" ) with
1929+ | Error msg -> Alcotest. fail msg
1930+ | Ok _ -> ()
1931+
1932+ (* * Catch arms must produce a clean UnsupportedFeature error in WASM 1.0. *)
1933+ let test_try_wasm_catch_unsupported () =
1934+ match run_wasm_pipeline (fixture " try_catch_wildcard.affine" ) with
1935+ | Ok _ ->
1936+ (* Acceptable if the WASM backend happens to support this in future. *)
1937+ ()
1938+ | Error msg ->
1939+ Alcotest. (check bool ) " UnsupportedFeature error for catch in WASM"
1940+ true (String. length msg > 0 )
1941+
1942+ (* * All five fixtures must produce Julia code without errors. *)
1943+ let test_try_julia_body_only () =
1944+ match run_julia_pipeline (fixture " try_body_only.affine" ) with
1945+ | Error msg -> Alcotest. fail msg
1946+ | Ok code ->
1947+ Alcotest. (check bool ) " non-empty Julia output" true
1948+ (String. length code > 0 )
1949+
1950+ let test_try_julia_finally () =
1951+ match run_julia_pipeline (fixture " try_finally.affine" ) with
1952+ | Error msg -> Alcotest. fail msg
1953+ | Ok code ->
1954+ Alcotest. (check bool ) " contains try keyword" true
1955+ (try let _ = Str. search_forward (Str. regexp " try" ) code 0 in true
1956+ with Not_found -> false )
1957+
1958+ let test_try_julia_catch_wildcard () =
1959+ match run_julia_pipeline (fixture " try_catch_wildcard.affine" ) with
1960+ | Error msg -> Alcotest. fail msg
1961+ | Ok code ->
1962+ Alcotest. (check bool ) " contains catch keyword" true
1963+ (try let _ = Str. search_forward (Str. regexp " catch" ) code 0 in true
1964+ with Not_found -> false )
1965+
1966+ let test_try_julia_catch_var () =
1967+ match run_julia_pipeline (fixture " try_catch_var.affine" ) with
1968+ | Error msg -> Alcotest. fail msg
1969+ | Ok code ->
1970+ Alcotest. (check bool ) " contains catch keyword" true
1971+ (try let _ = Str. search_forward (Str. regexp " catch" ) code 0 in true
1972+ with Not_found -> false )
1973+
1974+ let test_try_julia_full () =
1975+ match run_julia_pipeline (fixture " try_catch_finally.affine" ) with
1976+ | Error msg -> Alcotest. fail msg
1977+ | Ok code ->
1978+ let has_try = try let _ = Str. search_forward (Str. regexp " try" ) code 0 in true with Not_found -> false in
1979+ let has_catch = try let _ = Str. search_forward (Str. regexp " catch" ) code 0 in true with Not_found -> false in
1980+ let has_finally = try let _ = Str. search_forward (Str. regexp " finally" ) code 0 in true with Not_found -> false in
1981+ Alcotest. (check bool ) " has try" true has_try;
1982+ Alcotest. (check bool ) " has catch" true has_catch;
1983+ Alcotest. (check bool ) " has finally" true has_finally
1984+
1985+ let try_catch_tests = [
1986+ Alcotest. test_case " typecheck: body-only" `Quick test_try_typecheck_body_only;
1987+ Alcotest. test_case " typecheck: finally" `Quick test_try_typecheck_finally;
1988+ Alcotest. test_case " typecheck: catch wildcard" `Quick test_try_typecheck_catch_wildcard;
1989+ Alcotest. test_case " typecheck: catch var" `Quick test_try_typecheck_catch_var;
1990+ Alcotest. test_case " typecheck: full form" `Quick test_try_typecheck_full;
1991+ Alcotest. test_case " wasm: body-only compiles" `Quick test_try_wasm_body_only;
1992+ Alcotest. test_case " wasm: finally compiles" `Quick test_try_wasm_finally;
1993+ Alcotest. test_case " wasm: catch → unsupported" `Quick test_try_wasm_catch_unsupported;
1994+ Alcotest. test_case " julia: body-only" `Quick test_try_julia_body_only;
1995+ Alcotest. test_case " julia: finally" `Quick test_try_julia_finally;
1996+ Alcotest. test_case " julia: catch wildcard" `Quick test_try_julia_catch_wildcard;
1997+ Alcotest. test_case " julia: catch var" `Quick test_try_julia_catch_var;
1998+ Alcotest. test_case " julia: full form" `Quick test_try_julia_full;
1999+ ]
2000+
18842001(* ============================================================================
18852002 Test Suite Export
18862003 ============================================================================ *)
@@ -1907,4 +2024,5 @@ let tests =
19072024 (" E2E LSP Phase B" , lsp_phase_b_tests);
19082025 (" E2E LSP Phase C" , lsp_phase_c_tests);
19092026 (" E2E LSP Phase D" , lsp_phase_d_tests);
2027+ (" E2E Try/Catch/Finally" , try_catch_tests);
19102028 ]
0 commit comments