Moved implementation from header

This commit is contained in:
Robert Bendun 2022-05-07 18:39:29 +02:00
parent 03d02d608c
commit 108b7f1fee
2 changed files with 39 additions and 26 deletions

View File

@ -189,6 +189,34 @@ auto Lexer::consume() -> u32
return 0; return 0;
} }
auto Lexer::consume_if(auto test) -> bool
{
bool condition;
if constexpr (requires { test(peek()) && true; }) {
condition = test(peek());
} else if constexpr (std::is_integral_v<decltype(test)>) {
condition = (u32(test) == peek());
} else if constexpr (std::is_convertible_v<decltype(test), char const*>) {
auto const end = test + std::strlen(test);
condition = std::find(test, end, peek()) != end;
} else {
condition = std::find(std::begin(test), std::end(test), peek()) != std::end(test);
}
return condition && (consume(), true);
}
auto Lexer::consume_if(auto first, auto second) -> bool
{
if (consume_if(first)) {
if (consume_if(second)) {
return true;
} else {
rewind();
}
}
return false;
}
void Lexer::rewind() void Lexer::rewind()
{ {
assert(last_rune_length != 0); assert(last_rune_length != 0);

View File

@ -208,33 +208,18 @@ struct Lexer
// Finds next rune in source and returns it, advancing the string // Finds next rune in source and returns it, advancing the string
auto consume() -> u32; auto consume() -> u32;
inline auto consume_if(auto test) -> bool // For test beeing
{ // callable, current rune is passed to test
bool condition; // integral, current rune is tested for equality with test
if constexpr (requires { test(peek()) && true; }) { // string, current rune is tested for beeing in it
condition = test(peek()); // otherwise, current rune is tested for beeing in test
} else if constexpr (std::is_integral_v<decltype(test)>) { //
condition = (u32(test) == peek()); // When testing above yields truth, current rune is consumed.
} else if constexpr (std::is_convertible_v<decltype(test), char const*>) { // Returns if rune was consumed
auto const end = test + std::strlen(test); auto consume_if(auto test) -> bool;
condition = std::find(test, end, peek()) != end;
} else {
condition = std::find(std::begin(test), std::end(test), peek()) != std::end(test);
}
return condition && (consume(), true);
}
inline auto consume_if(auto first, auto second) -> bool // Consume two runes with given tests otherwise backtrack
{ auto consume_if(auto first, auto second) -> bool;
if (consume_if(first)) {
if (consume_if(second)) {
return true;
} else {
rewind();
}
}
return false;
}
// Goes back last rune // Goes back last rune
void rewind(); void rewind();