In a project, we have a file that contains something like a script which we need to parse. At the moment the validation is tough since we have an array of functions returing variable and taking variableList (basically std::variant<>and vector of variants, see definition below)
I am trying to have function metadata available (number of input arguments and its type, possibly return value type for validating the input "script". I would like to replace std::function with something like this:
using variable = std::variant<bool, int, double, std::string>;
using variableList = std::vector<variable>;
enum {
BOOL_TYPE = 0,
INT_TYPE = 1,
DOUBLE_TYPE = 2,
STRING_TYPE = 3,
VARIABLE_BOOL_TYPE = 0 | 0x80,
VARIABLE_INT_TYPE = 1 | 0x80,
VARIABLE_DOUBLE_TYPE = 2 | 0x80,
VARIABLE_STRING_TYPE = 3 | 0x80
};
struct Function
{
std::string fname;
std::vector<int> indexes;
std::function<variable(variableList &&)> fn;
variable operator()(variableList && list)
{
if (indexes.size() != list.size() &&
(indexes.size() == 0 || (indexes[0] & 0x80) != 0x80))
{
std::cout << "Invalid number of arguments" << std::endl;
return variable(0);
}
int idx = 0;
for (auto i : list)
{
if ((indexes[0] & 0x80) ? i.index() != (indexes[0] & 0x03), idx++ : i.index() != indexes[idx++])
{
std::cout << "Invalid argument type" << std::endl;
return variable(0);
}
}
return fn(std::forward<decltype(list)>(list));
}
};
int main()
{
Function f = { "fName", {BOOL_TYPE, INT_TYPE, BOOL_TYPE}, [](variableList && list) -> variable {
for (auto i : list)
{
std::visit([](auto && val) -> void {
std::cout << val << std::endl;
}, i);
}
return variable(0);
}};
auto arguments = {variable(true),variable(true),variable(true)};
auto returnValue = f(arguments);
}
The project supports c++17. Any modifications, suggestions are welcome.
EDIT: Initially I wanted to use templates instead of indices and enum, but I wasn't quite successful with creating array of Function class with different template arguments.