8 #include <unordered_map> 15 using AlgorithmTypes = std::unordered_map<
16 std::string, std::vector<decl::Algorithm>>;
18 inline void check_string_not_string(ast::Value& v) {
19 if (v.is_invokation()) {
21 ss <<
"option parser: ";
22 ss <<
"trying to evaluate " << v <<
" as a string";
23 throw std::runtime_error(ss.str());
27 inline void check_static_override_fits_to_be_evaled_algo(
28 ast::Value& fixed_static_args, ast::Value& v)
33 CHECK(fixed_static_args.is_invokation());
34 CHECK_EQ(fixed_static_args.invokation_name(), v.invokation_name());
37 inline void check_arg_has_value(decl::Arg& arg, ast::Value& arg_value) {
38 if (arg_value.is_empty()) {
40 ss <<
"option parser: ";
41 ss <<
"argument '" << arg.name() <<
"' of type '" 43 <<
"' has not been assigned a value";
44 throw std::runtime_error(ss.str());
46 if (arg_value.is_invokation()) {
47 if (std::any_of(arg_value.invokation_arguments().begin(),
48 arg_value.invokation_arguments().end(),
49 [](ast::Arg& arg) ->
bool {
50 return arg.has_type(); }))
53 ss <<
"option parser: ";
54 ss <<
"argument '" << arg.name() <<
"' of type '" 56 <<
"' has has types in its expression form: " << arg_value;
57 throw std::runtime_error(ss.str());
62 inline void check_algorithm_known(decl::Algorithm* found,
64 std::vector<decl::Algorithm> candidates) {
65 if (found ==
nullptr) {
68 ss <<
"option parser: ";
69 ss <<
"algorithm '" << v.invokation_name() <<
"'";
70 ss <<
" is not known to the evaluation engine. Currently known algorithms: [";
71 for (
auto& x : candidates) {
72 ss << x.name() <<
", ";
76 throw std::runtime_error(ss.str());
80 inline void check_argument_defined(
const View& arg,
const decl::Algorithm& algo) {
81 for (
auto& signature_arg : algo.arguments()) {
82 if(arg == signature_arg.name())
return;
88 ss <<
"option parser: ";
89 ss <<
"unknown option '" << arg <<
"' for ";
90 ss <<
"algorithm '" << algo.name() <<
"'.";
91 throw std::runtime_error(ss.str());
94 inline OptionValue eval(ast::Value&& v,
96 AlgorithmTypes& types,
98 ast::Value&& fixed_static_args = ast::Value())
101 if (type ==
"string") {
102 check_string_not_string(v);
103 return OptionValue(std::move(v.string_value()));
106 bool has_fixed_static_args = !fixed_static_args.is_empty();
108 if (has_fixed_static_args) {
109 check_static_override_fits_to_be_evaled_algo(fixed_static_args, v);
110 auto& a = fixed_static_args.invokation_arguments();
111 std::reverse(a.begin(), a.end());
116 CHECK(types.count(type) > 0);
118 CHECK(v.is_invokation());
119 auto& candidates = types[type];
120 decl::Algorithm* found =
nullptr;
121 for (
auto& candidate : candidates) {
122 if (candidate.name() == v.invokation_name()) {
126 check_algorithm_known(found, v, candidates);
129 auto& v_signature = *found;
132 ds::InputRestrictionsAndFlags r_ds_flags = v_signature.textds_flags();
133 std::string r_name = v_signature.name();
134 std::vector<pattern::Arg> r_static_args;
140 std::vector<View> v_argument_names;
143 bool positional_ok =
true;
145 for (
auto& unevaluated_arg : v.invokation_arguments()) {
147 DCHECK(!unevaluated_arg.has_type());
151 View argument_name(
"");
152 if (!unevaluated_arg.has_keyword()) {
155 CHECK(positional_ok);
159 argument_name = v_signature.arguments().at(i).name();
163 positional_ok =
false;
166 argument_name = unevaluated_arg.keyword();
169 check_argument_defined(argument_name, v_signature);
170 v_argument_names.push_back(argument_name);
177 for (
auto& signature_arg : v_signature.arguments()) {
178 if (pattern && !signature_arg.is_static()) {
184 for (
size_t i = 0; i < v_argument_names.size(); i++) {
185 if (v_argument_names[i] == signature_arg.name()) {
196 ast::Value arg_value;
197 ast::Value arg_fixed_static_value;
201 arg_value = v.invokation_arguments()[found].value();
202 }
else if (signature_arg.has_default()) {
203 arg_value = signature_arg.default_value();
208 if (has_fixed_static_args) {
209 if (signature_arg.is_static()) {
211 CHECK(fixed_static_args
212 .invokation_arguments()
215 auto& current_fixed_static = fixed_static_args
216 .invokation_arguments().back();
219 CHECK(current_fixed_static.keyword()
220 == signature_arg.name());
222 arg_fixed_static_value = current_fixed_static.value();
225 arg_value = std::move(current_fixed_static.value());
230 .invokation_arguments()
235 check_arg_has_value(signature_arg, arg_value);
238 OptionValue arg_evaluated
239 = eval(std::move(arg_value),
240 signature_arg.type(),
243 std::move(arg_fixed_static_value));
245 if (signature_arg.is_static()
246 && arg_evaluated.as_algorithm().static_selection().name() !=
"")
248 r_static_args.push_back(
250 std::string(signature_arg.name()),
251 pattern::Algorithm(arg_evaluated.as_algorithm().static_selection())));
254 r_dynamic_args[signature_arg.name()]
255 = std::move(arg_evaluated);
261 if (has_fixed_static_args) {
262 CHECK(fixed_static_args.invokation_arguments().size() == 0);
266 auto tmp = std::make_unique<pattern::Algorithm>(
268 std::move(r_static_args));
270 auto fr = OptionValue(AlgorithmValue(
272 std::move(r_dynamic_args),
279 inline OptionValue cl_eval(ast::Value&& v,
281 AlgorithmTypes& types,
282 ast::Value&& fixed_static_args = ast::Value()) {
283 return eval(std::move(v),
287 std::move(fixed_static_args));
289 inline pattern::Algorithm pattern_eval(ast::Value&& v,
291 AlgorithmTypes& types) {
292 return std::move(eval(std::move(v),
295 true).as_algorithm().static_selection());
Contains the text compression and encoding framework.
std::map< std::string, OptionValue > ArgumentMap