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
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
open Lambda_lib
let expect_ok src =
match Parser.parse src with
| Ok _ -> ()
| Error e ->
failwith (Format.asprintf "expected to parse: %s, got %a" src Parser.pp_error e)
;;
let expect_error src =
match Parser.parse src with
| Ok _ -> failwith (Printf.sprintf "expected parse failure: %s" src)
| Error _ -> ()
;;
let base_success =
[ "42"
; "x"
; "1 + 2"
; "1 + 2 * 3"
; "(1 + 2) * 3"
; "let x = 5 in x + 1"
; "let rec fact n = if n = 0 then 1 else n * fact (n - 1) in fact 4"
; "fun x -> x + 1"
; "fun x y -> x * y"
; "if 1 then 2 else 3"
; "let f x = x in f 3"
; "let x = fun y -> y in x 2"
; "let a = 1 in let b = 2 in a + b"
; "let rec f x = if x = 0 then 0 else f (x - 1) in f 3"
; "fix (fun self -> fun n -> if n = 0 then 1 else n * self (n - 1)) 3"
; "true"
; "false"
; "if true then 1 else 0"
; "if false then 1 else 0"
; "let x = -5 in x"
]
;;
let generated_success =
let open Printf in
List.init 120 (fun i ->
let n = i + 1 in
[ sprintf "%d + %d" n (n + 1)
; sprintf "%d - %d" (n * 2) n
; sprintf "%d * %d" n (n + 2)
; sprintf "%d / %d" (n * (n + 1)) (n + 1)
])
|> List.flatten
;;
let function_success =
let open Printf in
List.init 30 (fun i ->
let n = i + 1 in
[ sprintf "fun x -> x + %d" n
; sprintf "fun a b -> a * %d + b" n
; sprintf "let f x = x + %d in f %d" n (n * 2)
; sprintf "let rec f n = if n = 0 then %d else f (n - 1) in f %d" n n
; sprintf
"let rec g x y = if x = 0 then y else g (x - 1) (y + %d) in g %d %d"
n
n
(n * 2)
])
|> List.flatten
;;
let let_chains =
let open Printf in
List.init 40 (fun i ->
let n = i + 1 in
[ sprintf "let x = %d in x + %d" n n
; sprintf "let x = %d in let y = %d in x * y" n (n + 1)
; sprintf "let x = %d in let y = x + %d in y * x" n (n + 2)
])
|> List.flatten
;;
let error_cases =
[ ""
; "let"
; "1 +"
; "(1 + 2"
; "1 + 2)"
; "if false thenn elsen"
; "if then else"
; "fun -> 1"
; "let 5 = 3"
; "let rec = 1"
; "let x = in x"
; "fun x y"
; "if x"
; "let x = 1 in"
; "let x = 1 in in"
; "let rec f = fun -> 1"
]
;;
let () =
List.iter expect_ok base_success;
List.iter expect_ok generated_success;
List.iter expect_ok function_success;
List.iter expect_ok let_chains;
List.iter expect_error error_cases
;;