Pretty good pattern support, I'd say

pull/204/head
Jonathan Arnett 2021-12-20 00:43:08 +07:00
parent e691cc44f7
commit bd3a92b58c
5 changed files with 5156 additions and 3747 deletions

@ -10,6 +10,18 @@ fn replace(
each pattern: String,
with replacement: String
) {}
fn try_try_again(x, y) -> Int {
try int_x = todo
try _who_cares = todo
try file.IODevice() = todo
try Node = todo
try "hello" = todo
try 1 = todo
try 12.34 = todo
try #(a, b) = todo
try <<a:utf8, b:size(8)>> = todo
try [a, b] = todo
}
---
@ -36,7 +48,8 @@ fn replace(
(function_parameter
name: (identifier)
type: (type_var)))
return_type: (type_var))
return_type: (type_var)
(function_body))
(function
name: (identifier)
parameters: (function_parameters
@ -56,4 +69,47 @@ fn replace(
(function_parameter
label: (identifier)
name: (identifier)
type: (type)))))
type: (type))))
(function
name: (identifier)
parameters: (function_parameters
(function_parameter
name: (identifier))
(function_parameter
name: (identifier)))
return_type: (type)
(function_body
(try
pattern: (var))
(try
pattern: (discard_var))
(try
pattern: (remote_constructor_pattern
(pattern_constructor_args)))
(try
pattern: (constructor_pattern))
(try
pattern: (string))
(try
pattern: (integer))
(try
pattern: (float))
(try
pattern: (tuple_pattern
(var)
(var)))
(try
pattern: (bit_string_pattern
(bit_string_segment
value: (var)
options: (bit_string_segment_options
(bit_string_segment_option_utf8)))
(bit_string_segment
value: (var)
options: (bit_string_segment_options
(bit_string_segment_option_size
(integer))))))
(try
pattern: (list_pattern
(var)
(var))))))

@ -252,18 +252,14 @@ module.exports = grammar({
// This makes sense for the parser, but (IMO) would be more confusing for
// users and tooling which don't think about `try`s as having a "then". Thus,
// `try`s are essentially treated the same as any other expression.
_expression_seq: ($) =>
repeat1(
choice(
seq(
"try",
$._pattern,
optional($._type_annotation),
"=",
$._expression
),
$._expression
)
_expression_seq: ($) => repeat1(choice($.try, $._expression)),
try: ($) =>
seq(
"try",
field("pattern", $._pattern),
optional($._type_annotation),
"=",
field("value", $._expression)
),
_pattern: ($) =>
seq(
@ -275,16 +271,17 @@ module.exports = grammar({
$.string,
$.integer,
$.float,
$.constructor_tuple,
$.constructor_bitstring,
$.constructor_list
$.tuple_pattern,
alias($._pattern_bit_string, $.bit_string_pattern),
$.list_pattern
),
optional(seq("as", alias($._name, $.pattern_assign)))
optional(field("assign", seq("as", alias($._name, $.pattern_assign))))
),
_expression: ($) => "todo",
var: ($) => $._name,
discard_var: ($) => $._discard_name,
remote_constructor_pattern: ($) => seq($._name, $._constructor_pattern),
remote_constructor_pattern: ($) =>
seq($._name, ".", $._constructor_pattern),
constructor_pattern: ($) => $._constructor_pattern,
_constructor_pattern: ($) =>
seq($._upname, optional($.pattern_constructor_args)),
@ -303,6 +300,25 @@ module.exports = grammar({
pattern_constructor_named_arg: ($) =>
seq($._name, ":", $.constructor_pattern),
pattern_spread: ($) => seq("..", optional(",")),
tuple_pattern: ($) =>
seq("#", "(", optional(series_of($._pattern, ",")), ")"),
// The Gleam parser has a special catch for nested bitstrings here, which
// is interesting as the same error does not exist on constants. Anyhow, I
// wasn't really sure how to implement that easily here, and so didn't.
...bit_string_rules(
"pattern",
"_pattern",
"_pattern_bit_string_segment_arg"
),
_pattern_bit_string_segment_arg: ($) => choice($.var, $.integer),
list_pattern: ($) =>
seq(
"[",
optional(series_of($._pattern, ",")),
optional($.list_pattern_tail),
"]"
),
list_pattern_tail: ($) => seq("..", choice($.var, $.discard_var)),
/* Literals */
string: ($) => /\"(?:\\[efnrt\"\\]|[^\"])*\"/,

@ -1634,37 +1634,8 @@
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "try"
},
{
"type": "SYMBOL",
"name": "_pattern"
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_type_annotation"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "="
},
{
"type": "SYMBOL",
"name": "_expression"
}
]
"type": "SYMBOL",
"name": "try"
},
{
"type": "SYMBOL",
@ -1673,6 +1644,47 @@
]
}
},
"try": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "try"
},
{
"type": "FIELD",
"name": "pattern",
"content": {
"type": "SYMBOL",
"name": "_pattern"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_type_annotation"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "="
},
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_expression"
}
}
]
},
"_pattern": {
"type": "SEQ",
"members": [
@ -1707,14 +1719,22 @@
"type": "SYMBOL",
"name": "float"
},
{
"type": "SYMBOL",
"name": "tuple_pattern"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_pattern_tuple"
"name": "_pattern_bit_string"
},
"named": true,
"value": "tuple"
"value": "bit_string_pattern"
},
{
"type": "SYMBOL",
"name": "list_pattern"
}
]
},
@ -1722,22 +1742,26 @@
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "as"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_name"
"type": "FIELD",
"name": "assign",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "as"
},
"named": true,
"value": "pattern_assign"
}
]
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_name"
},
"named": true,
"value": "pattern_assign"
}
]
}
},
{
"type": "BLANK"
@ -1765,6 +1789,10 @@
"type": "SYMBOL",
"name": "_name"
},
{
"type": "STRING",
"value": "."
},
{
"type": "SYMBOL",
"name": "_constructor_pattern"
@ -1910,7 +1938,7 @@
}
]
},
"_pattern_tuple": {
"tuple_pattern": {
"type": "SEQ",
"members": [
{
@ -1960,6 +1988,279 @@
}
]
},
"_pattern_bit_string": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "<<"
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "pattern_bit_string_segment"
},
"named": true,
"value": "bit_string_segment"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "pattern_bit_string_segment"
},
"named": true,
"value": "bit_string_segment"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": ">>"
}
]
},
"pattern_bit_string_segment": {
"type": "SEQ",
"members": [
{
"type": "FIELD",
"name": "value",
"content": {
"type": "SYMBOL",
"name": "_pattern"
}
},
{
"type": "CHOICE",
"members": [
{
"type": "FIELD",
"name": "options",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ":"
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "pattern_bit_string_segment_options"
},
"named": true,
"value": "bit_string_segment_options"
}
]
}
},
{
"type": "BLANK"
}
]
}
]
},
"pattern_bit_string_segment_options": {
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_bit_string_segment_option"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "-"
},
{
"type": "SYMBOL",
"name": "_pattern_bit_string_segment_option"
}
]
}
}
]
},
"_pattern_bit_string_segment_option": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_pattern_bit_string_named_segment_option"
},
{
"type": "SYMBOL",
"name": "integer"
}
]
},
"_pattern_bit_string_named_segment_option": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "_bit_string_segment_option_unit"
},
{
"type": "SYMBOL",
"name": "_pattern_bit_string_segment_option_size"
},
{
"type": "SYMBOL",
"name": "_bit_string_segment_option_literal"
}
]
},
"_pattern_bit_string_segment_option_size": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "size"
},
{
"type": "STRING",
"value": "("
},
{
"type": "ALIAS",
"content": {
"type": "SYMBOL",
"name": "_pattern_bit_string_segment_arg"
},
"named": true,
"value": "bit_string_segment_option_size"
},
{
"type": "STRING",
"value": ")"
}
]
},
"_pattern_bit_string_segment_arg": {
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "var"
},
{
"type": "SYMBOL",
"name": "integer"
}
]
},
"list_pattern": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": "["
},
{
"type": "CHOICE",
"members": [
{
"type": "SEQ",
"members": [
{
"type": "SYMBOL",
"name": "_pattern"
},
{
"type": "REPEAT",
"content": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ","
},
{
"type": "SYMBOL",
"name": "_pattern"
}
]
}
}
]
},
{
"type": "BLANK"
}
]
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "list_pattern_tail"
},
{
"type": "BLANK"
}
]
},
{
"type": "STRING",
"value": "]"
}
]
},
"list_pattern_tail": {
"type": "SEQ",
"members": [
{
"type": "STRING",
"value": ".."
},
{
"type": "CHOICE",
"members": [
{
"type": "SYMBOL",
"name": "var"
},
{
"type": "SYMBOL",
"name": "discard_var"
}
]
}
]
},
"string": {
"type": "PATTERN",
"value": "\\\"(?:\\\\[efnrt\\\"\\\\]|[^\\\"])*\\\""

@ -19,10 +19,39 @@
]
}
},
{
"type": "bit_string_pattern",
"named": true,
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "bit_string_segment",
"named": true
}
]
}
},
{
"type": "bit_string_segment",
"named": true,
"fields": {
"assign": {
"multiple": true,
"required": false,
"types": [
{
"type": "as",
"named": false
},
{
"type": "pattern_assign",
"named": true
}
]
},
"options": {
"multiple": true,
"required": false,
@ -38,13 +67,29 @@
]
},
"value": {
"multiple": false,
"multiple": true,
"required": true,
"types": [
{
"type": "as",
"named": false
},
{
"type": "bit_string",
"named": true
},
{
"type": "bit_string_pattern",
"named": true
},
{
"type": "constructor_pattern",
"named": true
},
{
"type": "discard_var",
"named": true
},
{
"type": "float",
"named": true
@ -57,10 +102,22 @@
"type": "list",
"named": true
},
{
"type": "list_pattern",
"named": true
},
{
"type": "pattern_assign",
"named": true
},
{
"type": "record",
"named": true
},
{
"type": "remote_constructor_pattern",
"named": true
},
{
"type": "remote_record",
"named": true
@ -72,11 +129,38 @@
{
"type": "tuple",
"named": true
},
{
"type": "tuple_pattern",
"named": true
},
{
"type": "var",
"named": true
}
]
}
}
},
{
"type": "bit_string_segment_option_size",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": false,
"types": [
{
"type": "integer",
"named": true
},
{
"type": "var",
"named": true
}
]
}
},
{
"type": "bit_string_segment_options",
"named": true,
@ -461,88 +545,13 @@
{
"type": "function_body",
"named": true,
"fields": {
"type": {
"multiple": true,
"required": false,
"types": [
{
"type": ".",
"named": false
},
{
"type": "function_type",
"named": true
},
{
"type": "remote_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
},
"fields": {},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "constructor_pattern",
"named": true
},
{
"type": "discard_var",
"named": true
},
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "pattern_assign",
"named": true
},
{
"type": "remote_constructor_pattern",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple",
"named": true
},
{
"type": "var",
"type": "try",
"named": true
}
]
@ -816,6 +825,95 @@
]
}
},
{
"type": "list_pattern",
"named": true,
"fields": {
"assign": {
"multiple": true,
"required": false,
"types": [
{
"type": "as",
"named": false
},
{
"type": "pattern_assign",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "bit_string_pattern",
"named": true
},
{
"type": "constructor_pattern",
"named": true
},
{
"type": "discard_var",
"named": true
},
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list_pattern",
"named": true
},
{
"type": "list_pattern_tail",
"named": true
},
{
"type": "remote_constructor_pattern",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple_pattern",
"named": true
},
{
"type": "var",
"named": true
}
]
}
},
{
"type": "list_pattern_tail",
"named": true,
"fields": {},
"children": {
"multiple": false,
"required": true,
"types": [
{
"type": "discard_var",
"named": true
},
{
"type": "var",
"named": true
}
]
}
},
{
"type": "module",
"named": true,
@ -1306,6 +1404,122 @@
]
}
},
{
"type": "try",
"named": true,
"fields": {
"assign": {
"multiple": true,
"required": false,
"types": [
{
"type": "as",
"named": false
},
{
"type": "pattern_assign",
"named": true
}
]
},
"pattern": {
"multiple": true,
"required": true,
"types": [
{
"type": "as",
"named": false
},
{
"type": "bit_string_pattern",
"named": true
},
{
"type": "constructor_pattern",
"named": true
},
{
"type": "discard_var",
"named": true
},
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list_pattern",
"named": true
},
{
"type": "pattern_assign",
"named": true
},
{
"type": "remote_constructor_pattern",
"named": true
},
{
"type": "string",
"named": true
},
{
"type": "tuple_pattern",
"named": true
},
{
"type": "var",
"named": true
}
]
},
"type": {
"multiple": true,
"required": false,
"types": [
{
"type": ".",
"named": false
},
{
"type": "function_type",
"named": true
},
{
"type": "remote_type",
"named": true
},
{
"type": "remote_type_constructor",
"named": true
},
{
"type": "tuple_type",
"named": true
},
{
"type": "type",
"named": true
},
{
"type": "type_constructor",
"named": true
},
{
"type": "type_hole",
"named": true
},
{
"type": "type_var",
"named": true
}
]
}
}
},
{
"type": "tuple",
"named": true,
@ -1319,39 +1533,85 @@
"named": true
},
{
"type": "constructor_pattern",
"type": "float",
"named": true
},
{
"type": "discard_var",
"type": "integer",
"named": true
},
{
"type": "float",
"type": "list",
"named": true
},
{
"type": "integer",
"type": "record",
"named": true
},
{
"type": "list",
"type": "remote_record",
"named": true
},
{
"type": "pattern_assign",
"type": "string",
"named": true
},
{
"type": "record",
"type": "tuple",
"named": true
}
]
}
},
{
"type": "tuple_pattern",
"named": true,
"fields": {
"assign": {
"multiple": true,
"required": false,
"types": [
{
"type": "as",
"named": false
},
{
"type": "pattern_assign",
"named": true
}
]
}
},
"children": {
"multiple": true,
"required": false,
"types": [
{
"type": "bit_string_pattern",
"named": true
},
{
"type": "remote_constructor_pattern",
"type": "constructor_pattern",
"named": true
},
{
"type": "remote_record",
"type": "discard_var",
"named": true
},
{
"type": "float",
"named": true
},
{
"type": "integer",
"named": true
},
{
"type": "list_pattern",
"named": true
},
{
"type": "remote_constructor_pattern",
"named": true
},
{
@ -1359,7 +1619,7 @@
"named": true
},
{
"type": "tuple",
"type": "tuple_pattern",
"named": true
},
{
@ -1596,10 +1856,6 @@
"type": "bit_string_segment_option_signed",
"named": true
},
{
"type": "bit_string_segment_option_size",
"named": true
},
{
"type": "bit_string_segment_option_unit",
"named": true

File diff suppressed because it is too large Load Diff