-
Notifications
You must be signed in to change notification settings - Fork 43
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
Changes from 52 commits
Commits
Show all changes
53 commits
Select commit
Hold shift + click to select a range
bc50823
Using buffer in SQL query building
Emanon42 93f50ed
unique bufferize query building
Emanon42 ebd092a
fix sprintf and intermediate string building
Emanon42 a7adb2c
better higher-order buf_mapstrcat
Emanon42 c5e90d2
add wrappers
Emanon42 665b9ee
fix wrong side-effect execute order
Emanon42 3e6a25f
sweep the code
Emanon42 89bcdae
trim the trailing whitespace
Emanon42 6a6aa27
Fix #154 by raising runtime error
Emanon42 01a3b4f
move to Format module
Emanon42 709d7a6
improve fprintf structure
Emanon42 9fcaf34
use asprintf in tables
Emanon42 749d22e
merge upstream
Emanon42 6ddfbe8
fix quote
Emanon42 c5619c4
resolve conflict in webif
Emanon42 80fc6b1
remove old bufconcat
Emanon42 e86649e
trim space
Emanon42 f4e1019
many fine-grained fix
Emanon42 3594cd1
many fine-grained fix
Emanon42 5eb6b12
improve by james advice
Emanon42 f9780db
sweep the code
Emanon42 4e7881e
add delete where unit test
Emanon42 719ac5f
add pattern matching sugared node
Emanon42 47cdf67
add some traversal
Emanon42 cca27e8
fix type
Emanon42 90fd8f5
add sugar to parser
Emanon42 be36d66
fix BRACE
Emanon42 65839f7
fix pattern
Emanon42 7318fae
add transformation to normalfunlit
Emanon42 388fdf1
add non-exhaustive case and test
Emanon42 2071b57
merge upstream
Emanon42 ff47876
trim space
Emanon42 3043dd1
trim space
Emanon42 d1fe1ba
resolve Simon's review
Emanon42 6703c89
trim space
Emanon42 e802471
fix transformsugar
Emanon42 49f0122
fix test cases
Emanon42 e866a9f
change keyword to switch and remove redundant productions
Emanon42 7e12319
fix parser
Emanon42 b9ba88d
add flag and fix tests
Emanon42 2b6cc31
Merge remote-tracking branch 'upstream/master' into proposal-869
Emanon42 a2dbf5b
fix test
Emanon42 6b678ea
resolve daniel's review
Emanon42 f56256c
rename and fix nullary guard
Emanon42 6310d72
change switch function arg structure
Emanon42 873eebd
renaming pass and error
Emanon42 685d429
move currying guard to desugar pass
Emanon42 75895f9
make get_normal_funlit utility func
Emanon42 cc1d2e3
resolve simon's second review
Emanon42 85c68c3
fix last get_normal_fnlit
Emanon42 7f161bd
fix phrasenode desugaring
Emanon42 d2ff01f
space nitpick
Emanon42 e816b0f
fix error msg
Emanon42 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
open Sugartypes | ||
open Utility | ||
open SourceCode | ||
|
||
(* This module desugars pattern-matching functions | ||
|
||
This transformation convert `switch` functions of the form: | ||
|
||
fun foo(a1, ..., an) switch { | ||
case (p1_1, ..., p1_n) -> b_1 | ||
... | ||
case (pm_1, pm_n) -> b_m | ||
} | ||
|
||
to standard functions of the form: | ||
|
||
fun foo(a1 as x1, ..., an as xn) { | ||
switch ((x1, ..., xn)) { | ||
case (p1_1, ..., p1_n) -> b_1 | ||
... | ||
case (pm_1, ..., pm_n) -> b_m | ||
case (_, ..., _) -> error("non-exhaustive") | ||
} | ||
|
||
The last non-exhaustive case with wild card pattern is always attached to the end of switch body. | ||
|
||
*) | ||
|
||
let with_pos = SourceCode.WithPos.make | ||
|
||
let pattern_matching_sugar = | ||
Settings.( | ||
flag "pattern_matching_sugar" | ||
|> synopsis | ||
"Toggles whether to enable the switch pattern matching syntax sugar" | ||
|> convert parse_bool | ||
|> sync) | ||
|
||
let pattern_matching_sugar_guard pos = | ||
let pattern_matching_sugar_disabled pos = | ||
Errors.disabled_extension ~pos ~setting:("pattern_matching_sugar", true) "Pattern Matching Sugar" | ||
in | ||
if not (Settings.get pattern_matching_sugar) | ||
then raise (pattern_matching_sugar_disabled pos) | ||
|
||
let nullary_guard pss pos = | ||
let nullary_error pos = | ||
Errors.desugaring_error ~pos:pos ~stage:Errors.DesugarSwitchFuns ~message:"Can't match over nullary function" | ||
in | ||
match pss with | ||
| [] -> raise (nullary_error pos) | ||
| _ -> () | ||
|
||
let switch_fun_currying_guard pos args = | ||
match args with | ||
| [arg] -> arg | ||
| _ -> raise (Errors.Type_error (pos, "Curried switch functions are not yet supported.")) | ||
|
||
let construct_normal_funlit pos patterns cases = | ||
pattern_matching_sugar_guard pos; | ||
let patterns = switch_fun_currying_guard pos patterns in | ||
nullary_guard patterns pos; | ||
(* bind the arguments with unique var name *) | ||
let name_list = List.map (fun pat -> (pat, Utility.gensym())) patterns in | ||
let switch_tuple = List.map (fun (_, name) -> with_pos (Var name)) name_list in | ||
(* 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 | ||
let exhaustive_case = FnAppl (with_pos (Var "error"), [with_pos (Constant (CommonTypes.Constant.String exhaustive_position))]) in | ||
let normal_args = | ||
List.map | ||
(fun (pat, name) -> with_pos (Pattern.As (with_pos (Binder.make ~name ()), pat))) | ||
name_list | ||
in | ||
let cases = cases@[(exhaustive_patterns, with_pos exhaustive_case)] in | ||
let switch_body = Switch (with_pos (TupleLit switch_tuple), cases, None) in | ||
let normal_fnlit = NormalFunlit ([normal_args], with_pos switch_body) in | ||
Emanon42 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
normal_fnlit | ||
|
||
let desugar_switching = | ||
object ((self : 'self_type)) | ||
inherit SugarTraversals.map as super | ||
method! binding = fun b -> | ||
let pos = WithPos.pos b in | ||
match WithPos.node b with | ||
| Fun ({ fun_definition = (tvs, SwitchFunlit (patterns, cases)); _ } as fn) -> | ||
let normal_fnlit = construct_normal_funlit pos patterns cases in | ||
let normal_fnlit = self#funlit normal_fnlit in | ||
let node = Fun { fun_binder = fn.fun_binder; | ||
fun_linearity = fn.fun_linearity; | ||
fun_definition = (tvs, normal_fnlit); | ||
fun_location = fn.fun_location; | ||
fun_signature = fn.fun_signature; | ||
fun_unsafe_signature = fn.fun_unsafe_signature; | ||
fun_frozen = fn.fun_frozen; | ||
} in | ||
WithPos.make ~pos node | ||
| _ -> super#binding b | ||
|
||
method! phrase = fun p -> | ||
let pos = WithPos.pos p in | ||
match WithPos.node p with | ||
| FunLit (typing, linearity, SwitchFunlit (patterns, cases), loc) -> | ||
let normal_fnlit = construct_normal_funlit pos patterns cases in | ||
let normal_fnlit = self#funlit normal_fnlit in | ||
let node = FunLit (typing, linearity, normal_fnlit, loc) in | ||
WithPos.make ~pos node | ||
| _ -> super#phrase p | ||
end | ||
|
||
module Untyped | ||
= Transform.Untyped.Make.Transformer(struct | ||
let name = "desugar_switch_functions" | ||
let obj = desugar_switching | ||
end) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
val desugar_switching : SugarTraversals.map | ||
|
||
include Transform.Untyped.S |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note: This pattern/case may be redundant, though, currently we do not check for redundancy or exhaustiveness of patterns.