CONST LOOPS ARE HERE

This commit is contained in:
Aleksey Kladov 2020-08-27 18:11:33 +02:00
parent 6f6580dec7
commit 4b989009e3
8 changed files with 38 additions and 29 deletions

View file

@ -316,7 +316,7 @@ fn expr_bp(p: &mut Parser, mut r: Restrictions, bp: u8) -> (Option<CompletedMark
} }
const LHS_FIRST: TokenSet = const LHS_FIRST: TokenSet =
atom::ATOM_EXPR_FIRST.union(token_set![T![&], T![*], T![!], T![.], T![-]]); atom::ATOM_EXPR_FIRST.union(TokenSet::new(&[T![&], T![*], T![!], T![.], T![-]]));
fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { fn lhs(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
let m; let m;

View file

@ -15,7 +15,7 @@ use super::*;
// let _ = b"e"; // let _ = b"e";
// let _ = br"f"; // let _ = br"f";
// } // }
pub(crate) const LITERAL_FIRST: TokenSet = token_set![ pub(crate) const LITERAL_FIRST: TokenSet = TokenSet::new(&[
TRUE_KW, TRUE_KW,
FALSE_KW, FALSE_KW,
INT_NUMBER, INT_NUMBER,
@ -25,8 +25,8 @@ pub(crate) const LITERAL_FIRST: TokenSet = token_set![
STRING, STRING,
RAW_STRING, RAW_STRING,
BYTE_STRING, BYTE_STRING,
RAW_BYTE_STRING RAW_BYTE_STRING,
]; ]);
pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> { pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
if !p.at_ts(LITERAL_FIRST) { if !p.at_ts(LITERAL_FIRST) {
@ -39,7 +39,7 @@ pub(crate) fn literal(p: &mut Parser) -> Option<CompletedMarker> {
// E.g. for after the break in `if break {}`, this should not match // E.g. for after the break in `if break {}`, this should not match
pub(super) const ATOM_EXPR_FIRST: TokenSet = pub(super) const ATOM_EXPR_FIRST: TokenSet =
LITERAL_FIRST.union(paths::PATH_FIRST).union(token_set![ LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[
T!['('], T!['('],
T!['{'], T!['{'],
T!['['], T!['['],
@ -59,9 +59,9 @@ pub(super) const ATOM_EXPR_FIRST: TokenSet =
T![loop], T![loop],
T![for], T![for],
LIFETIME, LIFETIME,
]); ]));
const EXPR_RECOVERY_SET: TokenSet = token_set![LET_KW, R_DOLLAR]; const EXPR_RECOVERY_SET: TokenSet = TokenSet::new(&[LET_KW, R_DOLLAR]);
pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> { pub(super) fn atom_expr(p: &mut Parser, r: Restrictions) -> Option<(CompletedMarker, BlockLike)> {
if let Some(m) = literal(p) { if let Some(m) = literal(p) {

View file

@ -26,7 +26,7 @@ pub(super) fn mod_contents(p: &mut Parser, stop_on_r_curly: bool) {
} }
} }
pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![ pub(super) const ITEM_RECOVERY_SET: TokenSet = TokenSet::new(&[
FN_KW, FN_KW,
STRUCT_KW, STRUCT_KW,
ENUM_KW, ENUM_KW,
@ -41,7 +41,7 @@ pub(super) const ITEM_RECOVERY_SET: TokenSet = token_set![
USE_KW, USE_KW,
MACRO_KW, MACRO_KW,
T![;], T![;],
]; ]);
pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) { pub(super) fn item_or_macro(p: &mut Parser, stop_on_r_curly: bool) {
let m = p.start(); let m = p.start();

View file

@ -3,7 +3,7 @@
use super::*; use super::*;
pub(super) const PATH_FIRST: TokenSet = pub(super) const PATH_FIRST: TokenSet =
token_set![IDENT, T![self], T![super], T![crate], T![:], T![<]]; TokenSet::new(&[IDENT, T![self], T![super], T![crate], T![:], T![<]]);
pub(super) fn is_path_start(p: &Parser) -> bool { pub(super) fn is_path_start(p: &Parser) -> bool {
is_use_path_start(p) || p.at(T![<]) is_use_path_start(p) || p.at(T![<])

View file

@ -2,9 +2,18 @@
use super::*; use super::*;
pub(super) const PATTERN_FIRST: TokenSet = expressions::LITERAL_FIRST pub(super) const PATTERN_FIRST: TokenSet =
.union(paths::PATH_FIRST) expressions::LITERAL_FIRST.union(paths::PATH_FIRST).union(TokenSet::new(&[
.union(token_set![T![box], T![ref], T![mut], T!['('], T!['['], T![&], T![_], T![-], T![.]]); T![box],
T![ref],
T![mut],
T!['('],
T!['['],
T![&],
T![_],
T![-],
T![.],
]));
pub(crate) fn pattern(p: &mut Parser) { pub(crate) fn pattern(p: &mut Parser) {
pattern_r(p, PAT_RECOVERY_SET); pattern_r(p, PAT_RECOVERY_SET);
@ -74,7 +83,7 @@ fn pattern_single_r(p: &mut Parser, recovery_set: TokenSet) {
} }
const PAT_RECOVERY_SET: TokenSet = const PAT_RECOVERY_SET: TokenSet =
token_set![LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]; TokenSet::new(&[LET_KW, IF_KW, WHILE_KW, LOOP_KW, MATCH_KW, R_PAREN, COMMA]);
fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> { fn atom_pat(p: &mut Parser, recovery_set: TokenSet) -> Option<CompletedMarker> {
let m = match p.nth(0) { let m = match p.nth(0) {

View file

@ -2,7 +2,7 @@
use super::*; use super::*;
pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(TokenSet::new(&[
T!['('], T!['('],
T!['['], T!['['],
T![<], T![<],
@ -16,16 +16,16 @@ pub(super) const TYPE_FIRST: TokenSet = paths::PATH_FIRST.union(token_set![
T![for], T![for],
T![impl], T![impl],
T![dyn], T![dyn],
]); ]));
const TYPE_RECOVERY_SET: TokenSet = token_set![ const TYPE_RECOVERY_SET: TokenSet = TokenSet::new(&[
T![')'], T![')'],
T![,], T![,],
L_DOLLAR, L_DOLLAR,
// test_err struct_field_recover // test_err struct_field_recover
// struct S { f pub g: () } // struct S { f pub g: () }
T![pub], T![pub],
]; ]);
pub(crate) fn type_(p: &mut Parser) { pub(crate) fn type_(p: &mut Parser) {
type_with_bounds_cond(p, true); type_with_bounds_cond(p, true);

View file

@ -9,15 +9,21 @@ pub(crate) struct TokenSet(u128);
impl TokenSet { impl TokenSet {
pub(crate) const EMPTY: TokenSet = TokenSet(0); pub(crate) const EMPTY: TokenSet = TokenSet(0);
pub(crate) const fn singleton(kind: SyntaxKind) -> TokenSet { pub(crate) const fn new(kinds: &[SyntaxKind]) -> TokenSet {
TokenSet(mask(kind)) let mut res = 0u128;
let mut i = 0;
while i < kinds.len() {
res |= mask(kinds[i]);
i += 1
}
TokenSet(res)
} }
pub(crate) const fn union(self, other: TokenSet) -> TokenSet { pub(crate) const fn union(self, other: TokenSet) -> TokenSet {
TokenSet(self.0 | other.0) TokenSet(self.0 | other.0)
} }
pub(crate) fn contains(&self, kind: SyntaxKind) -> bool { pub(crate) const fn contains(&self, kind: SyntaxKind) -> bool {
self.0 & mask(kind) != 0 self.0 & mask(kind) != 0
} }
} }
@ -26,16 +32,10 @@ const fn mask(kind: SyntaxKind) -> u128 {
1u128 << (kind as usize) 1u128 << (kind as usize)
} }
#[macro_export]
macro_rules! token_set {
($($t:expr),*) => { TokenSet::EMPTY$(.union(TokenSet::singleton($t)))* };
($($t:expr),* ,) => { token_set!($($t),*) };
}
#[test] #[test]
fn token_set_works_for_tokens() { fn token_set_works_for_tokens() {
use crate::SyntaxKind::*; use crate::SyntaxKind::*;
let ts = token_set![EOF, SHEBANG]; let ts = TokenSet::new(&[EOF, SHEBANG]);
assert!(ts.contains(EOF)); assert!(ts.contains(EOF));
assert!(ts.contains(SHEBANG)); assert!(ts.contains(SHEBANG));
assert!(!ts.contains(PLUS)); assert!(!ts.contains(PLUS));

View file

@ -7,7 +7,7 @@ use anyhow::{bail, format_err, Context, Result};
use crate::not_bash::{pushd, run}; use crate::not_bash::{pushd, run};
// Latest stable, feel free to send a PR if this lags behind. // Latest stable, feel free to send a PR if this lags behind.
const REQUIRED_RUST_VERSION: u32 = 43; const REQUIRED_RUST_VERSION: u32 = 46;
pub struct InstallCmd { pub struct InstallCmd {
pub client: Option<ClientOpt>, pub client: Option<ClientOpt>,