#include "core.h" #include "alotalot.h" #include #include #include namespace nytl { struct Ditch { std::string result; size_t cur_line_width = 0; void append(const std::string& text) { size_t n = result.size(); result.resize(n + text.size()); memcpy((void*)&result.c_str()[n], text.c_str(), text.size()); for (char ch: text) { if (ch == '\n') cur_line_width = 0; else cur_line_width++; } } }; #define RFrame_passed const global_elem_set_t& elem_ns, Ditch& result, const std::function& escape struct RFrame { virtual uptr toMe(bool returned, RFrame_passed) {assert(false);} virtual ~RFrame() = default; }; struct RFrame_OverParts : public RFrame{ std::string name; std::vector passed_args; /* This parameter incapsulates `cur_line_width` at some point for multiline `put-parts` */ size_t multiline_put_start = 0; /* main iterator of this frame. Persistent across control returns */ size_t part_to_do = 0; RFrame_OverParts(const std::string &name, const std::vector &passed_args, size_t multiline_put_start) : name(name), passed_args(passed_args), multiline_put_start(multiline_put_start) { } uptr toMe(bool returned, RFrame_passed) override { if (!returned) ASSERT(elem_ns.count(name) == 1, "No such element"); const Element& el = elem_ns.at(name); if (!returned) { /* Continue to do checks */ size_t n = el.arguments.size(); ASSERT(n == passed_args.size(), "Argument count mismatch"); for (size_t i = 0; i < n; i++) { if (el.arguments[i].type == json::true_symbol) { ASSERT(passed_args[i].is_json, "Expected json element argument, got element"); } else { // If not json is expected, element must be expected assert(el.arguments[i].isArray()); ASSERT(!passed_args[i].is_json, "Expected element element arguemnt, got json"); ASSERT(elem_ns.count(passed_args[i].EL_name), "No such element, can't compare signatures of argument value"); const Element& arg_element = elem_ns.at(passed_args[i].EL_name); // ASSERT(passed_args); if(el.arguments[i].asArray() != arg_element.arguments) THROW("Signature of argument " + std::to_string(i) + " does not match"); } } } if (el.base) { assert(!returned); assert(passed_args.size() == 1); const json::JSON* X = passed_args[0].JSON_subval; assert(X); if (name == "jesc") { result.append(escape(json::generate_str(*X, json::print_pretty))); } else if (name == "str2text") { ASSERT(X->isString(), "str2text takes json string"); result.append(escape(X->asString())); } else if (name == "str2code") { ASSERT(X->isString(), "str2code takes json string"); result.append(X->asString()); } return NULL; } while (true) { if (part_to_do == el.parts.size()) return NULL; const ElementPart& cur_part = el.parts[part_to_do++]; if (cur_part.type == element_part_types::code) { const ElementPart::when_code_S& pt = cur_part.when_code; result.append(pt.lines); } else if (cur_part.type == element_part_types::put) { const ElementPart::when_put_S& pt = cur_part.when_put; LocalVarValue called_element_expv = rendering_core_execute_expression(elem_ns, passed_args, pt.called_element); ASSERT(!called_element_expv.is_json, "Can't PUT json variable"); size_t AN = pt.passed_arguments.size(); std::vector passed_arguments_expv(AN); for (size_t i = 0; i < AN; i++) passed_arguments_expv[i] = rendering_core_execute_expression(elem_ns, passed_args, pt.passed_arguments[i]); return uptr(new RFrame_OverParts(called_element_expv.EL_name, passed_arguments_expv, result.cur_line_width)); } else if (cur_part.type == element_part_types::for_put) { const ElementPart::when_for_put_S& pt = cur_part.when_for_put; // todo } else if (cur_part.type == element_part_types::ref_put) { const ElementPart::when_ref_put_S& pt = cur_part.when_ref_put; // todo } } } }; std::string rendering_core(const std::string& entry_func, const std::vector& entry_arguments, const global_elem_set_t& elem_ns, const std::function& escape) { Ditch result; std::vector> stack; { size_t AN = entry_arguments.size(); std::vector entry_arguments_conv(AN); for (size_t i = 0; i < AN; i++) entry_arguments_conv[i] = {true, "", &entry_arguments[i]}; // stack.push_back(std::make_unique<>()); // make_frame(entry_func, entry_arguments_conv); } while (!stack.empty()) { // Frame& cur = *stack.back(); } return result.result; } }