allow func to access ctx
This commit is contained in:
parent
adad34f64d
commit
c7f246e7a5
|
|
@ -57,9 +57,12 @@ void ensure_val(const value & ptr) {
|
|||
}
|
||||
// End Helper
|
||||
|
||||
struct context; // forward declaration
|
||||
|
||||
struct func_args {
|
||||
std::vector<value> args;
|
||||
context & ctx;
|
||||
func_args(context & ctx) : ctx(ctx) {}
|
||||
void ensure_count(size_t count) const {
|
||||
if (args.size() != count) {
|
||||
throw std::runtime_error("Expected " + std::to_string(count) + " arguments, got " + std::to_string(args.size()));
|
||||
|
|
@ -253,7 +256,7 @@ struct value_func_t : public value_t {
|
|||
}
|
||||
virtual value invoke(const func_args & args) const override {
|
||||
if (arg0) {
|
||||
func_args new_args;
|
||||
func_args new_args(args.ctx);
|
||||
new_args.args.push_back(arg0);
|
||||
for (const auto & a : args.args) {
|
||||
new_args.args.push_back(a);
|
||||
|
|
|
|||
|
|
@ -103,9 +103,8 @@ const func_builtins & global_builtins() {
|
|||
std::string format = args.args[0]->as_string().str();
|
||||
// get current time
|
||||
// TODO: make sure this is the same behavior as Python's strftime
|
||||
std::time_t t = std::time(nullptr);
|
||||
char buf[100];
|
||||
if (std::strftime(buf, sizeof(buf), format.c_str(), std::localtime(&t))) {
|
||||
if (std::strftime(buf, sizeof(buf), format.c_str(), std::localtime(&args.ctx.current_time))) {
|
||||
return mk_val<value_string>(std::string(buf));
|
||||
} else {
|
||||
throw raised_exception("strftime_now: failed to format time");
|
||||
|
|
|
|||
|
|
@ -258,14 +258,14 @@ value filter_expression::execute_impl(context & ctx) {
|
|||
filter_id = "strip"; // alias
|
||||
}
|
||||
JJ_DEBUG("Applying filter '%s' to %s", filter_id.c_str(), input->type().c_str());
|
||||
return try_builtin_func(filter_id, input)->invoke({});
|
||||
return try_builtin_func(filter_id, input)->invoke(func_args(ctx));
|
||||
|
||||
} else if (is_stmt<call_expression>(filter)) {
|
||||
auto call = cast_stmt<call_expression>(filter);
|
||||
auto filter_id = cast_stmt<identifier>(call->callee)->val;
|
||||
|
||||
JJ_DEBUG("Applying filter '%s' with arguments to %s", filter_id.c_str(), input->type().c_str());
|
||||
func_args args;
|
||||
func_args args(ctx);
|
||||
for (const auto & arg_expr : call->args) {
|
||||
args.args.push_back(arg_expr->execute(ctx));
|
||||
}
|
||||
|
|
@ -302,7 +302,7 @@ value test_expression::execute_impl(context & ctx) {
|
|||
throw std::runtime_error("Unknown test '" + test_id + "'");
|
||||
}
|
||||
|
||||
func_args args;
|
||||
func_args args(ctx);
|
||||
args.args.push_back(operand->execute(ctx));
|
||||
auto res = it->second(args);
|
||||
|
||||
|
|
@ -574,7 +574,7 @@ value member_expression::execute_impl(context & ctx) {
|
|||
stop_val->as_repr().c_str(),
|
||||
step_val->as_repr().c_str());
|
||||
auto slice_func = try_builtin_func("slice", object);
|
||||
func_args args;
|
||||
func_args args(ctx);
|
||||
args.args.push_back(start_val);
|
||||
args.args.push_back(stop_val);
|
||||
args.args.push_back(step_val);
|
||||
|
|
@ -643,7 +643,7 @@ value member_expression::execute_impl(context & ctx) {
|
|||
|
||||
value call_expression::execute_impl(context & ctx) {
|
||||
// gather arguments
|
||||
func_args args;
|
||||
func_args args(ctx);
|
||||
for (auto & arg_stmt : this->args) {
|
||||
auto arg_val = arg_stmt->execute(ctx);
|
||||
JJ_DEBUG(" Argument type: %s", arg_val->type().c_str());
|
||||
|
|
|
|||
|
|
@ -50,10 +50,13 @@ struct context {
|
|||
std::map<std::string, value> var;
|
||||
std::string source; // for debugging
|
||||
|
||||
std::time_t current_time; // for functions that need current time
|
||||
|
||||
context() {
|
||||
var["true"] = mk_val<value_bool>(true);
|
||||
var["false"] = mk_val<value_bool>(false);
|
||||
var["none"] = mk_val<value_null>();
|
||||
current_time = std::time(nullptr);
|
||||
}
|
||||
~context() = default;
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue