Make parser optional.
This commit is contained in:
@@ -15,6 +15,7 @@ struct BEd {
|
|||||||
internal::commands::Command eof_op;
|
internal::commands::Command eof_op;
|
||||||
std::array<std::optional<internal::commands::Suffix>, 26> suffixes;
|
std::array<std::optional<internal::commands::Suffix>, 26> suffixes;
|
||||||
internal::theme::Theme theme;
|
internal::theme::Theme theme;
|
||||||
|
std::unordered_map<std::string, internal::syntax::Language> languages;
|
||||||
|
|
||||||
bool help_mode = false;
|
bool help_mode = false;
|
||||||
std::string last_help = "";
|
std::string last_help = "";
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ namespace bed::internal::buffer {
|
|||||||
struct Buffer {
|
struct Buffer {
|
||||||
vase::Vase vase;
|
vase::Vase vase;
|
||||||
marks::MarksEngine marks;
|
marks::MarksEngine marks;
|
||||||
syntax::Language lang;
|
std::string language;
|
||||||
syntax::Parser parser;
|
std::optional<syntax::Parser> parser;
|
||||||
uint64_t line = 0;
|
uint64_t line = 0;
|
||||||
bool modified;
|
bool modified;
|
||||||
std::filesystem::path save_path = "";
|
std::filesystem::path save_path = "";
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ struct TreeCursor {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/*struct Symbol {
|
struct Symbol {
|
||||||
uint64_t definition;
|
uint64_t definition;
|
||||||
std::vector<uint64_t> references;
|
std::vector<uint64_t> references;
|
||||||
};
|
};
|
||||||
@@ -178,5 +178,5 @@ struct Scope {
|
|||||||
uint32_t type;
|
uint32_t type;
|
||||||
trie::Trie<Symbol> symbols;
|
trie::Trie<Symbol> symbols;
|
||||||
std::vector<std::variant<Space, Scope>> children;
|
std::vector<std::variant<Space, Scope>> children;
|
||||||
};*/
|
};
|
||||||
} // namespace bed::internal::syntax
|
} // namespace bed::internal::syntax
|
||||||
|
|||||||
@@ -6,12 +6,17 @@
|
|||||||
|
|
||||||
namespace bed::internal::syntax {
|
namespace bed::internal::syntax {
|
||||||
struct Parser {
|
struct Parser {
|
||||||
ParseState *root;
|
static constexpr const uint64_t MAX_CHUNK = 256;
|
||||||
Language ⟨
|
|
||||||
|
|
||||||
Parser(vase::Vase &, uint64_t, Language &);
|
ParseState *root;
|
||||||
|
Language lang;
|
||||||
|
|
||||||
|
Parser(vase::Vase &, uint64_t, Language);
|
||||||
~Parser();
|
~Parser();
|
||||||
void reset(vase::Vase &, uint64_t, Language &);
|
Parser(const Parser &) = delete;
|
||||||
|
Parser &operator=(const Parser &) = delete;
|
||||||
|
|
||||||
|
void reset(vase::Vase &, uint64_t, Language);
|
||||||
void erase(vase::Vase &, uint64_t, uint64_t);
|
void erase(vase::Vase &, uint64_t, uint64_t);
|
||||||
void insert(vase::Vase &, uint64_t, uint64_t);
|
void insert(vase::Vase &, uint64_t, uint64_t);
|
||||||
void modify(vase::Vase &, uint64_t, uint64_t);
|
void modify(vase::Vase &, uint64_t, uint64_t);
|
||||||
@@ -19,8 +24,9 @@ struct Parser {
|
|||||||
std::pair<ParseState *, ParseState *> split_tree(ParseState *node, uint64_t line);
|
std::pair<ParseState *, ParseState *> split_tree(ParseState *node, uint64_t line);
|
||||||
ParseState *join_tree(ParseState *a, ParseState *b);
|
ParseState *join_tree(ParseState *a, ParseState *b);
|
||||||
|
|
||||||
// Scope root;
|
Scope scope_root;
|
||||||
// Scope &get_scope(uint64_t);
|
Scope &get_scope(uint64_t);
|
||||||
|
|
||||||
struct Iterator {
|
struct Iterator {
|
||||||
Parser *p;
|
Parser *p;
|
||||||
std::optional<vase::Iterator> it;
|
std::optional<vase::Iterator> it;
|
||||||
|
|||||||
@@ -2,17 +2,14 @@
|
|||||||
#include "bed.h"
|
#include "bed.h"
|
||||||
|
|
||||||
namespace bed::internal::buffer {
|
namespace bed::internal::buffer {
|
||||||
Buffer::Buffer()
|
Buffer::Buffer() : vase("/tmp") {
|
||||||
: vase("/tmp"), lang(syntax::ruby::lang_ruby()),
|
parser.emplace(vase, vase.lines(), syntax::ruby::lang_ruby());
|
||||||
parser(vase, vase.lines(), lang) {
|
|
||||||
line = vase.lines();
|
line = vase.lines();
|
||||||
modified = false;
|
modified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(std::string command)
|
Buffer::Buffer(std::string command) : vase(command, "/tmp") {
|
||||||
: vase(command, "/tmp"),
|
parser.emplace(vase, vase.lines(), syntax::ruby::lang_ruby());
|
||||||
lang(syntax::ruby::lang_ruby()),
|
|
||||||
parser(vase, vase.lines(), lang) {
|
|
||||||
line = vase.lines();
|
line = vase.lines();
|
||||||
if (!line)
|
if (!line)
|
||||||
return;
|
return;
|
||||||
@@ -21,10 +18,8 @@ Buffer::Buffer(std::string command)
|
|||||||
modified = false;
|
modified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
Buffer::Buffer(std::filesystem::path path)
|
Buffer::Buffer(std::filesystem::path path) : vase(path, "/tmp") {
|
||||||
: vase(path, "/tmp"),
|
parser.emplace(vase, vase.lines(), syntax::ruby::lang_ruby());
|
||||||
lang(syntax::ruby::lang_ruby()),
|
|
||||||
parser(vase, vase.lines(), lang) {
|
|
||||||
line = vase.lines();
|
line = vase.lines();
|
||||||
if (!line)
|
if (!line)
|
||||||
return;
|
return;
|
||||||
@@ -37,7 +32,7 @@ Buffer::Buffer(std::filesystem::path path)
|
|||||||
void Buffer::load(std::string command) {
|
void Buffer::load(std::string command) {
|
||||||
vase::Vase new_vase = vase::Vase(command, "/tmp");
|
vase::Vase new_vase = vase::Vase(command, "/tmp");
|
||||||
vase = std::move(new_vase);
|
vase = std::move(new_vase);
|
||||||
parser.reset(vase, vase.lines(), lang);
|
parser.emplace(vase, vase.lines(), syntax::ruby::lang_ruby());
|
||||||
line = vase.lines();
|
line = vase.lines();
|
||||||
if (!line) {
|
if (!line) {
|
||||||
prev_range.start = 0;
|
prev_range.start = 0;
|
||||||
@@ -52,7 +47,7 @@ void Buffer::load(std::string command) {
|
|||||||
void Buffer::load(std::filesystem::path path) {
|
void Buffer::load(std::filesystem::path path) {
|
||||||
vase::Vase new_vase = vase::Vase(path, "/tmp");
|
vase::Vase new_vase = vase::Vase(path, "/tmp");
|
||||||
vase = std::move(new_vase);
|
vase = std::move(new_vase);
|
||||||
parser.reset(vase, vase.lines(), lang);
|
parser.emplace(vase, vase.lines(), syntax::ruby::lang_ruby());
|
||||||
line = vase.lines();
|
line = vase.lines();
|
||||||
if (!line) {
|
if (!line) {
|
||||||
prev_range.start = 0;
|
prev_range.start = 0;
|
||||||
@@ -110,17 +105,17 @@ inline void apply(std::ostream &out, const theme::Highlight &hl) {
|
|||||||
const uint8_t g = (hl.fg >> 8) & 0xff;
|
const uint8_t g = (hl.fg >> 8) & 0xff;
|
||||||
const uint8_t b = hl.fg & 0xff;
|
const uint8_t b = hl.fg & 0xff;
|
||||||
out << "\x1b[38;2;"
|
out << "\x1b[38;2;"
|
||||||
<< static_cast<unsigned>(r) << ';'
|
<< (unsigned)r << ';'
|
||||||
<< static_cast<unsigned>(g) << ';'
|
<< (unsigned)g << ';'
|
||||||
<< static_cast<unsigned>(b) << 'm';
|
<< (unsigned)b << 'm';
|
||||||
if (hl.bg != 0) {
|
if (hl.bg != 0) {
|
||||||
const uint8_t br = (hl.bg >> 16) & 0xff;
|
const uint8_t br = (hl.bg >> 16) & 0xff;
|
||||||
const uint8_t bg = (hl.bg >> 8) & 0xff;
|
const uint8_t bg = (hl.bg >> 8) & 0xff;
|
||||||
const uint8_t bb = hl.bg & 0xff;
|
const uint8_t bb = hl.bg & 0xff;
|
||||||
out << "\x1b[48;2;"
|
out << "\x1b[48;2;"
|
||||||
<< static_cast<unsigned>(br) << ';'
|
<< (unsigned)br << ';'
|
||||||
<< static_cast<unsigned>(bg) << ';'
|
<< (unsigned)bg << ';'
|
||||||
<< static_cast<unsigned>(bb) << 'm';
|
<< (unsigned)bb << 'm';
|
||||||
}
|
}
|
||||||
if (hl.flags & theme::Highlight::Bold)
|
if (hl.flags & theme::Highlight::Bold)
|
||||||
out << "\x1b[1m";
|
out << "\x1b[1m";
|
||||||
@@ -137,9 +132,8 @@ inline void reset(std::ostream &out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void Buffer::print(BEd &ctx, uint64_t start_line, uint64_t end_line) {
|
void Buffer::print(BEd &ctx, uint64_t start_line, uint64_t end_line) {
|
||||||
std::optional<syntax::Parser::Iterator> it_o = parser.get_hl(vase, start_line - 1);
|
if (parser) {
|
||||||
if (!it_o)
|
std::optional<syntax::Parser::Iterator> it_o = parser->get_hl(vase, start_line - 1);
|
||||||
throw ed_error("shouldn't be possible if line existed, which is checked by print's callers.");
|
|
||||||
auto &it = *it_o;
|
auto &it = *it_o;
|
||||||
while (start_line <= end_line) {
|
while (start_line <= end_line) {
|
||||||
it.next();
|
it.next();
|
||||||
@@ -167,9 +161,14 @@ void Buffer::print(BEd &ctx, uint64_t start_line, uint64_t end_line) {
|
|||||||
}
|
}
|
||||||
if (cursor < line.size())
|
if (cursor < line.size())
|
||||||
std::cout.write(line.data() + cursor, line.size() - cursor);
|
std::cout.write(line.data() + cursor, line.size() - cursor);
|
||||||
std::cout << '\n';
|
std::cout << std::endl;
|
||||||
++start_line;
|
++start_line;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
vase::Iterator it = vase.iterate(start_line - 1, Direction::Forward);
|
||||||
|
while (it.next() && start_line++ <= end_line)
|
||||||
|
std::cout << it.line << std::endl;
|
||||||
|
}
|
||||||
prev_range.start = start_line;
|
prev_range.start = start_line;
|
||||||
prev_range.end = end_line;
|
prev_range.end = end_line;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ static ParseState *build_tree(std::vector<ParseStateLeaf *> &leaves, size_t begi
|
|||||||
return make_branch(left, right);
|
return make_branch(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
Parser::Parser(vase::Vase &vase, uint64_t lines, Language &lang)
|
Parser::Parser(vase::Vase &vase, uint64_t lines, Language lang)
|
||||||
: root(nullptr), lang(lang) {
|
: root(nullptr), lang(lang) {
|
||||||
reset(vase, lines, lang);
|
reset(vase, lines, lang);
|
||||||
}
|
}
|
||||||
@@ -51,17 +51,17 @@ Parser::~Parser() {
|
|||||||
destroy_tree(root, lang);
|
destroy_tree(root, lang);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Parser::reset(vase::Vase &vase, uint64_t lines, Language &lang_) {
|
void Parser::reset(vase::Vase &vase, uint64_t lines, Language lang_) {
|
||||||
destroy_tree(root, lang);
|
destroy_tree(root, lang);
|
||||||
root = nullptr;
|
root = nullptr;
|
||||||
if (lines == 0)
|
if (lines == 0)
|
||||||
return;
|
return;
|
||||||
lang = lang_;
|
lang = std::move(lang_);
|
||||||
vase::Iterator it = vase.iterate(0, Direction::Forward);
|
vase::Iterator it = vase.iterate(0, Direction::Forward);
|
||||||
it.next();
|
it.next();
|
||||||
std::vector<ParseStateLeaf *> leaves;
|
std::vector<ParseStateLeaf *> leaves;
|
||||||
std::vector<Token> tokens;
|
std::vector<Token> tokens;
|
||||||
leaves.reserve((lines + 63) / 64);
|
leaves.reserve((lines + MAX_CHUNK - 1) / MAX_CHUNK);
|
||||||
void *state = lang.none_state();
|
void *state = lang.none_state();
|
||||||
uint32_t consumed = 0;
|
uint32_t consumed = 0;
|
||||||
while (consumed < lines) {
|
while (consumed < lines) {
|
||||||
@@ -69,7 +69,7 @@ void Parser::reset(vase::Vase &vase, uint64_t lines, Language &lang_) {
|
|||||||
leaf->header = 0;
|
leaf->header = 0;
|
||||||
leaf->state = lang.copy(state);
|
leaf->state = lang.copy(state);
|
||||||
uint32_t chunk_lines = 0;
|
uint32_t chunk_lines = 0;
|
||||||
while (chunk_lines < 64 && consumed < lines) {
|
while (chunk_lines < MAX_CHUNK && consumed < lines) {
|
||||||
tokens.clear();
|
tokens.clear();
|
||||||
lang.parse(&state, it.line, consumed == 0, &tokens);
|
lang.parse(&state, it.line, consumed == 0, &tokens);
|
||||||
++chunk_lines;
|
++chunk_lines;
|
||||||
@@ -140,17 +140,15 @@ void Parser::insert(vase::Vase &vase, uint64_t start, uint64_t count) {
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
std::vector<ParseStateLeaf *> leaves;
|
std::vector<ParseStateLeaf *> leaves;
|
||||||
leaves.reserve((count + 63) / 64);
|
leaves.reserve((count + MAX_CHUNK - 1) / MAX_CHUNK);
|
||||||
uint64_t consumed = 0;
|
uint64_t consumed = 0;
|
||||||
while (consumed < count) {
|
while (consumed < count) {
|
||||||
auto *leaf = new ParseStateLeaf;
|
auto *leaf = new ParseStateLeaf;
|
||||||
leaf->state = nullptr;
|
leaf->state = nullptr;
|
||||||
uint64_t chunk = 0;
|
uint64_t chunk = 0;
|
||||||
while (chunk < 64 && consumed < count) {
|
while (chunk < MAX_CHUNK && consumed < count) {
|
||||||
++chunk;
|
++chunk;
|
||||||
++consumed;
|
++consumed;
|
||||||
if (consumed < count)
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
leaf->header = chunk;
|
leaf->header = chunk;
|
||||||
leaves.push_back(leaf);
|
leaves.push_back(leaf);
|
||||||
@@ -277,6 +275,6 @@ Parser::Iterator &Parser::Iterator::operator=(Iterator &&other) {
|
|||||||
void Parser::Iterator::next() {
|
void Parser::Iterator::next() {
|
||||||
it->next();
|
it->next();
|
||||||
tokens.clear();
|
tokens.clear();
|
||||||
p->lang.parse(&state, it->line, at == 0, &tokens);
|
p->lang.parse(&state, it->line, at++ == 0, &tokens);
|
||||||
}
|
}
|
||||||
} // namespace bed::internal::syntax
|
} // namespace bed::internal::syntax
|
||||||
|
|||||||
Reference in New Issue
Block a user