summaryrefslogtreecommitdiff
path: root/src/command_manager.cc
diff options
context:
space:
mode:
authorMaxime Coste <mawww@kakoune.org>2021-07-20 19:53:06 +1000
committerMaxime Coste <mawww@kakoune.org>2021-07-20 22:30:41 +1000
commite3957bb24c85b156877cd21f89b15d5bb7836415 (patch)
treeb039b72369e243d84b3a5175e3cb805bc540183b /src/command_manager.cc
parenta4dd89f214e72005f551cd071d7642652c2922c5 (diff)
Generate different parse_quoted_balanced for each quote pair
This seems to slightly improve parse speed which is where kakoune spends most of its time during startup.
Diffstat (limited to 'src/command_manager.cc')
-rw-r--r--src/command_manager.cc25
1 files changed, 14 insertions, 11 deletions
diff --git a/src/command_manager.cc b/src/command_manager.cc
index 0a7ecaad..32c25322 100644
--- a/src/command_manager.cc
+++ b/src/command_manager.cc
@@ -131,7 +131,8 @@ ParseResult parse_quoted(ParseState& state, Codepoint delimiter)
return {str, false};
}
-ParseResult parse_quoted_balanced(ParseState& state, char opening_delimiter, char closing_delimiter)
+template<char opening_delimiter, char closing_delimiter>
+ParseResult parse_quoted_balanced(ParseState& state)
{
int level = 1;
const char* pos = state.pos;
@@ -255,8 +256,11 @@ Token parse_percent_token(ParseState& state, bool throw_on_unterminated)
Token::Type type = token_type(type_name, throw_on_unterminated);
- constexpr struct CharPair { char opening; char closing; } matching_pairs[] = {
- { '(', ')' }, { '[', ']' }, { '{', '}' }, { '<', '>' }
+ constexpr struct CharPair { char opening; char closing; ParseResult (*parse_func)(ParseState&); } matching_pairs[] = {
+ { '(', ')', parse_quoted_balanced<'(', ')'> },
+ { '[', ']', parse_quoted_balanced<'[', ']'> },
+ { '{', '}', parse_quoted_balanced<'{', '}'> },
+ { '<', '>', parse_quoted_balanced<'<', '>'> }
};
auto start = state.pos;
@@ -265,14 +269,13 @@ Token parse_percent_token(ParseState& state, bool throw_on_unterminated)
if (auto it = find_if(matching_pairs, [=](const CharPair& cp) { return opening_delimiter == cp.opening; });
it != std::end(matching_pairs))
{
- const Codepoint closing_delimiter = it->closing;
- auto quoted = parse_quoted_balanced(state, opening_delimiter, closing_delimiter);
+ auto quoted = it->parse_func(state);
if (throw_on_unterminated and not quoted.terminated)
{
auto coord = compute_coord({state.str.begin(), start});
throw parse_error{format("{}:{}: unterminated string '%{}{}...{}'",
coord.line+1, coord.column+1, type_name,
- opening_delimiter, closing_delimiter)};
+ it->opening, it->closing)};
}
return {type, byte_pos, std::move(quoted.content), quoted.terminated};
@@ -801,16 +804,16 @@ UnitTest test_command_parsing{[]
check_quoted("'abc''def", false, "abc'def");
check_quoted("'abc''def'''", true, "abc'def'");
- auto check_balanced = [](StringView str, Codepoint opening, Codepoint closing, bool terminated, StringView content)
+ auto check_balanced = [](StringView str, bool terminated, StringView content)
{
ParseState state{str, str.begin()+1};
- auto quoted = parse_quoted_balanced(state, opening, closing);
+ auto quoted = parse_quoted_balanced<'{', '}'>(state);
kak_assert(quoted.terminated == terminated);
kak_assert(quoted.content == content);
};
- check_balanced("{abc}", '{', '}', true, "abc");
- check_balanced("{abc{def}}", '{', '}', true, "abc{def}");
- check_balanced("{{abc}{def}", '{', '}', false, "{abc}{def}");
+ check_balanced("{abc}", true, "abc");
+ check_balanced("{abc{def}}", true, "abc{def}");
+ check_balanced("{{abc}{def}", false, "{abc}{def}");
auto check_unquoted = [](StringView str, StringView content)
{