#pragma once #include "internal/functions/functions.h" #include "internal/functions/suffixes.h" #include "internal/ui/command.h" #include "pch.h" namespace bed::internal::parser { struct AddressPromise { struct None {}; // struct Current {}; // . struct Last {}; // $ struct Number { // n uint64_t i; }; struct Mark { // 'm char m; }; struct Regex { // /re/ or ?re? internal::Direction dir; std::string re; }; struct Diagnostic { // ^ or ~ for previous/next diagnostic internal::Direction dir; }; struct SymbolDefinition { // goto symbol definition. (From lsp or using internal language parsers) std::string sym; }; struct SymbolReference { // >sym> or bufname; std::variant< None, Current, Last, Number, Mark, Regex, Diagnostic, SymbolDefinition, SymbolReference, Block, Scripted, LastRange> base{}; int64_t offset = 0; bool jumping{false}; // ; == jumping and , == non jumping buffer::Line resolve(BEd &ctx); static std::optional get_line(BEd &ctx, std::vector &); static std::optional get_range(BEd &ctx, std::vector &); }; struct Command { bool temp_address{false}; std::vector addresses{}; functions::Function *function{nullptr}; functions::Function::Argument argument{std::monostate()}; std::vector argument_addresses{}; functions::Suffix *suffix{nullptr}; }; struct CompletionContext { enum { Error, Valid, Incomplete } error; // TODO: store a state of typing context to think about possible completions. }; struct Parser { BEd &bed; std::string_view cmd; uint16_t i; Command *command; std::vector *tokens; CompletionContext *completion; explicit Parser( std::string_view cmd, BEd &bed, Command *command, std::vector *tokens, CompletionContext *completion ); char peek(uint16_t = 0); // == \0 if at eof. std::string_view peek_str(uint16_t = UINT16_MAX); void advance(uint16_t = 1); void skip_ws(); void locator(AddressPromise &); int64_t offset(); void address(AddressPromise &addr); void addresses(std::vector &addresses); void operation(); void parse(); static std::vector get_highlight(std::string_view cmd, BEd &bed); static Command get_command(std::string_view, BEd &); static std::vector get_addresses(std::string_view cmd, BEd &bed); }; } // namespace bed::internal::parser