Update minja to https://github.com/google/minja/pull/25
This commit is contained in:
parent
8347da907d
commit
ff2cce57ad
1 changed files with 46 additions and 15 deletions
|
@ -206,6 +206,38 @@ public:
|
||||||
throw std::runtime_error("Value is not an array: " + dump());
|
throw std::runtime_error("Value is not an array: " + dump());
|
||||||
array_->push_back(v);
|
array_->push_back(v);
|
||||||
}
|
}
|
||||||
|
Value pop(const Value& index) {
|
||||||
|
if (is_array()) {
|
||||||
|
if (array_->empty())
|
||||||
|
throw std::runtime_error("pop from empty list");
|
||||||
|
if (index.is_null()) {
|
||||||
|
auto ret = array_->back();
|
||||||
|
array_->pop_back();
|
||||||
|
return ret;
|
||||||
|
} else if (!index.is_number_integer()) {
|
||||||
|
throw std::runtime_error("pop index must be an integer: " + index.dump());
|
||||||
|
} else {
|
||||||
|
auto i = index.get<int>();
|
||||||
|
if (i < 0 || i >= static_cast<int>(array_->size()))
|
||||||
|
throw std::runtime_error("pop index out of range: " + index.dump());
|
||||||
|
auto it = array_->begin() + (i < 0 ? array_->size() + i : i);
|
||||||
|
auto ret = *it;
|
||||||
|
array_->erase(it);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
} else if (is_object()) {
|
||||||
|
if (!index.is_hashable())
|
||||||
|
throw std::runtime_error("Unashable type: " + index.dump());
|
||||||
|
auto it = object_->find(index.primitive_);
|
||||||
|
if (it == object_->end())
|
||||||
|
throw std::runtime_error("Key not found: " + index.dump());
|
||||||
|
auto ret = it->second;
|
||||||
|
object_->erase(it);
|
||||||
|
return ret;
|
||||||
|
} else {
|
||||||
|
throw std::runtime_error("Value is not an array or object: " + dump());
|
||||||
|
}
|
||||||
|
}
|
||||||
Value get(const Value& key) {
|
Value get(const Value& key) {
|
||||||
if (array_) {
|
if (array_) {
|
||||||
if (!key.is_number_integer()) {
|
if (!key.is_number_integer()) {
|
||||||
|
@ -366,11 +398,13 @@ public:
|
||||||
throw std::runtime_error("contains can only be called on arrays and objects: " + dump());
|
throw std::runtime_error("contains can only be called on arrays and objects: " + dump());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Value pop(size_t index) {
|
void erase(size_t index) {
|
||||||
if (!array_) throw std::runtime_error("Value is not an array: " + dump());
|
if (!array_) throw std::runtime_error("Value is not an array: " + dump());
|
||||||
auto value = array_->at(index);
|
|
||||||
array_->erase(array_->begin() + index);
|
array_->erase(array_->begin() + index);
|
||||||
return value;
|
}
|
||||||
|
void erase(const std::string & key) {
|
||||||
|
if (!object_) throw std::runtime_error("Value is not an object: " + dump());
|
||||||
|
object_->erase(key);
|
||||||
}
|
}
|
||||||
const Value& at(const Value & index) const {
|
const Value& at(const Value & index) const {
|
||||||
return const_cast<Value*>(this)->at(index);
|
return const_cast<Value*>(this)->at(index);
|
||||||
|
@ -1345,21 +1379,15 @@ public:
|
||||||
vargs.expectArgs("append method", {1, 1}, {0, 0});
|
vargs.expectArgs("append method", {1, 1}, {0, 0});
|
||||||
obj.push_back(vargs.args[0]);
|
obj.push_back(vargs.args[0]);
|
||||||
return Value();
|
return Value();
|
||||||
|
} else if (method->get_name() == "pop") {
|
||||||
|
vargs.expectArgs("pop method", {0, 1}, {0, 0});
|
||||||
|
return obj.pop(vargs.args.empty() ? Value() : vargs.args[0]);
|
||||||
} else if (method->get_name() == "insert") {
|
} else if (method->get_name() == "insert") {
|
||||||
vargs.expectArgs("insert method", {2, 2}, {0, 0});
|
vargs.expectArgs("insert method", {2, 2}, {0, 0});
|
||||||
auto index = vargs.args[0].get<int64_t>();
|
auto index = vargs.args[0].get<int64_t>();
|
||||||
if (index < 0 || index > (int64_t) obj.size()) throw std::runtime_error("Index out of range for insert method");
|
if (index < 0 || index > (int64_t) obj.size()) throw std::runtime_error("Index out of range for insert method");
|
||||||
obj.insert(index, vargs.args[1]);
|
obj.insert(index, vargs.args[1]);
|
||||||
return Value();
|
return Value();
|
||||||
} else if (method->get_name() == "pop") {
|
|
||||||
vargs.expectArgs("pop method", {0, 1}, {0, 0});
|
|
||||||
if (vargs.args.empty()) {
|
|
||||||
return obj.pop(obj.size() - 1);
|
|
||||||
} else {
|
|
||||||
auto index = vargs.args[0].get<int64_t>();
|
|
||||||
if (index < 0 || index >= (int64_t) obj.size()) throw std::runtime_error("Index out of range for pop method");
|
|
||||||
return obj.pop(index);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (obj.is_object()) {
|
} else if (obj.is_object()) {
|
||||||
if (method->get_name() == "items") {
|
if (method->get_name() == "items") {
|
||||||
|
@ -1369,6 +1397,9 @@ public:
|
||||||
result.push_back(Value::array({key, obj.at(key)}));
|
result.push_back(Value::array({key, obj.at(key)}));
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
|
} else if (method->get_name() == "pop") {
|
||||||
|
vargs.expectArgs("pop method", {1, 1}, {0, 0});
|
||||||
|
return obj.pop(vargs.args[0]);
|
||||||
} else if (method->get_name() == "get") {
|
} else if (method->get_name() == "get") {
|
||||||
vargs.expectArgs("get method", {1, 2}, {0, 0});
|
vargs.expectArgs("get method", {1, 2}, {0, 0});
|
||||||
auto key = vargs.args[0];
|
auto key = vargs.args[0];
|
||||||
|
@ -2546,7 +2577,7 @@ inline std::shared_ptr<Context> Context::builtins() {
|
||||||
}));
|
}));
|
||||||
globals.set("namespace", Value::callable([=](const std::shared_ptr<Context> &, ArgumentsValue & args) {
|
globals.set("namespace", Value::callable([=](const std::shared_ptr<Context> &, ArgumentsValue & args) {
|
||||||
auto ns = Value::object();
|
auto ns = Value::object();
|
||||||
args.expectArgs("namespace", {0, 0}, {0, std::numeric_limits<size_t>::max()});
|
args.expectArgs("namespace", {0, 0}, {0, (std::numeric_limits<size_t>::max)()});
|
||||||
for (auto & [name, value] : args.kwargs) {
|
for (auto & [name, value] : args.kwargs) {
|
||||||
ns.set(name, value);
|
ns.set(name, value);
|
||||||
}
|
}
|
||||||
|
@ -2601,7 +2632,7 @@ inline std::shared_ptr<Context> Context::builtins() {
|
||||||
};
|
};
|
||||||
// https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.reject
|
// https://jinja.palletsprojects.com/en/3.0.x/templates/#jinja-filters.reject
|
||||||
globals.set("reject", Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
globals.set("reject", Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
||||||
args.expectArgs("reject", {2, std::numeric_limits<size_t>::max()}, {0, 0});
|
args.expectArgs("reject", {2, (std::numeric_limits<size_t>::max)()}, {0, 0});
|
||||||
auto & items = args.args[0];
|
auto & items = args.args[0];
|
||||||
auto filter_fn = context->get(args.args[1]);
|
auto filter_fn = context->get(args.args[1]);
|
||||||
if (filter_fn.is_null()) throw std::runtime_error("Undefined filter: " + args.args[1].dump());
|
if (filter_fn.is_null()) throw std::runtime_error("Undefined filter: " + args.args[1].dump());
|
||||||
|
@ -2672,7 +2703,7 @@ inline std::shared_ptr<Context> Context::builtins() {
|
||||||
return out;
|
return out;
|
||||||
}));
|
}));
|
||||||
globals.set("selectattr", Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
globals.set("selectattr", Value::callable([=](const std::shared_ptr<Context> & context, ArgumentsValue & args) {
|
||||||
args.expectArgs("selectattr", {2, std::numeric_limits<size_t>::max()}, {0, 0});
|
args.expectArgs("selectattr", {2, (std::numeric_limits<size_t>::max)()}, {0, 0});
|
||||||
auto & items = args.args[0];
|
auto & items = args.args[0];
|
||||||
if (items.is_null())
|
if (items.is_null())
|
||||||
return Value::array();
|
return Value::array();
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue