let usage = {|coollang toolchain 사용법: coolc check ... 타입/effect/capability 검사 (import를 따라 모듈 그래프 전체) coolc iface interface 표면과 해시 출력 coolc run typed IR 인터프리터로 실행 coolc tokens 토큰 덤프 (렉서 디버깅) coolc ast 구문 트리 덤프 (파서 디버깅) coolc deps 외부 참조 목록 (모듈의 의존 표면) coolc version 버전 출력 |} let report_errors errors = List.iter (fun e -> prerr_endline (Coollang.Driver.string_of_error e)) errors; 1 let report = function Ok () -> 0 | Error errors -> report_errors errors let dump_tokens file = match Coollang.Driver.tokens file with | Error errors -> report_errors errors | Ok tokens -> List.iter (fun t -> print_endline (Coollang.Token.show t)) tokens; 0 let dump_ast file = match Coollang.Driver.ast file with | Error errors -> report_errors errors | Ok m -> List.iter (fun it -> print_endline (Coollang.Ast.show_item it)) m.Coollang.Ast.items; 0 (* import를 따라 모듈 그래프를 로드하고 전부 검사한다. root는 첫 파일의 디렉터리다. *) let check_graph files = match files with | [] -> prerr_endline "검사할 파일이 없습니다"; 2 | first :: _ -> let st = Coollang.Session.create ~root:(Filename.dirname first) () in List.iter (fun f -> Coollang.Session.load st f) files; let errors = Coollang.Session.errors st in List.iter (fun e -> prerr_endline (Coollang.Session.string_of_error e)) errors; if errors = [] then 0 else 1 let dump_iface file = let st = Coollang.Session.create ~root:(Filename.dirname file) () in Coollang.Session.load st file; match Coollang.Session.find st file with | None -> 1 | Some e -> Printf.printf "hash %s\n" e.iface.Coollang.Iface.hash; List.iter (fun it -> print_endline (Coollang.Ast.show_item it)) e.iface.Coollang.Iface.items; 0 let dump_deps file = match Coollang.Driver.resolve file with | Error errors -> report_errors errors | Ok info -> List.iter (fun (name, (p : Coollang.Token.pos)) -> Printf.printf "%d:%d %s\n" p.line p.col name) info.Coollang.Resolve.externals; 0 let () = let argv = Array.to_list Sys.argv in let code = match List.tl argv with | "check" :: files -> check_graph files | [ "iface"; file ] -> dump_iface file | [ "run"; file ] -> report (Coollang.Driver.run file) | [ "tokens"; file ] -> dump_tokens file | [ "ast"; file ] -> dump_ast file | [ "deps"; file ] -> dump_deps file | [ "version" ] -> print_endline Coollang.Version.string; 0 | [] | [ "help" ] | [ "--help" ] | [ "-h" ] -> print_string usage; 0 | cmd :: _ -> Printf.eprintf "알 수 없는 명령: %s\n\n%s" cmd usage; 2 in exit code