Skip to content

Commit 1cfcd59

Browse files
authored
Merge pull request #833 from CakeML/parse-err
Improve compiler error messages
2 parents 9e079b9 + d5a3d1b commit 1cfcd59

File tree

4 files changed

+87
-27
lines changed

4 files changed

+87
-27
lines changed

basis/basis_ffi.c

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -158,16 +158,17 @@ int hasT = 0;
158158
void cml_exit(int arg) {
159159

160160
#ifdef STDERR_MEM_EXHAUST
161-
if(arg == 1) {
162-
fprintf(stderr,"CakeML heap space exhausted.\n");
163-
}
164-
else if(arg == 2) {
165-
fprintf(stderr,"CakeML stack space exhausted.\n");
166-
}
161+
fprintf(stderr,"Program exited with nonzero exit code.\n");
167162
#endif
168163

169164
#ifdef DEBUG_FFI
170165
{
166+
if(arg == 1) {
167+
fprintf(stderr,"CakeML heap space exhausted.\n");
168+
}
169+
else if(arg == 2) {
170+
fprintf(stderr,"CakeML stack space exhausted.\n");
171+
}
171172
fprintf(stderr,"GCNum: %d, GCTime(us): %ld\n",numGC,microsecs);
172173
}
173174
#endif

compiler/bootstrap/translation/compiler32ProgScript.sml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,22 @@ val res = translate (spec32 word_to_string_def);
131131

132132
(* compilerTheory *)
133133

134-
val _ = translate compilerTheory.locn_to_string_def;
134+
val res = translate compilerTheory.find_next_newline_def;
135+
136+
Theorem find_next_newline_side = prove(
137+
“∀n s. compiler_find_next_newline_side n s”,
138+
ho_match_mp_tac compilerTheory.find_next_newline_ind \\ rw []
139+
\\ once_rewrite_tac [fetch "-" "compiler_find_next_newline_side_def"]
140+
\\ fs []) |> update_precondition;
141+
142+
val res = translate compilerTheory.safe_substring_def;
143+
144+
Theorem safe_substring_side = prove(
145+
“compiler_safe_substring_side s n l”,
146+
fs [fetch "-" "compiler_safe_substring_side_def"])
147+
|> update_precondition;
148+
149+
val _ = translate compilerTheory.get_nth_line_def;
135150
val _ = translate compilerTheory.locs_to_string_def;
136151
val _ = translate compilerTheory.parse_cml_input_def;
137152
val _ = translate (compilerTheory.parse_sexp_input_def
@@ -236,7 +251,9 @@ val res = translate compilerTheory.help_string_def;
236251
val nonzero_exit_code_for_error_msg_def = Define `
237252
nonzero_exit_code_for_error_msg e =
238253
if compiler$is_error_msg e then
239-
ml_translator$force_out_of_memory_error () else ()`;
254+
(let a = empty_ffi (strlit "nonzero_exit") in
255+
ml_translator$force_out_of_memory_error ())
256+
else ()`;
240257

241258
val res = translate compilerTheory.is_error_msg_def;
242259
val res = translate nonzero_exit_code_for_error_msg_def;

compiler/bootstrap/translation/compiler64ProgScript.sml

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,22 @@ val res = translate (spec64 word_to_string_def);
132132

133133
(* compilerTheory *)
134134

135-
val _ = translate compilerTheory.locn_to_string_def;
135+
val res = translate compilerTheory.find_next_newline_def;
136+
137+
Theorem find_next_newline_side = prove(
138+
“∀n s. compiler_find_next_newline_side n s”,
139+
ho_match_mp_tac compilerTheory.find_next_newline_ind \\ rw []
140+
\\ once_rewrite_tac [fetch "-" "compiler_find_next_newline_side_def"]
141+
\\ fs []) |> update_precondition;
142+
143+
val res = translate compilerTheory.safe_substring_def;
144+
145+
Theorem safe_substring_side = prove(
146+
“compiler_safe_substring_side s n l”,
147+
fs [fetch "-" "compiler_safe_substring_side_def"])
148+
|> update_precondition;
149+
150+
val _ = translate compilerTheory.get_nth_line_def;
136151
val _ = translate compilerTheory.locs_to_string_def;
137152
val _ = translate compilerTheory.parse_cml_input_def;
138153
val _ = translate (compilerTheory.parse_sexp_input_def
@@ -255,7 +270,9 @@ val res = translate compilerTheory.help_string_def;
255270
val nonzero_exit_code_for_error_msg_def = Define `
256271
nonzero_exit_code_for_error_msg e =
257272
if compiler$is_error_msg e then
258-
ml_translator$force_out_of_memory_error () else ()`;
273+
(let a = empty_ffi (strlit "nonzero_exit") in
274+
ml_translator$force_out_of_memory_error ())
275+
else ()`;
259276

260277
val res = translate compilerTheory.is_error_msg_def;
261278
val res = translate nonzero_exit_code_for_error_msg_def;

compiler/compilerScript.sml

Lines changed: 42 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -172,24 +172,49 @@ Datatype:
172172
| ConfigError mlstring
173173
End
174174

175-
Definition locn_to_string_def:
176-
locn_to_string UNKNOWNpt = implode "unknown point"
177-
locn_to_string EOFpt = implode "end-of-file"
178-
locn_to_string (POSN r c) =
179-
concat [strlit "row " ; toString r ; strlit ", column " ; toString c]
175+
Definition find_next_newline_def:
176+
find_next_newline n s =
177+
if strlen s ≤ n then n else
178+
if strsub s n = #"\n" then n else
179+
find_next_newline (n+1) s
180+
Termination
181+
WF_REL_TAC ‘measure (λ(n,s). strlen s - n)’
180182
End
181183

182-
val locs_to_string_def = Define `
183-
(locs_to_string NONE = implode "unknown location") ∧
184-
(locs_to_string (SOME (Locs startl endl)) =
185-
if Locs startl endl = unknown_loc then
186-
implode "unknown location"
184+
Definition safe_substring_def:
185+
safe_substring s n l =
186+
let k = strlen s in
187+
if k ≤ n then strlit "" else
188+
if n + l ≤ k then
189+
substring s n l
190+
else substring s n (k - n)
191+
End
192+
193+
Definition get_nth_line_def:
194+
get_nth_line k s n =
195+
if k = 0 then
196+
let n1 = find_next_newline n s in
197+
safe_substring s n (n1 - n)
187198
else
188-
concat
189-
[implode "location starting at ";
190-
locn_to_string startl ;
191-
implode ", ending at ";
192-
locn_to_string endl])`;
199+
get_nth_line (k-1:num) s (find_next_newline n s + 1)
200+
End
201+
202+
Definition locs_to_string_def:
203+
(locs_to_string input NONE = implode "unknown location") ∧
204+
(locs_to_string input (SOME (Locs startl endl)) =
205+
case startl of
206+
| POSN r c =>
207+
(let line = get_nth_line r input 0 in
208+
let len = strlen line in
209+
let stop =
210+
(case endl of POSN r1 c1 => (if r1 = r then c1 else len) | _ => len) in
211+
let underline =
212+
concat (REPLICATE c (strlit " ") ++ REPLICATE ((stop - c) + 1) (strlit [CHR 94])) in
213+
concat [strlit "line "; toString (r+1); strlit "\n\n";
214+
line; strlit "\n";
215+
underline; strlit "\n"])
216+
| _ => implode "unknown location")
217+
End
193218

194219
(* this is a rather annoying feature of peg_exec requiring locs... *)
195220
Overload add_locs = ``MAP (λc. (c,unknown_loc))``
@@ -207,7 +232,7 @@ End
207232
Definition parse_cml_input_def:
208233
parse_cml_input input =
209234
case parse_prog (lexer_fun input) of
210-
| Failure l _ => INL (strlit "Parsing failed at " ^ locs_to_string (SOME l))
235+
| Failure l _ => INL (strlit "Parsing failed at " ^ locs_to_string (implode input) (SOME l))
211236
| Success _ x _ => INR x
212237
End
213238

@@ -230,7 +255,7 @@ val compile_def = Define`
230255
of
231256
| Failure (locs, msg) =>
232257
(Failure (TypeError (concat [msg; implode " at ";
233-
locs_to_string locs])), [])
258+
locs_to_string (implode input) locs])), [])
234259
| Success ic =>
235260
let _ = empty_ffi (strlit "finished: type inference") in
236261
if c.only_print_types then

0 commit comments

Comments
 (0)