Mhm, I wrote something, for some reason nothing works
This commit is contained in:
parent
83c17c22e6
commit
076a941a6e
@ -1,10 +1,3 @@
|
|||||||
<!DOCTYPE html>
|
{% ELDEF main %}
|
||||||
<html lang="en">
|
AAAAAAAA
|
||||||
<head>
|
{% ENDELDEF %}
|
||||||
<meta charset="UTF-8">
|
|
||||||
<title>{% WRITE arg1 %}</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<p>{% WRITE arg1 %}</p>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
@ -6,39 +6,11 @@
|
|||||||
|
|
||||||
namespace nytl {
|
namespace nytl {
|
||||||
/* ============== For parsing =============================*/
|
/* ============== For parsing =============================*/
|
||||||
struct ParsingContext {
|
|
||||||
std::string text;
|
|
||||||
size_t pos = 0;
|
|
||||||
size_t column = 0;
|
|
||||||
size_t line = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
constexpr int EOFVAL = -999;
|
|
||||||
|
|
||||||
int peep(ParsingContext& ctx);
|
|
||||||
|
|
||||||
char skip(ParsingContext& ctx);
|
|
||||||
void skip(ParsingContext& ctx, char ch);
|
|
||||||
|
|
||||||
void skipWhitespace(ParsingContext& ctx);
|
|
||||||
|
|
||||||
void skipString(ParsingContext& ctx, const std::string& str);
|
|
||||||
|
|
||||||
/* Returns empty if what is ahead of us is not name */
|
|
||||||
std::string readName(ParsingContext& ctx);
|
|
||||||
|
|
||||||
/* Returns empty if what is ahead of us is not uint */
|
|
||||||
std::string readUint(ParsingContext& ctx);
|
|
||||||
|
|
||||||
std::vector<std::string> splitIntoLines(const std::string& str);
|
|
||||||
std::string concatenateLines(const std::vector<std::string>& lines);
|
|
||||||
void one_part_update_min_start_wsp_non_empty(const std::string& str, bool is_first, size_t& min);
|
|
||||||
std::string one_part_cut_excess_tab(const std::string& str, bool is_first, size_t cut);
|
|
||||||
|
|
||||||
void parse_bare_file(const std::string& filename, const std::string& content,
|
void parse_bare_file(const std::string& filename, const std::string& content,
|
||||||
global_elem_set_t& result);
|
global_elem_set_t& result);
|
||||||
|
|
||||||
void parse_special_file(const std::string& filename, const std::string& content,
|
void parse_special_file(const std::string& filename, const std::string& content,
|
||||||
global_elem_set_t& result);
|
global_elem_set_t& result, TemplaterSettings& syntax);
|
||||||
|
|
||||||
/* =================== For rendering ====================*/
|
/* =================== For rendering ====================*/
|
||||||
struct LocalVarValue {
|
struct LocalVarValue {
|
||||||
|
@ -34,6 +34,15 @@ namespace nytl {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ParsingContext {
|
||||||
|
std::string text;
|
||||||
|
size_t pos = 0;
|
||||||
|
size_t column = 0;
|
||||||
|
size_t line = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
constexpr int EOFVAL = -999;
|
||||||
|
|
||||||
int peep(ParsingContext &ctx) {
|
int peep(ParsingContext &ctx) {
|
||||||
if (ctx.text.size() <= ctx.pos)
|
if (ctx.text.size() <= ctx.pos)
|
||||||
return EOFVAL;
|
return EOFVAL;
|
||||||
@ -159,7 +168,7 @@ namespace nytl {
|
|||||||
uptr<TPFrame> toMe(bool returned, ParsingContext& ctx) {
|
uptr<TPFrame> toMe(bool returned, ParsingContext& ctx) {
|
||||||
if (!returned) {
|
if (!returned) {
|
||||||
std::string nm = readName(ctx);
|
std::string nm = readName(ctx);
|
||||||
ASSERT(!nm.empty, "Type specification expected");
|
ASSERT(!nm.empty(), "Type specification expected");
|
||||||
nm = make_uppercase(nm);
|
nm = make_uppercase(nm);
|
||||||
if (nm == "JSON") {
|
if (nm == "JSON") {
|
||||||
result = json::JSON(true);
|
result = json::JSON(true);
|
||||||
@ -183,7 +192,7 @@ namespace nytl {
|
|||||||
std::vector<uptr<TPFrame>> stack;
|
std::vector<uptr<TPFrame>> stack;
|
||||||
stack.push_back(mv(std::make_unique<TPFrame>(result)));
|
stack.push_back(mv(std::make_unique<TPFrame>(result)));
|
||||||
bool returned = false;
|
bool returned = false;
|
||||||
while (!stack.empty) {
|
while (!stack.empty()) {
|
||||||
uptr<TPFrame> ret = stack.back()->toMe(returned, ctx);
|
uptr<TPFrame> ret = stack.back()->toMe(returned, ctx);
|
||||||
returned = !(bool)ret;
|
returned = !(bool)ret;
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -252,7 +261,7 @@ namespace nytl {
|
|||||||
std::vector<uptr<EPFrame>> stack;
|
std::vector<uptr<EPFrame>> stack;
|
||||||
stack.push_back(mv(std::make_unique<EPFrame>(result)));
|
stack.push_back(mv(std::make_unique<EPFrame>(result)));
|
||||||
bool returned = false;
|
bool returned = false;
|
||||||
while (!stack.empty) {
|
while (!stack.empty()) {
|
||||||
uptr<EPFrame> ret = stack.back()->toMe(returned, ctx, local_var_names);
|
uptr<EPFrame> ret = stack.back()->toMe(returned, ctx, local_var_names);
|
||||||
returned = !(bool)ret;
|
returned = !(bool)ret;
|
||||||
if (ret)
|
if (ret)
|
||||||
@ -283,7 +292,7 @@ namespace nytl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool isIt_magic_block_end(ParsingContext& ctx, const TemplaterSettings& syntax) {
|
bool isIt_magic_block_end(ParsingContext& ctx, const TemplaterSettings& syntax) {
|
||||||
return peep(ctx) == syntax.magic_block_start[0];
|
return peep(ctx) == syntax.magic_block_end[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ECPFrame {
|
struct ECPFrame {
|
||||||
@ -320,27 +329,10 @@ namespace nytl {
|
|||||||
result.parts.back().when_for_put.line_feed = true;
|
result.parts.back().when_for_put.line_feed = true;
|
||||||
else
|
else
|
||||||
assert(false);
|
assert(false);
|
||||||
}
|
} else
|
||||||
// skip_magic_block_start(ctx, syntax);
|
assert(ret_data_int == 0);
|
||||||
// std::string ender = make_uppercase(readName(ctx));
|
|
||||||
// if (gone_for == gone_for_for) {
|
|
||||||
// ASSERT(ender == "ENDFOR", "Expected ENDFOR");
|
|
||||||
// skipWhitespace(ctx);
|
|
||||||
// std::string lf_arg = make_uppercase(readName(ctx));
|
|
||||||
// if (lf_arg == "LF") {
|
|
||||||
// result.back().when_for_put.line_feed = true;
|
|
||||||
// } else if (lf_arg == "NOLF") {
|
|
||||||
// result.back().when_for_put.line_feed = false;
|
|
||||||
// } else
|
|
||||||
// ASSERT(lf_arg == "", "Expected nothing, LF or NOLF");
|
|
||||||
// skip_magic_block_end(ctx, syntax);
|
|
||||||
// } else if (gone_for == gone_for_ref) {
|
|
||||||
// skip_magic_block_start(ctx, syntax);
|
|
||||||
// ASSERT(ender == "ENDREF", "Expected ENDREF");
|
|
||||||
// } else
|
|
||||||
// assert(false);
|
|
||||||
// skip_magic_block_end(ctx, syntax);
|
|
||||||
}
|
}
|
||||||
|
ret_data_int = 0;
|
||||||
ya_e_ya_h_i_ya_g_d_o:
|
ya_e_ya_h_i_ya_g_d_o:
|
||||||
result.parts.emplace_back();
|
result.parts.emplace_back();
|
||||||
result.parts.back().when_code.lines = read_code_up_to_mag_block_start(ctx, syntax);
|
result.parts.back().when_code.lines = read_code_up_to_mag_block_start(ctx, syntax);
|
||||||
@ -440,8 +432,61 @@ namespace nytl {
|
|||||||
P.called_element["V"] = json::JSON(base_el);
|
P.called_element["V"] = json::JSON(base_el);
|
||||||
P.called_element["C"] = json::JSON(json::array);
|
P.called_element["C"] = json::JSON(json::array);
|
||||||
skipWhitespace(ctx);
|
skipWhitespace(ctx);
|
||||||
|
P.passed_arguments = {parse_expression(ctx, local_var_names)};
|
||||||
};
|
};
|
||||||
// todo REF, PUT, WRITE, ROUGHINSERT todo enders todo else (error)
|
if (op == "WRITE") {
|
||||||
|
mediocre_operator("str2text");
|
||||||
|
goto ya_e_ya_h_i_ya_g_d_o;;
|
||||||
|
}
|
||||||
|
if (op == "ROUGHINSERT") {
|
||||||
|
mediocre_operator("str2code");
|
||||||
|
goto ya_e_ya_h_i_ya_g_d_o;;
|
||||||
|
}
|
||||||
|
if (op == "ENDELDEF") {
|
||||||
|
ASSERT(myself == gone_for_nothing, "Unexpected end of element");
|
||||||
|
skip_magic_block_end(ctx, syntax);
|
||||||
|
if (!result.parts.empty()) {
|
||||||
|
if (result.parts[0].type == element_part_type_t::code)
|
||||||
|
result.parts[0].when_code.lines = clement_lstrip(result.parts[0].when_code.lines);
|
||||||
|
if (result.parts.back().type == element_part_type_t::code)
|
||||||
|
rstrip(result.parts.back().when_code.lines);
|
||||||
|
size_t cut = 999999999999;
|
||||||
|
size_t N = result.parts.size();
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
if (result.parts[i].type == element_part_type_t::code) {
|
||||||
|
one_part_update_min_start_wsp_non_empty(result.parts[i].when_code.lines, i == 0, cut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (size_t i = 0; i < N; i++) {
|
||||||
|
if (result.parts[i].type == element_part_type_t::code) {
|
||||||
|
result.parts[i].when_code.lines = one_part_cut_excess_tab(result.parts[i].when_code.lines, i == 0, cut);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (op == "ENDFOR") {
|
||||||
|
ASSERT(myself == gone_for_for, "Unexpected end of for cycle");
|
||||||
|
skipWhitespace(ctx);
|
||||||
|
/* Here I am using ret_data_int to return info about NOLF(1)/LF(2) decision */
|
||||||
|
ret_data_int = 2; // Default is to do LF
|
||||||
|
if (!isIt_magic_block_end(ctx, syntax)) {
|
||||||
|
op = make_uppercase(readName(ctx));
|
||||||
|
if (op == "LF") {
|
||||||
|
ret_data_int = 2;
|
||||||
|
} else if (op == "NOLF") {
|
||||||
|
ret_data_int = 1;
|
||||||
|
} else
|
||||||
|
THROW("Expected LF, NOLF or end of magic block");
|
||||||
|
}
|
||||||
|
skip_magic_block_end(ctx, syntax);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (op == "ENDREF") {
|
||||||
|
skip_magic_block_end(ctx, syntax);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
THROW("Unknown operator. Expected FOR, REF, PUT, WRITE, ROUGHINSERT, ENDELDEF, ENDFOR, ENDREF");
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -462,8 +507,37 @@ namespace nytl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void parse_special_file(const std::string& filename, const std::string& content,
|
void parse_special_file(const std::string& filename, const std::string& content,
|
||||||
std::map<std::string, Element>& result)
|
global_elem_set_t& result, TemplaterSettings& syntax)
|
||||||
{
|
{
|
||||||
// THROW("Don't know how to parse it yet");
|
ParsingContext ctx{content};
|
||||||
|
while(true) {
|
||||||
|
skipWhitespace(ctx);
|
||||||
|
if (peep(ctx) == EOFVAL)
|
||||||
|
break;
|
||||||
|
skip_magic_block_start(ctx, syntax);
|
||||||
|
ASSERT(make_uppercase(readName(ctx)) == "ELDEF", "Expected ELDEF");
|
||||||
|
skipWhitespace(ctx);
|
||||||
|
std::string elname_postfix = readName(ctx);
|
||||||
|
ASSERT(elname_postfix != "_", "please don't");
|
||||||
|
std::string fullname = elname_postfix == "main" ? filename : filename + "." + elname_postfix;
|
||||||
|
ASSERT(result.count(fullname) == 0, "Element " + fullname + " has been already defined");
|
||||||
|
Element& newborn = result[fullname];
|
||||||
|
arg_name_list_t arglist;
|
||||||
|
while (true) {
|
||||||
|
skipWhitespace(ctx);
|
||||||
|
if (isIt_magic_block_end(ctx, syntax))
|
||||||
|
break;
|
||||||
|
newborn.arguments.push_back(parse_type(ctx));
|
||||||
|
skipWhitespace(ctx);
|
||||||
|
std::string argname = readName(ctx);
|
||||||
|
ASSERT(!argname.empty(), "Expected argument name");
|
||||||
|
if (argname != "_") {
|
||||||
|
size_t k = arglist.size();
|
||||||
|
arglist[argname] = k;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
skip_magic_block_end(ctx, syntax);
|
||||||
|
parse_element_content(fullname, ctx, syntax, arglist, newborn, result);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -119,7 +119,7 @@ namespace nytl {
|
|||||||
for (const InterestingFile& file: intersting_files) {
|
for (const InterestingFile& file: intersting_files) {
|
||||||
std::string content = readFile(file.path);
|
std::string content = readFile(file.path);
|
||||||
if (file.special_syntax_applied) {
|
if (file.special_syntax_applied) {
|
||||||
parse_special_file(file.dot_name, content, elements);
|
parse_special_file(file.dot_name, content, elements, settings);
|
||||||
} else {
|
} else {
|
||||||
parse_bare_file(file.dot_name, content, elements);
|
parse_bare_file(file.dot_name, content, elements);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user