Drop more high-order stuff

This commit is contained in:
Aleksey Kladov 2018-01-20 21:49:58 +03:00
parent 111743d82c
commit be60d5aa66
5 changed files with 100 additions and 93 deletions

View file

@ -1,5 +1,6 @@
use super::*; use super::*;
#[derive(PartialEq, Eq)]
enum AttrKind { enum AttrKind {
Inner, Outer Inner, Outer
} }
@ -14,18 +15,27 @@ pub(super) fn outer_attributes(p: &mut Parser) {
fn attribute(p: &mut Parser, kind: AttrKind) -> bool { fn attribute(p: &mut Parser, kind: AttrKind) -> bool {
fn attr_tail(p: &mut Parser) { if p.at(POUND) {
meta_item(p) && p.expect(R_BRACK); if kind == AttrKind::Inner && p.raw_lookahead(1) != EXCL {
} return false;
}
match kind { p.start(ATTR);
AttrKind::Inner => node_if(p, [POUND, EXCL, L_BRACK], ATTR, attr_tail), p.bump();
AttrKind::Outer => node_if(p, [POUND, L_BRACK], ATTR, attr_tail), if kind == AttrKind::Inner {
p.bump();
}
p.expect(L_BRACK) && meta_item(p) && p.expect(R_BRACK);
p.finish();
true
} else {
false
} }
} }
fn meta_item(p: &mut Parser) -> bool { fn meta_item(p: &mut Parser) -> bool {
node_if(p, IDENT, META_ITEM, |p| { if p.at(IDENT) {
p.start(META_ITEM);
p.bump();
if p.eat(EQ) { if p.eat(EQ) {
if !expressions::literal(p) { if !expressions::literal(p) {
p.error() p.error()
@ -36,7 +46,12 @@ fn meta_item(p: &mut Parser) -> bool {
comma_list(p, R_PAREN, meta_item_inner); comma_list(p, R_PAREN, meta_item_inner);
p.expect(R_PAREN); p.expect(R_PAREN);
} }
}) p.finish();
true
} else {
false
}
} }
fn meta_item_inner(p: &mut Parser) -> bool { fn meta_item_inner(p: &mut Parser) -> bool {

View file

@ -1,11 +1,16 @@
use super::*; use super::*;
pub(super) fn literal(p: &mut Parser) -> bool { pub(super) fn literal(p: &mut Parser) -> bool {
let literals = [ match p.current() {
TRUE_KW, FALSE_KW, TRUE_KW | FALSE_KW |
INT_NUMBER, FLOAT_NUMBER, INT_NUMBER | FLOAT_NUMBER |
BYTE, CHAR, BYTE | CHAR |
STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING, STRING | RAW_STRING | BYTE_STRING | RAW_BYTE_STRING => {
]; p.start(LITERAL);
node_if(p, AnyOf(&literals), LITERAL, |_| ()) p.bump();
} p.finish();
true
}
_ => false
}
}

View file

@ -7,7 +7,7 @@ pub(super) fn mod_contents(p: &mut Parser) {
} }
} }
fn item(p: &mut Parser){ fn item(p: &mut Parser) {
let attrs_start = p.mark(); let attrs_start = p.mark();
attributes::outer_attributes(p); attributes::outer_attributes(p);
visibility(p); visibility(p);
@ -51,7 +51,7 @@ fn struct_item(p: &mut Parser) {
fn struct_inner(p: &mut Parser) { fn struct_inner(p: &mut Parser) {
if !p.expect(IDENT) { if !p.expect(IDENT) {
p.finish(); p.finish();
return return;
} }
generic_parameters(p); generic_parameters(p);
match p.current() { match p.current() {
@ -60,31 +60,31 @@ fn struct_item(p: &mut Parser) {
match p.current() { match p.current() {
SEMI => { SEMI => {
p.bump(); p.bump();
return return;
} }
L_CURLY => named_fields(p), L_CURLY => named_fields(p),
_ => { //TODO: special case `(` error message _ => { //TODO: special case `(` error message
p.error() p.error()
.message("expected `;` or `{`") .message("expected `;` or `{`")
.emit(); .emit();
return return;
} }
} }
} }
SEMI => { SEMI => {
p.bump(); p.bump();
return return;
} }
L_CURLY => named_fields(p), L_CURLY => named_fields(p),
L_PAREN => { L_PAREN => {
tuple_fields(p); tuple_fields(p);
p.expect(SEMI); p.expect(SEMI);
}, }
_ => { _ => {
p.error() p.error()
.message("expected `;`, `{`, or `(`") .message("expected `;`, `{`, or `(`")
.emit(); .emit();
return return;
} }
} }
} }
@ -108,7 +108,7 @@ fn named_fields(p: &mut Parser) {
fn tuple_fields(p: &mut Parser) { fn tuple_fields(p: &mut Parser) {
if !p.expect(L_PAREN) { if !p.expect(L_PAREN) {
return return;
} }
comma_list(p, R_PAREN, |p| { comma_list(p, R_PAREN, |p| {
tuple_field(p); tuple_field(p);
@ -124,11 +124,9 @@ fn tuple_fields(p: &mut Parser) {
} }
} }
fn generic_parameters(_: &mut Parser) { fn generic_parameters(_: &mut Parser) {}
}
fn where_clause(_: &mut Parser) { fn where_clause(_: &mut Parser) {}
}
fn extern_crate_item(p: &mut Parser) { fn extern_crate_item(p: &mut Parser) {
p.start(EXTERN_CRATE_ITEM); p.start(EXTERN_CRATE_ITEM);
@ -168,24 +166,29 @@ fn use_item(p: &mut Parser) {
p.expect(SEMI); p.expect(SEMI);
p.finish(); p.finish();
fn use_tree(p: &mut Parser) -> bool{ fn use_tree(p: &mut Parser) -> bool {
if node_if(p, STAR, USE_TREE, |_| ()) { let la = p.raw_lookahead(1);
return true match (p.current(), la) {
} (STAR, _) => {
if node_if(p, [COLONCOLON, STAR], USE_TREE, |_| ()) { p.start(USE_TREE);
return true p.bump();
} }
if [COLONCOLON, L_CURLY].is_ahead(p) || L_CURLY.is_ahead(p) { (COLONCOLON, STAR) => {
node(p, USE_TREE, |p| { p.start(USE_TREE);
p.eat(COLONCOLON); p.bump();
p.bump();
}
(L_CURLY, _) | (COLONCOLON, L_CURLY) => {
p.start(USE_TREE);
if p.at(COLONCOLON) {
p.bump();
}
p.curly_block(|p| { p.curly_block(|p| {
comma_list(p, EOF, use_tree); comma_list(p, EOF, use_tree);
}); });
}); }
return true; _ if paths::is_path_start(p) => {
} p.start(USE_TREE);
if paths::is_path_start(p) {
node(p, USE_TREE, |p| {
paths::use_path(p); paths::use_path(p);
match p.current() { match p.current() {
AS_KW => { AS_KW => {
@ -212,15 +215,15 @@ fn use_item(p: &mut Parser) {
} }
_ => (), _ => (),
} }
}); }
return true; _ => return false,
} }
false p.finish();
return true;
} }
} }
fn fn_item(p: &mut Parser) { fn fn_item(p: &mut Parser) {
p.start(FN_ITEM); p.start(FN_ITEM);

View file

@ -46,21 +46,6 @@ fn alias(p: &mut Parser) -> bool {
true //FIXME: return false if three are errors true //FIXME: return false if three are errors
} }
fn node_if<F: FnOnce(&mut Parser), L: Lookahead>(
p: &mut Parser,
first: L,
node_kind: SyntaxKind,
rest: F
) -> bool {
first.is_ahead(p) && { node(p, node_kind, |p| { L::consume(p); rest(p); }); true }
}
fn node<F: FnOnce(&mut Parser)>(p: &mut Parser, node_kind: SyntaxKind, rest: F) {
p.start(node_kind);
rest(p);
p.finish();
}
fn repeat<F: FnMut(&mut Parser) -> bool>(p: &mut Parser, mut f: F) { fn repeat<F: FnMut(&mut Parser) -> bool>(p: &mut Parser, mut f: F) {
loop { loop {
let pos = p.pos(); let pos = p.pos();

View file

@ -1,6 +1,6 @@
use super::*; use super::*;
pub (crate) fn is_path_start(p: &Parser) -> bool { pub(crate) fn is_path_start(p: &Parser) -> bool {
AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p) AnyOf(&[IDENT, SELF_KW, SUPER_KW, COLONCOLON]).is_ahead(p)
} }
@ -9,39 +9,38 @@ pub(crate) fn use_path(p: &mut Parser) {
return; return;
} }
let mut prev = p.mark(); let mut prev = p.mark();
node(p, PATH, |p| { p.start(PATH);
path_segment(p, true); path_segment(p, true);
}); p.finish();
repeat(p, |p| { loop {
let curr = p.mark(); let curr = p.mark();
if p.current() == COLONCOLON && !items::is_use_tree_start(p.raw_lookahead(1)) { if p.at(COLONCOLON) && !items::is_use_tree_start(p.raw_lookahead(1)) {
node(p, PATH, |p| { p.start(PATH);
p.bump(); p.bump();
path_segment(p, false); path_segment(p, false);
p.forward_parent(prev, curr); p.forward_parent(prev, curr);
prev = curr; prev = curr;
}); p.finish();
true
} else { } else {
false break;
} }
}); }
} }
fn path_segment(p: &mut Parser, first: bool) { fn path_segment(p: &mut Parser, first: bool) {
node(p, PATH_SEGMENT, |p| { p.start(PATH_SEGMENT);
if first { if first {
p.eat(COLONCOLON); p.eat(COLONCOLON);
}
match p.current() {
IDENT | SELF_KW | SUPER_KW => {
p.bump();
} }
match p.current() { _ => {
IDENT | SELF_KW | SUPER_KW => { p.error()
p.bump(); .message("expected identifier")
}, .emit();
_ => { }
p.error() };
.message("expected identifier") p.finish();
.emit(); }
}
};
})
}