interp: 실패해도 그때까지의 출력을 보여준다

0으로 나누는 프로그램을 돌려보니 실패 전에 출력한 것이 통째로 사라졌다.
Interp.run이 출력을 버퍼에 모았다가 성공했을 때만 돌려주고 실패하면 버렸다.

print는 실제로 일어난 effect다. 일어난 일을 안 보여주면 "어디까지 갔나"를
알 수 없고, 그게 실패했을 때 가장 먼저 보고 싶은 것이다.

Interp.run과 Session.run이 이제 (출력, 실패 여부)를 함께 돌려준다.
result가 아니라 짝인 이유는 둘이 배타가 아니기 때문이다 — 실패했어도
출력은 있다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019ZVDeU6KLuUVL3gs18Hm3E
This commit is contained in:
2026-08-30 17:21:34 +09:00
co-authored by Claude Opus 5
parent bb19a39e04
commit 8ff35c5d9b
4 changed files with 53 additions and 25 deletions
+6 -5
View File
@@ -258,14 +258,15 @@ let main_params (m : Ast.modul) =
| _ -> [])
m.items
let run ?(args = []) st path : (string, error) result =
(* 출력과 실패를 함께 돌려준다. 실패해도 그때까지 나온 것은 보여줘야 한다 *)
let run ?(args = []) st path : string * error option =
load st path;
let errs = errors st in
if errs <> [] then Error (List.hd errs)
if errs <> [] then ("", Some (List.hd errs))
else
match find st path with
| None ->
Error { file = path; line = 0; col = 0; message = "모듈을 찾을 수 없습니다" }
("", Some { file = path; line = 0; col = 0; message = "모듈을 찾을 수 없습니다" })
| Some e -> (
(* IR은 그래프 전체를 받는다. 별칭이 실행 의미에 남지 않도록. *)
let mods =
@@ -276,5 +277,5 @@ let run ?(args = []) st path : (string, error) result =
in
let prog = Ir.of_program mods in
match Interp.run ~args prog path (main_params e.ast) with
| Ok out -> Ok out
| Error (pos, msg) -> Error (err_of path pos msg))
| out, None -> (out, None)
| out, Some (pos, msg) -> (out, Some (err_of path pos msg)))