CommandsRepository
This commit is contained in:
@@ -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() {
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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);
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user