From db09a7468d849cb40c56a8916f27250c193435af Mon Sep 17 00:00:00 2001 From: Xuan Son Nguyen Date: Sun, 28 Dec 2025 19:07:01 +0100 Subject: [PATCH] fix negate test --- common/jinja/jinja-vm-builtins.cpp | 7 ++++++- common/jinja/jinja-vm.cpp | 12 +++++++++--- tests/test-chat-jinja.cpp | 5 ++--- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/common/jinja/jinja-vm-builtins.cpp b/common/jinja/jinja-vm-builtins.cpp index 5802253a3e..cf9de3636e 100644 --- a/common/jinja/jinja-vm-builtins.cpp +++ b/common/jinja/jinja-vm-builtins.cpp @@ -9,6 +9,8 @@ #include #include +#define FILENAME "jinja-vm-builtins" + namespace jinja { /** @@ -88,6 +90,7 @@ const func_builtins & global_builtins() { throw raised_exception("namespace() arguments must be kwargs"); } auto kwarg = cast_val(arg); + JJ_DEBUG("namespace: adding key '%s'", kwarg->key.c_str()); out->insert(kwarg->key, kwarg->val); } return out; @@ -132,7 +135,9 @@ const func_builtins & global_builtins() { {"test_is_none", test_type_fn}, {"test_is_defined", [](const func_args & args) -> value { args.ensure_count(1); - return mk_val(!is_val(args.args[0])); + bool res = !args.args[0]->is_undefined(); + JJ_DEBUG("test_is_defined: result=%d", res ? 1 : 0); + return mk_val(res); }}, {"test_is_undefined", test_type_fn}, }; diff --git a/common/jinja/jinja-vm.cpp b/common/jinja/jinja-vm.cpp index ca213b0462..7aef38cfbd 100644 --- a/common/jinja/jinja-vm.cpp +++ b/common/jinja/jinja-vm.cpp @@ -257,14 +257,20 @@ value test_expression::execute_impl(context & ctx) { auto test_id = cast_stmt(test)->val; auto it = builtins.find("test_is_" + test_id); - JJ_DEBUG("Test expression %s '%s'", operand->type().c_str(), test_id.c_str()); + JJ_DEBUG("Test expression %s '%s' %s", operand->type().c_str(), test_id.c_str(), negate ? "(negate)" : ""); if (it == builtins.end()) { throw std::runtime_error("Unknown test '" + test_id + "'"); } func_args args; args.args.push_back(operand->execute(ctx)); - return it->second(args); + auto res = it->second(args); + + if (negate) { + return mk_val(!res->as_bool()); + } else { + return res; + } } value unary_expression::execute_impl(context & ctx) { @@ -538,7 +544,6 @@ value member_expression::execute_impl(context & ctx) { throw std::runtime_error("Cannot access object with non-string: got " + property->type()); } auto key = property->as_string().str(); - JJ_DEBUG("Accessing object property '%s'", key.c_str()); auto & obj = object->as_object(); auto it = obj.find(key); if (it != obj.end()) { @@ -546,6 +551,7 @@ value member_expression::execute_impl(context & ctx) { } else { val = try_builtin_func(key, object, true); } + JJ_DEBUG("Accessed property '%s' value, got type: %s", key.c_str(), val->type().c_str()); } else if (is_val(object) || is_val(object)) { if (is_val(property)) { diff --git a/tests/test-chat-jinja.cpp b/tests/test-chat-jinja.cpp index 36cfde7c5f..097c60a543 100644 --- a/tests/test-chat-jinja.cpp +++ b/tests/test-chat-jinja.cpp @@ -17,10 +17,9 @@ int main(void) { //std::string contents = "{% if messages[0]['role'] != 'system' %}nice {{ messages[0]['content'] }}{% endif %}"; //std::string contents = " {{ messages[a]['content'] }} "; - //std::string contents = "{{ aaa[bbb] }}"; + //std::string contents = "{% if a is not defined %}hello{% endif %}"; - std::ifstream infile("models/templates/mistralai-Ministral-3-14B-Reasoning-2512.jinja"); - std::string contents((std::istreambuf_iterator(infile)), std::istreambuf_iterator()); + std::ifstream infile("models/templates/mistralai-Ministral-3-14B-Reasoning-2512.jinja"); std::string contents((std::istreambuf_iterator(infile)), std::istreambuf_iterator()); std::cout << "=== INPUT ===\n" << contents << "\n\n";