CommandsRepository

This commit is contained in:
MihailRis
2024-05-09 20:16:15 +03:00
parent e1a083015e
commit 022c97b200
4 changed files with 58 additions and 8 deletions
+7 -2
View File
@@ -154,8 +154,13 @@ void BasicParser::expectNewLine() {
} }
} }
void BasicParser::goBack() { void BasicParser::goBack(size_t count) {
if (pos) pos--; if (pos < count) {
throw std::runtime_error("pos < jump");
}
if (pos) {
pos -= count;
}
} }
char BasicParser::peek() { char BasicParser::peek() {
+1 -1
View File
@@ -86,7 +86,7 @@ protected:
void expect(const std::string& substring); void expect(const std::string& substring);
bool isNext(const std::string& substring); bool isNext(const std::string& substring);
void expectNewLine(); void expectNewLine();
void goBack(); void goBack(size_t count=1);
int64_t parseSimpleInt(int base); int64_t parseSimpleInt(int base);
dynamic::Value parseNumber(int sign); dynamic::Value parseNumber(int sign);
+30 -5
View File
@@ -11,7 +11,7 @@ inline bool is_cmd_identifier_part(char c) {
return is_identifier_part(c) || c == '.' || c == '$' || c == '@'; return is_identifier_part(c) || c == '.' || c == '$' || c == '@';
} }
class SchemeParser : BasicParser { class CommandParser : BasicParser {
std::string parseIdentifier() { std::string parseIdentifier() {
char c = peek(); char c = peek();
if (!is_identifier_start(c) && c != '$') { if (!is_identifier_start(c) && c != '$') {
@@ -36,7 +36,7 @@ class SchemeParser : BasicParser {
{"enum", ArgType::enumvalue}, {"enum", ArgType::enumvalue},
}; };
public: public:
SchemeParser(std::string_view filename, std::string_view source) CommandParser(std::string_view filename, std::string_view source)
: BasicParser(filename, source) { : BasicParser(filename, source) {
} }
@@ -84,7 +84,9 @@ public:
throw error("empty enumeration is not allowed"); throw error("empty enumeration is not allowed");
} }
auto enumvalue = std::string(readUntil(']')); auto enumvalue = std::string(readUntil(']'));
if (enumvalue.find(' ') != std::string::npos) { size_t offset = enumvalue.find(' ');
if (offset != std::string::npos) {
goBack(enumvalue.length()-offset);
throw error("use '|' as separator, not a space"); throw error("use '|' as separator, not a space");
} }
nextChar(); nextChar();
@@ -130,7 +132,7 @@ public:
return Argument {name, type, optional, def, origin, enumname}; return Argument {name, type, optional, def, origin, enumname};
} }
Command parse(executor_func executor) { Command parseScheme(executor_func executor) {
std::string name = parseIdentifier(); std::string name = parseIdentifier();
std::vector<Argument> args; std::vector<Argument> args;
std::unordered_map<std::string, Argument> kwargs; std::unordered_map<std::string, Argument> kwargs;
@@ -150,8 +152,31 @@ public:
} }
return Command(name, std::move(args), std::move(kwargs), executor); return Command(name, std::move(args), std::move(kwargs), executor);
} }
CommandInput parsePrompt() {
std::string name = parseIdentifier();
return CommandInput {name, nullptr, nullptr};
}
}; };
Command Command::create(std::string_view scheme, executor_func executor) { Command Command::create(std::string_view scheme, executor_func executor) {
return SchemeParser("<string>", scheme).parse(executor); return CommandParser("<string>", scheme).parseScheme(executor);
}
void CommandsRepository::add(std::string_view scheme, executor_func executor) {
Command command = Command::create(scheme, executor);
commands[command.getName()] = command;
}
Command* CommandsRepository::get(const std::string& name) {
auto found = commands.find(name);
if (found == commands.end()) {
return nullptr;
}
return &found->second;
}
CommandInput CommandsInterpreter::parse(std::string_view text) {
return CommandParser("<string>", text).parsePrompt();
} }
+20
View File
@@ -23,6 +23,7 @@ namespace cmd {
}; };
struct CommandInput { struct CommandInput {
std::string name; // command name
dynamic::List_sptr args; // positional arguments list dynamic::List_sptr args; // positional arguments list
dynamic::Map_sptr kwargs; // keyword arguments table dynamic::Map_sptr kwargs; // keyword arguments table
}; };
@@ -38,6 +39,8 @@ namespace cmd {
std::unordered_map<std::string, Argument> kwargs; std::unordered_map<std::string, Argument> kwargs;
executor_func executor; executor_func executor;
public: public:
Command() {}
Command( Command(
std::string name, std::string name,
std::vector<Argument> args, std::vector<Argument> args,
@@ -52,10 +55,27 @@ namespace cmd {
return executor(input.args, input.kwargs); return executor(input.args, input.kwargs);
} }
const std::string& getName() const {
return name;
}
static Command create(std::string_view scheme, executor_func); static Command create(std::string_view scheme, executor_func);
}; };
class CommandsRepository {
std::unordered_map<std::string, Command> commands;
public:
void add(std::string_view scheme, executor_func);
Command* get(const std::string& name);
};
class CommandsInterpreter { class CommandsInterpreter {
std::unique_ptr<CommandsRepository> repository;
public:
CommandsInterpreter(std::unique_ptr<CommandsRepository> repository)
: repository(std::move(repository)){}
CommandInput parse(std::string_view text);
}; };
} }