Major updates/cleanup.
This commit is contained in:
@@ -0,0 +1,120 @@
|
||||
#include "internal/syntax/miniparser.h"
|
||||
|
||||
namespace bed::internal::syntax {
|
||||
MiniParser::MiniParser(Language &lang, vase::Shard *vase, void *initial_state)
|
||||
: lang(lang),
|
||||
start_state(initial_state ? lang.copy(initial_state) : lang.none_state()) {
|
||||
vase::Iterator it(vase, 0, Direction::Forward);
|
||||
void *state = lang.copy(start_state);
|
||||
std::vector<io::Token> tokens;
|
||||
std::vector<ParseEvent> events;
|
||||
const uint64_t count = vase ? vase->lines + 1 : 0;
|
||||
lines.reserve(count);
|
||||
for (uint64_t i = 0; i < count; ++i) {
|
||||
it.next();
|
||||
tokens.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, i == 0, &tokens, &events);
|
||||
lines.emplace_back(lang.copy(state), std::move(tokens));
|
||||
}
|
||||
lang.destroy(state);
|
||||
}
|
||||
|
||||
MiniParser::~MiniParser() {
|
||||
if (start_state)
|
||||
lang.destroy(start_state);
|
||||
for (auto &[state, tokens] : lines)
|
||||
if (state)
|
||||
lang.destroy(state);
|
||||
}
|
||||
|
||||
void MiniParser::dirty(vase::Shard *vase, uint64_t start, uint64_t count) {
|
||||
vase::Iterator it(vase, start, Direction::Forward);
|
||||
void *state = start ? lang.copy(lines[start - 1].first)
|
||||
: lang.copy(start_state);
|
||||
std::vector<ParseEvent> events;
|
||||
uint64_t i = start;
|
||||
for (; i < start + count; i++) {
|
||||
it.next();
|
||||
auto &line = lines[i];
|
||||
line.second.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, i == 0, &line.second, &events);
|
||||
lang.destroy(line.first);
|
||||
line.first = lang.copy(state);
|
||||
}
|
||||
while (it.next()) {
|
||||
auto &line = lines[i++];
|
||||
line.second.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, false, &line.second, &events);
|
||||
if (lang.equal(line.first, state))
|
||||
break;
|
||||
lang.destroy(line.first);
|
||||
line.first = lang.copy(state);
|
||||
}
|
||||
lang.destroy(state);
|
||||
}
|
||||
|
||||
void MiniParser::insert(vase::Shard *vase, uint64_t start, uint64_t count) {
|
||||
vase::Iterator it(vase, start, Direction::Forward);
|
||||
void *state = start ? lang.copy(lines[start - 1].first)
|
||||
: lang.copy(start_state);
|
||||
std::vector<ParseEvent> events;
|
||||
std::vector<std::pair<void *, std::vector<io::Token>>> lines_new;
|
||||
std::vector<io::Token> tokens;
|
||||
lines_new.reserve(count);
|
||||
for (uint64_t i = 0; i < count; ++i) {
|
||||
it.next();
|
||||
tokens.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, start + i == 0, &tokens, &events);
|
||||
lines_new.emplace_back(lang.copy(state), std::move(tokens));
|
||||
}
|
||||
uint64_t i = start;
|
||||
while (it.next()) {
|
||||
auto &line = lines[i++];
|
||||
line.second.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, i == 0, &line.second, &events);
|
||||
if (lang.equal(line.first, state))
|
||||
break;
|
||||
lang.destroy(line.first);
|
||||
line.first = lang.copy(state);
|
||||
}
|
||||
lines.insert(
|
||||
lines.begin() + start,
|
||||
std::make_move_iterator(lines_new.begin()),
|
||||
std::make_move_iterator(lines_new.end())
|
||||
);
|
||||
lang.destroy(state);
|
||||
}
|
||||
|
||||
void MiniParser::erase(vase::Shard *vase, uint64_t start, uint64_t count) {
|
||||
if (count == 0)
|
||||
return;
|
||||
void *state = start ? lang.copy(lines[start - 1].first)
|
||||
: lang.copy(start_state);
|
||||
std::vector<ParseEvent> events;
|
||||
for (uint64_t i = start; i < start + count; ++i)
|
||||
if (lines[i].first)
|
||||
lang.destroy(lines[i].first);
|
||||
lines.erase(
|
||||
lines.begin() + start,
|
||||
lines.begin() + start + count
|
||||
);
|
||||
vase::Iterator it(vase, start, Direction::Forward);
|
||||
uint64_t i = start;
|
||||
while (i < lines.size() && it.next()) {
|
||||
auto &line = lines[i];
|
||||
line.second.clear();
|
||||
events.clear();
|
||||
lang.parse(&state, it.line, i++ == 0, &line.second, &events);
|
||||
if (lang.equal(line.first, state))
|
||||
break;
|
||||
lang.destroy(line.first);
|
||||
line.first = lang.copy(state);
|
||||
}
|
||||
lang.destroy(state);
|
||||
}
|
||||
} // namespace bed::internal::syntax
|
||||
Reference in New Issue
Block a user