Modified parser to handle alt type andadded a few tests
ast.ml - modified arm types for easier polymorphism - fixed a bug in fmt_type_arm dead.ml - modified arm types for easier polymorphism common.ml - added 'either' - added some useful auxiliary functions item.ml - modified arm code to be more polymorphic and handle both alt-tag and alt-type, also fixed the problematic case in bad-alt.rs Makefile - added XFAIL for new alt-type test bad-alt.rs - added test for invalid alt syntax alt-type-simple.rs - added simple test for alt type
This commit is contained in:
parent
4467d7683d
commit
0830b5bf24
7 changed files with 166 additions and 66 deletions
|
@ -362,6 +362,7 @@ self: $(CFG_COMPILER)
|
||||||
# of inter-task shutdown races introduced with notification proxies.
|
# of inter-task shutdown races introduced with notification proxies.
|
||||||
|
|
||||||
TASK_XFAILS := test/run-pass/acyclic-unwind.rs \
|
TASK_XFAILS := test/run-pass/acyclic-unwind.rs \
|
||||||
|
test/run-pass/alt-type-simple.rs \
|
||||||
test/run-pass/basic.rs \
|
test/run-pass/basic.rs \
|
||||||
test/run-pass/clone-with-exterior.rs \
|
test/run-pass/clone-with-exterior.rs \
|
||||||
test/run-pass/comm.rs \
|
test/run-pass/comm.rs \
|
||||||
|
|
|
@ -322,7 +322,7 @@ and pat =
|
||||||
and tag_arm' = pat * block
|
and tag_arm' = pat * block
|
||||||
and tag_arm = tag_arm' identified
|
and tag_arm = tag_arm' identified
|
||||||
|
|
||||||
and type_arm' = ident * slot * block
|
and type_arm' = (ident * slot) * block
|
||||||
and type_arm = type_arm' identified
|
and type_arm = type_arm' identified
|
||||||
|
|
||||||
and port_arm' = port_case * block
|
and port_arm' = port_case * block
|
||||||
|
@ -1305,8 +1305,11 @@ and fmt_tag_arm (ff:Format.formatter) (tag_arm:tag_arm) : unit =
|
||||||
fmt_arm ff (fun ff -> fmt_pat ff pat) block;
|
fmt_arm ff (fun ff -> fmt_pat ff pat) block;
|
||||||
|
|
||||||
and fmt_type_arm (ff:Format.formatter) (type_arm:type_arm) : unit =
|
and fmt_type_arm (ff:Format.formatter) (type_arm:type_arm) : unit =
|
||||||
let (_, slot, block) = type_arm.node in
|
let ((ident, slot), block) = type_arm.node in
|
||||||
fmt_arm ff (fun ff -> fmt_slot ff slot) block;
|
let fmt_type_arm_case (ff:Format.formatter) =
|
||||||
|
fmt_slot ff slot; fmt ff " "; fmt_ident ff ident
|
||||||
|
in
|
||||||
|
fmt_arm ff fmt_type_arm_case block;
|
||||||
|
|
||||||
and fmt_port_arm (ff:Format.formatter) (port_arm:port_arm) : unit =
|
and fmt_port_arm (ff:Format.formatter) (port_arm:port_arm) : unit =
|
||||||
let (port_case, block) = port_arm.node in
|
let (port_case, block) = port_arm.node in
|
||||||
|
|
|
@ -225,69 +225,117 @@ and parse_stmts (ps:pstate) : Ast.stmt array =
|
||||||
|
|
||||||
| ALT ->
|
| ALT ->
|
||||||
bump ps;
|
bump ps;
|
||||||
begin
|
let rec parse_pat ps =
|
||||||
match peek ps with
|
match peek ps with
|
||||||
TYPE -> [| |]
|
IDENT _ ->
|
||||||
| LPAREN ->
|
let apos = lexpos ps in
|
||||||
let (stmts, lval) = bracketed LPAREN RPAREN parse_lval ps in
|
let name = Pexp.parse_name ps in
|
||||||
let rec parse_pat ps =
|
let bpos = lexpos ps in
|
||||||
match peek ps with
|
|
||||||
IDENT _ ->
|
if peek ps != LPAREN then
|
||||||
let apos = lexpos ps in
|
begin
|
||||||
let name = Pexp.parse_name ps in
|
match name with
|
||||||
let bpos = lexpos ps in
|
Ast.NAME_base (Ast.BASE_ident ident) ->
|
||||||
|
let slot =
|
||||||
if peek ps != LPAREN then
|
{ Ast.slot_mode = Ast.MODE_local;
|
||||||
begin
|
Ast.slot_ty = None }
|
||||||
match name with
|
in
|
||||||
Ast.NAME_base (Ast.BASE_ident ident) ->
|
Left
|
||||||
let slot =
|
(Ast.PAT_slot ((span ps apos bpos slot),
|
||||||
{ Ast.slot_mode = Ast.MODE_local;
|
ident))
|
||||||
Ast.slot_ty = None }
|
|_ -> raise (unexpected ps)
|
||||||
in
|
end
|
||||||
Ast.PAT_slot
|
else
|
||||||
((span ps apos bpos slot), ident)
|
let lv = name_to_lval apos bpos name in
|
||||||
|_ -> raise (unexpected ps)
|
let parse_pat ps = either_get_left (parse_pat ps) in
|
||||||
end
|
Left
|
||||||
else
|
(Ast.PAT_tag (lv, paren_comma_list parse_pat ps))
|
||||||
let lv = name_to_lval apos bpos name in
|
|
||||||
Ast.PAT_tag (lv, paren_comma_list parse_pat ps)
|
| LIT_INT _
|
||||||
|
| LIT_UINT _
|
||||||
| LIT_INT _
|
| LIT_CHAR _
|
||||||
| LIT_UINT _
|
| LIT_BOOL _ ->
|
||||||
| LIT_CHAR _
|
Left (Ast.PAT_lit (Pexp.parse_lit ps))
|
||||||
| LIT_BOOL _ ->
|
|
||||||
Ast.PAT_lit (Pexp.parse_lit ps)
|
| UNDERSCORE -> bump ps; Left (Ast.PAT_wild)
|
||||||
|
|
||||||
| UNDERSCORE -> bump ps; Ast.PAT_wild
|
| tok -> raise (Parse_err (ps,
|
||||||
|
"Expected pattern but found '" ^
|
||||||
| tok -> raise (Parse_err (ps,
|
(string_of_tok tok) ^ "'"))
|
||||||
"Expected pattern but found '" ^
|
in
|
||||||
(string_of_tok tok) ^ "'"))
|
let rec parse_arms ps parse_case =
|
||||||
in
|
match peek ps with
|
||||||
let rec parse_arms ps =
|
CASE ->
|
||||||
match peek ps with
|
bump ps;
|
||||||
CASE ->
|
let case = parse_case ps in
|
||||||
bump ps;
|
let blk = parse_block ps in
|
||||||
let pat = bracketed LPAREN RPAREN parse_pat ps in
|
let combine_and_span case =
|
||||||
let block = parse_block ps in
|
(span ps apos (lexpos ps) (case, blk)) in
|
||||||
let arm = (pat, block) in
|
let is_default = either_has_right case in
|
||||||
(span ps apos (lexpos ps) arm)::(parse_arms ps)
|
if is_default then
|
||||||
| _ -> []
|
let arm = combine_and_span (either_get_right case) in
|
||||||
in
|
([], Some arm)
|
||||||
let parse_alt_block ps =
|
else
|
||||||
let arms = ctxt "alt tag arms" parse_arms ps in
|
let rec_result = parse_arms ps parse_case in
|
||||||
spans ps stmts apos begin
|
let arm = combine_and_span (either_get_left case) in
|
||||||
Ast.STMT_alt_tag {
|
(arm::(fst rec_result), (snd rec_result))
|
||||||
Ast.alt_tag_lval = lval;
|
| _ -> ([], None)
|
||||||
Ast.alt_tag_arms = Array.of_list arms
|
in
|
||||||
}
|
let parse_alt_block ps str parse_case make_stmt =
|
||||||
end
|
let br_parse_case = bracketed LPAREN RPAREN parse_case in
|
||||||
in
|
let arms = (ctxt (String.concat " " ["alt"; str; "arms"])
|
||||||
bracketed LBRACE RBRACE parse_alt_block ps
|
(fun ps -> parse_arms ps br_parse_case) ps) in
|
||||||
| _ -> [| |]
|
make_stmt (fst arms) (snd arms)
|
||||||
end
|
in
|
||||||
|
let which_alt = match peek ps with
|
||||||
|
TYPE -> "type" | LPAREN -> "tag" | _ -> raise (unexpected ps)
|
||||||
|
in
|
||||||
|
let (stmts, lval) = if which_alt = "type" then bump ps;
|
||||||
|
bracketed LPAREN RPAREN parse_lval ps
|
||||||
|
in
|
||||||
|
let make_alt_tag_stmt val_arms dflt_arm =
|
||||||
|
assert (not (bool_of_option dflt_arm));
|
||||||
|
spans ps stmts apos begin
|
||||||
|
Ast.STMT_alt_tag {
|
||||||
|
Ast.alt_tag_lval = lval;
|
||||||
|
Ast.alt_tag_arms = Array.of_list val_arms;
|
||||||
|
}
|
||||||
|
end
|
||||||
|
in
|
||||||
|
let make_alt_type_stmt val_arms dflt_arm =
|
||||||
|
spans ps stmts apos begin
|
||||||
|
Ast.STMT_alt_type {
|
||||||
|
Ast.alt_type_lval = lval;
|
||||||
|
Ast.alt_type_arms = Array.of_list val_arms;
|
||||||
|
Ast.alt_type_else = option_map (fun x -> snd x.node) dflt_arm;
|
||||||
|
}
|
||||||
|
end
|
||||||
|
in
|
||||||
|
let parse_slot_and_ident ps =
|
||||||
|
match peek ps with
|
||||||
|
UNDERSCORE -> Right ()
|
||||||
|
| _ -> Left (pair_rev (Pexp.parse_slot_and_ident false ps))
|
||||||
|
|
||||||
|
in
|
||||||
|
let parse_alt_tag_block ps =
|
||||||
|
parse_alt_block ps
|
||||||
|
"tag"
|
||||||
|
parse_pat
|
||||||
|
make_alt_tag_stmt
|
||||||
|
in
|
||||||
|
let parse_alt_type_block ps =
|
||||||
|
parse_alt_block ps
|
||||||
|
"type"
|
||||||
|
parse_slot_and_ident
|
||||||
|
make_alt_type_stmt
|
||||||
|
in
|
||||||
|
let parse_alt_block2 ps =
|
||||||
|
match which_alt with
|
||||||
|
"type" -> parse_alt_type_block ps
|
||||||
|
| "tag" -> parse_alt_tag_block ps
|
||||||
|
| _ -> assert false
|
||||||
|
in
|
||||||
|
bracketed LBRACE RBRACE parse_alt_block2 ps
|
||||||
| IF ->
|
| IF ->
|
||||||
let final_else = ref None in
|
let final_else = ref None in
|
||||||
let rec parse_stmt_if _ =
|
let rec parse_stmt_if _ =
|
||||||
|
|
|
@ -70,7 +70,7 @@ let dead_code_visitor
|
||||||
|
|
||||||
| Ast.STMT_alt_type { Ast.alt_type_arms = arms;
|
| Ast.STMT_alt_type { Ast.alt_type_arms = arms;
|
||||||
Ast.alt_type_else = alt_type_else } ->
|
Ast.alt_type_else = alt_type_else } ->
|
||||||
let arm_ids = Array.map (fun { node = (_, _, block) } ->
|
let arm_ids = Array.map (fun { node = ((_, _), block) } ->
|
||||||
block.id) arms in
|
block.id) arms in
|
||||||
let else_ids =
|
let else_ids =
|
||||||
begin
|
begin
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
* types shared across all phases of the compiler.
|
* types shared across all phases of the compiler.
|
||||||
*)
|
*)
|
||||||
|
|
||||||
|
type ('a, 'b) either = Left of 'a | Right of 'b
|
||||||
|
|
||||||
type filename = string
|
type filename = string
|
||||||
type pos = (filename * int * int)
|
type pos = (filename * int * int)
|
||||||
type span = {lo: pos; hi: pos}
|
type span = {lo: pos; hi: pos}
|
||||||
|
@ -343,6 +345,11 @@ let rec list_drop n ls =
|
||||||
;;
|
;;
|
||||||
|
|
||||||
|
|
||||||
|
(*
|
||||||
|
* Auxiliary pair functions.
|
||||||
|
*)
|
||||||
|
let pair_rev (x,y) = (y,x)
|
||||||
|
|
||||||
(*
|
(*
|
||||||
* Auxiliary option functions.
|
* Auxiliary option functions.
|
||||||
*)
|
*)
|
||||||
|
@ -357,11 +364,35 @@ let may f x =
|
||||||
Some x' -> f x'
|
Some x' -> f x'
|
||||||
| None -> ()
|
| None -> ()
|
||||||
|
|
||||||
|
let option_map f x =
|
||||||
|
match x with
|
||||||
|
Some x' -> Some (f x')
|
||||||
|
| None -> None
|
||||||
|
|
||||||
let option_get x =
|
let option_get x =
|
||||||
match x with
|
match x with
|
||||||
Some x -> x
|
Some x -> x
|
||||||
| None -> raise Not_found
|
| None -> raise Not_found
|
||||||
|
|
||||||
|
(*
|
||||||
|
* Auxiliary either functions.
|
||||||
|
*)
|
||||||
|
let either_has_left x =
|
||||||
|
match x with
|
||||||
|
Left _ -> true
|
||||||
|
| Right _ -> false
|
||||||
|
|
||||||
|
let either_has_right x = not (either_has_left x)
|
||||||
|
|
||||||
|
let either_get_left x =
|
||||||
|
match x with
|
||||||
|
Left x -> x
|
||||||
|
| Right _ -> raise Not_found
|
||||||
|
|
||||||
|
let either_get_right x =
|
||||||
|
match x with
|
||||||
|
Right x -> x
|
||||||
|
| Left _ -> raise Not_found
|
||||||
(*
|
(*
|
||||||
* Auxiliary stack functions.
|
* Auxiliary stack functions.
|
||||||
*)
|
*)
|
||||||
|
|
6
src/test/compile-fail/bad-alt.rs
Normal file
6
src/test/compile-fail/bad-alt.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
// error-pattern: Unexpected token 'x'
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
let int x = 5;
|
||||||
|
alt x;
|
||||||
|
}
|
11
src/test/run-pass/alt-type-simple.rs
Normal file
11
src/test/run-pass/alt-type-simple.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
fn altsimple(any x) {
|
||||||
|
alt type (f) {
|
||||||
|
case (int i) { print("int"); }
|
||||||
|
case (str s) { print("str"); }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
altsimple(5);
|
||||||
|
altsimple("asdfasdfsDF");
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue