basic printers, type printers, some fixes, part of expression printers

This commit is contained in:
ProgramSnail 2023-07-24 18:47:57 +03:00
parent 3914ff7d8b
commit 3669084f55
14 changed files with 795 additions and 39 deletions

View file

@ -8,8 +8,8 @@
namespace builders {
namespace utils {
std::optional<char> to_escape_symbol(char symbol) {
switch (symbol) {
std::optional<char> to_escape_symbol(char ch) {
switch (ch) {
case 'a':
return '\a';
case 'b':
@ -41,7 +41,7 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
if (modifier == "?") {
return nodes::Modifier::OR_FALSE;
} else if (modifier == "!") {
return nodes::Modifier::OR_PANIC;
return nodes::Modifier::OR_RETURN;
} else if (modifier == "->" || modifier == "out") {
return nodes::Modifier::OUT;
} else if (modifier == "<-" || modifier == "in") {

83
src/basic_printers.cpp Normal file
View file

@ -0,0 +1,83 @@
#include "basic_printers.hpp"
#include "error_handling.hpp"
namespace printers {
namespace utils {
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 "\\s";
default:
return std::string(1, ch);
}
}
} // namespace utils
void print_literal(const nodes::Literal &literal, Printer &printer) {
switch (literal.get_any()->index()) {
case 0: // double
// print in parseable form ??
printer.print(literal.get<double>().value());
return;
case 1: // long long
printer.print(literal.get<long long>().value());
return;
case 2: // std::string
printer.print("\"\"");
// more efficient approach ??
for (auto &ch : *literal.get<std::string>().value()) {
printer.print(utils::to_printable_symbol(ch));
}
printer.print("\"\"");
return;
case 3: // char
printer.print("\'\'");
printer.print(utils::to_printable_symbol(*literal.get<char>().value()));
printer.print("\'\'");
return;
case 4: // bool
printer.print(literal.get<bool>().value() ? "true" : "false");
return;
case 5: // unit
printer.print("()");
return;
case 6: // null
printer.print("null");
return;
default:
break;
}
error_handling::handle_general_error("Unreachable");
exit(1); // unreachable
}
void print_identifier(const nodes::Identifier &identifier, Printer &printer) {
printer.print(identifier.get());
}
void print_annotation(const std::string &annotation, Printer &printer) {
printer.print('@');
printer.print(annotation);
}
} // namespace printers

View file

@ -258,7 +258,7 @@ build_comma_expression(parser::ParseTree::Node parser_node,
nodes::Identifier(
build_node(parser_node), // can't find more precise location'
nodes::Identifier::SIMPLE_NAME, ","),
std::move(arguments), std::nullopt, false);
std::move(arguments), std::nullopt, false, true);
}
// expression operator expression
@ -281,7 +281,7 @@ build_operator_expression(parser::ParseTree::Node parser_node,
return nodes::NameExpression(build_node(parser_node),
build_operator(name_node), std::move(arguments),
std::nullopt, false);
std::nullopt, false, true);
}
// --- continers
@ -475,7 +475,7 @@ build_name_expression(parser::ParseTree::Node parser_node,
std::move(arguments),
prefix_node.has_value() ? build_type(prefix_node.value(), type_storage)
: std::optional<nodes::TypeProxy>(),
is_point_call);
is_point_call, false);
}
// type (annotation? expression)*

225
src/expression_printers.cpp Normal file
View file

