Skip to content

Commit 4563785

Browse files
committed
Add the flexpect tool
1 parent 3b20658 commit 4563785

File tree

14 files changed

+1021
-791
lines changed

14 files changed

+1021
-791
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,7 @@ middle_end/flambda/types/flambda_type.ml
222222
/testsuite/tools/codegen
223223
/testsuite/tools/expect_test
224224
/testsuite/tools/fldiff
225+
/testsuite/tools/flexpect
225226
/testsuite/tools/lexcmm.ml
226227
/testsuite/tools/parsecmm.ml
227228
/testsuite/tools/parsecmm.mli

flambdatest/expect/test1.flt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
let code f _ -> k = cont k (42) in
2+
let f = closure f in
3+
let symbol B = Block 0 (f) in
4+
cont done (B)
5+
===>
6+
let code f _ -> k = cont k (43) in
7+
let symbol F = closure f in
8+
let symbol B = Block 0 (F) in
9+
cont done (B)

middle_end/flambda/compare/compare.ml

Lines changed: 27 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -108,28 +108,41 @@ module Comparison = struct
108108
;;
109109
end
110110

111+
let debugging = false
112+
111113
let log f e1 e2 thunk =
112-
Format.eprintf "@[<v>@[<hv>COMPARING@;<1 2>%a@;<1 0>TO@;<1 2>%a@]@,---@;<0 2>"
113-
f e1 f e2;
114-
let ans = thunk () in
115-
Format.eprintf "%a@]@," (Comparison.print f) ans;
116-
ans
114+
if debugging
115+
then begin
116+
Format.eprintf
117+
"@[<v>@[<hv>COMPARING@;<1 2>%a@;<1 0>TO@;<1 2>%a@]@,---@;<0 2>"
118+
f e1 f e2;
119+
let ans = thunk () in
120+
Format.eprintf "%a@]@," (Comparison.print f) ans;
121+
ans
122+
end
123+
else
124+
thunk ()
125+
;;
117126

118127
let log_rel f e1 rel e2 =
119-
Format.eprintf "@[<hv>%a@;<1 2>%s@;<1 0>%a@]@," f e1 rel f e2
128+
if debugging then
129+
Format.eprintf "@[<hv>%a@;<1 2>%s@;<1 0>%a@]@," f e1 rel f e2
130+
;;
120131

121132
let log_eq p f e1 e2 =
122-
let rel = if p e1 e2 then "=" else "/=" in
123-
log_rel f e1 rel e2
133+
if debugging then
134+
let rel = if p e1 e2 then "=" else "/=" in
135+
log_rel f e1 rel e2
124136
;;
125137

126138
let log_comp c f e1 e2 =
127-
let rel = match c e1 e2 with
128-
| n when n < 0 -> "<"
129-
| 0 -> "="
130-
| _ -> ">"
131-
in
132-
log_rel f e1 rel e2
139+
if debugging then
140+
let rel = match c e1 e2 with
141+
| n when n < 0 -> "<"
142+
| 0 -> "="
143+
| _ -> ">"
144+
in
145+
log_rel f e1 rel e2
133146
;;
134147

135148
module Env = struct

