2023-07-24 18:47:57 +03:00
|
|
|
#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,
|
2023-07-24 18:47:57 +03:00
|
|
|
bool print_words_instead_of_symbols)
|
2023-07-24 21:23:18 +03:00
|
|
|
: output_(output), tab_width_(tab_width), width_limit_(width_limit),
|
2023-07-24 18:47:57 +03:00
|
|
|
print_words_instead_of_symbols_(print_words_instead_of_symbols),
|
2023-07-24 21:23:18 +03:00
|
|
|
current_position_(0), current_indentation_level_(0) {}
|
2023-07-24 18:47:57 +03:00
|
|
|
|
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();
|
|
|
|
|
print_spaces(current_indentation_level_ * tab_width_);
|
|
|
|
|
}
|
2023-07-24 18:47:57 +03:00
|
|
|
|
2023-07-24 21:23:18 +03:00
|
|
|
void new_line(size_t indentation) {
|
|
|
|
|
end_line();
|
|
|
|
|
print_spaces(indentation);
|
2023-07-24 18:47:57 +03:00
|
|
|
}
|
|
|
|
|
|
2023-07-24 23:55:11 +03:00
|
|
|
void indent() { current_indentation_level_ += tab_width_; }
|
2023-07-24 18:47:57 +03:00
|
|
|
|
2023-07-24 23:55:11 +03:00
|
|
|
void deindent() { current_indentation_level_ -= tab_width_; }
|
2023-07-24 18:47:57 +03:00
|
|
|
|
|
|
|
|
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 {
|
2023-07-24 18:47:57 +03:00
|
|
|
return print_words_instead_of_symbols_;
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-24 23:55:11 +03:00
|
|
|
size_t get_current_position() const { return current_position_; }
|
|
|
|
|
|
|
|
|
|
size_t get_current_indentation_level() const {
|
|
|
|
|
return current_indentation_level_;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
size_t set_current_indentation_level(size_t indentation_level) {
|
|
|
|
|
current_indentation_level_ = indentation_level;
|
|
|
|
|
}
|
2023-07-24 21:23:18 +03:00
|
|
|
|
2023-07-24 18:47:57 +03:00
|
|
|
private:
|
2023-07-24 21:23:18 +03:00
|
|
|
void end_line() {
|
|
|
|
|
output_ << "\n";
|
|
|
|
|
current_position_ = 0;
|
|
|
|
|
}
|
2023-07-24 18:47:57 +03:00
|
|
|
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);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-07-24 18:47:57 +03:00
|
|
|
private:
|
|
|
|
|
std::ostream &output_;
|
2023-07-24 21:23:18 +03:00
|
|
|
size_t tab_width_ = 0;
|
|
|
|
|
size_t width_limit_ = 0;
|
2023-07-24 18:47:57 +03:00
|
|
|
bool print_words_instead_of_symbols_ = false;
|
|
|
|
|
|
2023-07-24 21:23:18 +03:00
|
|
|
size_t current_position_ = 0;
|
|
|
|
|
size_t current_indentation_level_ = 0;
|
2023-07-24 18:47:57 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
} // namespace printers
|