or references, prining improvements, comments now printed, fixes

This commit is contained in:
ProgramSnail 2023-07-31 22:07:32 +03:00
parent 73263193a9
commit 5e70f0015f
19 changed files with 354 additions and 429 deletions

View file

@ -46,16 +46,36 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
return nodes::Modifier::OPTIONAL;
} else if (modifier == "!") {
return nodes::Modifier::RESULT;
} else if (modifier == "->" || modifier == "out") {
return nodes::Modifier::OUT;
} else if (modifier == "<-" || modifier == "in") {
return nodes::Modifier::IN;
} else if (modifier == "<>" || modifier == "ref") {
return nodes::Modifier::REF;
} else if (modifier == "|->" || modifier == "or_out") {
return nodes::Modifier::OR_OUT;
} else if (modifier == "<-|" || modifier == "or_in") {
return nodes::Modifier::OR_IN;
} else if (modifier == "--" || modifier == "const") {
return nodes::Modifier::CONST;
} else if (modifier == "->" || modifier == "out") {
return nodes::Modifier::OUT;
} else if (modifier == "<-|<>" || modifier == "in|ref") {
return nodes::Modifier::IN_OR_REF;
} else if (modifier == "<-|--" || modifier == "in|const") {
return nodes::Modifier::IN_OR_CONST;
} else if (modifier == "<>|->" || modifier == "ref|out") {
return nodes::Modifier::REF_OR_OUT;
} else if (modifier == "--|->" || modifier == "const|out") {
return nodes::Modifier::CONST_OR_OUT;
} else if (modifier == "<>|--" || modifier == "ref|const") {
return nodes::Modifier::REF_OR_CONST;
} else if (modifier == "<-|->" || modifier == "in|out") {
return nodes::Modifier::IN_OR_OUT;
} else if (modifier == "<-|<>|->" || modifier == "in|ref|out") {
return nodes::Modifier::IN_OR_REF_OR_OUT;
} else if (modifier == "<-|--|->" || modifier == "in|const|out") {
return nodes::Modifier::IN_OR_CONST_OR_OUT;
} else if (modifier == "<-|<>|--" || modifier == "in|ref|const") {
return nodes::Modifier::IN_OR_REF_OR_CONST;
} else if (modifier == "<>|--|->" || modifier == "ref|const|out") {
return nodes::Modifier::REF_OR_CONST_OR_OUT;
} else if (modifier == "<-|<>|--|->" || modifier == "in|ref|const|out") {
return nodes::Modifier::IN_OR_REF_OR_CONST_OR_OUT;
} else {
return nodes::Modifier::NONE;
}
@ -244,11 +264,31 @@ nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) {
nodes::Identifier::PLACEHOLDER, "_");
}
// --- extra
nodes::Extra build_extra(parser::ParseTree::Node parser_node) {
return nodes::Extra(build_node(parser_node), parser_node.get_value());
}
// --- empty lines
nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) {
return nodes::EmptyLines(build_node(parser_node),
parser_node.get_value_length() - 1);
std::string empty_lines = parser_node.get_value();
size_t empty_lines_count = 0;
for (auto &ch : empty_lines) {
if (ch == '\n') {
++empty_lines_count;
}
}
if (empty_lines_count == 0) {
error_handling::handle_parsing_error("Empty lines node with zero new lines",
parser_node);
}
return nodes::EmptyLines(build_node(parser_node), empty_lines_count - 1);
}
} // namespace builders

View file

