Mhm, I wrote something, for some reason nothing works

This commit is contained in:
Андреев Григорий 2024-08-14 01:15:13 +03:00
parent 83c17c22e6
commit 076a941a6e
4 changed files with 108 additions and 69 deletions

View File

@ -1,10 +1,3 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>{% WRITE arg1 %}</title>
</head>
<body>
<p>{% WRITE arg1 %}</p>
</body>
</html>
{% ELDEF main %}
AAAAAAAA
{% ENDELDEF %}

View File

@ -6,39 +6,11 @@
namespace nytl {
/* ============== 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,
global_elem_set_t& result);
global_elem_set_t& result);
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 ====================*/
struct LocalVarValue {

View File

@ -34,6 +34,15 @@ namespace nytl {
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) {
if (ctx.text.size() <= ctx.pos)
return EOFVAL;
@ -159,7 +168,7 @@ namespace nytl {
uptr<TPFrame> toMe(bool returned, ParsingContext& ctx) {
if (!returned) {
std::string nm = readName(ctx);
ASSERT(!nm.empty, "Type specification expected");
ASSERT(!nm.empty(), "Type specification expected");
nm = make_uppercase(nm);
if (nm == "JSON") {
result = json::JSON(true);
@ -183,7 +192,7 @@ namespace nytl {
std::vector<uptr<TPFrame>> stack;
stack.push_back(mv(std::make_unique<TPFrame>(result)));
bool returned = false;
while (!stack.empty) {
while (!stack.empty()) {
uptr<TPFrame> ret = stack.back()->toMe(returned, ctx);
returned = !(bool)ret;
if (ret)
@ -252,7 +261,7 @@ namespace nytl {
std::vector<uptr<EPFrame>> stack;
stack.push_back(mv(std::make_unique<EPFrame>(result)));
bool returned = false;
while (!stack.empty) {
while (!stack.empty()) {
uptr<EPFrame> ret = stack.back()->toMe(returned, ctx, local_var_names);
returned = !(bool)ret;
if (ret)
@ -283,7 +292,7 @@ namespace nytl {
}
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 {
@ -320,27 +329,10 @@ namespace nytl {
result.parts.back().when_for_put.line_feed = true;
else
assert(false);
}
// skip_magic_block_start(ctx, syntax);
// 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);
} else
assert(ret_data_int == 0);
}
ret_data_int = 0;
ya_e_ya_h_i_ya_g_d_o:
result.parts.emplace_back();
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["C"] = json::JSON(json::array);
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,
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);
}
}
}

View File

@ -119,7 +119,7 @@ namespace nytl {
for (const InterestingFile& file: intersting_files) {
std::string content = readFile(file.path);
if (file.special_syntax_applied) {
parse_special_file(file.dot_name, content, elements);
parse_special_file(file.dot_name, content, elements, settings);
} else {
parse_bare_file(file.dot_name, content, elements);
}