From 7c67612b8a894187fa3b64725531a5459f9211bf Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 10 Aug 2018 22:33:29 +0300 Subject: organizize --- src/grammar/expressions/atom.rs | 348 ------------------------------------ src/grammar/expressions/mod.rs | 379 ---------------------------------------- 2 files changed, 727 deletions(-) delete mode 100644 src/grammar/expressions/atom.rs delete mode 100644 src/grammar/expressions/mod.rs (limited to 'src/grammar/expressions') diff --git a/src/grammar/expressions/atom.rs b/src/grammar/expressions/atom.rs deleted file mode 100644 index af9f47c5e..000000000 --- a/src/grammar/expressions/atom.rs +++ /dev/null @@ -1,348 +0,0 @@ -use super::*; - -// test expr_literals -// fn foo() { -// let _ = true; -// let _ = false; -// let _ = 1; -// let _ = 2.0; -// let _ = b'a'; -// let _ = 'b'; -// let _ = "c"; -// let _ = r"d"; -// let _ = b"e"; -// let _ = br"f"; -// } -const LITERAL_FIRST: TokenSet = - token_set![TRUE_KW, FALSE_KW, INT_NUMBER, FLOAT_NUMBER, BYTE, CHAR, - STRING, RAW_STRING, BYTE_STRING, RAW_BYTE_STRING]; - -pub(crate) fn literal(p: &mut Parser) -> Option { - if !LITERAL_FIRST.contains(p.current()) { - return None; - } - let m = p.start(); - p.bump(); - Some(m.complete(p, LITERAL)) -} - -pub(super) const ATOM_EXPR_FIRST: TokenSet = - token_set_union![ - LITERAL_FIRST, - token_set![L_PAREN, PIPE, MOVE_KW, IF_KW, WHILE_KW, MATCH_KW, UNSAFE_KW, L_CURLY, RETURN_KW, - IDENT, SELF_KW, SUPER_KW, COLONCOLON ], - ]; - -pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option { - match literal(p) { - Some(m) => return Some(m), - None => (), - } - if paths::is_path_start(p) { - return Some(path_expr(p, r)); - } - let la = p.nth(1); - let done = match p.current() { - L_PAREN => tuple_expr(p), - L_BRACK => array_expr(p), - PIPE => lambda_expr(p), - MOVE_KW if la == PIPE => lambda_expr(p), - IF_KW => if_expr(p), - WHILE_KW => while_expr(p), - LOOP_KW => loop_expr(p), - FOR_KW => for_expr(p), - MATCH_KW => match_expr(p), - UNSAFE_KW if la == L_CURLY => block_expr(p), - L_CURLY => block_expr(p), - RETURN_KW => return_expr(p), - _ => { - p.err_and_bump("expected expression"); - return None; - } - }; - Some(done) -} - -// test tuple_expr -// fn foo() { -// (); -// (1); -// (1,); -// } -fn tuple_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.expect(L_PAREN); - - let mut saw_comma = false; - let mut saw_expr = false; - while !p.at(EOF) && !p.at(R_PAREN) { - saw_expr = true; - expr(p); - if !p.at(R_PAREN) { - saw_comma = true; - p.expect(COMMA); - } - } - p.expect(R_PAREN); - m.complete(p, if saw_expr && !saw_comma { PAREN_EXPR } else { TUPLE_EXPR }) -} - -// test array_expr -// fn foo() { -// []; -// [1]; -// [1, 2,]; -// [1; 2]; -// } -fn array_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_BRACK)); - let m = p.start(); - p.bump(); - if p.eat(R_BRACK) { - return m.complete(p, ARRAY_EXPR); - } - expr(p); - if p.eat(SEMI) { - expr(p); - p.expect(R_BRACK); - return m.complete(p, ARRAY_EXPR); - } - while !p.at(EOF) && !p.at(R_BRACK) { - p.expect(COMMA); - if !p.at(R_BRACK) { - expr(p); - } - } - p.expect(R_BRACK); - m.complete(p, ARRAY_EXPR) -} - -// test lambda_expr -// fn foo() { -// || (); -// || -> i32 { 92 }; -// |x| x; -// move |x: i32,| x; -// } -fn lambda_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(PIPE) || (p.at(MOVE_KW) && p.nth(1) == PIPE)); - let m = p.start(); - p.eat(MOVE_KW); - params::param_list_opt_types(p); - if fn_ret_type(p) { - block(p); - } else { - expr(p); - } - m.complete(p, LAMBDA_EXPR) -} - -// test if_expr -// fn foo() { -// if true {}; -// if true {} else {}; -// if true {} else if false {} else {}; -// if S {}; -// } -fn if_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(IF_KW)); - let m = p.start(); - p.bump(); - cond(p); - block(p); - if p.at(ELSE_KW) { - p.bump(); - if p.at(IF_KW) { - if_expr(p); - } else { - block(p); - } - } - m.complete(p, IF_EXPR) -} - -// test while_expr -// fn foo() { -// while true {}; -// while let Some(x) = it.next() {}; -// } -fn while_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(WHILE_KW)); - let m = p.start(); - p.bump(); - cond(p); - block(p); - m.complete(p, WHILE_EXPR) -} - -// test loop_expr -// fn foo() { -// loop {}; -// } -fn loop_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(LOOP_KW)); - let m = p.start(); - p.bump(); - block(p); - m.complete(p, LOOP_EXPR) -} - -// test for_expr -// fn foo() { -// for x in [] {}; -// } -fn for_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(FOR_KW)); - let m = p.start(); - p.bump(); - patterns::pattern(p); - p.expect(IN_KW); - expr_no_struct(p); - block(p); - m.complete(p, FOR_EXPR) -} - -// test cond -// fn foo() { if let Some(_) = None {} } -fn cond(p: &mut Parser) { - if p.eat(LET_KW) { - patterns::pattern(p); - p.expect(EQ); - } - expr_no_struct(p) -} - -// test match_expr -// fn foo() { -// match () { }; -// match S {}; -// } -fn match_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(MATCH_KW)); - let m = p.start(); - p.bump(); - expr_no_struct(p); - p.eat(L_CURLY); - while !p.at(EOF) && !p.at(R_CURLY) { - // test match_arms_commas - // fn foo() { - // match () { - // _ => (), - // _ => {} - // _ => () - // } - // } - if match_arm(p).is_block() { - p.eat(COMMA); - } else if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); - m.complete(p, MATCH_EXPR) -} - -// test match_arm -// fn foo() { -// match () { -// _ => (), -// X | Y if Z => (), -// }; -// } -fn match_arm(p: &mut Parser) -> BlockLike { - let m = p.start(); - loop { - patterns::pattern(p); - if !p.eat(PIPE) { - break; - } - } - if p.eat(IF_KW) { - expr_no_struct(p); - } - p.expect(FAT_ARROW); - let ret = expr_stmt(p); - m.complete(p, MATCH_ARM); - ret -} - -// test block_expr -// fn foo() { -// {}; -// unsafe {}; -// } -pub(super) fn block_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(L_CURLY) || p.at(UNSAFE_KW) && p.nth(1) == L_CURLY); - let m = p.start(); - p.eat(UNSAFE_KW); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - LET_KW => let_stmt(p), - _ => { - // test block_items - // fn a() { fn b() {} } - let m = p.start(); - match items::maybe_item(p) { - items::MaybeItem::Item(kind) => { - m.complete(p, kind); - } - items::MaybeItem::Modifiers => { - m.abandon(p); - p.error("expected an item"); - } - // test pub_expr - // fn foo() { pub 92; } //FIXME - items::MaybeItem::None => { - let is_blocklike = expressions::expr_stmt(p) == BlockLike::Block; - if p.eat(SEMI) || (is_blocklike && !p.at(R_CURLY)) { - m.complete(p, EXPR_STMT); - } else { - m.abandon(p); - } - } - } - } - } - } - p.expect(R_CURLY); - m.complete(p, BLOCK_EXPR) -} - -// test let_stmt; -// fn foo() { -// let a; -// let b: i32; -// let c = 92; -// let d: i32 = 92; -// } -fn let_stmt(p: &mut Parser) { - assert!(p.at(LET_KW)); - let m = p.start(); - p.bump(); - patterns::pattern(p); - if p.at(COLON) { - types::ascription(p); - } - if p.eat(EQ) { - expressions::expr(p); - } - p.expect(SEMI); - m.complete(p, LET_STMT); -} - -// test return_expr -// fn foo() { -// return; -// return 92; -// } -fn return_expr(p: &mut Parser) -> CompletedMarker { - assert!(p.at(RETURN_KW)); - let m = p.start(); - p.bump(); - if EXPR_FIRST.contains(p.current()) { - expr(p); - } - m.complete(p, RETURN_EXPR) -} diff --git a/src/grammar/expressions/mod.rs b/src/grammar/expressions/mod.rs deleted file mode 100644 index dcbb1e2a8..000000000 --- a/src/grammar/expressions/mod.rs +++ /dev/null @@ -1,379 +0,0 @@ -mod atom; - -use super::*; -pub(super) use self::atom::literal; - -const EXPR_FIRST: TokenSet = LHS_FIRST; - -pub(super) fn expr(p: &mut Parser) -> BlockLike { - let r = Restrictions { forbid_structs: false, prefer_stmt: false }; - expr_bp(p, r, 1) -} - -pub(super) fn expr_stmt(p: &mut Parser) -> BlockLike { - let r = Restrictions { forbid_structs: false, prefer_stmt: true }; - expr_bp(p, r, 1) -} - -fn expr_no_struct(p: &mut Parser) { - let r = Restrictions { forbid_structs: true, prefer_stmt: false }; - expr_bp(p, r, 1); -} - -// test block -// fn a() {} -// fn b() { let _ = 1; } -// fn c() { 1; 2; } -// fn d() { 1; 2 } -pub(super) fn block(p: &mut Parser) { - if !p.at(L_CURLY) { - p.error("expected block"); - return; - } - atom::block_expr(p); -} - -#[derive(Clone, Copy)] -struct Restrictions { - forbid_structs: bool, - prefer_stmt: bool, -} - -enum Op { - Simple, - Composite(SyntaxKind, u8), -} - -fn current_op(p: &Parser) -> (u8, Op) { - if p.at_compound2(PLUS, EQ) { - return (1, Op::Composite(PLUSEQ, 2)); - } - if p.at_compound2(MINUS, EQ) { - return (1, Op::Composite(MINUSEQ, 2)); - } - if p.at_compound3(L_ANGLE, L_ANGLE, EQ) { - return (1, Op::Composite(SHLEQ, 3)); - } - if p.at_compound3(R_ANGLE, R_ANGLE, EQ) { - return (1, Op::Composite(SHREQ, 3)); - } - if p.at_compound2(PIPE, PIPE) { - return (3, Op::Composite(PIPEPIPE, 2)); - } - if p.at_compound2(AMP, AMP) { - return (4, Op::Composite(AMPAMP, 2)); - } - if p.at_compound2(L_ANGLE, EQ) { - return (5, Op::Composite(LTEQ, 2)); - } - if p.at_compound2(R_ANGLE, EQ) { - return (5, Op::Composite(GTEQ, 2)); - } - if p.at_compound2(L_ANGLE, L_ANGLE) { - return (9, Op::Composite(SHL, 2)); - } - if p.at_compound2(R_ANGLE, R_ANGLE) { - return (9, Op::Composite(SHR, 2)); - } - - let bp = match p.current() { - EQ => 1, - DOTDOT => 2, - EQEQ | NEQ | L_ANGLE | R_ANGLE => 5, - PIPE => 6, - CARET => 7, - AMP => 8, - MINUS | PLUS => 10, - STAR | SLASH | PERCENT => 11, - _ => 0, - }; - (bp, Op::Simple) -} - -// Parses expression with binding power of at least bp. -fn expr_bp(p: &mut Parser, r: Restrictions, bp: u8) -> BlockLike { - let mut lhs = match lhs(p, r) { - Some(lhs) => { - // test stmt_bin_expr_ambiguity - // fn foo() { - // let _ = {1} & 2; - // {1} &2; - // } - if r.prefer_stmt && is_block(lhs.kind()) { - return BlockLike::Block; - } - lhs - } - None => return BlockLike::NotBlock, - }; - - loop { - let is_range = p.current() == DOTDOT; - let (op_bp, op) = current_op(p); - if op_bp < bp { - break; - } - let m = lhs.precede(p); - match op { - Op::Simple => p.bump(), - Op::Composite(kind, n) => { - p.bump_compound(kind, n); - } - } - expr_bp(p, r, op_bp + 1); - lhs = m.complete(p, if is_range { RANGE_EXPR } else { BIN_EXPR }); - } - BlockLike::NotBlock -} - -// test no_semi_after_block -// fn foo() { -// if true {} -// loop {} -// match () {} -// while true {} -// for _ in () {} -// {} -// {} -// } -fn is_block(kind: SyntaxKind) -> bool { - match kind { - IF_EXPR | WHILE_EXPR | FOR_EXPR | LOOP_EXPR | MATCH_EXPR | BLOCK_EXPR => true, - _ => false, - } -} - -const LHS_FIRST: TokenSet = - token_set_union![ - token_set![AMP, STAR, EXCL, DOTDOT, MINUS], - atom::ATOM_EXPR_FIRST, - ]; - -fn lhs(p: &mut Parser, r: Restrictions) -> Option { - let m; - let kind = match p.current() { - // test ref_expr - // fn foo() { - // let _ = &1; - // let _ = &mut &f(); - // } - AMP => { - m = p.start(); - p.bump(); - p.eat(MUT_KW); - REF_EXPR - } - // test unary_expr - // fn foo() { - // **&1; - // !!true; - // --1; - // } - STAR | EXCL | MINUS => { - m = p.start(); - p.bump(); - PREFIX_EXPR - } - DOTDOT => { - m = p.start(); - p.bump(); - expr_bp(p, r, 2); - return Some(m.complete(p, RANGE_EXPR)); - } - _ => { - let lhs = atom::atom_expr(p, r)?; - return Some(postfix_expr(p, r, lhs)); - } - }; - expr_bp(p, r, 255); - Some(m.complete(p, kind)) -} - -fn postfix_expr(p: &mut Parser, r: Restrictions, mut lhs: CompletedMarker) -> CompletedMarker { - let mut allow_calls = !r.prefer_stmt || !is_block(lhs.kind()); - loop { - lhs = match p.current() { - // test stmt_postfix_expr_ambiguity - // fn foo() { - // match () { - // _ => {} - // () => {} - // [] => {} - // } - // } - L_PAREN if allow_calls => call_expr(p, lhs), - L_BRACK if allow_calls => index_expr(p, lhs), - DOT if p.nth(1) == IDENT => if p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON { - method_call_expr(p, lhs) - } else { - field_expr(p, lhs) - }, - DOT if p.nth(1) == INT_NUMBER => field_expr(p, lhs), - // test postfix_range - // fn foo() { let x = 1..; } - DOTDOT if !EXPR_FIRST.contains(p.nth(1)) => { - let m = lhs.precede(p); - p.bump(); - m.complete(p, RANGE_EXPR) - } - QUESTION => try_expr(p, lhs), - AS_KW => cast_expr(p, lhs), - _ => break, - }; - allow_calls = true - } - lhs -} - -// test call_expr -// fn foo() { -// let _ = f(); -// let _ = f()(1)(1, 2,); -// } -fn call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(L_PAREN)); - let m = lhs.precede(p); - arg_list(p); - m.complete(p, CALL_EXPR) -} - -// test index_expr -// fn foo() { -// x[1][2]; -// } -fn index_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(L_BRACK)); - let m = lhs.precede(p); - p.bump(); - expr(p); - p.expect(R_BRACK); - m.complete(p, INDEX_EXPR) -} - -// test method_call_expr -// fn foo() { -// x.foo(); -// y.bar::(1, 2,); -// } -fn method_call_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!( - p.at(DOT) && p.nth(1) == IDENT - && (p.nth(2) == L_PAREN || p.nth(2) == COLONCOLON) - ); - let m = lhs.precede(p); - p.bump(); - name_ref(p); - type_args::type_arg_list(p, true); - arg_list(p); - m.complete(p, METHOD_CALL_EXPR) -} - -// test field_expr -// fn foo() { -// x.foo; -// x.0.bar; -// } -fn field_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(DOT) && (p.nth(1) == IDENT || p.nth(1) == INT_NUMBER)); - let m = lhs.precede(p); - p.bump(); - if p.at(IDENT) { - name_ref(p) - } else { - p.bump() - } - m.complete(p, FIELD_EXPR) -} - -// test try_expr -// fn foo() { -// x?; -// } -fn try_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(QUESTION)); - let m = lhs.precede(p); - p.bump(); - m.complete(p, TRY_EXPR) -} - -// test cast_expr -// fn foo() { -// 82 as i32; -// } -fn cast_expr(p: &mut Parser, lhs: CompletedMarker) -> CompletedMarker { - assert!(p.at(AS_KW)); - let m = lhs.precede(p); - p.bump(); - types::type_(p); - m.complete(p, CAST_EXPR) -} - -fn arg_list(p: &mut Parser) { - assert!(p.at(L_PAREN)); - let m = p.start(); - p.bump(); - while !p.at(R_PAREN) && !p.at(EOF) { - expr(p); - if !p.at(R_PAREN) && !p.expect(COMMA) { - break; - } - } - p.eat(R_PAREN); - m.complete(p, ARG_LIST); -} - -// test path_expr -// fn foo() { -// let _ = a; -// let _ = a::b; -// let _ = ::a::; -// let _ = format!(); -// } -fn path_expr(p: &mut Parser, r: Restrictions) -> CompletedMarker { - assert!(paths::is_path_start(p)); - let m = p.start(); - paths::expr_path(p); - match p.current() { - L_CURLY if !r.forbid_structs => { - struct_lit(p); - m.complete(p, STRUCT_LIT) - } - EXCL => { - items::macro_call_after_excl(p); - m.complete(p, MACRO_CALL) - } - _ => m.complete(p, PATH_EXPR) - } -} - -// test struct_lit -// fn foo() { -// S {}; -// S { x, y: 32, }; -// S { x, y: 32, ..Default::default() }; -// } -fn struct_lit(p: &mut Parser) { - assert!(p.at(L_CURLY)); - p.bump(); - while !p.at(EOF) && !p.at(R_CURLY) { - match p.current() { - IDENT => { - let m = p.start(); - name_ref(p); - if p.eat(COLON) { - expr(p); - } - m.complete(p, STRUCT_LIT_FIELD); - } - DOTDOT => { - p.bump(); - expr(p); - } - _ => p.err_and_bump("expected identifier"), - } - if !p.at(R_CURLY) { - p.expect(COMMA); - } - } - p.expect(R_CURLY); -} -- cgit v1.2.3