@ -1,29 +1,77 @@
#include "basic_printers.hpp"
#include "error_handling.hpp"
#include <string>
#include "basic_nodes.hpp"
#include "utils.hpp"
namespace printers {
void print_modifier(const nodes::Modifier &modifier, Printer &printer) {
void print_modifier(const nodes::Modifier &modifier, Printer &printer,
bool const_is_none) {
switch (modifier) {
case nodes::Modifier::OUT:
printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> ");
break;
case nodes::Modifier::IN:
printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- ");
break;
case nodes::Modifier::REF:
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
break;
case nodes::Modifier::OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "or_out "
: "|-> ");
case nodes::Modifier::CONST:
if (!const_is_none) {
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
}
break;
case nodes::Modifier::OR_IN:
printer.print(printer.print_words_instead_of_symbols() ? "or_in " : "<-| ");
case nodes::Modifier::OUT:
printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> ");
break;
// ---
case nodes::Modifier::IN_OR_REF:
printer.print(printer.print_words_instead_of_symbols() ? "in|ref "
: "<-|<> ");
break;
case nodes::Modifier::IN_OR_CONST:
printer.print(printer.print_words_instead_of_symbols() ? "in|const "
: "<-|-- ");
break;
case nodes::Modifier::REF_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "ref|out "
: "<>|-> ");
break;
case nodes::Modifier::CONST_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "const|out "
: "--|-> ");
break;
case nodes::Modifier::REF_OR_CONST:
printer.print(printer.print_words_instead_of_symbols() ? "ref|const "
: "<>|-- ");
break;
case nodes::Modifier::IN_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "in|out "
: "<-|-> ");
break;
// ---
case nodes::Modifier::IN_OR_REF_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|out "
: "<-|<>|-> ");
break;
case nodes::Modifier::IN_OR_CONST_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "in|const|out "
: "<-|--|-> ");
break;
case nodes::Modifier::IN_OR_REF_OR_CONST:
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const "
: "<-|<>|-- ");
break;
case nodes::Modifier::REF_OR_CONST_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "ref|const|out "
: "<>|--|-> ");
break;
// ---
case nodes::Modifier::IN_OR_REF_OR_CONST_OR_OUT:
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const|out "
: "<-|<>|--|-> ");
break;
//
case nodes::Modifier::OPTIONAL:
printer.print("?");
break;
@ -84,8 +132,12 @@ void print_annotation(const std::string &annotation, Printer &printer) {
printer.print(annotation);
}
void print_extra(const nodes::Extra &extra, Printer &printer) {
printer.print(*extra.content());
}
void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer) {
for (size_t i = 0; i < empty_lines.size(); ++i) {
for (size_t i = 0; i < empty_lines.line_count(); ++i) {
printer.new_indent_line();
}
}

View file

@ -120,6 +120,9 @@ build_expression(parser::ParseTree::Node parser_node,
case tokens::Type::NULL_LITERAL:
return expression_storage.add_expression(
nodes::Expression(build_null_literal(parser_node), is_scoped));
case tokens::Type::EXTRA:
return expression_storage.add_expression(
nodes::Expression(build_extra(parser_node), is_scoped));
case tokens::Type::EMPTY_LINES:
return expression_storage.add_expression(
nodes::Expression(build_empty_lines(parser_node), is_scoped));

View file

@ -71,7 +71,10 @@ void print_expression(const nodes::Expression &expression,
print_literal(*expression.get<nodes::Literal>().value(), printer);
break;
// --- empty lines
case 13: // EmptyLines
case 13: // Extra
print_extra(*expression.get<nodes::Extra>().value(), printer);
break;
case 14: // EmptyLines
print_empty_lines(*expression.get<nodes::EmptyLines>().value(), printer);
break;
}
@ -212,10 +215,13 @@ void print_container(const nodes::Container &expression,
}
for (size_t i = 0; i < expression.expressions_size(); ++i) {
bool is_empty_lines_expression =
bool is_empty_lines =
expression.get_expression(i)->get<nodes::EmptyLines>().has_value();
if (!is_array && !is_empty_lines_expression) {
bool is_extra =
expression.get_expression(i)->get<nodes::Extra>().has_value();
if (!is_array && !is_empty_lines) {
printer.new_indent_line();
}
print_expression(*expression.get_expression(i), printer);
@ -224,7 +230,7 @@ void print_container(const nodes::Container &expression,
printer.space();
}
} else {
if (!is_empty_lines_expression) {
if (!is_empty_lines && !is_extra) {
printer.print(";");
}
}

View file

@ -1,6 +1,7 @@
#include "name_tree.hpp"
#include "error_handling.hpp"
#include "statement_nodes.hpp"
#include "utils.hpp"
namespace names {
@ -88,10 +89,7 @@ void NameTree::add_statement_children_to_tree() {
case 2: // TypeDefinition
// TODO: link methods + link children to types + connect to typeclasses
break;
case 3: // TypeclassDefinition
// TODO: link methods + connect typeclasses
break;
case 4: // EmptyLines
case 3: // EmptyLines
break;
default:
error_handling::handle_general_error(

View file

@ -27,10 +27,13 @@ build_source_file(parser::ParseTree::Node parser_node,
names::NameTree &name_tree) {
std::vector<nodes::Statement> statements;
std::optional<nodes::Identifier> last_defined_type_name;
auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
statements.push_back(build_statement(current_node, expression_storage,
type_storage, name_tree));
statements.push_back(build_statement(current_node, last_defined_type_name,
expression_storage, type_storage,
name_tree));
current_node = current_node.next_named_sibling();
}
@ -38,10 +41,11 @@ build_source_file(parser::ParseTree::Node parser_node,
}
// import | type_definition | function_definition | typeclass_definition
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage,
names::NameTree &name_tree) {
nodes::Statement
build_statement(parser::ParseTree::Node parser_node,
std::optional<nodes::Identifier> &last_defined_type_name,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage, names::NameTree &name_tree) {
tokens::Type type = tokens::string_to_type(parser_node.get_type());
std::optional<std::string> statement_name;
@ -57,8 +61,10 @@ nodes::Statement build_statement(parser::ParseTree::Node parser_node,
->get();
break;
case tokens::Type::TYPE_DEFINITION:
statement = nodes::Statement(
build_type_definition(parser_node, expression_storage, type_storage));
statement =
nodes::Statement(build_type_definition(parser_node, type_storage));
last_defined_type_name =
*statement.value().get<nodes::TypeDefinition>().value()->get_name();
statement_name = *statement.value()
.get<nodes::TypeDefinition>()
.value()
@ -67,21 +73,15 @@ nodes::Statement build_statement(parser::ParseTree::Node parser_node,
break;
case tokens::Type::FUNCTION_DEFINITION:
statement = nodes::Statement(build_function_definition(
parser_node, expression_storage, type_storage));
parser_node, last_defined_type_name, expression_storage, type_storage));
statement_name = *statement.value()
.get<nodes::FunctionDefinition>()
.value()
->get_name()
->get_full_name()
->get();
break;
case tokens::Type::TYPECLASS_DEFINITION:
statement = nodes::Statement(build_typeclass_definition(
parser_node, expression_storage, type_storage));
statement_name = *statement.value()
.get<nodes::TypeclassDefinition>()
.value()
->get_name()
->get();
case tokens::Type::EXTRA:
statement = nodes::Statement(build_extra(parser_node));
break;
case tokens::Type::EMPTY_LINES:
statement = nodes::Statement(build_empty_lines(parser_node));
@ -168,10 +168,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
// definition_info? annotation_info* '^'? simple_type (argument_type* '='
// variant_type)? ('{' function_definition* '}' | ';')
nodes::TypeDefinition
build_type_definition(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
bool is_on_heap = parser_node.nth_child(0).get_value() == "^";
std::optional<parser::ParseTree::Node> description_node;
@ -180,14 +178,31 @@ build_type_definition(parser::ParseTree::Node parser_node,
auto name_node = collect_symbol_doc_nodes(parser_node.nth_named_child(0),
description_node, annotation_nodes);
nodes::Identifier name = build_identifier(name_node);
bool is_typeclass = (name.get_type() == nodes::Identifier::TYPECLASS);
//
if (is_typeclass && !annotation_nodes.empty()) {
error_handling::handle_parsing_error(
"Typeclass definition can't have annotation documentation",
parser_node);
}
//
std::vector<nodes::Identifier> typeclasses;
std::vector<nodes::Identifier> arguments;
std::vector<nodes::FunctionDefinition> methods;
std::optional<parser::ParseTree::Node> type_node;
auto current_node = name_node.next_named_sibling();
while (!current_node.is_null()) {
switch (tokens::string_to_type(current_node.get_type())) {
case tokens::Type::TYPECLASS_IDENTIFIER:
typeclasses.push_back(build_identifier(current_node));
break;
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
arguments.push_back(build_identifier(current_node));
break;
@ -198,10 +213,6 @@ build_type_definition(parser::ParseTree::Node parser_node,
}
type_node = current_node;
break;
case tokens::Type::FUNCTION_DEFINITION:
methods.push_back(build_function_definition(
current_node, expression_storage, type_storage));
break;
default:
error_handling::handle_parsing_error(
"Unexprected node type in type definition", parser_node);
@ -210,7 +221,21 @@ build_type_definition(parser::ParseTree::Node parser_node,
}
if (!type_node.has_value() && !annotation_nodes.empty()) {
error_handling::handle_parsing_error("", parser_node);
error_handling::handle_parsing_error(
"Type declaration can't contain annotation documentation", parser_node);
}
if (is_typeclass) {
if (!arguments.empty()) {
error_handling::handle_parsing_error("Typeclass can't have arguments",
parser_node);
}
if (type_node.has_value()) {
error_handling::handle_parsing_error(
"Typeclass can't be type (contain constructors / fields)",
type_node.value());
}
}
std::optional<nodes::VariantType> type =
@ -233,18 +258,19 @@ build_type_definition(parser::ParseTree::Node parser_node,
return nodes::TypeDefinition(
build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations),
is_on_heap, build_identifier(name_node), std::move(arguments),
std::move(type), std::move(methods));
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments),
std::move(type));
}
// definition_info? annotation_info* (constraint ';')* _var_let_? (simple_name
// | '(' operator ')') (annotation? _reference_? argument_name '?'?)* (:
// (annotation? _reference_ type)+)?
// ('=' (block | expression ';') | ';')
nodes::FunctionDefinition
build_function_definition(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
nodes::FunctionDefinition build_function_definition(
parser::ParseTree::Node parser_node,
const std::optional<nodes::Identifier> &last_defined_type_name,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
std::optional<parser::ParseTree::Node> description_node;
std::vector<parser::ParseTree::Node> annotation_nodes;
@ -264,17 +290,20 @@ build_function_definition(parser::ParseTree::Node parser_node,
auto name_node = current_node;
nodes::FunctionDefinition::MethodModifier method_modifier =
nodes::FunctionDefinition::STATIC;
bool is_method = false;
std::optional<nodes::Identifier> name_prefix;
current_node = name_node.previous_sibling();
if (!current_node.is_null() && !current_node.is_named()) {
std::string modifier_str = current_node.get_value();
if (modifier_str == "%" || modifier_str == "let") {
method_modifier = nodes::FunctionDefinition::LET;
} else if (modifier_str == "$" || modifier_str == "var") {
method_modifier = nodes::FunctionDefinition::VAR;
if (!current_node.is_null() && !current_node.is_named() &&
current_node.get_value() == ".") {
is_method = true;
if (!last_defined_type_name.has_value()) {
error_handling::handle_parsing_error(
"Can't define method without associated type", parser_node);
}
name_prefix = last_defined_type_name.value();
}
nodes::Modifier return_modifier = nodes::Modifier::NONE;
@ -412,7 +441,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
return nodes::FunctionDefinition(
build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations_set),
std::move(constraints), return_modifier, method_modifier,
std::move(constraints), return_modifier, is_method, name_prefix,
build_identifier(name_node), std::move(arguments),
are_annotations_same_to_names,
expression_node.has_value()
@ -421,48 +450,4 @@ build_function_definition(parser::ParseTree::Node parser_node,
: std::optional<nodes::ExpressionProxy>());
}
// definition_info? annotation_info* typeclass_identifier (':'
// typeclass_identifier+)? ('{' function_definition* '}' | ';')
nodes::TypeclassDefinition
build_typeclass_definition(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
std::optional<parser::ParseTree::Node> description_node;
std::vector<parser::ParseTree::Node> annotation_nodes;
auto name_node = collect_symbol_doc_nodes(parser_node.nth_named_child(0),
description_node, annotation_nodes);
if (!annotation_nodes.empty()) {
error_handling::handle_parsing_error(
"Typeclass can't have annotation info nodes", parser_node);
}
std::vector<nodes::Identifier> base_typeclasses;
std::vector<nodes::FunctionDefinition> methods;
auto current_node = name_node.next_named_sibling();
while (!current_node.is_null()) {
switch (tokens::string_to_type(current_node.get_type())) {
case tokens::Type::TYPECLASS_IDENTIFIER:
base_typeclasses.push_back(build_identifier(current_node));
break;
case tokens::Type::FUNCTION_DEFINITION:
methods.push_back(build_function_definition(
current_node, expression_storage, type_storage));
break;
default:
error_handling::handle_parsing_error(
"Unexprected node type in type definition", parser_node);
}
current_node = current_node.next_named_sibling();
}
return nodes::TypeclassDefinition(
build_node(parser_node), build_symbol_docs(description_node),
build_identifier(name_node), std::move(base_typeclasses),
std::move(methods));
}
} // namespace builders

View file

@ -25,8 +25,8 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
if (return_modifier_ != other_function_definition.return_modifier_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
}
if (method_modifier_ != other_function_definition.method_modifier_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
if (is_method_ != other_function_definition.is_method_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ??
}
if (are_annotations_same_to_names_ !=
@ -228,98 +228,6 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
type_ = std::move(other_type_definition.type_);
}
// TODO: can be in incorrect state if error occure here
// combine methods ??
methods_.reserve(methods_.size() + other_type_definition.methods_.size());
for (size_t i = 0; i < other_type_definition.methods_.size(); ++i) {
auto method_iter = methods_by_name_.find(
*other_type_definition.methods_[i].get_name()->get());
if (method_iter == methods_by_name_.end()) {
methods_by_name_[*other_type_definition.methods_[i].get_name()->get()] =
methods_.size();
methods_.push_back(std::move(other_type_definition.methods_[i]));
} else {
auto method_combine_result = methods_[method_iter->second].combine(
std::move(other_type_definition.methods_[i]));
if (method_combine_result != CombineResult::OK) {
return method_combine_result;
}
}
}
return CombineResult::OK;
}
bool TypeclassDefinition::is_same_to(
const TypeclassDefinition &other_typeclass_definition) const {
if (*name_.get() != *other_typeclass_definition.name_.get()) {
return false;
}
return true;
}
CombineResult
TypeclassDefinition::combine(TypeclassDefinition &&other_typeclass_definition) {
// should be same in all definitions of one typeclass
if (*name_.get() != *other_typeclass_definition.name_.get()) {
return CombineResult::DIFFERENT_NAME_ERROR;
}
// only one definition should have documentation
if (docs_.get_description().has_value() &&
other_typeclass_definition.docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
if (docs_.get_annotations_info_size() > 0 &&
other_typeclass_definition.docs_.get_annotations_info_size() > 0) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
// only one definition should define base typeclasses
if (!base_typeclasses_.empty() &&
!other_typeclass_definition.base_typeclasses_.empty()) {
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
}
// combine docs
// all docs should be in one definition
if (other_typeclass_definition.docs_.get_description().has_value() ||
other_typeclass_definition.docs_.get_annotations_info_size() > 0) {
if (docs_.get_annotations_info_size() > 0 ||
docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
docs_ = std::move(other_typeclass_definition.docs_);
}
if (!other_typeclass_definition.base_typeclasses_.empty()) {
base_typeclasses_ = std::move(other_typeclass_definition.base_typeclasses_);
}
// TODO: can be in incorrect state if error occure here
// combine methods ??
methods_.reserve(methods_.size() +
other_typeclass_definition.methods_.size());
for (size_t i = 0; i < other_typeclass_definition.methods_.size(); ++i) {
auto method_iter = methods_by_name_.find(
*other_typeclass_definition.methods_[i].get_name()->get());
if (method_iter == methods_by_name_.end()) {
methods_by_name_
[*other_typeclass_definition.methods_[i].get_name()->get()] =
methods_.size();
methods_.push_back(std::move(other_typeclass_definition.methods_[i]));
} else {
auto method_combine_result = methods_[method_iter->second].combine(
std::move(other_typeclass_definition.methods_[i]));
if (method_combine_result != CombineResult::OK) {
return method_combine_result;
}
}
}
return CombineResult::OK;
}
@ -339,11 +247,7 @@ bool Statement::is_same_to(const Statement &other_statement) const {
return std::get<FunctionDefinition>(expression_)
.is_same_to(std::move(
std::get<FunctionDefinition>(other_statement.expression_)));
case 3: // TypeclassDefinition
return std::get<TypeclassDefinition>(expression_)
.is_same_to(std::move(
std::get<TypeclassDefinition>(other_statement.expression_)));
case 4: // EmptyLines
case 3: // EmptyLines
return false;
default:
break;
@ -369,11 +273,7 @@ CombineResult Statement::combine(Statement &&other_statement) {
return std::get<FunctionDefinition>(expression_)
.combine(std::move(
std::get<FunctionDefinition>(other_statement.expression_)));
case 3: // TypeclassDefinition
return std::get<TypeclassDefinition>(expression_)
.combine(std::move(
std::get<TypeclassDefinition>(other_statement.expression_)));
case 4: // EmptyLines
case 3: // EmptyLines
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
default:
break;

View file

@ -1,5 +1,6 @@
#include "statement_printers.hpp"
#include "basic_nodes.hpp"
#include "basic_printers.hpp"
#include "doc_printers.hpp"
#include "expression_nodes.hpp"
@ -32,9 +33,8 @@ void print_statement(const nodes::Statement &statement, Printer &printer) {
*statement.get<nodes::FunctionDefinition>().value(), printer);
printer.new_indent_line();
break;
case 3: // TypeclassDefinition
print_typeclass_definition(
*statement.get<nodes::TypeclassDefinition>().value(), printer);
case 3: // Extra
print_extra(*statement.get<nodes::Extra>().value(), printer);
printer.new_indent_line();
break;
case 4: // EmptyLines
@ -82,28 +82,6 @@ void print_constraint(const nodes::Constraint &statement, Printer &printer) {
printer.print(";");
}
template <typename T>
void print_statement_methods(const T &statement, Printer &printer) {
if (statement.get_methods_size() > 0) {
printer.print(" {");
printer.indent();
for (size_t i = 0; i < statement.get_methods_size(); ++i) {
printer.new_indent_line();
print_function_definition(*statement.get_method(i), printer);
if (i + 1 < statement.get_methods_size()) {
printer.new_indent_line();
}
}
printer.deindent();
printer.new_indent_line();
printer.print("}");
} else {
printer.print(";");
}
}
void print_type_definition(const nodes::TypeDefinition &statement,
Printer &printer) {
print_docs(*statement.get_docs(), printer);
@ -130,10 +108,10 @@ void print_type_definition(const nodes::TypeDefinition &statement,
printer.set_indentation_level(previous_indentation_level);
}
print_statement_methods(statement, printer);
printer.print(";");
} // IN PROGRESS
// TODO: do not print prefix type for names
void print_function_definition(const nodes::FunctionDefinition &statement,
Printer &printer) {
print_docs(*statement.get_docs(), printer);
@ -143,17 +121,8 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
printer.new_indent_line();
}
switch (statement.get_method_modifier()) {
case nodes::FunctionDefinition::STATIC:
break;
case nodes::FunctionDefinition::LET:
printer.print(printer.print_words_instead_of_symbols() ? "let " : "%");
break;
case nodes::FunctionDefinition::VAR:
printer.print(printer.print_words_instead_of_symbols() ? "var " : "$");
break;
default: // remove ??
break;
if (statement.is_method()) {
printer.print(".");
}
bool identifier_is_operator =
@ -169,7 +138,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
printer.print(" )");
}
print_modifier(statement.get_return_modifier(), printer);
print_modifier(statement.get_return_modifier(), printer); // ! or ?
for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
if (!statement.get_argument(i)->get_name().has_value()) {
@ -189,7 +158,8 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
printer.space();
}
print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
print_modifier(statement.get_argument(i)->get_before_modifier(), printer,
true);
}
print_identifier(*statement.get_argument(i)->get_name().value(), printer);
@ -214,19 +184,26 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
printer.space();
}
print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
print_modifier(statement.get_argument(i)->get_before_modifier(), printer,
true);
print_type(*statement.get_argument(i)->get_type().value(), printer);
}
}
if (statement.get_expression().has_value()) {
bool expression_is_container =
statement.get_expression().value()->get<nodes::Container>().has_value();
printer.print(" = ");
size_t previous_indentation_level = printer.get_indentation_level();
if (!expression_is_container) {
printer.set_indentation_level(printer.current_position());
}
print_expression(*statement.get_expression().value(), printer);
if (!statement.get_expression()
.value()
->get<nodes::Container>()
.has_value()) {
if (!expression_is_container) {
printer.set_indentation_level(previous_indentation_level);
printer.print(";");
}
} else {
@ -234,21 +211,4 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
}
} // IN PROGRESS
void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
Printer &printer) {
print_docs(*statement.get_docs(), printer);
print_identifier(*statement.get_name(), printer);
if (statement.get_base_typeclasses_size() > 0) {
printer.print(" :");
for (size_t i = 0; i < statement.get_base_typeclasses_size(); ++i) {
printer.space();
print_identifier(*statement.get_base_typeclass(i), printer);
}
}
print_statement_methods(statement, printer);
} // IN PROGRESS
} // namespace printers