middle_end/flambda/parser/fexpr.ml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -285,3 +285,8 @@ and static_closure_binding = {
285285
type flambda_unit = {
286286
body : expr;
287287
}
288+
289+
type expect_test_spec = {
290+
before : flambda_unit;
291+
after : flambda_unit;
292+
}

middle_end/flambda/parser/flambda_lex.ml

Lines changed: 372 additions & 367 deletions
Large diffs are not rendered by default.

middle_end/flambda/parser/flambda_lex.mll

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ rule token = parse
159159
| "->" { MINUSGREATER }
160160
| "@" { AT }
161161
| "|" { PIPE }
162+
| "===>" { BIGARROW }
162163
| lowercase identchar *
163164
{ let s = Lexing.lexeme lexbuf in
164165
try Hashtbl.find keyword_table s

middle_end/flambda/parser/flambda_parser.ml

Lines changed: 462 additions & 394 deletions
Large diffs are not rendered by default.

middle_end/flambda/parser/flambda_parser.mli

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ type token =
6363
| CLOSURE
6464
| CCALL
6565
| BLOCK
66+
| BIGARROW
6667
| AT
6768
| APPLY
6869
| ANDWHERE
@@ -76,6 +77,8 @@ exception Error
7677

7778
val flambda_unit: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> (Fexpr.flambda_unit)
7879

80+
val expect_test_spec: (Lexing.lexbuf -> token) -> Lexing.lexbuf -> (Fexpr.expect_test_spec)
81+
7982
module MenhirInterpreter : sig
8083

8184
(* The incremental API. *)
@@ -91,4 +94,6 @@ module Incremental : sig
9194

9295
val flambda_unit: Lexing.position -> (Fexpr.flambda_unit) MenhirInterpreter.checkpoint
9396

97+
val expect_test_spec: Lexing.position -> (Fexpr.expect_test_spec) MenhirInterpreter.checkpoint
98+
9499
end

middle_end/flambda/parser/flambda_parser.mly

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ let make_const_float (i, m) =
4343
%token ANDWHERE [@symbol "andwhere"]
4444
%token AT [@symbol "@"]
4545
%token APPLY [@symbol "apply"]
46+
%token BIGARROW [@symbol "===>"]
4647
%token BLOCK [@symbol "Block"]
4748
%token CCALL [@symbol "ccall"]
4849
%token CLOSURE [@symbol "closure"]
@@ -105,23 +106,32 @@ let make_const_float (i, m) =
105106
%token WITH [@symbol "with"]
106107
%token EOF
107108

108-
%start flambda_unit
109+
%start flambda_unit expect_test_spec
109110
%type <Fexpr.flambda_unit> flambda_unit
111+
%type <Fexpr.expect_test_spec> expect_test_spec
110112
%type <Fexpr.static_structure> static_structure
111-
%type <Fexpr.expr> expr
112-
(* %type <Fexpr.name> name *)
113113
%type <Fexpr.kind> kind
114114
%type <Fexpr.named> named
115115
%type <Fexpr.of_kind_value> of_kind_value
116116
%%
117117

118+
flambda_unit:
119+
| body = module_
120+
EOF
121+
{ body }
122+
;
123+
124+
expect_test_spec:
125+
| before = module_; BIGARROW; after = module_; EOF
126+
{ { before; after } }
127+
;
128+
118129
(* XCR lwhite: Probably easier to just use some default names for these
119130
continuations
120131
121132
lmaurer: Makes sense. I went with "done" and "error" for the names. *)
122-
flambda_unit:
133+
module_:
123134
| body = expr
124-
EOF
125135
{ { body } }
126136
;
127137

middle_end/flambda/parser/parse_flambda.ml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,15 @@ let make_loc (startpos, endpos) = {
1111
Location.loc_ghost = false;
1212
}
1313

14-
let parse_fexpr filename =
14+
let run_parser ~start_symbol filename =
1515
let ic = open_in filename in
1616
try
1717
let pos = { Lexing.pos_fname = filename; pos_lnum = 1; pos_bol = 0; pos_cnum = 0 } in
1818
let lb = Lexing.from_channel ic in
1919
let lb = { lb with lex_start_p = pos; lex_curr_p = pos } in
2020
let supplier = Parser.MenhirInterpreter.lexer_lexbuf_to_supplier Lex.token lb in
21-
let start = Parser.Incremental.flambda_unit pos in
22-
let unit =
21+
let start = start_symbol pos in
22+
let result =
2323
try Parser.MenhirInterpreter.loop_handle
2424
(fun ans -> Ok ans)
2525
(function
@@ -44,15 +44,23 @@ let parse_fexpr filename =
4444
Error (Lexing_error (error, make_loc loc))
4545
in
4646
close_in ic;
47-
unit
47+
result
4848
with
4949
| e ->
5050
let x = Printexc.get_raw_backtrace () in
5151
close_in ic;
5252
Printexc.raise_with_backtrace e x
5353

54-
let make_compilation_unit file =
55-
let basename = Filename.chop_suffix file ".fl" |> Filename.basename in
54+
let parse_fexpr = run_parser ~start_symbol:Parser.Incremental.flambda_unit
55+
56+
let parse_expect_test_spec =
57+
run_parser ~start_symbol:Parser.Incremental.expect_test_spec
58+
59+
let make_compilation_unit ~extension ~filename =
60+
let basename =
61+
Filename.chop_suffix filename ("." ^ extension)
62+
|> Filename.basename
63+
in
5664
let name = String.capitalize_ascii basename in
5765
let linkage_name = Linkage_name.create name in
5866
let id = Ident.create_persistent name in
@@ -61,7 +69,7 @@ let make_compilation_unit file =
6169
let parse ~backend filename =
6270
parse_fexpr filename
6371
|> Result.map (fun fexpr ->
64-
let comp_unit = make_compilation_unit filename in
72+
let comp_unit = make_compilation_unit ~extension:"fl" ~filename in
6573
let old_comp_unit = Compilation_unit.get_current () in
6674
Compilation_unit.set_current comp_unit;
6775
let module_ident = Compilation_unit.get_persistent_ident comp_unit in

middle_end/flambda/parser/parse_flambda.mli

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,17 @@ type error =
22
| Lexing_error of Flambda_lex.error * Location.t
33
| Parsing_error of string * Location.t
44

5+
val parse_expect_test_spec
6+
: string
7+
-> (Fexpr.expect_test_spec, error) result
8+
59
val parse_fexpr
610
: string
711
-> (Fexpr.flambda_unit, error) result
812

913
val make_compilation_unit
10-
: string
14+
: extension:string
15+
-> filename:string
1116
-> Compilation_unit.t
1217

1318
val parse

testsuite/tools/Makefile

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ fldiff_OCAMLFLAGS = $(addprefix -I $(TOPDIR)/, $(fldiff_DIRS))
7070
fldiff_LIBS = $(addprefix $(COMPILERLIBSDIR)/,\
7171
ocamlcommon ocamloptcomp)
7272

73+
flexpect_MAIN=flexpect
74+
flexpect_PROG=$(flexpect_MAIN)$(EXE)
75+
flexpect_DIRS=\
76+
asmcomp \
77+
parsing \
78+
utils \
79+
middle_end/flambda/compilenv_deps \
80+
middle_end/flambda/parser \
81+
middle_end/flambda/compare \
82+
middle_end/flambda/simplify \
83+
middle_end/flambda/terms
84+
flexpect_OCAMLFLAGS = $(addprefix -I $(TOPDIR)/, $(flexpect_DIRS))
85+
86+
flexpect_LIBS = $(addprefix $(COMPILERLIBSDIR)/,\
87+
ocamlcommon ocamloptcomp)
88+
7389
tools := $(expect_PROG)
7490

7591
ifeq "$(NATIVE_COMPILER)" "true"
@@ -94,6 +110,8 @@ $(parseflambda_PROG): COMPFLAGS = $(parseflambda_OCAMLFLAGS)
94110

95111
$(fldiff_PROG): COMPFLAGS = $(fldiff_OCAMLFLAGS)
96112

113+
$(flexpect_PROG): COMPFLAGS = $(flexpect_OCAMLFLAGS)
114+
97115
codegen_main.cmo: parsecmm.cmo
98116

99117
$(codegen_PROG): $(codegen_OBJECTS)
@@ -105,6 +123,9 @@ $(parseflambda_PROG): $(parseflambda_MAIN).cmo
105123
$(fldiff_PROG): $(fldiff_MAIN).cmo
106124
$(OCAMLC) -o $@ $(fldiff_LIBS:=.cma) $^
107125

126+
$(flexpect_PROG): $(flexpect_MAIN).cmo
127+
$(OCAMLC) -o $@ $(flexpect_LIBS:=.cma) $^
128+
108129
parsecmm.mli parsecmm.ml: parsecmm.mly
109130
$(OCAMLYACC) -q parsecmm.mly
110131

testsuite/tools/flexpect.ml

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
let check_invariants program =
2+
try Flambda_unit.invariant program
3+
with exn ->
4+
Format.eprintf "Program which failed invariant check:@ %a\n%!"
5+
Flambda_unit.print program;
6+
raise exn
7+
8+
module Outcome = struct
9+
type t = Success | Failure | Error
10+
11+
let to_exit_code = function
12+
| Success -> 0
13+
| Failure -> 1
14+
| Error -> 2
15+
end
16+
17+
let run_expect_test ~backend filename : Outcome.t =
18+
match Parse_flambda.parse_expect_test_spec filename with
19+
| Ok { before; after = expected } ->
20+
begin
21+
let comp_unit =
22+
Parse_flambda.make_compilation_unit ~extension:"flt" ~filename
23+
in
24+
Compilation_unit.set_current comp_unit;
25+
let module_ident = Compilation_unit.get_persistent_ident comp_unit in
26+
let before_fl = Fexpr_to_flambda.conv ~backend ~module_ident before in
27+
check_invariants before_fl;
28+
let { Simplify.unit = actual_fl; _ } =
29+
Simplify.run ~backend ~round:1 before_fl
30+
in
31+
let expected_fl = Fexpr_to_flambda.conv ~backend ~module_ident expected in
32+
match Compare.flambda_units actual_fl expected_fl with
33+
| Equivalent ->
34+
Format.eprintf "PASS@.";
35+
Success
36+
| Different { approximant = actual' } ->
37+
let actual_fexpr = Flambda_to_fexpr.conv actual' in
38+
let corrected_filename = filename ^ ".corrected" in
39+
let corrected_out = open_out corrected_filename in
40+
Format.fprintf (corrected_out |> Format.formatter_of_out_channel)
41+
"@[<v>%a@ ===>@ %a@]@."
42+
Print_fexpr.flambda_unit before
43+
Print_fexpr.flambda_unit actual_fexpr;
44+
close_out corrected_out;
45+
Format.eprintf "FAIL - Saving corrected test as %s@."
46+
corrected_filename;
47+
Failure
48+
end
49+
| Error e ->
50+
begin match e with
51+
| Parsing_error (msg, loc) ->
52+
Format.eprintf
53+
"%a:@.\
54+
Syntax error: %s@."
55+
Location.print_loc loc
56+
msg
57+
| Lexing_error (error, loc) ->
58+
Format.eprintf
59+
"%a:@.\
60+
Lex error: %a@."
61+
Location.print_loc loc
62+
Flambda_lex.pp_error error
63+
end;
64+
Error
65+
66+
let _ =
67+
let file = Sys.argv.(1) in
68+
let ext = Filename.extension file in
69+
let outcome =
70+
match ext with
71+
| ".flt" ->
72+
run_expect_test ~backend:(module Asmgen.Flambda_backend) file
73+
| _ ->
74+
Misc.fatal_errorf "Unrecognized extension %s; expected .flt" ext
75+
in
76+
exit (outcome |> Outcome.to_exit_code)
77+

testsuite/tools/parseflambda.ml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ let check_invariants program =
77
Flambda_unit.print program;
88
raise exn
99

10-
let parse_flambda ~backend file =
11-
match Parse_flambda.parse_fexpr file with
10+
let parse_flambda ~backend filename =
11+
match Parse_flambda.parse_fexpr filename with
1212
| Ok unit ->
13-
let comp_unit = Parse_flambda.make_compilation_unit file in
13+
let comp_unit =
14+
Parse_flambda.make_compilation_unit ~extension:"fl" ~filename
15+
in
1416
Compilation_unit.set_current comp_unit;
1517
Format.printf "%a@.@."
1618
Print_fexpr.flambda_unit unit;

0 commit comments

Comments
 (0)