Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal 869: pattern-matching syntax #908

Merged
merged 53 commits into from
Sep 4, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
bc50823
Using buffer in SQL query building
Emanon42 May 27, 2020
93f50ed
unique bufferize query building
Emanon42 Jun 3, 2020
ebd092a
fix sprintf and intermediate string building
Emanon42 Jun 3, 2020
a7adb2c
better higher-order buf_mapstrcat
Emanon42 Jun 5, 2020
c5e90d2
add wrappers
Emanon42 Jun 8, 2020
665b9ee
fix wrong side-effect execute order
Emanon42 Jun 8, 2020
3e6a25f
sweep the code
Emanon42 Jun 8, 2020
89bcdae
trim the trailing whitespace
Emanon42 Jun 8, 2020
6a6aa27
Fix #154 by raising runtime error
Emanon42 Jun 19, 2020
01a3b4f
move to Format module
Emanon42 Jul 2, 2020
709d7a6
improve fprintf structure
Emanon42 Jul 3, 2020
9fcaf34
use asprintf in tables
Emanon42 Jul 3, 2020
749d22e
merge upstream
Emanon42 Jul 3, 2020
6ddfbe8
fix quote
Emanon42 Jul 3, 2020
c5619c4
resolve conflict in webif
Emanon42 Jul 3, 2020
80fc6b1
remove old bufconcat
Emanon42 Jul 3, 2020
e86649e
trim space
Emanon42 Jul 3, 2020
f4e1019
many fine-grained fix
Emanon42 Jul 5, 2020
3594cd1
many fine-grained fix
Emanon42 Jul 5, 2020
5eb6b12
improve by james advice
Emanon42 Jul 7, 2020
f9780db
sweep the code
Emanon42 Jul 7, 2020
4e7881e
add delete where unit test
Emanon42 Jul 7, 2020
719ac5f
add pattern matching sugared node
Emanon42 Jul 14, 2020
47cdf67
add some traversal
Emanon42 Jul 20, 2020
cca27e8
fix type
Emanon42 Jul 24, 2020
90fd8f5
add sugar to parser
Emanon42 Jul 25, 2020
be36d66
fix BRACE
Emanon42 Jul 25, 2020
65839f7
fix pattern
Emanon42 Jul 25, 2020
7318fae
add transformation to normalfunlit
Emanon42 Aug 3, 2020
388fdf1
add non-exhaustive case and test
Emanon42 Aug 4, 2020
2071b57
merge upstream
Emanon42 Aug 4, 2020
ff47876
trim space
Emanon42 Aug 4, 2020
3043dd1
trim space
Emanon42 Aug 4, 2020
d1fe1ba
resolve Simon's review
Emanon42 Aug 4, 2020
6703c89
trim space
Emanon42 Aug 4, 2020
e802471
fix transformsugar
Emanon42 Aug 4, 2020
49f0122
fix test cases
Emanon42 Aug 4, 2020
e866a9f
change keyword to switch and remove redundant productions
Emanon42 Aug 13, 2020
7e12319
fix parser
Emanon42 Aug 13, 2020
b9ba88d
add flag and fix tests
Emanon42 Aug 24, 2020
2b6cc31
Merge remote-tracking branch 'upstream/master' into proposal-869
Emanon42 Aug 24, 2020
a2dbf5b
fix test
Emanon42 Aug 24, 2020
6b678ea
resolve daniel's review
Emanon42 Aug 25, 2020
f56256c
rename and fix nullary guard
Emanon42 Aug 26, 2020
6310d72
change switch function arg structure
Emanon42 Aug 26, 2020
873eebd
renaming pass and error
Emanon42 Aug 27, 2020
685d429
move currying guard to desugar pass
Emanon42 Aug 28, 2020
75895f9
make get_normal_funlit utility func
Emanon42 Aug 29, 2020
cc1d2e3
resolve simon's second review
Emanon42 Aug 31, 2020
85c68c3
fix last get_normal_fnlit
Emanon42 Aug 31, 2020
7f161bd
fix phrasenode desugaring
Emanon42 Sep 2, 2020
d2ff01f
space nitpick
Emanon42 Sep 2, 2020
e816b0f
fix error msg
Emanon42 Sep 2, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions core/desugarMatching.ml
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ open SourceCode

This transformation convert function like that:

