#include "core.h" #include "alotalot.h" #include #include namespace nytl { size_t first_nw_char(const std::string& str) { size_t i = 0; for (; i < str.size(); i++) if (!isSPACE(str[i])) break; return i; } bool is_space_only(const std::string& str) { return first_nw_char(str) == str.size(); } void rstrip(std::string& str) { while (!str.empty() && isSPACE(str.back())) str.resize(str.size() - 1); } std::string clement_lstrip(const std::string& str) { size_t gone = 0; size_t n = str.size(); for (size_t i = 0; i < n; i++) { if (str[i] == '\n') { gone = i + 1; } else if (!isSPACE(str[i])) { return str.substr(gone); } } return ""; } void parse_bare_file(const std::string& filename, const std::string& content, global_elem_set_t& result) { ASSERT(result.count(filename) == 0, "Repeated element " + filename); std::vector lines; bool had_nw_line = false; size_t smallest_tab; std::string current_line; auto finish = [&]() { size_t tab_sz = first_nw_char(current_line); if (tab_sz == current_line.size()) { if (had_nw_line) lines.emplace_back(); } else { if (had_nw_line) { if (smallest_tab > tab_sz) smallest_tab = tab_sz; } else { smallest_tab = tab_sz; had_nw_line = true; } lines.push_back(current_line); } current_line.clear(); }; for (char ch: content) { if (ch == '\n') { finish(); } else { current_line += ch; } } finish(); while (!lines.empty() && lines.back().empty()) lines.pop_back(); for (std::string& line: lines) { if (!line.empty()) { assert(line.size() > smallest_tab); line = line.substr(smallest_tab); } } Element& el = result[filename]; el.parts = {ElementPart{element_part_types::code}}; std::string lines_cat = concatenateLines(lines); el.parts[0].when_code.lines = mv(lines_cat); } int peep(ParsingContext &ctx) { if (ctx.text.size() <= ctx.pos) return EOFVAL; return ctx.text[ctx.pos]; } void advance(ParsingContext& ctx) { if (ctx.text[ctx.pos] == '\n') { ctx.line++; ctx.column = 0; } else { ctx.column++; } ctx.pos++; } void skip(ParsingContext& ctx) { ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF"); advance(ctx); } void skip(ParsingContext& ctx, char ch) { ASSERT(ctx.pos < ctx.text.size(), "Unexpected EOF"); ASSERT(ctx.text[ctx.pos] == ch, "Unexpected character"); advance(ctx); } void skipWhitespace(ParsingContext &ctx) { while (peep(ctx) > 0 && isSPACE((char)peep(ctx))) skip(ctx); } std::vector splitIntoLines(const std::string &str) { std::vector result; for (char ch: str) { if (ch == '\n') result.emplace_back(); else result.back() += ch; } return result; } std::string concatenateLines(const std::vector& lines) { std::string result; size_t n = lines.size(); for (size_t i = 0; i < n; i++) { if (i) result += '\n'; result += lines[i]; } return result; } void parse_special_file(const std::string& filename, const std::string& content, std::map& result) { THROW("Don't know how to parse it yet"); } }