Skip to content

Commit 6e3a77c

Browse files
committed
Merge remote branch 'tohava/master'
Conflicts: src/boot/fe/ast.ml
2 parents ed92925 + 0830b5b commit 6e3a77c

File tree

7 files changed

+166
-70
lines changed

7 files changed

+166
-70
lines changed

src/Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,7 @@ self: $(CFG_COMPILER)
371371
# of inter-task shutdown races introduced with notification proxies.
372372

373373
TASK_XFAILS := test/run-pass/acyclic-unwind.rs \
374+
test/run-pass/alt-type-simple.rs \
374375
test/run-pass/basic.rs \
375376
test/run-pass/clone-with-exterior.rs \
376377
test/run-pass/comm.rs \

src/boot/fe/ast.ml

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -322,7 +322,7 @@ and pat =
322322
and tag_arm' = pat * block
323323
and tag_arm = tag_arm' identified
324324

325-
and type_arm' = ident * slot * block
325+
and type_arm' = (ident * slot) * block
326326
and type_arm = type_arm' identified
327327

328328
and port_arm' = port_case * block
@@ -1253,7 +1253,6 @@ and fmt_stmt_body (ff:Format.formatter) (s:stmt) : unit =
12531253
fmt_cbb ff;
12541254
end;
12551255
fmt_cbb ff;
1256-
12571256
| STMT_alt_port at ->
12581257
fmt_obox ff;
12591258
fmt ff "alt ";
@@ -1273,7 +1272,6 @@ and fmt_stmt_body (ff:Format.formatter) (s:stmt) : unit =
12731272
fmt_cbb ff;
12741273
end;
12751274
fmt_cbb ff;
1276-
12771275
| STMT_note at ->
12781276
begin
12791277
fmt ff "note ";
@@ -1308,10 +1306,11 @@ and fmt_tag_arm (ff:Format.formatter) (tag_arm:tag_arm) : unit =
13081306
fmt_arm ff (fun ff -> fmt_pat ff pat) block;
13091307

13101308
and fmt_type_arm (ff:Format.formatter) (type_arm:type_arm) : unit =
1311-
let (_, slot, block) = type_arm.node in
1312-
fmt_arm ff (fun ff -> fmt_slot ff slot) block;
1313-
1314-
1309+
let ((ident, slot), block) = type_arm.node in
1310+
let fmt_type_arm_case (ff:Format.formatter) =
1311+
fmt_slot ff slot; fmt ff " "; fmt_ident ff ident
1312+
in
1313+
fmt_arm ff fmt_type_arm_case block;
13151314
and fmt_port_arm (ff:Format.formatter) (port_arm:port_arm) : unit =
13161315
let (port_case, block) = port_arm.node in
13171316
fmt_arm ff (fun ff -> fmt_port_case ff port_case) block;

src/boot/fe/item.ml

Lines changed: 110 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -225,69 +225,117 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
225225

