nytl: merged files rendering.cpp and execute_expression.cpp
This commit is contained in:
parent
dd806a5633
commit
ea7d50a183
@ -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",
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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;
|
|
||||||
}
|
|
||||||
}
|
|
@ -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;
|
||||||
|
Loading…
Reference in New Issue
Block a user