Introduce param falvor

This commit is contained in:
Aleksey Kladov 2018-08-08 18:13:30 +03:00
parent 99f6976b20
commit de7b1887ae

View File

@ -6,35 +6,67 @@ use super::*;
// fn c(x: i32, ) {} // fn c(x: i32, ) {}
// fn d(x: i32, y: ()) {} // fn d(x: i32, y: ()) {}
pub(super) fn param_list(p: &mut Parser) { pub(super) fn param_list(p: &mut Parser) {
list_(p, true) list_(p, Flavor::Normal)
}
// test param_list_opt_patterns
// fn foo<F: FnMut(&mut Foo<'a>)>(){}
pub(super) fn param_list_opt_patterns(p: &mut Parser) {
list_(p, Flavor::OptionalPattern)
} }
pub(super) fn param_list_opt_types(p: &mut Parser) { pub(super) fn param_list_opt_types(p: &mut Parser) {
list_(p, false) list_(p, Flavor::OptionalType)
} }
fn list_(p: &mut Parser, require_types: bool) { #[derive(Clone, Copy, Eq, PartialEq)]
assert!(p.at(if require_types { L_PAREN } else { PIPE })); enum Flavor {
OptionalType,
OptionalPattern,
Normal,
}
impl Flavor {
fn type_required(self) -> bool {
match self {
Flavor::OptionalType => false,
_ => true,
}
}
fn pattern_required(self) -> bool {
match self {
Flavor::OptionalPattern => false,
_ => true,
}
}
}
fn list_(p: &mut Parser, flavor: Flavor) {
let (bra, ket) = if flavor.type_required() {
(L_PAREN, R_PAREN)
} else {
(PIPE, PIPE)
};
assert!(p.at(bra));
let m = p.start(); let m = p.start();
p.bump(); p.bump();
if require_types { if flavor.type_required() {
self_param(p); self_param(p);
} }
let terminator = if require_types { R_PAREN } else { PIPE }; while !p.at(EOF) && !p.at(ket) {
while !p.at(EOF) && !p.at(terminator) { value_parameter(p, flavor);
value_parameter(p, require_types); if !p.at(ket) {
if !p.at(terminator) {
p.expect(COMMA); p.expect(COMMA);
} }
} }
p.expect(terminator); p.expect(ket);
m.complete(p, PARAM_LIST); m.complete(p, PARAM_LIST);
} }
fn value_parameter(p: &mut Parser, require_type: bool) { fn value_parameter(p: &mut Parser, flavor: Flavor) {
let m = p.start(); let m = p.start();
patterns::pattern(p); patterns::pattern(p);
if p.at(COLON) || require_type { if p.at(COLON) || flavor.type_required() {
types::ascription(p) types::ascription(p)
} }
m.complete(p, PARAM); m.complete(p, PARAM);