fun foo(a1, ..., an) match {
| case (p1_1, ..., p1_n) -> b_1
| ...
| case (pm_1, pm_n) -> b_m
fun foo(a1, ..., an) switch {
case (p1_1, ..., p1_n) -> b_1
...
case (pm_1, pm_n) -> b_m
}

to function with switch body like that:
Expand Down Expand Up @@ -43,12 +43,12 @@ let pattern_matching_sugar_guard pos =
if not (Settings.get pattern_matching_sugar)
then raise (pattern_matching_sugar_disabled pos)

let nullary_guard tuple pos =
let nullary_guard pss pos =
let nullary_error pos =
Errors.desugaring_error ~pos:pos ~stage:Errors.DesugarMatching ~message:"Can't match over nullary function"
in
match tuple with
| [] -> raise (nullary_error pos)
match pss with
| [[]] -> raise (nullary_error pos)
| _ -> ()
Emanon42 marked this conversation as resolved.
Show resolved Hide resolved

let desugar_matching =
Expand All @@ -57,12 +57,12 @@ object ((self : 'self_type))
method! binding = fun b ->
let pos = WithPos.pos b in
match WithPos.node b with
| Fun ({ fun_definition = (tvs, MatchFunlit (patterns, cases)); _ } as fn) ->
| Fun ({ fun_definition = (tvs, SwitchFunlit (patterns, cases)); _ } as fn) ->
pattern_matching_sugar_guard pos;
nullary_guard patterns pos;
(* bind the arguments with unique var name *)
let name_list = List.map (fun pats -> List.map (fun pat -> (pat, Utility.gensym())) pats) patterns in
let switch_tuple = List.map (fun (_, name) -> with_pos (Var name)) (List.flatten name_list) in
nullary_guard switch_tuple pos;
(* assemble exhaustive handler *)
let exhaustive_patterns = with_pos (Pattern.Any) in
let exhaustive_position = Format.sprintf "non-exhaustive pattern matching at %s" (SourceCode.Position.show pos) in
Expand Down
2 changes: 1 addition & 1 deletion core/lens_sugar_conv.ml
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,6 @@ let lens_sugar_phrase_of_sugar p =
| _ ->
Format.asprintf "Unsupported binder: %a" S.pp_phrase p
|> Error.internal_error_res )
| S.FunLit (_, _, Sugartypes.MatchFunlit (_, _), _) -> assert false
| S.FunLit (_, _, Sugartypes.SwitchFunlit (_, _), _) -> assert false
| _ -> lens_sugar_phrase_of_body "" p )
|> Result.ok_exn
16 changes: 8 additions & 8 deletions core/parser.mly
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ fun_declarations:
fun_declaration:
| tlfunbinding { fun_binding ~ppos:$loc($1) None $1 }
| signatures tlfunbinding { fun_binding ~ppos:$loc($2) (fst $1) ~unsafe_sig:(snd $1) $2 }
| match_tlfunbinding { match_fun_binding ~ppos:$loc($1) None $1 }
| signatures match_tlfunbinding { match_fun_binding ~ppos:$loc($2) (fst $1) ~unsafe_sig:(snd $1) $2 }
| switch_tlfunbinding { switch_fun_binding ~ppos:$loc($1) None $1 }
| signatures switch_tlfunbinding { switch_fun_binding ~ppos:$loc($2) (fst $1) ~unsafe_sig:(snd $1) $2 }

Emanon42 marked this conversation as resolved.
Show resolved Hide resolved
linearity:
| FUN { dl_unl }
Expand All @@ -445,10 +445,10 @@ tlfunbinding:
| OP OPERATOR pattern perhaps_location block { ((dl_unl, false), $2, [[$3]], $4, $5) }
| OP pattern OPERATOR perhaps_location block { ((dl_unl, false), $3, [[$2]], $4, $5) }

match_tlfunbinding:
| fun_kind VARIABLE arg_lists perhaps_location match_body { ($1, $2, $3, $4, $5) }
switch_tlfunbinding:
| fun_kind VARIABLE arg_lists perhaps_location switch_body { ($1, $2, $3, $4, $5) }

match_body:
switch_body:
Emanon42 marked this conversation as resolved.
Show resolved Hide resolved
| SWITCH LBRACE case+ RBRACE { $3 }

tlvarbinding:
Expand Down Expand Up @@ -555,7 +555,7 @@ primary_expression:
| LBRACKET exp DOTDOT exp RBRACKET { with_pos $loc (RangeLit($2, $4)) }
| xml { $1 }
| linearity arg_lists block { fun_lit ~ppos:$loc $1 $2 $3 }
| linearity arg_lists match_body { match_fun_lit ~ppos:$loc $1 $2 $3 }
| linearity arg_lists switch_body { switch_fun_lit ~ppos:$loc $1 $2 $3 }
| LEFTTRIANGLE cp_expression RIGHTTRIANGLE { with_pos $loc (CP $2) }
| DOLLAR primary_expression { with_pos $loc (Generalise $2) }

Expand Down Expand Up @@ -838,8 +838,8 @@ binding:
| exp SEMICOLON { with_pos $loc (Exp $1) }
| signatures fun_kind VARIABLE arg_lists block { fun_binding ~ppos:$loc (fst $1) ~unsafe_sig:(snd $1) ($2, $3, $4, loc_unknown, $5) }
| fun_kind VARIABLE arg_lists block { fun_binding ~ppos:$loc None ($1, $2, $3, loc_unknown, $4) }
| signatures fun_kind VARIABLE arg_lists match_body { match_fun_binding ~ppos:$loc (fst $1) ~unsafe_sig:(snd $1) ($2, $3, $4, loc_unknown, $5) }
| fun_kind VARIABLE arg_lists match_body { match_fun_binding ~ppos:$loc None ($1, $2, $3, loc_unknown, $4) }
| signatures fun_kind VARIABLE arg_lists switch_body { switch_fun_binding ~ppos:$loc (fst $1) ~unsafe_sig:(snd $1) ($2, $3, $4, loc_unknown, $5) }
| fun_kind VARIABLE arg_lists switch_body { switch_fun_binding ~ppos:$loc None ($1, $2, $3, loc_unknown, $4) }
| typedecl SEMICOLON | links_module
| links_open SEMICOLON { $1 }

Expand Down
8 changes: 4 additions & 4 deletions core/sugarConstructors.ml
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ module SugarConstructors (Position : Pos)
let fun_lit ?(ppos=dp) ?args ?(location=loc_unknown) linearity pats blk =
with_pos ppos (FunLit (args, linearity, NormalFunlit (pats, blk), location))

let match_fun_lit ?(ppos=dp) ?args ?(location=loc_unknown) linearity pats match_body =
with_pos ppos (FunLit (args, linearity, MatchFunlit (pats, match_body), location))
let switch_fun_lit ?(ppos=dp) ?args ?(location=loc_unknown) linearity pats switch_funlit_body =
with_pos ppos (FunLit (args, linearity, SwitchFunlit (pats, switch_funlit_body), location))

(* Create a Spawn. *)
let spawn ?(ppos=dp) ?row spawn_kind location blk =
Expand Down Expand Up @@ -175,11 +175,11 @@ module SugarConstructors (Position : Pos)
fun_frozen = false;
fun_unsafe_signature = false })

