Skip to content

Commit ee5ff37

Browse files
committed
chore: Improve keyword_enum macro
No need to use a separate slice for storing `CaseInsensitiveStr` members. Implemented binary search with custom case insensitive comparator using `binary_search_by`. Removed the dependency of the `keyword_enum` to `CaseInsensitiveStr` altogether.
1 parent 78bc712 commit ee5ff37

5 files changed

Lines changed: 18 additions & 32 deletions

File tree

rusty_common/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,6 @@ mod positioned;
77

88
pub use self::case_insensitive_str::*;
99
pub use self::case_insensitive_string::*;
10+
pub use self::case_insensitive_utils::*;
1011
pub use self::position::*;
1112
pub use self::positioned::*;

rusty_parser/src/specific/built_ins/built_in_function.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
1-
use crate::keyword_enum;
21
use crate::specific::{QualifiedName, TypeQualifier};
2+
use crate::{keyword_enum, BareName};
33
use rusty_common::*;
4-
use std::borrow::Borrow;
54
use std::convert::TryFrom;
65

76
keyword_enum!(
8-
pub enum BuiltInFunction SORTED_BUILT_IN_FUNCTIONS SORTED_BUILT_IN_FUNCTION_NAMES SORTED_BUILT_IN_FUNCTIONS_CI_STR {
7+
pub enum BuiltInFunction SORTED_BUILT_IN_FUNCTIONS SORTED_BUILT_IN_FUNCTION_NAMES {
98
/// `CHR$(ascii-code%)` returns the text representation of the given ascii code
109
Chr,
1110

@@ -163,10 +162,7 @@ impl From<BuiltInFunction> for QualifiedName {
163162
// CaseInsensitiveString -> BuiltInFunction
164163

165164
impl BuiltInFunction {
166-
pub fn try_parse<S>(s: &S) -> Option<Self>
167-
where
168-
S: Borrow<CaseInsensitiveStr>,
169-
{
170-
Self::try_from(s.borrow()).ok()
165+
pub fn try_parse(s: &BareName) -> Option<Self> {
166+
Self::try_from(s.as_str()).ok()
171167
}
172168
}

rusty_parser/src/specific/core/keyword.rs

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use crate::pc::Token;
22
use crate::specific::pc_specific::TokenType;
3-
use rusty_common::CaseInsensitiveStr;
3+
4+
use rusty_common::cmp_str;
45

56
// From the internets:
67
// Doc comments are secretly just attributes,
@@ -13,7 +14,7 @@ use rusty_common::CaseInsensitiveStr;
1314

1415
#[macro_export]
1516
macro_rules! keyword_enum {
16-
($vis:vis enum $name:ident $all_names:ident $all_names_as_str:ident $all_names_as_case_insensitive_str:ident {
17+
($vis:vis enum $name:ident $all_names:ident $all_names_as_str:ident {
1718
$($(#[$($attrss:tt)*])*$member:ident),+$(,)?
1819
}) => {
1920
#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
@@ -25,14 +26,10 @@ macro_rules! keyword_enum {
2526
$($name::$member),+
2627
];
2728

28-
pub const $all_names_as_str : &[&str] = &[
29+
const $all_names_as_str : &[&str] = &[
2930
$(stringify!($member)),+
3031
];
3132

32-
const $all_names_as_case_insensitive_str : &[&CaseInsensitiveStr] = &[
33-
$( CaseInsensitiveStr::new( stringify!($member) ) ),+
34-
];
35-
3633
impl std::fmt::Display for $name {
3734
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
3835
self.as_ref().to_uppercase().fmt(f)
@@ -48,19 +45,19 @@ macro_rules! keyword_enum {
4845
}
4946
}
5047

51-
impl TryFrom<&CaseInsensitiveStr> for $name {
48+
impl TryFrom<&str> for $name {
5249
type Error = usize;
5350

54-
fn try_from(s: &CaseInsensitiveStr) -> Result<$name, usize> {
55-
$all_names_as_case_insensitive_str.binary_search(&s)
51+
fn try_from(s: &str) -> Result<$name, usize> {
52+
$all_names_as_str.binary_search_by(|probe| cmp_str(probe, s))
5653
.map(|index| $all_names[index])
5754
}
5855
}
5956

6057
};
6158
}
6259

63-
keyword_enum!(pub enum Keyword SORTED_KEYWORDS SORTED_KEYWORDS_STR SORTED_KEYWORDS_CI_STR {
60+
keyword_enum!(pub enum Keyword SORTED_KEYWORDS SORTED_KEYWORDS_STR {
6461
/// ACCESS
6562
Access,
6663
/// AND
@@ -220,8 +217,7 @@ impl PartialEq<Token> for Keyword {
220217
impl From<&Token> for Keyword {
221218
fn from(token: &Token) -> Self {
222219
debug_assert_eq!(token.kind, TokenType::Keyword.into());
223-
let temp = CaseInsensitiveStr::new(&token.text);
224-
Self::try_from(temp).expect("Token keyword not found in keywords!")
220+
Self::try_from(token.text.as_str()).expect("Token keyword not found in keywords!")
225221
}
226222
}
227223

rusty_parser/src/specific/core/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ pub use self::global_statement::{
5959
program_parser_p, FunctionDeclaration, FunctionImplementation, GlobalStatement,
6060
GlobalStatementPos, Program, SubDeclaration, SubImplementation, SubprogramImplementation,
6161
};
62-
pub use self::keyword::{Keyword, SORTED_KEYWORDS_STR};
62+
pub use self::keyword::Keyword;
6363
pub use self::letter_range::LetterRange;
6464
pub use self::name::{Name, NameAsTokens, NamePos};
6565
pub use self::operator::Operator;

rusty_parser/src/specific/pc_specific/recognizers_impl.rs

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::pc::*;
55
use crate::specific::pc_specific::recognizers_impl::string_parsers::CharToStringParser;
66
use crate::specific::pc_specific::recognizers_impl::token_parsers::StringToTokenParser;
77
use crate::specific::pc_specific::TokenType;
8-
use crate::specific::SORTED_KEYWORDS_STR;
8+
use crate::Keyword;
99
use std::fs::File;
1010

1111
// TODO keyword --> ensure not followed by dollar sign
@@ -137,15 +137,8 @@ fn digits() -> impl Parser<RcStringView, Output = Token> {
137137
fn keyword() -> impl Parser<RcStringView, Output = Token> {
138138
// using is_ascii_alphanumeric to read e.g. Sub1 and determine it is not a keyword
139139
// TODO can be done in a different way e.g. read alphabetic and then ensure it's followed by something other than alphanumeric
140-
many(TokenType::Keyword, char::is_ascii_alphanumeric).filter(|token| {
141-
let text = &token.text;
142-
for keyword in SORTED_KEYWORDS_STR {
143-
if keyword.eq_ignore_ascii_case(text) {
144-
return true;
145-
}
146-
}
147-
false
148-
})
140+
many(TokenType::Keyword, char::is_ascii_alphanumeric)
141+
.filter(|token| Keyword::try_from(token.text.as_str()).is_ok())
149142
}
150143

151144
fn identifier() -> impl Parser<RcStringView, Output = Token> {

0 commit comments

Comments
 (0)