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 d(x: i32, y: ()) {}
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) {
list_(p, false)
list_(p, Flavor::OptionalType)
}
fn list_(p: &mut Parser, require_types: bool) {
assert!(p.at(if require_types { L_PAREN } else { PIPE }));
#[derive(Clone, Copy, Eq, PartialEq)]
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();
p.bump();
if require_types {
if flavor.type_required() {
self_param(p);
}
let terminator = if require_types { R_PAREN } else { PIPE };
while !p.at(EOF) && !p.at(terminator) {
value_parameter(p, require_types);
if !p.at(terminator) {
while !p.at(EOF) && !p.at(ket) {
value_parameter(p, flavor);
if !p.at(ket) {
p.expect(COMMA);
}
}
p.expect(terminator);
p.expect(ket);
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();
patterns::pattern(p);
if p.at(COLON) || require_type {
if p.at(COLON) || flavor.type_required() {
types::ascription(p)
}
m.complete(p, PARAM);