allow func to access ctx

This commit is contained in:
Xuan Son Nguyen 2025-12-28 22:15:10 +01:00
parent adad34f64d
commit c7f246e7a5
4 changed files with 13 additions and 8 deletions

View File

@ -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);

View File

@ -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");

View File

@ -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());

View File

@ -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;