feat(backpassing): implements multi patterns
The main trick here was transforming Assignment to contain `Vec<UntypedPattern, Option<Annotation>>` in a field called patterns. This then meant that I could remove the `pattern` and `annotation` field from `Assignment`. The parser handles `=` and `<-` just fine because in the future `=` with multi patterns will mean some kind of optimization on tuples. But, since we don't have that optimization yet, when someone uses multi patterns with an `=` there will be an error returned from the type checker right where `infer_seq` looks for `backpassing`. From there the rest of the work was in `Project::backpassing` where I only needed to rework some things to work with a list of patterns instead of just one.
This commit is contained in:
@@ -14,20 +14,24 @@ Test(
|
||||
location: 45..50,
|
||||
name: "False",
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 38..42,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Constructor {
|
||||
is_record: false,
|
||||
location: 38..42,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Expect {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Var {
|
||||
location: 54..59,
|
||||
|
||||
@@ -25,14 +25,18 @@ Fn(
|
||||
},
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 17..18,
|
||||
name: "x",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 17..18,
|
||||
name: "x",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
doc: None,
|
||||
location: 0..8,
|
||||
|
||||
@@ -9,23 +9,30 @@ pub fn let_(
|
||||
r: Recursive<'_, Token, UntypedExpr, ParseError>,
|
||||
) -> impl Parser<Token, UntypedExpr, Error = ParseError> + '_ {
|
||||
just(Token::Let)
|
||||
.ignore_then(pattern())
|
||||
.then(just(Token::Colon).ignore_then(annotation()).or_not())
|
||||
.ignore_then(
|
||||
pattern()
|
||||
.then(just(Token::Colon).ignore_then(annotation()).or_not())
|
||||
.separated_by(just(Token::Comma))
|
||||
.at_least(1),
|
||||
)
|
||||
.then(choice((just(Token::Equal), just(Token::LArrow))))
|
||||
.then(r.clone())
|
||||
.validate(move |(((pattern, annotation), kind), value), span, emit| {
|
||||
.validate(move |((patterns, kind), value), span, emit| {
|
||||
if matches!(value, UntypedExpr::Assignment { .. }) {
|
||||
emit(ParseError::invalid_assignment_right_hand_side(span))
|
||||
}
|
||||
|
||||
let patterns = patterns
|
||||
.try_into()
|
||||
.expect("We use at_least(1) so this should never be empty");
|
||||
|
||||
UntypedExpr::Assignment {
|
||||
location: span,
|
||||
value: Box::new(value),
|
||||
pattern,
|
||||
patterns,
|
||||
kind: ast::AssignmentKind::Let {
|
||||
backpassing: kind == Token::LArrow,
|
||||
},
|
||||
annotation,
|
||||
}
|
||||
})
|
||||
}
|
||||
@@ -37,14 +44,20 @@ pub fn expect(
|
||||
.ignore_then(
|
||||
pattern()
|
||||
.then(just(Token::Colon).ignore_then(annotation()).or_not())
|
||||
.separated_by(just(Token::Comma))
|
||||
.at_least(1)
|
||||
.then(choice((just(Token::Equal), just(Token::LArrow))))
|
||||
.or_not(),
|
||||
)
|
||||
.then(r.clone())
|
||||
.validate(move |(opt_pattern, value), span, emit| {
|
||||
let ((pattern, annotation), kind) = opt_pattern.unwrap_or_else(|| {
|
||||
if matches!(value, UntypedExpr::Assignment { .. }) {
|
||||
emit(ParseError::invalid_assignment_right_hand_side(span))
|
||||
}
|
||||
|
||||
let (patterns, kind) = opt_pattern.unwrap_or_else(|| {
|
||||
(
|
||||
(
|
||||
vec![(
|
||||
ast::UntypedPattern::Constructor {
|
||||
is_record: false,
|
||||
location: span,
|
||||
@@ -56,23 +69,22 @@ pub fn expect(
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
)],
|
||||
Token::Equal,
|
||||
)
|
||||
});
|
||||
|
||||
if matches!(value, UntypedExpr::Assignment { .. }) {
|
||||
emit(ParseError::invalid_assignment_right_hand_side(span))
|
||||
}
|
||||
let patterns = patterns
|
||||
.try_into()
|
||||
.expect("We use at_least(1) so this should never be empty");
|
||||
|
||||
UntypedExpr::Assignment {
|
||||
location: span,
|
||||
patterns,
|
||||
value: Box::new(value),
|
||||
pattern,
|
||||
kind: ast::AssignmentKind::Expect {
|
||||
backpassing: kind == Token::LArrow,
|
||||
},
|
||||
annotation,
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -16,14 +16,18 @@ Assignment {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 16..17,
|
||||
name: "x",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 16..17,
|
||||
name: "x",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
BinOp {
|
||||
location: 24..29,
|
||||
@@ -42,12 +46,16 @@ Assignment {
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "b",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "b",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -12,27 +12,31 @@ Assignment {
|
||||
name: "something",
|
||||
},
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 7..14,
|
||||
name: "Some",
|
||||
arguments: [
|
||||
CallArg {
|
||||
label: None,
|
||||
location: 12..13,
|
||||
value: Var {
|
||||
location: 12..13,
|
||||
name: "x",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Constructor {
|
||||
is_record: false,
|
||||
location: 7..14,
|
||||
name: "Some",
|
||||
arguments: [
|
||||
CallArg {
|
||||
label: None,
|
||||
location: 12..13,
|
||||
value: Var {
|
||||
location: 12..13,
|
||||
name: "x",
|
||||
},
|
||||
},
|
||||
],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Expect {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -20,18 +20,22 @@ Assignment {
|
||||
name: "wow",
|
||||
},
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 0..29,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Constructor {
|
||||
is_record: false,
|
||||
location: 0..29,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Expect {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -16,29 +16,37 @@ Assignment {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 13..14,
|
||||
name: "a",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 13..14,
|
||||
name: "a",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 0..21,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Constructor {
|
||||
is_record: false,
|
||||
location: 0..21,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Expect {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -16,23 +16,31 @@ Assignment {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 14..15,
|
||||
name: "b",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 14..15,
|
||||
name: "b",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -16,23 +16,31 @@ Assignment {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 14..15,
|
||||
name: "b",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 14..15,
|
||||
name: "b",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -16,14 +16,18 @@ Assignment {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 16..17,
|
||||
name: "b",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 16..17,
|
||||
name: "b",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Var {
|
||||
location: 25..26,
|
||||
@@ -31,12 +35,16 @@ Assignment {
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -11,18 +11,22 @@ Assignment {
|
||||
name: "foo",
|
||||
},
|
||||
},
|
||||
pattern: Constructor {
|
||||
is_record: false,
|
||||
location: 0..11,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Constructor {
|
||||
is_record: false,
|
||||
location: 0..11,
|
||||
name: "True",
|
||||
arguments: [],
|
||||
module: None,
|
||||
constructor: (),
|
||||
with_spread: false,
|
||||
tipo: (),
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Expect {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -27,14 +27,18 @@ Sequence {
|
||||
},
|
||||
location: 8..18,
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "x",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "x",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 20..65,
|
||||
@@ -113,14 +117,18 @@ Sequence {
|
||||
},
|
||||
return_annotation: None,
|
||||
},
|
||||
pattern: Var {
|
||||
location: 24..33,
|
||||
name: "map_add_x",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 24..33,
|
||||
name: "map_add_x",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Call {
|
||||
arguments: [
|
||||
|
||||
@@ -14,14 +14,18 @@ Sequence {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 8..9,
|
||||
name: "i",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 8..9,
|
||||
name: "i",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 24..41,
|
||||
@@ -32,14 +36,18 @@ Sequence {
|
||||
numeric_underscore: true,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 28..29,
|
||||
name: "j",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 28..29,
|
||||
name: "j",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Assignment {
|
||||
location: 44..59,
|
||||
@@ -54,14 +62,18 @@ Sequence {
|
||||
},
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 48..49,
|
||||
name: "k",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 48..49,
|
||||
name: "k",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
@@ -28,12 +28,16 @@ Assignment {
|
||||
],
|
||||
tail: None,
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..9,
|
||||
name: "thing",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..9,
|
||||
name: "thing",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
}
|
||||
|
||||
@@ -40,14 +40,18 @@ Sequence {
|
||||
},
|
||||
],
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..9,
|
||||
name: "tuple",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..9,
|
||||
name: "tuple",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
BinOp {
|
||||
location: 25..70,
|
||||
|
||||
@@ -27,14 +27,18 @@ Sequence {
|
||||
},
|
||||
location: 8..15,
|
||||
},
|
||||
pattern: Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 4..5,
|
||||
name: "a",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Tuple {
|
||||
location: 16..23,
|
||||
|
||||
@@ -85,14 +85,18 @@ When {
|
||||
numeric_underscore: false,
|
||||
},
|
||||
},
|
||||
pattern: Var {
|
||||
location: 55..62,
|
||||
name: "amazing",
|
||||
},
|
||||
patterns: [
|
||||
(
|
||||
Var {
|
||||
location: 55..62,
|
||||
name: "amazing",
|
||||
},
|
||||
None,
|
||||
),
|
||||
],
|
||||
kind: Let {
|
||||
backpassing: false,
|
||||
},
|
||||
annotation: None,
|
||||
},
|
||||
Var {
|
||||
location: 71..78,
|
||||
|
||||
Reference in New Issue
Block a user