226226
| ALT ->
227227
bump ps;
228-
begin
228+
let rec parse_pat ps =
229229
match peek ps with
230-
TYPE -> [| |]
231-
| LPAREN ->
232-
let (stmts, lval) = bracketed LPAREN RPAREN parse_lval ps in
233-
let rec parse_pat ps =
234-
match peek ps with
235-
IDENT _ ->
236-
let apos = lexpos ps in
237-
let name = Pexp.parse_name ps in
238-
let bpos = lexpos ps in
239-
240-
if peek ps != LPAREN then
241-
begin
242-
match name with
243-
Ast.NAME_base (Ast.BASE_ident ident) ->
244-
let slot =
245-
{ Ast.slot_mode = Ast.MODE_local;
246-
Ast.slot_ty = None }
247-
in
248-
Ast.PAT_slot
249-
((span ps apos bpos slot), ident)
250-
|_ -> raise (unexpected ps)
251-
end
252-
else
253-
let lv = name_to_lval apos bpos name in
254-
Ast.PAT_tag (lv, paren_comma_list parse_pat ps)
255-
256-
| LIT_INT _
257-
| LIT_UINT _
258-
| LIT_CHAR _
259-
| LIT_BOOL _ ->
260-
Ast.PAT_lit (Pexp.parse_lit ps)
261-
262-
| UNDERSCORE -> bump ps; Ast.PAT_wild
263-
264-
| tok -> raise (Parse_err (ps,
265-
"Expected pattern but found '" ^
266-
(string_of_tok tok) ^ "'"))
267-
in
268-
let rec parse_arms ps =
269-
match peek ps with
270-
CASE ->
271-
bump ps;
272-
let pat = bracketed LPAREN RPAREN parse_pat ps in
273-
let block = parse_block ps in
274-
let arm = (pat, block) in
275-
(span ps apos (lexpos ps) arm)::(parse_arms ps)
276-
| _ -> []
277-
in
278-
let parse_alt_block ps =
279-
let arms = ctxt "alt tag arms" parse_arms ps in
280-
spans ps stmts apos begin
281-
Ast.STMT_alt_tag {
282-
Ast.alt_tag_lval = lval;
283-
Ast.alt_tag_arms = Array.of_list arms
284-
}
285-
end
286-
in
287-
bracketed LBRACE RBRACE parse_alt_block ps
288-
| _ -> [| |]
289-
end
290-
230+
IDENT _ ->
231+
let apos = lexpos ps in
232+
let name = Pexp.parse_name ps in
233+
let bpos = lexpos ps in
234+
235+
if peek ps != LPAREN then
236+
begin
237+
match name with
238+
Ast.NAME_base (Ast.BASE_ident ident) ->
239+
let slot =
240+
{ Ast.slot_mode = Ast.MODE_local;
241+
Ast.slot_ty = None }
242+
in
243+
Left
244+
(Ast.PAT_slot ((span ps apos bpos slot),
245+
ident))
246+
|_ -> raise (unexpected ps)
247+
end
248+
else
249+
let lv = name_to_lval apos bpos name in
250+
let parse_pat ps = either_get_left (parse_pat ps) in
251+
Left
252+
(Ast.PAT_tag (lv, paren_comma_list parse_pat ps))
253+
254+
| LIT_INT _
255+
| LIT_UINT _
256+
| LIT_CHAR _
257+
| LIT_BOOL _ ->
258+
Left (Ast.PAT_lit (Pexp.parse_lit ps))
259+
260+
| UNDERSCORE -> bump ps; Left (Ast.PAT_wild)
261+
262+
| tok -> raise (Parse_err (ps,
263+
"Expected pattern but found '" ^
264+
(string_of_tok tok) ^ "'"))
265+
in
266+
let rec parse_arms ps parse_case =
267+
match peek ps with
268+
CASE ->
269+
bump ps;
270+
let case = parse_case ps in
271+
let blk = parse_block ps in
272+
let combine_and_span case =
273+
(span ps apos (lexpos ps) (case, blk)) in
274+
let is_default = either_has_right case in
275+
if is_default then
276+
let arm = combine_and_span (either_get_right case) in
277+
([], Some arm)
278+
else
279+
let rec_result = parse_arms ps parse_case in
280+
let arm = combine_and_span (either_get_left case) in
281+
(arm::(fst rec_result), (snd rec_result))
282+
| _ -> ([], None)
283+
in
284+
let parse_alt_block ps str parse_case make_stmt =
285+
let br_parse_case = bracketed LPAREN RPAREN parse_case in
286+
let arms = (ctxt (String.concat " " ["alt"; str; "arms"])
287+
(fun ps -> parse_arms ps br_parse_case) ps) in
288+
make_stmt (fst arms) (snd arms)
289+
in
290+
let which_alt = match peek ps with
291+
TYPE -> "type" | LPAREN -> "tag" | _ -> raise (unexpected ps)
292+
in
293+
let (stmts, lval) = if which_alt = "type" then bump ps;
294+
bracketed LPAREN RPAREN parse_lval ps
295+
in
296+
let make_alt_tag_stmt val_arms dflt_arm =
297+
assert (not (bool_of_option dflt_arm));
298+
spans ps stmts apos begin
299+
Ast.STMT_alt_tag {
300+
Ast.alt_tag_lval = lval;
301+
Ast.alt_tag_arms = Array.of_list val_arms;
302+
}
303+
end
304+
in
305+
let make_alt_type_stmt val_arms dflt_arm =
306+
spans ps stmts apos begin
307+
Ast.STMT_alt_type {
308+
Ast.alt_type_lval = lval;
309+
Ast.alt_type_arms = Array.of_list val_arms;
310+
Ast.alt_type_else = option_map (fun x -> snd x.node) dflt_arm;
311+
}
312+
end
313+
in
314+
let parse_slot_and_ident ps =
315+
match peek ps with
316+
UNDERSCORE -> Right ()
317+
| _ -> Left (pair_rev (Pexp.parse_slot_and_ident false ps))
318+
319+
in
320+
let parse_alt_tag_block ps =
321+
parse_alt_block ps
322+
"tag"
323+
parse_pat
324+
make_alt_tag_stmt
325+
in
326+
let parse_alt_type_block ps =
327+
parse_alt_block ps
328+
"type"
329+
parse_slot_and_ident
330+
make_alt_type_stmt
331+
in
332+
let parse_alt_block2 ps =
333+
match which_alt with
334+
"type" -> parse_alt_type_block ps
335+
| "tag" -> parse_alt_tag_block ps
336+
| _ -> assert false
337+
in
338+
bracketed LBRACE RBRACE parse_alt_block2 ps
291339
| IF ->
292340
let final_else = ref None in
293341
let rec parse_stmt_if _ =

