| 2696 | }; |
| 2697 | |
| 2698 | static Value simple_function(const std::string & fn_name, const std::vector<std::string> & params, const std::function<Value(const std::shared_ptr<Context> &, Value & args)> & fn) { |
| 2699 | std::map<std::string, size_t> named_positions; |
| 2700 | for (size_t i = 0, n = params.size(); i < n; i++) named_positions[params[i]] = i; |
| 2701 | |
| 2702 | return Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) -> Value { |
| 2703 | auto args_obj = Value::object(); |
| 2704 | std::vector<bool> provided_args(params.size()); |
| 2705 | for (size_t i = 0, n = args.args.size(); i < n; i++) { |
| 2706 | auto & arg = args.args[i]; |
| 2707 | if (i < params.size()) { |
| 2708 | args_obj.set(params[i], arg); |
| 2709 | provided_args[i] = true; |
| 2710 | } else { |
| 2711 | throw std::runtime_error("Too many positional params for " + fn_name); |
| 2712 | } |
| 2713 | } |
| 2714 | for (auto & [name, value] : args.kwargs) { |
| 2715 | auto named_pos_it = named_positions.find(name); |
| 2716 | if (named_pos_it == named_positions.end()) { |
| 2717 | throw std::runtime_error("Unknown argument " + name + " for function " + fn_name); |
| 2718 | } |
| 2719 | provided_args[named_pos_it->second] = true; |
| 2720 | args_obj.set(name, value); |
| 2721 | } |
| 2722 | return fn(context, args_obj); |
| 2723 | }); |
| 2724 | } |
| 2725 | |
| 2726 | inline std::shared_ptr<Context> Context::builtins() { |
| 2727 | auto globals = Value::object(); |