mirror of
https://github.com/pantor/inja.git
synced 2026-02-17 09:03:58 +00:00
update single include
This commit is contained in:
@@ -1604,8 +1604,7 @@ struct Bytecode {
|
||||
|
||||
// start loop
|
||||
// value popped off stack is what is iterated over
|
||||
// args is index of bytecode after end loop (jumped to if iterable is
|
||||
// empty)
|
||||
// args is index of bytecode after end loop (jumped to if iterable is empty)
|
||||
// immediate value is key name (for maps)
|
||||
// str is value name
|
||||
StartLoop,
|
||||
@@ -1990,9 +1989,10 @@ public:
|
||||
m_tok_start = m_pos;
|
||||
|
||||
again:
|
||||
if (m_tok_start >= m_in.size())
|
||||
if (m_tok_start >= m_in.size()) {
|
||||
return make_token(Token::Kind::Eof);
|
||||
|
||||
}
|
||||
|
||||
switch (m_state) {
|
||||
default:
|
||||
case State::Text: {
|
||||
@@ -2082,8 +2082,9 @@ private:
|
||||
Token scan_body(nonstd::string_view close, Token::Kind closeKind, bool trim = false) {
|
||||
again:
|
||||
// skip whitespace (except for \n as it might be a close)
|
||||
if (m_tok_start >= m_in.size())
|
||||
if (m_tok_start >= m_in.size()) {
|
||||
return make_token(Token::Kind::Eof);
|
||||
}
|
||||
char ch = m_in[m_tok_start];
|
||||
if (ch == ' ' || ch == '\t' || ch == '\r') {
|
||||
m_tok_start += 1;
|
||||
@@ -2344,25 +2345,31 @@ public:
|
||||
m_static(ParserStatic::get_instance()) {}
|
||||
|
||||
bool parse_expression(Template &tmpl) {
|
||||
if (!parse_expression_and(tmpl))
|
||||
if (!parse_expression_and(tmpl)) {
|
||||
return false;
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("or"))
|
||||
}
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("or")) {
|
||||
return true;
|
||||
}
|
||||
get_next_token();
|
||||
if (!parse_expression_and(tmpl))
|
||||
if (!parse_expression_and(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
append_function(tmpl, Bytecode::Op::Or, 2);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool parse_expression_and(Template &tmpl) {
|
||||
if (!parse_expression_not(tmpl))
|
||||
if (!parse_expression_not(tmpl)) {
|
||||
return false;
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("and"))
|
||||
}
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("and")) {
|
||||
return true;
|
||||
}
|
||||
get_next_token();
|
||||
if (!parse_expression_not(tmpl))
|
||||
if (!parse_expression_not(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
append_function(tmpl, Bytecode::Op::And, 2);
|
||||
return true;
|
||||
}
|
||||
@@ -2370,8 +2377,9 @@ public:
|
||||
bool parse_expression_not(Template &tmpl) {
|
||||
if (m_tok.kind == Token::Kind::Id && m_tok.text == static_cast<decltype(m_tok.text)>("not")) {
|
||||
get_next_token();
|
||||
if (!parse_expression_not(tmpl))
|
||||
if (!parse_expression_not(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
append_function(tmpl, Bytecode::Op::Not, 1);
|
||||
return true;
|
||||
} else {
|
||||
@@ -2380,8 +2388,9 @@ public:
|
||||
}
|
||||
|
||||
bool parse_expression_comparison(Template &tmpl) {
|
||||
if (!parse_expression_datum(tmpl))
|
||||
if (!parse_expression_datum(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
Bytecode::Op op;
|
||||
switch (m_tok.kind) {
|
||||
case Token::Kind::Id:
|
||||
@@ -2412,8 +2421,9 @@ public:
|
||||
return true;
|
||||
}
|
||||
get_next_token();
|
||||
if (!parse_expression_datum(tmpl))
|
||||
if (!parse_expression_datum(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
append_function(tmpl, op, 2);
|
||||
return true;
|
||||
}
|
||||
@@ -2427,8 +2437,9 @@ public:
|
||||
switch (m_tok.kind) {
|
||||
case Token::Kind::LeftParen: {
|
||||
get_next_token();
|
||||
if (!parse_expression(tmpl))
|
||||
if (!parse_expression(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
if (m_tok.kind != Token::Kind::RightParen) {
|
||||
throw_parser_error("unmatched '('");
|
||||
}
|
||||
@@ -2467,8 +2478,9 @@ public:
|
||||
|
||||
if (op != Bytecode::Op::Nop) {
|
||||
// swap arguments for default(); see comment in RenderTo()
|
||||
if (op == Bytecode::Op::Default)
|
||||
if (op == Bytecode::Op::Default) {
|
||||
std::swap(tmpl.bytecodes.back(), *(tmpl.bytecodes.rbegin() + 1));
|
||||
}
|
||||
append_function(tmpl, op, num_args);
|
||||
return true;
|
||||
} else {
|
||||
@@ -2522,17 +2534,19 @@ public:
|
||||
if (bracket_level == 0) {
|
||||
throw_parser_error("unexpected ']'");
|
||||
}
|
||||
--bracket_level;
|
||||
if (brace_level == 0 && bracket_level == 0)
|
||||
bracket_level -= 1;
|
||||
if (brace_level == 0 && bracket_level == 0) {
|
||||
goto returnJson;
|
||||
}
|
||||
break;
|
||||
case Token::Kind::RightBrace:
|
||||
if (brace_level == 0) {
|
||||
throw_parser_error("unexpected '}'");
|
||||
}
|
||||
--brace_level;
|
||||
if (brace_level == 0 && bracket_level == 0)
|
||||
brace_level -= 1;
|
||||
if (brace_level == 0 && bracket_level == 0) {
|
||||
goto returnJson;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (brace_level != 0) {
|
||||
@@ -2556,15 +2570,17 @@ public:
|
||||
}
|
||||
|
||||
bool parse_statement(Template &tmpl, nonstd::string_view path) {
|
||||
if (m_tok.kind != Token::Kind::Id)
|
||||
if (m_tok.kind != Token::Kind::Id) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m_tok.text == static_cast<decltype(m_tok.text)>("if")) {
|
||||
get_next_token();
|
||||
|
||||
// evaluate expression
|
||||
if (!parse_expression(tmpl))
|
||||
if (!parse_expression(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// start a new if block on if stack
|
||||
m_if_stack.emplace_back(static_cast<decltype(m_if_stack)::value_type::jump_t>(tmpl.bytecodes.size()));
|
||||
@@ -2591,8 +2607,9 @@ public:
|
||||
// pop if stack
|
||||
m_if_stack.pop_back();
|
||||
} else if (m_tok.text == static_cast<decltype(m_tok.text)>("else")) {
|
||||
if (m_if_stack.empty())
|
||||
if (m_if_stack.empty()) {
|
||||
throw_parser_error("else without matching if");
|
||||
}
|
||||
auto &if_data = m_if_stack.back();
|
||||
get_next_token();
|
||||
|
||||
@@ -2610,8 +2627,9 @@ public:
|
||||
get_next_token();
|
||||
|
||||
// evaluate expression
|
||||
if (!parse_expression(tmpl))
|
||||
if (!parse_expression(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// update "previous jump"
|
||||
if_data.prev_cond_jump = tmpl.bytecodes.size();
|
||||
@@ -2623,27 +2641,31 @@ public:
|
||||
get_next_token();
|
||||
|
||||
// options: for a in arr; for a, b in obj
|
||||
if (m_tok.kind != Token::Kind::Id)
|
||||
if (m_tok.kind != Token::Kind::Id) {
|
||||
throw_parser_error("expected id, got '" + m_tok.describe() + "'");
|
||||
}
|
||||
Token value_token = m_tok;
|
||||
get_next_token();
|
||||
|
||||
Token key_token;
|
||||
if (m_tok.kind == Token::Kind::Comma) {
|
||||
get_next_token();
|
||||
if (m_tok.kind != Token::Kind::Id)
|
||||
if (m_tok.kind != Token::Kind::Id) {
|
||||
throw_parser_error("expected id, got '" + m_tok.describe() + "'");
|
||||
}
|
||||
key_token = std::move(value_token);
|
||||
value_token = m_tok;
|
||||
get_next_token();
|
||||
}
|
||||
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("in"))
|
||||
if (m_tok.kind != Token::Kind::Id || m_tok.text != static_cast<decltype(m_tok.text)>("in")) {
|
||||
throw_parser_error("expected 'in', got '" + m_tok.describe() + "'");
|
||||
}
|
||||
get_next_token();
|
||||
|
||||
if (!parse_expression(tmpl))
|
||||
if (!parse_expression(tmpl)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
m_loop_stack.push_back(tmpl.bytecodes.size());
|
||||
|
||||
@@ -2734,10 +2756,12 @@ public:
|
||||
get_next_token();
|
||||
switch (m_tok.kind) {
|
||||
case Token::Kind::Eof:
|
||||
if (!m_if_stack.empty())
|
||||
if (!m_if_stack.empty()) {
|
||||
throw_parser_error("unmatched if");
|
||||
if (!m_loop_stack.empty())
|
||||
}
|
||||
if (!m_loop_stack.empty()) {
|
||||
throw_parser_error("unmatched for");
|
||||
}
|
||||
return;
|
||||
case Token::Kind::Text:
|
||||
tmpl.bytecodes.emplace_back(Bytecode::Op::PrintText, m_tok.text, 0u);
|
||||
@@ -2939,6 +2963,7 @@ class Renderer {
|
||||
ptr = ptr_buffer;
|
||||
break;
|
||||
}
|
||||
|
||||
json::json_pointer json_ptr(ptr.data());
|
||||
try {
|
||||
// first try to evaluate as a loop variable
|
||||
@@ -2954,6 +2979,7 @@ class Renderer {
|
||||
m_tmp_val = callback(arguments);
|
||||
return &m_tmp_val;
|
||||
}
|
||||
|
||||
throw RenderError("variable '" + static_cast<std::string>(bc.str) + "' not found");
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user