1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
[@@@ocaml.text "/*"]
(** Copyright 2021-2024, Kakadu and contributors *)
(** SPDX-License-Identifier: LGPL-3.0-or-later *)
[@@@ocaml.text "/*"]
open Base
open Stdio
open Lambda_lib
open Lambda_lib.Interpret
(** Parse command line arguments*)
let parse_args args =
let rec parse max_steps = function
| [] -> Some max_steps
| "-max-steps" :: n :: rest ->
(match Stdlib.int_of_string_opt n with
| Some steps -> parse steps rest
| None ->
eprintf "Error: Invalid value for -max-steps: %s\n" n;
None)
| arg :: _ ->
eprintf "Error: Unknown argument: %s\n" arg;
None
in
match parse 10000 args with
| Some max_steps -> max_steps
| None -> Stdlib.exit 1
;;
let () =
let max_steps = parse_args (List.tl_exn (Array.to_list (Sys.get_argv ()))) in
let input = In_channel.input_all In_channel.stdin |> String.strip in
match Parser.parse input with
| Error e ->
let msg = Stdlib.Format.asprintf "%a" Parser.pp_error e in
eprintf "Error: %s\n" msg;
Stdlib.exit 1
| Result.Ok ast ->
(match eval_expr ~max_steps ast with
| Result.Ok (VInt n) -> printf "%d\n" n
| Result.Ok (VClosure _) -> printf "<fun>\n"
| Result.Ok (VBuiltin (name, _)) -> printf "<builtin:%s>\n" name
| Result.Ok VUnit -> printf "()\n"
| Result.Error (UnknownVariable name) ->
eprintf "Unbound variable: %s\n" name;
Stdlib.exit 1
| Result.Error DivisionByZero ->
eprintf "Division by zero\n";
Stdlib.exit 1
| Result.Error TypeMismatch ->
eprintf "Type error\n";
Stdlib.exit 1
| Result.Error StepLimitExceeded ->
eprintf "Step limit exceeded\n";
Stdlib.exit 1)
;;