Support unboxed tuples in patterns

pull/315/head
Torsten Schmits 2022-05-07 14:08:42 +07:00
parent f194fcb08a
commit 60bc6ef282
9 changed files with 372408 additions and 353880 deletions

@ -49,7 +49,7 @@ module.exports = grammar({
$.quasiquote_bar,
$.quasiquote_body,
$._strict,
$._unboxed_tuple_close,
$._unboxed_close,
'|',
'in',
/\n/,
@ -203,6 +203,11 @@ module.exports = grammar({
*/
[$._type_or_implicit, $._context_constraints],
/**
* `(# | | ...` can start both `pat` and `exp`.
*/
[$.pat_sum_empty, $.exp_sum_empty],
[$.exp_lambda_case],
],

@ -30,9 +30,9 @@ module.exports = {
exp_tuple: $ => parens($._exp_tuple),
exp_unboxed_tuple: $ => seq('(# ', $._exp_tuple, $._unboxed_tuple_close),
exp_unboxed_tuple: $ => seq('(# ', $._exp_tuple, $._unboxed_close),
exp_unboxed_sum: $ => seq('(# ', $._exp_sum, $._unboxed_tuple_close),
exp_unboxed_sum: $ => seq('(# ', $._exp_sum, $._unboxed_close),
exp_list: $ => brackets(sep1($.comma, $._exp)),

@ -16,7 +16,13 @@ module.exports = {
pat_tuple: $ => parens(sep2($.comma, $._nested_pat)),
pat_unboxed_tuple: $ => seq('(# ', sep1($.comma, $._nested_pat), $._unboxed_tuple_close),
pat_unboxed_tuple: $ => seq('(# ', sep($.comma, $._nested_pat), $._unboxed_close),
pat_sum_empty: _ => ' ',
_pat_sum: $ => sep2('|', choice($._nested_pat, $.pat_sum_empty)),
pat_unboxed_sum: $ => seq('(# ', $._pat_sum, $._unboxed_close),
pat_list: $ => brackets(sep1($.comma, $._nested_pat)),
@ -47,6 +53,7 @@ module.exports = {
$.pat_parens,
$.pat_tuple,
$.pat_unboxed_tuple,
$.pat_unboxed_sum,
$.pat_list,
$.pat_strict,
$.pat_irrefutable,

@ -62,9 +62,9 @@ module.exports = {
type_star: _ => '*',
type_unboxed_tuple: $ => seq('(# ', $._type_tuple, $._unboxed_tuple_close),
type_unboxed_tuple: $ => seq('(# ', $._type_tuple, $._unboxed_close),
type_unboxed_sum: $ => seq('(# ', $._type_sum, $._unboxed_tuple_close),
type_unboxed_sum: $ => seq('(# ', $._type_sum, $._unboxed_close),
_atype: $ => choice(
$.type_name,

108
src/grammar.json vendored

@ -1810,7 +1810,7 @@
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
}
]
},
@ -1827,7 +1827,7 @@
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
}
]
},
@ -2983,7 +2983,7 @@
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
}
]
},
@ -3000,7 +3000,7 @@
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
}
]
},
@ -4966,33 +4966,105 @@
"value": "(# "
},
{
"type": "SEQ",
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_nested_pat"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "comma"
},
{
"type": "SYMBOL",
"name": "_nested_pat"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "SYMBOL",
"name": "_unboxed_close"
}
]
},
"pat_sum_empty": {
"type": "STRING",
"value": " "
},
"_pat_sum": {
"type": "SEQ",
"members": [
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_nested_pat"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"type": "SYMBOL",
"name": "pat_sum_empty"
}
]
},
{
"type": "REPEAT1",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "|"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "comma"
"name": "_nested_pat"
},
{
"type": "SYMBOL",
"name": "_nested_pat"
"name": "pat_sum_empty"
}
]
}
}
]
]
}
}
]
},
"pat_unboxed_sum": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "(# "
},
{
"type": "SYMBOL",
"name": "_pat_sum"
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
}
]
},
@ -5155,6 +5227,10 @@
"type": "SYMBOL",
"name": "pat_unboxed_tuple"
},
{
"type": "SYMBOL",
"name": "pat_unboxed_sum"
},
{
"type": "SYMBOL",
"name": "pat_list"
@ -9072,6 +9148,10 @@
"_type_or_implicit",
"_context_constraints"
],
[
"pat_sum_empty",
"exp_sum_empty"
],
[
"exp_lambda_case"
]
@ -9175,7 +9255,7 @@
},
{
"type": "SYMBOL",
"name": "_unboxed_tuple_close"
"name": "_unboxed_close"
},
{
"type": "STRING",

203
src/node-types.json vendored

@ -378,6 +378,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -737,6 +741,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -2204,6 +2212,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -2390,6 +2402,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -2603,6 +2619,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -4977,6 +4997,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -6185,6 +6209,11 @@
]
}
},
{
"type": "exp_sum_empty",
"named": true,
"fields": {}
},
{
"type": "exp_th_quoted_name",
"named": true,
@ -7486,6 +7515,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -8886,6 +8919,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -8966,6 +9003,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -9681,6 +9722,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -9744,6 +9789,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -9838,6 +9887,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -9960,6 +10013,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10031,6 +10088,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10114,6 +10175,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10290,6 +10355,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10383,6 +10452,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10402,6 +10475,11 @@
]
}
},
{
"type": "pat_sum_empty",
"named": true,
"fields": {}
},
{
"type": "pat_tuple",
"named": true,
@ -10466,6 +10544,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10545,6 +10627,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10640,12 +10726,103 @@
}
},
{
"type": "pat_unboxed_tuple",
"type": "pat_unboxed_sum",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": true,
"types": [
{
"type": "pat_apply",
"named": true
},
{
"type": "pat_as",
"named": true
},
{
"type": "pat_infix",
"named": true
},
{
"type": "pat_irrefutable",
"named": true
},
{
"type": "pat_list",
"named": true
},
{
"type": "pat_literal",
"named": true
},
{
"type": "pat_name",
"named": true
},
{
"type": "pat_negation",
"named": true
},
{
"type": "pat_parens",
"named": true
},
{
"type": "pat_record",
"named": true
},
{
"type": "pat_strict",
"named": true
},
{
"type": "pat_sum_empty",
"named": true
},
{
"type": "pat_tuple",
"named": true
},
{
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
},
{
"type": "pat_view",
"named": true
},
{
"type": "pat_wildcard",
"named": true
},
{
"type": "quasiquote",
"named": true
},
{
"type": "splice",
"named": true
}
]
}
},
{
"type": "pat_unboxed_tuple",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "comma",
@ -10703,6 +10880,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -10957,6 +11138,10 @@
"type": "pat_typed",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -11237,6 +11422,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -11319,6 +11508,10 @@
"type": "pat_tuple",
"named": true
},
{
"type": "pat_unboxed_sum",
"named": true
},
{
"type": "pat_unboxed_tuple",
"named": true
@ -13806,6 +13999,10 @@
]
}
},
{
"type": " ",
"named": false
},
{
"type": "%",
"named": false
@ -13966,10 +14163,6 @@
"type": "empty_file",
"named": true
},
{
"type": "exp_sum_empty",
"named": true
},
{
"type": "export",
"named": false

725922
src/parser.c vendored

File diff suppressed because it is too large Load Diff

12
src/scanner.c vendored

@ -87,7 +87,7 @@
* when the quasiquote body starts with an operator character.
* - qq_body: Prevent extras, like comments, from breaking quasiquotes
* - strict: Disambiguate strictness annotation `!` from symbolic operators
* - unboxed_tuple_close: Disambiguate the closing parens for unboxed tuples `#)` from symbolic operators
* - unboxed_close: Disambiguate the closing parens for unboxed tuples/sums `#)` from symbolic operators
* - bar: The vertical bar `|`, used for guards and list comprehension
* - in: Closes the layout of a `let` and consumes the token `in`
* - indent: Used as a dummy symbol for initialization; uses newline in the grammar to ensure the scanner is called
@ -138,7 +138,7 @@ static char *sym_names[] = {
"qq_bar",
"qq_body",
"strict",
"unboxed_tuple_close",
"unboxed_close",
"bar",
"in",
"indent",
@ -1008,12 +1008,12 @@ static Result splice(State *state) {
return res_cont;
}
static Result unboxed_tuple_close(State *state) {
static Result unboxed_close(State *state) {
if (state->symbols[UNBOXED_TUPLE_CLOSE]) {
if (PEEK == ')') {
S_ADVANCE;
MARK("unboxed_tuple_close", false, state);
return finish(UNBOXED_TUPLE_CLOSE, "unboxed_tuple_close");
MARK("unboxed_close", false, state);
return finish(UNBOXED_TUPLE_CLOSE, "unboxed_close");
}
}
return res_cont;
@ -1079,7 +1079,7 @@ static Result symop_marked(Symbolic type, State *state) {
return res_fail;
}
case S_UNBOXED_TUPLE_CLOSE:
return unboxed_tuple_close(state);
return unboxed_close(state);
default:
return res_cont;
}

@ -351,6 +351,25 @@ a (# a, a, a #) = a
(patterns (pat_unboxed_tuple (pat_name (variable)) (comma) (pat_name (variable)) (comma) (pat_name (variable))))
(exp_name (variable))))
================================================================================
pat: unboxed sum, nullary tuple
================================================================================
a (# (# #) | | #) = a
---
(haskell
(function
(variable)
(patterns
(pat_unboxed_sum
(pat_unboxed_tuple)
(pat_sum_empty)
(pat_sum_empty)))
(exp_name
(variable))))
================================================================================
pat: signature
================================================================================