@ -0,0 +1,225 @@
#include "expression_printers.hpp"
#include "basic_nodes.hpp"
#include "basic_printers.hpp"
#include "expression_nodes.hpp"
#include "type_printers.hpp"
namespace printers {
void print_expression(const nodes::Expression &expression,
printers::Printer &printer) {} // IN PROGRESS
// --- flow control
void print_match(const nodes::Match &expression, printers::Printer &printer) {
} // IN PROGRESS
void print_condition(const nodes::Condition &expression,
printers::Printer &printer) {} // IN PROGRESS
void print_loop(const nodes::Loop &expression, printers::Printer &printer) {
} // IN PROGRESS
// --- containers
void print_container(const nodes::Container &expression,
printers::Printer &printer) {} // IN PROGRESS
// --- modifiers
void print_return(const nodes::Return &expression, printers::Printer &printer) {
switch (expression.get_type()) {
case nodes::Return::RETURN:
printer.print("return ");
break;
case nodes::Return::BRING:
printer.print("bring ");
break;
default:
break;
}
print_expression(*expression.get_expression(), printer);
}
void print_name_definition(const nodes::NameDefinition &expression,
printers::Printer &printer) {
if (printer.print_words_instead_of_symbols()) {
switch (expression.get_modifier()) {
case nodes::NameDefinition::LET:
printer.print("let ");
break;
case nodes::NameDefinition::VAR:
printer.print("var ");
break;
default:
break;
}
} else {
switch (expression.get_modifier()) {
case nodes::NameDefinition::LET:
printer.print("% ");
break;
case nodes::NameDefinition::VAR:
printer.print("$ ");
break;
default:
break;
}
}
print_identifier(*expression.get_name(), printer);
}
void print_access(const nodes::Access &expression, printers::Printer &printer) {
print_expression(*expression.get_value(), printer);
switch (expression.get_type()) {
case nodes::Access::ARRAY:
printer.print('[');
break;
case nodes::Access::TUPLE:
printer.print('.');
break;
default:
break;
}
print_expression(*expression.get_index(), printer);
switch (expression.get_type()) {
case nodes::Access::ARRAY:
printer.print(']');
break;
case nodes::Access::TUPLE:
break;
default:
break;
}
}
void print_loop_control(const nodes::LoopControl &expression,
printers::Printer &printer) {
switch (expression.get_type()) {
case nodes::LoopControl::BREAK:
printer.print("break");
break;
case nodes::LoopControl::CONTINUE:
printer.print("continue");
break;
default:
break;
}
}
void print_modifier_expression(const nodes::ModifierExpression &expression,
printers::Printer &printer) {
if (printer.print_words_instead_of_symbols()) {
switch (expression.get_modifier()) {
case nodes::Modifier::OUT:
printer.print("out ");
break;
case nodes::Modifier::IN:
printer.print("in ");
break;
case nodes::Modifier::REF:
printer.print("ref ");
break;
default:
break;
}
} else {
switch (expression.get_modifier()) {
case nodes::Modifier::OUT:
printer.print("-> ");
break;
case nodes::Modifier::IN:
printer.print("<- ");
break;
case nodes::Modifier::REF:
printer.print("<> ");
break;
default:
break;
}
}
print_expression(*expression.get_expression(), printer);
switch (expression.get_modifier()) {
case nodes::Modifier::OR_FALSE:
printer.print('?');
break;
case nodes::Modifier::OR_RETURN:
printer.print('!');
break;
default:
break;
}
}
// --- other
void print_name_expression(const nodes::NameExpression &expression,
printers::Printer &printer) {
if (expression.is_operator_call() || expression.is_point_call()) {
print_expression(*expression.get_argument_value(0), printer);
if (expression.is_point_call()) {
printer.print('.');
} else {
printer.space();
}
} else if (expression.get_prefix().has_value()) {
print_type(*expression.get_prefix().value(), printer);
printer.print('.');
}
print_identifier(*expression.get_name(), printer);
for (size_t i = 0; i < expression.arguments_size(); ++i) {
printer.space();
if (expression.get_argument_annotation(i).has_value()) {
print_annotation(*expression.get_argument_annotation(i).value(), printer);
printer.space();
}
print_expression(*expression.get_argument_value(i), printer);
}
} // IN PROGRESS
void print_constructor(const nodes::Constructor &expression,
printers::Printer &printer) {
print_type(*expression.get_type(), printer);
for (size_t i = 0; i < expression.arguments_size(); ++i) {
printer.space();
if (expression.get_argument_annotation(i).has_value()) {
print_annotation(*expression.get_argument_annotation(i).value(), printer);
printer.space();
}
print_expression(*expression.get_argument_value(i), printer);
}
} // IN PROGRESS
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer) {
printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ ");
for (size_t i = 0; i < expression.arguments_size(); ++i) {
print_identifier(*expression.get_argument(i), printer);
printer.space();
}
printer.print(printer.print_words_instead_of_symbols() ? "do " : "-> ");
print_expression(*expression.get_expression(), printer);
} // IN PROGRESS
} // namespace printers

61
src/type_printers.cpp Normal file
View file

@ -0,0 +1,61 @@
#include "type_printers.hpp"
#include "basic_printers.hpp"
#include "type_nodes.hpp"
namespace printers {
void print_type(const nodes::Type &type, printers::Printer &printer) {
if (type.is_on_heap()) {
printer.print('^');
}
printer.print(type.get_name());
if (type.is_optional()) {
printer.print('?');
}
if (type.is_result()) {
printer.print('!');
}
printer.print('[');
for (size_t i = 0; i < type.get_parametrs_size(); ++i) {
print_type(*type.get_parameter(i), printer);
printer.space();
}
printer.print(']');
}
void print_tuple_type(const nodes::TupleType &type,
printers::Printer &printer) {
for (size_t i = 0; i < type.size(); ++i) {
if (i > 0) {
printer.print(" & ");
}
auto annotation = type.get_annotation(i);
if (annotation.has_value()) {
print_annotation(*annotation.value(), printer);
}
print_type(*type.get(i), printer);
}
}
void print_variant_type(const nodes::VariantType &type,
printers::Printer &printer) {
for (size_t i = 0; i < type.size(); ++i) {
if (type.size() > 1 || i > 0) {
printer.print("| ");
}
print_tuple_type(*type.get(i), printer);
if (i + 1 < type.size()) {
printer.new_line();
}
}
} // IN PROGRESS
} // namespace printers