lang/include/basic_printers.hpp

141 lines
3.4 KiB
C++
Raw Normal View History

#pragma once
#include "basic_nodes.hpp"
#include <iostream>
namespace printers {
class Printer {
public:
2023-07-24 21:23:18 +03:00
Printer(std::ostream &output, size_t tab_width, size_t width_limit,
bool print_words_instead_of_symbols)
2023-07-24 21:23:18 +03:00
: output_(output), tab_width_(tab_width), width_limit_(width_limit),
print_words_instead_of_symbols_(print_words_instead_of_symbols),
2023-07-25 21:33:57 +03:00
current_position_(0), indentation_level_(0) {}
2023-07-24 21:23:18 +03:00
void print_converted(const std::string &value) {
for (auto &ch : value) {
output_ << to_printable_symbol(ch);
current_position_ += to_printable_symbol(ch).size();
}
}
// value shouldn't contain '\n', '\t', etc.
void print(const std::string &value) {
output_ << value;
current_position_ += value.size();
}
void column_down() {
size_t current_position = current_position_;
end_line();
print_spaces(current_position);
}
void new_indent_line() {
end_line();
2023-07-25 21:33:57 +03:00
print_spaces(indentation_level_);
2023-07-24 21:23:18 +03:00
}
2023-07-24 21:23:18 +03:00
void new_line(size_t indentation) {
end_line();
print_spaces(indentation);
}
void to_indentation_level() {
if (indentation_level_ > current_position_) {
print_spaces(indentation_level_ - current_position_);
}
}
2023-07-25 21:33:57 +03:00
void indent() { indentation_level_ += tab_width_; }
2023-07-25 21:33:57 +03:00
void deindent() { indentation_level_ -= tab_width_; }
void tab() { print_spaces(tab_width_); }
void space() { print_spaces(1); }
2023-07-24 21:23:18 +03:00
size_t current_position() const { return current_position_; }
size_t width_limit() const { return width_limit_; }
size_t width_left() const {
return std::max(static_cast<int64_t>(width_limit_) -
static_cast<int64_t>(current_position_),
static_cast<int64_t>(0));
}
bool print_words_instead_of_symbols() const {
return print_words_instead_of_symbols_;
}
2023-07-24 23:55:11 +03:00
size_t get_current_position() const { return current_position_; }
2023-07-25 21:33:57 +03:00
size_t get_indentation_level() const { return indentation_level_; }
2023-07-24 23:55:11 +03:00
2023-07-25 21:33:57 +03:00
void set_indentation_level(size_t indentation_level) {
indentation_level_ = indentation_level;
2023-07-24 23:55:11 +03:00
}
2023-07-24 21:23:18 +03:00
private:
2023-07-24 21:23:18 +03:00
void end_line() {
output_ << "\n";
current_position_ = 0;
}
void print_spaces(size_t n) { print(std::string(n, ' ')); }
2023-07-24 21:23:18 +03:00
static std::string to_printable_symbol(char ch) {
switch (ch) {
case '\a':
return "\\a";
case '\b':
return "\\b";
case '\e':
return "\\e";
case '\f':
return "\\f";
case '\n':
return "\\n";
case '\r':
return "\\r";
case '\t':
return "\\t";
case '\v':
return "\\v";
case '\'':
return "\\\'";
case '\"':
return "\\\"";
// case ' ':
// return "\\s";
default:
return std::string(1, ch);
}
}
private:
std::ostream &output_;
2023-07-24 21:23:18 +03:00
size_t tab_width_ = 0;
size_t width_limit_ = 0;
bool print_words_instead_of_symbols_ = false;
2023-07-24 21:23:18 +03:00
size_t current_position_ = 0;
2023-07-25 21:33:57 +03:00
size_t indentation_level_ = 0;
};
void print_modifier(const nodes::Modifier &modifier, Printer &printer,
bool const_is_none = false);
void print_literal(const nodes::Literal &literal, Printer &printer);
void print_identifier(const nodes::Identifier &identifier, Printer &printer);
void print_annotation(const std::string &annotation, Printer &printer);
void print_extra(const nodes::Extra &extra, Printer &printer);
2023-07-25 21:33:57 +03:00
void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer);
} // namespace printers