nytl: merged files rendering.cpp and execute_expression.cpp

This commit is contained in:
Андреев Григорий 2024-08-14 21:24:27 +03:00
parent dd806a5633
commit ea7d50a183
4 changed files with 96 additions and 112 deletions

View File

@ -116,7 +116,6 @@ struct CAWebChat {
}; };
T.units = { T.units = {
"alotalot.cpp", "alotalot.cpp",
"execute_expression.cpp",
"html_case.cpp", "html_case.cpp",
"parser.cpp", "parser.cpp",
"rendering.cpp", "rendering.cpp",

View File

@ -17,17 +17,6 @@ namespace nytl {
global_elem_set_t& result, TemplaterSettings& syntax); global_elem_set_t& result, TemplaterSettings& syntax);
/* =================== For rendering ====================*/ /* =================== For rendering ====================*/
struct LocalVarValue {
bool is_json = false;
std::string EL_name;
const json::JSON* JSON_subval = NULL;
};
/* No new JSON object will ever be created, I have one root json argument,
* all the other json variables are subtrees of it */
LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
const std::vector<LocalVarValue>& local_vars, const json::JSON& expr);
std::string rendering_core(const std::string& entry_func, const std::vector<const json::JSON*>& entry_arguments, std::string rendering_core(const std::string& entry_func, const std::vector<const json::JSON*>& entry_arguments,
const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape); const global_elem_set_t& elem_ns, const std::function<std::string(std::string)>& escape);
} }

View File

@ -1,100 +0,0 @@
#include "core.h"
#include "alotalot.h"
#include <assert.h>
namespace nytl {
/* Expression Execution Frame */
struct EEFrame {
const json::JSON& expr;
LocalVarValue& result;
LocalVarValue temp_ret;
size_t chain_el = 0;
EEFrame(const json::JSON &expr, LocalVarValue &result)
: expr(expr),
result(result) {
}
// todo: remove this debug function
// void print_result() {
// if (result.is_json) {
// printf("print_result %%p: %p\n", result.JSON_subval);
// printf("%s\n", json::generate_str(*result.JSON_subval, json::print_compact).c_str());
// } else
// printf("element %s\n", result.EL_name.c_str());
// }
void descend(const json::JSON& what) {
if (result.is_json) {
const json::JSON& P = *result.JSON_subval;
if (P.isArray() && what.isInteger()) {
const std::vector<json::JSON> arr_p = P.asArray();
int64_t ind_w = what.asInteger().get_int();
ASSERT(ind_w > 0 && ind_w < arr_p.size(), "Expression \"array[integer]\" caused out-of-bound situation");
result = LocalVarValue{true, "", &arr_p[ind_w]};
} else if (P.isDictionary() && what.isString()) {
const std::map<std::string, json::JSON>& dict_p = P.asDictionary();
const std::string& key_w = what.asString();
ASSERT(dict_p.count(key_w) == 1, "No such key exception");
result = LocalVarValue{true, "", &dict_p.at(key_w)};
} else
THROW("Incorrect type of \"json[json]\" expression. Unallowed signature of [] operator");
} else {
ASSERT(what.isString(), "Expression \"element[X]\" allowed only if X is string (json object)");
if (what.asString().empty())
return;
if (!is_uname_dotted_sequence(what.asString()))
THROW("Incorrect X in \"element[X]\"");
result.EL_name += ("." + what.asString());
}
}
uptr<EEFrame> toMe(bool returned, const global_elem_set_t& global_elems,
const std::vector<LocalVarValue>& local_vars) {
if (returned) {
ASSERT(temp_ret.is_json, "Expression \"X[ element ]\" is not allowed");
assert(temp_ret.JSON_subval);
descend(*(temp_ret.JSON_subval));
} else {
assert(expr.isDictionary());
const json::JSON& val = expr["V"].g();
if (val.isInteger()) {
size_t lv_ind = val.asInteger().get_int();
assert(lv_ind < local_vars.size());
result = local_vars[lv_ind];
} else if (val.isString()) {
std::string cur_el_name_str = expr["V"].g().asString();
result = LocalVarValue{false, cur_el_name_str, NULL};
} else
assert(false);
}
const std::vector<json::JSON>& chain = expr["C"].g().asArray();
while (true) {
if (chain_el >= chain.size())
return NULL;
const json::JSON& t = chain[chain_el++];
if (t.isDictionary())
return std::make_unique<EEFrame>(t, temp_ret);
descend(t);
}
}
};
LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
const std::vector<LocalVarValue>& local_vars, const json::JSON& expr) {
bool returned = false;
std::vector<uptr<EEFrame>> stack;
LocalVarValue result;
stack.push_back(std::make_unique<EEFrame>(expr, result));
while (!stack.empty()) {
EEFrame& cur = *stack.back();
uptr<EEFrame> todo = cur.toMe(returned, global_elems, local_vars);
returned = !(bool)todo;
if (todo)
stack.push_back(mv(todo));
else
stack.pop_back();
}
return result;
}
}

View File

@ -5,6 +5,101 @@
#include <assert.h> #include <assert.h>
namespace nytl { namespace nytl {
struct LocalVarValue {
bool is_json = false;
std::string EL_name;
const json::JSON* JSON_subval = NULL;
};
/* Expression Execution Frame */
struct EEFrame {
const json::JSON& expr;
LocalVarValue& result;
LocalVarValue temp_ret;
size_t chain_el = 0;
EEFrame(const json::JSON &expr, LocalVarValue &result)
: expr(expr),
result(result) {
}
void descend(const json::JSON& what) {
if (result.is_json) {
const json::JSON& P = *result.JSON_subval;
if (P.isArray() && what.isInteger()) {
const std::vector<json::JSON> arr_p = P.asArray();
int64_t ind_w = what.asInteger().get_int();
ASSERT(ind_w > 0 && ind_w < arr_p.size(), "Expression \"array[integer]\" caused out-of-bound situation");
result = LocalVarValue{true, "", &arr_p[ind_w]};
} else if (P.isDictionary() && what.isString()) {
const std::map<std::string, json::JSON>& dict_p = P.asDictionary();
const std::string& key_w = what.asString();
ASSERT(dict_p.count(key_w) == 1, "No such key exception");
result = LocalVarValue{true, "", &dict_p.at(key_w)};
} else
THROW("Incorrect type of \"json[json]\" expression. Unallowed signature of [] operator");
} else {
ASSERT(what.isString(), "Expression \"element[X]\" allowed only if X is string (json object)");
if (what.asString().empty())
return;
if (!is_uname_dotted_sequence(what.asString()))
THROW("Incorrect X in \"element[X]\"");
result.EL_name += ("." + what.asString());
}
}
uptr<EEFrame> toMe(bool returned, const global_elem_set_t& global_elems,
const std::vector<LocalVarValue>& local_vars) {
if (returned) {
ASSERT(temp_ret.is_json, "Expression \"X[ element ]\" is not allowed");
assert(temp_ret.JSON_subval);
descend(*(temp_ret.JSON_subval));
} else {
assert(expr.isDictionary());
const json::JSON& val = expr["V"].g();
if (val.isInteger()) {
size_t lv_ind = val.asInteger().get_int();
assert(lv_ind < local_vars.size());
result = local_vars[lv_ind];
} else if (val.isString()) {
std::string cur_el_name_str = expr["V"].g().asString();
result = LocalVarValue{false, cur_el_name_str, NULL};
} else
assert(false);
}
const std::vector<json::JSON>& chain = expr["C"].g().asArray();
while (true) {
if (chain_el >= chain.size())
return NULL;
const json::JSON& t = chain[chain_el++];
if (t.isDictionary())
return std::make_unique<EEFrame>(t, temp_ret);
descend(t);
}
}
};
/* No new JSON object will ever be created, I have N root json arguments,
* all the other json variables are subtrees of them. With one exception: Key iterators for arrays
* and dictionaries. They are stored in json in rendering stack */
LocalVarValue rendering_core_execute_expression(const global_elem_set_t& global_elems,
const std::vector<LocalVarValue>& local_vars, const json::JSON& expr) {
bool returned = false;
std::vector<uptr<EEFrame>> stack;
LocalVarValue result;
stack.push_back(std::make_unique<EEFrame>(expr, result));
while (!stack.empty()) {
EEFrame& cur = *stack.back();
uptr<EEFrame> todo = cur.toMe(returned, global_elems, local_vars);
returned = !(bool)todo;
if (todo)
stack.push_back(mv(todo));
else
stack.pop_back();
}
return result;
}
struct Ditch { struct Ditch {
std::string result; std::string result;
size_t cur_line_width = 0; size_t cur_line_width = 0;
@ -33,6 +128,7 @@ namespace nytl {
}; };
#define RFrame_passed const global_elem_set_t& elem_ns, Ditch& result, const std::function<std::string(std::string)>& escape #define RFrame_passed const global_elem_set_t& elem_ns, Ditch& result, const std::function<std::string(std::string)>& escape
/* Rendering Frame */
struct RFrame { struct RFrame {
size_t wsp_before_newlines = 0; size_t wsp_before_newlines = 0;
bool newlined_somewhere = false; bool newlined_somewhere = false;