Skip to content
This repository was archived by the owner on Jun 1, 2022. It is now read-only.

Commit 1a91a89

Browse files
authored
[#31] Pattern matching (#32)
1 parent 32c90f7 commit 1a91a89

File tree

6 files changed

+178
-105
lines changed

6 files changed

+178
-105
lines changed

grammar.js

Lines changed: 84 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@ const PREC = Object.freeze({
1515
PREFIX: 13,
1616
EXPRESSION: 14,
1717
PARAMETER: 14,
18+
PATTERN: 14,
1819
APPLICATION: 15,
1920
PIPELINE: 16,
20-
DESTRUCTURING_PATTERN: 17
2121
});
2222

2323
module.exports = grammar({
@@ -33,7 +33,17 @@ module.exports = grammar({
3333
],
3434
extras: $ => [$.comment, /\s+/],
3535
word: $ => $._identifier_without_operators,
36-
conflicts: $ => [[$.parameter, $._expression], [$.infix_application]],
36+
conflicts: $ => [
37+
[$.infix_application],
38+
[$.parameter, $._expression],
39+
[$.parameter, $._pattern],
40+
[$._expression, $._pattern],
41+
[$.parameter, $._expression, $._pattern],
42+
[$._literal, $._literal_pattern],
43+
[$.string, $.string_pattern],
44+
[$.map, $.map_pattern],
45+
[$.pattern_pair, $._literal]
46+
],
3747

3848
rules: {
3949
program: $ => seq(optional($.hash_bang_line), optional($._statement_seq)),
@@ -111,11 +121,70 @@ module.exports = grammar({
111121
argument: $ => choice('?', field('value', $._expression)),
112122
arguments: $ => commaSep1($.argument),
113123

114-
_destructuring_pattern: $ => prec(PREC.DESTRUCTURING_PATTERN, choice(
115-
$.map,
116-
$.tuple,
117-
$.list
124+
_pattern: $ => prec(PREC.PATTERN, choice(
125+
$._destructuring_pattern,
126+
$._literal_pattern,
127+
alias($.identifier, $.identifier_pattern)
118128
)),
129+
_destructuring_pattern: $ => prec(PREC.PATTERN, choice(
130+
$.map_pattern,
131+
$.tuple_pattern,
132+
$.list_pattern
133+
)),
134+
_literal_pattern: $ => choice(
135+
$.boolean,
136+
$.number,
137+
$.string_pattern,
138+
prec(PREC.REGEX, $.regex)
139+
),
140+
map_pattern: $ => prec(PREC.PATTERN, seq(
141+
// '{',
142+
// commaSep1(choice(
143+
// $.pattern_pair,
144+
// alias($.identifier, $.shorthand_pair_identifier)
145+
// )),
146+
// optional($.rest),
147+
// '}'
148+
'{',
149+
commaSep1(choice(
150+
$.pattern_pair,
151+
alias($.identifier, $.shorthand_pair_identifier_pattern),
152+
$.rest
153+
)),
154+
'}'
155+
)),
156+
tuple_pattern: $ => prec(PREC.PATTERN, choice(
157+
// seq('(', $._pattern, $.rest, ')'),
158+
// seq(
159+
// '(',
160+
// commaSep2($._pattern),
161+
// optional($.rest),
162+
// ')'
163+
// )
164+
seq('(', $._pattern, $.rest, ')'),
165+
seq('(', commaSep2(choice($._pattern, $.rest)), ')')
166+
)),
167+
list_pattern: $ => prec(PREC.PATTERN, seq(
168+
// '[',
169+
// commaSep1($._pattern),
170+
// optional($.rest),
171+
// ']'
172+
'[', commaSep1(choice($._pattern, $.rest)), ']'
173+
)),
174+
pattern_pair: $ => seq(
175+
field('left', $.string_pattern),
176+
'->',
177+
field('right', $._pattern)
178+
),
179+
rest: $ => seq(
180+
'...',
181+
field('name', alias($.identifier, $.identifier_pattern))
182+
),
183+
string_pattern: $ => seq(
184+
$._string_start,
185+
repeat(choice($.escape_sequence, $._string_content)),
186+
$._string_end
187+
),
119188

120189
_group: $ => seq('(', $._expression, ')'),
121190

@@ -177,7 +246,10 @@ module.exports = grammar({
177246
)),
178247

179248
assignment: $ => seq(
180-
field('left', choice($.identifier, $._destructuring_pattern)),
249+
field('left', choice(
250+
alias($.identifier, $.identifier_pattern),
251+
$._destructuring_pattern
252+
)),
181253
':=',
182254
field('right', $._expression)
183255
),
@@ -189,38 +261,21 @@ module.exports = grammar({
189261

190262
map: $ => seq(
191263
'{',
192-
commaSep(optional(choice(
264+
commaSep(choice(
193265
$.expression_pair,
194266
alias($.identifier, $.shorthand_pair_identifier),
195267
$.spread
196-
))),
197-
'}'
198-
),
199-
tuple: $ => seq(
200-
'(',
201-
commaSep2(choice(
202-
$._expression,
203-
$.spread
204-
)),
205-
')'
206-
),
207-
list: $ => seq(
208-
'[',
209-
commaSep(choice(
210-
$._expression,
211-
$.spread
212268
)),
213-
']'
269+
'}'
214270
),
271+
tuple: $ => seq('(', commaSep2(choice($._expression, $.spread)), ')'),
272+
list: $ => seq('[', commaSep(choice($._expression, $.spread)), ']'),
215273
expression_pair: $ => seq(
216274
field('left', $._expression),
217275
'->',
218276
field('right', $._expression)
219277
),
220-
spread: $ => seq(
221-
'...',
222-
field('value', $._expression)
223-
),
278+
spread: $ => seq('...', field('value', $._expression)),
224279

225280
list_comprehension: $ => seq(
226281
'[',

test/corpus/destructuring.txt

Lines changed: 0 additions & 61 deletions
This file was deleted.

test/corpus/expressions.txt

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ fib := (0) =>
3434
(parameter
3535
value: (number))
3636
(parameter
37-
pattern: (map
38-
(shorthand_pair_identifier))))
37+
pattern: (map_pattern
38+
(shorthand_pair_identifier_pattern))))
3939
body: (identifier)))
4040
(assignment
41-
left: (identifier)
41+
left: (identifier_pattern)
4242
right: (abstraction
4343
(abstraction_branch
4444
parameters: (parameters
@@ -349,10 +349,10 @@ a := (a) =>
349349

350350
(program
351351
(assignment
352-
left: (identifier)
352+
left: (identifier_pattern)
353353
right: (number))
354354
(assignment
355-
left: (identifier)
355+
left: (identifier_pattern)
356356
right: (abstraction
357357
(abstraction_branch
358358
parameters: (parameters

test/corpus/literals.txt

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,28 +3,33 @@ map
33
==================
44

55
{}
6-
{'a' -> 1, b, 'c' -> 'str', d, e}
6+
{a, b}
7+
{'a' -> 1, ...b, 'c' -> 'str', d, e}
78

89
---
910

1011
(program
1112
(map)
1213
(map
13-
(expression_pair
14-
(string)
15-
(number))
1614
(shorthand_pair_identifier)
15+
(shorthand_pair_identifier))
16+
(map
17+
(expression_pair
18+
left: (string)
19+
right: (number))
20+
(spread
21+
value: (identifier))
1722
(expression_pair
18-
(string)
19-
(string))
23+
left: (string)
24+
right: (string))
2025
(shorthand_pair_identifier)
2126
(shorthand_pair_identifier)))
2227

2328
==================
2429
tuple
2530
==================
2631

27-
(a, 1, 'str')
32+
(a, 1, ...b, 'str')
2833
(1,1)
2934

3035
---
@@ -33,6 +38,8 @@ tuple
3338
(tuple
3439
(identifier)
3540
(number)
41+
(spread
42+
value: (identifier))
3643
(string))
3744
(tuple
3845
(number)
@@ -43,7 +50,7 @@ list
4350
==================
4451

4552
[]
46-
[a, 1, 'str']
53+
[a, 1, ...b, 'str']
4754
[1,1..1,1]
4855

4956
---
@@ -53,6 +60,8 @@ list
5360
(list
5461
(identifier)
5562
(number)
63+
(spread
64+
value: (identifier))
5665
(string))
5766
(list
5867
(number)

test/corpus/patterns.txt

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
============================================
2+
map pattern
3+
============================================
4+
5+
{'b' -> b} := a
6+
{'b' -> b, c, ...d} := a
7+
8+
---
9+
10+
(program
11+
(assignment
12+
left: (map_pattern
13+
(pattern_pair
14+
left: (string_pattern)
15+
right: (identifier_pattern)))
16+
right: (identifier))
17+
(assignment
18+
left: (map_pattern
19+
(pattern_pair
20+
left: (string_pattern)
21+
right: (identifier_pattern))
22+
(shorthand_pair_identifier_pattern)
23+
(rest
24+
name: (identifier_pattern)))
25+
right: (identifier)))
26+
27+
============================================
28+
tuple pattern
29+
============================================
30+
31+
(b, c) := a
32+
(b, ...d) := a
33+
34+
---
35+
36+
(program
37+
(assignment
38+
left: (tuple_pattern
39+
(identifier_pattern)
40+
(identifier_pattern))
41+
right: (identifier))
42+
(assignment
43+
left: (tuple_pattern
44+
(identifier_pattern)
45+
(rest
46+
name: (identifier_pattern)))
47+
right: (identifier)))
48+
49+
============================================
50+
list pattern
51+
============================================
52+
53+
[b, c] := a
54+
[b, c, ...d] := a
55+
56+
---
57+
58+
(program
59+
(assignment
60+
left: (list_pattern
61+
(identifier_pattern)
62+
(identifier_pattern))
63+
right: (identifier))
64+
(assignment
65+
left: (list_pattern
66+
(identifier_pattern)
67+
(identifier_pattern)
68+
(rest
69+
name: (identifier_pattern)))
70+
right: (identifier)))

0 commit comments

Comments
 (0)