src/boot/me/dead.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ let dead_code_visitor
7070

7171
| Ast.STMT_alt_type { Ast.alt_type_arms = arms;
7272
Ast.alt_type_else = alt_type_else } ->
73-
let arm_ids = Array.map (fun { node = (_, _, block) } ->
73+
let arm_ids = Array.map (fun { node = ((_, _), block) } ->
7474
block.id) arms in
7575
let else_ids =
7676
begin

src/boot/util/common.ml

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
* types shared across all phases of the compiler.
44
*)
55

6+
type ('a, 'b) either = Left of 'a | Right of 'b
7+
68
type filename = string
79
type pos = (filename * int * int)
810
type span = {lo: pos; hi: pos}
@@ -343,6 +345,11 @@ let rec list_drop n ls =
343345
;;
344346

345347

348+
(*
349+
* Auxiliary pair functions.
350+
*)
351+
let pair_rev (x,y) = (y,x)
352+
346353
(*
347354
* Auxiliary option functions.
348355
*)
@@ -357,11 +364,35 @@ let may f x =
357364
Some x' -> f x'
358365
| None -> ()
359366

367+
let option_map f x =
368+
match x with
369+
Some x' -> Some (f x')
370+
| None -> None
371+
360372
let option_get x =
361373
match x with
362374
Some x -> x
363375
| None -> raise Not_found
364376

377+
(*
378+
* Auxiliary either functions.
379+
*)
380+
let either_has_left x =
381+
match x with
382+
Left _ -> true
383+
| Right _ -> false
384+
385+
let either_has_right x = not (either_has_left x)
386+
387+
let either_get_left x =
388+
match x with
389+
Left x -> x
390+
| Right _ -> raise Not_found
391+
392+
let either_get_right x =
393+
match x with
394+
Right x -> x
395+
| Left _ -> raise Not_found
365396
(*
366397
* Auxiliary stack functions.
367398
*)

src/test/compile-fail/bad-alt.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// error-pattern: Unexpected token 'x'
2+
3+
fn main() {
4+
let int x = 5;
5+
alt x;
6+
}

src/test/run-pass/alt-type-simple.rs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
fn altsimple(any x) {
2+
alt type (f) {
3+
case (int i) { print("int"); }
4+
case (str s) { print("str"); }
5+
}
6+
}
7+
8+
fn main() {
9+
altsimple(5);
10+
altsimple("asdfasdfsDF");
11+
}

0 commit comments

Comments
 (0)