let match_fun_binding ?(ppos=dp) sig_opt ?(unsafe_sig=false) ((linearity, frozen), bndr, args, location, blk) =
let switch_fun_binding ?(ppos=dp) sig_opt ?(unsafe_sig=false) ((linearity, frozen), bndr, args, location, blk) =
let fun_signature = datatype_opt_of_sig_opt sig_opt bndr in
with_pos ppos (Fun { fun_binder = binder bndr;
fun_linearity = linearity;
fun_definition = ([], MatchFunlit (args, blk));
fun_definition = ([], SwitchFunlit (args, blk));
fun_location = location;
fun_signature;
fun_frozen = frozen;
Expand Down
8 changes: 4 additions & 4 deletions core/sugarConstructorsIntf.ml
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,10 @@ module type SugarConstructorsSig = sig
-> ?location:Location.t -> DeclaredLinearity.t
-> Pattern.with_pos list list -> phrase
-> phrase
val match_fun_lit
val switch_fun_lit
: ?ppos:t -> ?args:((Types.datatype * Types.row) list)
-> ?location:Location.t -> DeclaredLinearity.t
-> Pattern.with_pos list list -> match_body
-> Pattern.with_pos list list -> switch_funlit_body
-> phrase
val spawn
: ?ppos:t
Expand All @@ -119,9 +119,9 @@ module type SugarConstructorsSig = sig
-> ?location:Location.t -> ?annotation:datatype'
-> Binder.with_pos -> funlit
-> binding
val match_fun_binding
val switch_fun_binding
: ?ppos:t -> signature -> ?unsafe_sig:bool
-> ((DeclaredLinearity.t * bool) * Name.t * Pattern.with_pos list list * Location.t * match_body)
-> ((DeclaredLinearity.t * bool) * Name.t * Pattern.with_pos list list * Location.t * switch_funlit_body)
-> binding
val val_binding'
: ?ppos:t -> signature -> (name_or_pat * phrase * Location.t)
Expand Down
10 changes: 5 additions & 5 deletions core/sugarTraversals.ml
Original file line number Diff line number Diff line change
Expand Up @@ -564,9 +564,9 @@ class map =
| NormalFunlit (_x, _x_i1) ->
let _x = o#list (fun o -> o#list (fun o -> o#pattern)) _x in
let _x_i1 = o#phrase _x_i1 in NormalFunlit (_x, _x_i1)
| MatchFunlit (pat, body) ->
| SwitchFunlit (pat, body) ->
let pat = o#list (fun o -> o#list (fun o -> o#pattern)) pat in
let body = o#list (fun o (p, c) -> let p = o#pattern p in let c = o#phrase c in (p, c)) body in MatchFunlit (pat, body)
let body = o#list (fun o (p, c) -> let p = o#pattern p in let c = o#phrase c in (p, c)) body in SwitchFunlit (pat, body)

method handle_params : handler_parameterisation -> handler_parameterisation =
fun { shp_bindings; shp_types }->
Expand Down Expand Up @@ -1297,7 +1297,7 @@ class fold =
| NormalFunlit (_x, _x_i1) ->
let o = o#list (fun o -> o#list (fun o -> o#pattern)) _x in
let o = o#phrase _x_i1 in o
| MatchFunlit (pat, body) ->
| SwitchFunlit (pat, body) ->
let o = o#list (fun o -> o#list (fun o -> o#pattern)) pat in
let o = o#list (fun o (p, c) -> let o = o#pattern p in let o = o#phrase c in o) body in o

Expand Down Expand Up @@ -2131,9 +2131,9 @@ class fold_map =
| NormalFunlit (_x, _x_i1) ->
let (o, _x) = o#list (fun o -> o#list (fun o -> o#pattern)) _x in
let (o, _x_i1) = o#phrase _x_i1 in (o, NormalFunlit (_x, _x_i1))
| MatchFunlit (pat, body) ->
| SwitchFunlit (pat, body) ->
let (o, pat) = o#list (fun o -> o#list (fun o -> o#pattern)) pat in
let (o, body) = o#list (fun o (p, c) -> let (o, p) = o#pattern p in let (o, c) = o#phrase c in (o, (p, c))) body in (o, MatchFunlit (pat, body))
let (o, body) = o#list (fun o (p, c) -> let (o, p) = o#pattern p in let (o, c) = o#phrase c in (o, (p, c))) body in (o, SwitchFunlit (pat, body))

method handle_params : handler_parameterisation -> ('self_type * handler_parameterisation) =
fun { shp_bindings; shp_types } ->
Expand Down
14 changes: 7 additions & 7 deletions core/sugartypes.ml
Original file line number Diff line number Diff line change
Expand Up @@ -369,9 +369,9 @@ and regex =
| Splice of phrase
| Replace of regex * replace_rhs
and clause = Pattern.with_pos * phrase
and funlit = NormalFunlit of normal_funlit | MatchFunlit of match_funlit
and match_funlit = Pattern.with_pos list list * match_body
and match_body = (Pattern.with_pos * phrase) list
and funlit = NormalFunlit of normal_funlit | SwitchFunlit of switch_funlit
and switch_funlit = Pattern.with_pos list list * switch_funlit_body
and switch_funlit_body = (Pattern.with_pos * phrase) list
and normal_funlit = Pattern.with_pos list list * phrase
and handler =
{ sh_expr : phrase
Expand Down Expand Up @@ -772,12 +772,12 @@ struct
and funlit (fn : funlit) : StringSet.t =
match fn with
| NormalFunlit n_fn -> normal_funlit n_fn
| MatchFunlit m_fn -> match_funlit m_fn
| SwitchFunlit m_fn -> switch_funlit m_fn
and normal_funlit (args, body : normal_funlit) : StringSet.t =
diff (phrase body) (union_map (union_map pattern) args)
and match_funlit (args, body : match_funlit) : StringSet.t =
diff (match_body body) (union_map (union_map pattern) args)
and match_body (body : (Pattern.with_pos * phrase) list) : StringSet.t =
and switch_funlit (args, body : switch_funlit) : StringSet.t =
diff (switch_funlit_body body) (union_map (union_map pattern) args)
and switch_funlit_body (body : (Pattern.with_pos * phrase) list) : StringSet.t =
union_map (fun (pat, phr) -> union (pattern pat) (phrase phr)) body
and block (binds, expr : binding list * phrase) : StringSet.t =
ListLabels.fold_right binds ~init:(phrase expr)
Expand Down
4 changes: 2 additions & 2 deletions core/transformSugar.ml
Original file line number Diff line number Diff line change
Expand Up @@ -738,13 +738,13 @@ class transform (env : Types.typing_environment) =
let (o, e, t) = o#phrase e in
let o = o#restore_envs envs in
(o, NormalFunlit (pss, e), t)
| MatchFunlit (pss, body) ->
| SwitchFunlit (pss, body) ->
let envs = o#backup_envs in
let (o, pss) = listu o (fun o -> listu o (fun o -> o#pattern)) pss in
let o = o#with_effects inner_eff in
let (o, body) = listu o (fun o (p, c) -> let (o, p) = o#pattern p in let (o, c, _) = o#phrase c in (o, (p, c))) body in
Emanon42 marked this conversation as resolved.
Show resolved Hide resolved
let o = o#restore_envs envs in
(o, MatchFunlit (pss, body), Types.unit_type)
(o, SwitchFunlit (pss, body), Types.unit_type)

method constant : Constant.t -> ('self_type * Constant.t * Types.datatype) =
function
Expand Down