diff --git a/CMakeLists.txt b/CMakeLists.txt
index 97bce64..c3f4f84 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,13 +12,22 @@ include_directories(include
add_executable(lang src/main.cpp
+
src/type_nodes.cpp
src/expression_nodes.cpp
+
src/basic_builders.cpp
src/type_builders.cpp
src/doc_builders.cpp
src/expression_builders.cpp
src/statement_builders.cpp
+
+ src/basic_printers.cpp
+ src/type_printers.cpp
+ src/doc_printers.cpp
+ src/expression_printers.cpp
+ src/statement_printers.cpp
+
include/tree_sitter_wrapper.hpp
deps/tree-sitter-lang/src/tree_sitter/parser.h
deps/tree-sitter-lang/src/parser.c
diff --git a/deps/tree-sitter-lang b/deps/tree-sitter-lang
index 18d84f5..1c19b47 160000
--- a/deps/tree-sitter-lang
+++ b/deps/tree-sitter-lang
@@ -1 +1 @@
-Subproject commit 18d84f5f28da3722749477b3bfa58e1dba397bf5
+Subproject commit 1c19b471990acb91cc0ccc9426d988debab8cb27
diff --git a/etc/kate_highlighting_lang.xml b/etc/kate_highlighting_lang.xml
index e6eb2c5..d58a95a 100644
--- a/etc/kate_highlighting_lang.xml
+++ b/etc/kate_highlighting_lang.xml
@@ -44,6 +44,8 @@
+
+
diff --git a/include/basic_builders.hpp b/include/basic_builders.hpp
index 86d2d8b..733cd73 100644
--- a/include/basic_builders.hpp
+++ b/include/basic_builders.hpp
@@ -47,4 +47,8 @@ nodes::Identifier build_operator(parser::ParseTree::Node parser_node);
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node);
+// --- empty lines
+
+nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node);
+
} // namespace builders
diff --git a/include/basic_nodes.hpp b/include/basic_nodes.hpp
index 1cf34a1..150157a 100644
--- a/include/basic_nodes.hpp
+++ b/include/basic_nodes.hpp
@@ -53,15 +53,9 @@ public:
return std::nullopt;
}
- std::variant *
- get_any() {
- return &value_;
- }
+ auto get_any() { return &value_; }
- const std::variant *
- get_any() const {
- return &value_;
- }
+ auto get_any() const { return &value_; }
private:
std::variant value_;
@@ -86,7 +80,7 @@ public:
Identifier(Node node, IdentifierType type, const std::string &value)
: Node(node), type_(type), value_(value) {}
- IdentifierType get_type() { return type_; }
+ IdentifierType get_type() const { return type_; }
std::string *get() { return &value_; }
@@ -97,4 +91,14 @@ private:
std::string value_;
};
+class EmptyLines : public Node {
+public:
+ EmptyLines(Node node, size_t size) : Node(node), size_(size) {}
+
+ size_t size() const { return size_; }
+
+private:
+ size_t size_;
+};
+
} // namespace nodes
diff --git a/include/basic_printers.hpp b/include/basic_printers.hpp
index e584761..6059c7d 100644
--- a/include/basic_printers.hpp
+++ b/include/basic_printers.hpp
@@ -11,7 +11,7 @@ public:
bool print_words_instead_of_symbols)
: output_(output), tab_width_(tab_width), width_limit_(width_limit),
print_words_instead_of_symbols_(print_words_instead_of_symbols),
- current_position_(0), current_indentation_level_(0) {}
+ current_position_(0), indentation_level_(0) {}
void print_converted(const std::string &value) {
for (auto &ch : value) {
@@ -34,7 +34,7 @@ public:
void new_indent_line() {
end_line();
- print_spaces(current_indentation_level_ * tab_width_);
+ print_spaces(indentation_level_);
}
void new_line(size_t indentation) {
@@ -42,9 +42,9 @@ public:
print_spaces(indentation);
}
- void indent() { current_indentation_level_ += tab_width_; }
+ void indent() { indentation_level_ += tab_width_; }
- void deindent() { current_indentation_level_ -= tab_width_; }
+ void deindent() { indentation_level_ -= tab_width_; }
void tab() { print_spaces(tab_width_); }
@@ -66,12 +66,10 @@ public:
size_t get_current_position() const { return current_position_; }
- size_t get_current_indentation_level() const {
- return current_indentation_level_;
- }
+ size_t get_indentation_level() const { return indentation_level_; }
- size_t set_current_indentation_level(size_t indentation_level) {
- current_indentation_level_ = indentation_level;
+ void set_indentation_level(size_t indentation_level) {
+ indentation_level_ = indentation_level;
}
private:
@@ -117,7 +115,7 @@ private:
bool print_words_instead_of_symbols_ = false;
size_t current_position_ = 0;
- size_t current_indentation_level_ = 0;
+ size_t indentation_level_ = 0;
};
void print_literal(const nodes::Literal &literal, Printer &printer);
@@ -126,4 +124,6 @@ void print_identifier(const nodes::Identifier &identifier, Printer &printer);
void print_annotation(const std::string &annotation, Printer &printer);
+void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer);
+
} // namespace printers
diff --git a/include/doc_nodes.hpp b/include/doc_nodes.hpp
index 52bde93..ef6a128 100644
--- a/include/doc_nodes.hpp
+++ b/include/doc_nodes.hpp
@@ -3,6 +3,7 @@
#include
#include
#include
+#include
namespace nodes {
@@ -16,8 +17,9 @@ public:
SymbolDocs(const std::string &description) : description_(description) {}
bool add_annotation_info(const std::string &annotation, std::string &&info) {
- if (annotations_info_.count(annotation) == 0) {
- annotations_info_[annotation] = std::move(info);
+ if (annotations_info_ids_.count(annotation) == 0) {
+ annotations_info_ids_[annotation] = annotations_info_.size();
+ annotations_info_.emplace_back(annotation, std::move(info));
return true;
}
return false;
@@ -25,13 +27,16 @@ public:
bool add_annotation_info(const std::string &annotation,
const std::string &info) {
- if (annotations_info_.count(annotation) == 0) {
- annotations_info_[annotation] = info;
+ if (annotations_info_ids_.count(annotation) == 0) {
+ annotations_info_ids_[annotation] = annotations_info_.size();
+ annotations_info_.emplace_back(annotation, std::move(info));
return true;
}
return false;
}
+ //
+
std::optional get_description() {
if (description_.has_value()) {
return &description_.value();
@@ -46,27 +51,52 @@ public:
return std::nullopt;
}
+ //
+
std::optional
get_annotation_info(const std::string &annotation) {
- auto info_iterator = annotations_info_.find(annotation);
- if (info_iterator != annotations_info_.end()) {
- return &info_iterator->second;
+ auto info_iterator = annotations_info_ids_.find(annotation);
+ if (info_iterator != annotations_info_ids_.end()) {
+ return &annotations_info_[info_iterator->second].second;
}
return std::nullopt;
}
std::optional
get_annotation_info(const std::string &annotation) const {
- auto info_iterator = annotations_info_.find(annotation);
- if (info_iterator != annotations_info_.end()) {
- return &info_iterator->second;
+ auto info_iterator = annotations_info_ids_.find(annotation);
+ if (info_iterator != annotations_info_ids_.end()) {
+ return &annotations_info_[info_iterator->second].second;
}
return std::nullopt;
}
+ //
+
+ size_t get_annotations_info_size() const { return annotations_info_.size(); }
+
+ std::string *get_annotation(size_t id) {
+ return &annotations_info_[id].first;
+ }
+
+ const std::string *get_annotation(size_t id) const {
+ return &annotations_info_[id].first;
+ }
+
+ std::string *get_annotation_info(size_t id) {
+ return &annotations_info_[id].second;
+ }
+
+ const std::string *get_annotation_info(size_t id) const {
+ return &annotations_info_[id].second;
+ }
+
+ //
+
private:
std::optional description_;
- std::unordered_map annotations_info_;
+ std::vector> annotations_info_;
+ std::unordered_map annotations_info_ids_;
};
} // namespace nodes
diff --git a/include/expression_nodes.hpp b/include/expression_nodes.hpp
index bb49b6f..28098e5 100644
--- a/include/expression_nodes.hpp
+++ b/include/expression_nodes.hpp
@@ -167,13 +167,13 @@ public:
: Node(node), type_(LOOP), expression_(expression) {}
// WHILE
- Loop(Node node, ExpressionProxy expression, ExpressionProxy condition)
+ Loop(Node node, ExpressionProxy condition, ExpressionProxy expression)
: Node(node), type_(WHILE), expression_(expression),
condition_(condition) {}
// FOR
- Loop(Node node, ExpressionProxy expression, ExpressionProxy variable,
- ExpressionProxy interval)
+ Loop(Node node, ExpressionProxy variable, ExpressionProxy interval,
+ ExpressionProxy expression)
: Node(node), type_(FOR), expression_(expression), variable_(variable),
interval_(interval) {}
@@ -528,19 +528,9 @@ public:
return std::nullopt;
}
- std::variant *
- get_any() {
- return &expression_;
- }
+ auto get_any() { return &expression_; }
- const std::variant *
- get_any() const {
- return &expression_;
- }
+ auto get_any() const { return &expression_; }
bool is_scoped() const { return is_scoped_; }
@@ -570,7 +560,10 @@ private:
NameExpression, Constructor, Lambda,
// --- literal
- Literal
+ Literal,
+
+ // --- empty lines
+ EmptyLines
>
expression_;
diff --git a/include/statement_nodes.hpp b/include/statement_nodes.hpp
index 8078f93..82006cb 100644
--- a/include/statement_nodes.hpp
+++ b/include/statement_nodes.hpp
@@ -75,13 +75,16 @@ public:
std::vector &&types,
std::vector &&optional_arguments,
std::vector &&result_arguments,
+ bool is_annotations_same_to_names,
std::optional expression)
: Node(node), docs_(std::move(docs)),
constraints_(std::move(constraints)), modifier_(modifier), name_(name),
annotations_(std::move(annotations)), arguments_(std::move(arguments)),
reference_types_(std::move(reference_types)), types_(std::move(types)),
optional_arguments_(optional_arguments),
- result_arguments_(result_arguments), expression_(expression) {}
+ result_arguments_(result_arguments),
+ is_annotations_same_to_names_(is_annotations_same_to_names),
+ expression_(expression) {}
//
@@ -91,7 +94,7 @@ public:
//
- size_t get_constraints_size() const { return arguments_.size(); }
+ size_t get_constraints_size() const { return constraints_.size(); }
Constraint *get_constraint(size_t id) { return &constraints_.at(id); }
@@ -159,6 +162,12 @@ public:
//
+ bool is_annotations_same_to_names() const {
+ return is_annotations_same_to_names_;
+ }
+
+ //
+
std::optional get_expression() {
if (expression_.has_value()) {
return expression_.value().get();
@@ -184,6 +193,7 @@ private:
std::vector types_;
std::vector optional_arguments_;
std::vector result_arguments_;
+ bool is_annotations_same_to_names_;
std::optional expression_;
}; // refactor ??
diff --git a/include/statement_printers.hpp b/include/statement_printers.hpp
index 29c3013..40bc228 100644
--- a/include/statement_printers.hpp
+++ b/include/statement_printers.hpp
@@ -5,9 +5,9 @@
namespace printers {
-void print_source_file(Printer &printer); // TODO
+// void print_source_file(Printer &printer); // TODO
-void print_statement(Printer &printer); // TODO
+// void print_statement(Printer &printer); // TODO
void print_import(const nodes::Import &statement, Printer &printer);
diff --git a/include/tokens.hpp b/include/tokens.hpp
index 51ef609..051ccbf 100644
--- a/include/tokens.hpp
+++ b/include/tokens.hpp
@@ -62,6 +62,8 @@ enum class Type {
DEFINITION_INFO,
ANNOTATION_INFO,
+ EMPTY_LINES,
+
// --- tokens
PLACEHOLDER,
@@ -146,6 +148,8 @@ const static std::string TYPE = "type";
const static std::string DEFINITION_INFO = "definition_info";
const static std::string ANNOTATION_INFO = "annotation_info";
+const static std::string EMPTY_LINES = "empty_lines";
+
// --- tokens
const static std::string PLACEHOLDER = "placeholder";
@@ -228,6 +232,8 @@ inline Type string_to_type(const std::string &str) {
return Type::DEFINITION_INFO;
} else if (str == ANNOTATION_INFO) {
return Type::ANNOTATION_INFO;
+ } else if (str == EMPTY_LINES) {
+ return Type::EMPTY_LINES;
} else if (str == PLACEHOLDER) {
return Type::PLACEHOLDER;
} else if (str == SIMPLE_NAME_IDENTIFIER) {
diff --git a/include/tree_sitter_wrapper.hpp b/include/tree_sitter_wrapper.hpp
index 87e35f4..717495a 100644
--- a/include/tree_sitter_wrapper.hpp
+++ b/include/tree_sitter_wrapper.hpp
@@ -63,6 +63,16 @@ public:
return source_->substr(start, end - start);
}
+ size_t get_value_length() const { // from source
+ if (is_null()) {
+ error_handling::handle_general_error(
+ "Null parsing node method called (get_value_length)");
+ }
+ size_t start = ts_node_start_byte(node_);
+ size_t end = ts_node_end_byte(node_);
+ return end - start;
+ }
+
bool is_null() const { return ts_node_is_null(node_); }
bool is_named() const {
diff --git a/src/basic_builders.cpp b/src/basic_builders.cpp
index f354525..387e223 100644
--- a/src/basic_builders.cpp
+++ b/src/basic_builders.cpp
@@ -224,12 +224,14 @@ std::string build_annotation(parser::ParseTree::Node parser_node) {
nodes::Identifier build_operator(parser::ParseTree::Node parser_node) {
std::string identifier = parser_node.get_value();
- if (identifier.size() > 0 && identifier.front() != '.') {
- // for not point only identifiers
- while (identifier.size() > 0 && identifier.back() == '.') {
- identifier.pop_back();
- }
- }
+ // --- points needed for proper printing
+ // if (identifier.size() > 0 && identifier.front() != '.') {
+ // // for not point only identifiers
+ // while (identifier.size() > 0 && identifier.back() == '.') {
+ // identifier.pop_back();
+ // }
+ // }
+ // ---
return nodes::Identifier(build_node(parser_node), nodes::Identifier::OPERATOR,
identifier);
@@ -240,4 +242,11 @@ nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) {
nodes::Identifier::PLACEHOLDER, "_");
}
+// --- 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);
+}
+
} // namespace builders
diff --git a/src/basic_printers.cpp b/src/basic_printers.cpp
index dfca297..eedde37 100644
--- a/src/basic_printers.cpp
+++ b/src/basic_printers.cpp
@@ -53,4 +53,10 @@ void print_annotation(const std::string &annotation, Printer &printer) {
printer.print(annotation);
}
+void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer) {
+ for (size_t i = 0; i < empty_lines.size(); ++i) {
+ printer.new_indent_line();
+ }
+}
+
} // namespace printers
diff --git a/src/doc_builders.cpp b/src/doc_builders.cpp
index d2604d7..9d5f6db 100644
--- a/src/doc_builders.cpp
+++ b/src/doc_builders.cpp
@@ -18,8 +18,8 @@ nodes::SymbolDocs build_symbol_docs(
// remove newline delimeters (": " at each new line
size_t j = 0;
- for (size_t i = 0; i < description.value().size(); ++i, ++j) {
- if (j != i) {
+ for (size_t i = 2; i < description.value().size(); ++i, ++j) {
+ if (j != i) { // always true
description.value()[j] = description.value()[i];
}
diff --git a/src/doc_printers.cpp b/src/doc_printers.cpp
index 3c0bada..e2e0906 100644
--- a/src/doc_printers.cpp
+++ b/src/doc_printers.cpp
@@ -1,4 +1,5 @@
#include "doc_printers.hpp"
+#include "basic_printers.hpp"
#include "utils.hpp"
namespace printers {
@@ -6,8 +7,27 @@ namespace printers {
// TODO
void print_docs(const nodes::SymbolDocs &docs, Printer &printer) {
+ auto description = docs.get_description();
- error_handling::handle_general_error("Docs printing unimplemented yet");
+ if (description.has_value()) {
+ printer.print(": ");
+ for (auto &ch : *description.value()) {
+ if (ch == '\n') {
+ printer.new_indent_line();
+ printer.print(": ");
+ } else {
+ printer.print(std::string(1, ch));
+ }
+ }
+ printer.new_indent_line();
+ }
+
+ for (size_t i = 0; i < docs.get_annotations_info_size(); ++i) {
+ print_annotation(*docs.get_annotation(i), printer);
+ printer.space();
+ printer.print(*docs.get_annotation_info(i));
+ printer.new_indent_line();
+ }
} // IN PROGRESS
diff --git a/src/expression_builders.cpp b/src/expression_builders.cpp
index 883b826..754149a 100644
--- a/src/expression_builders.cpp
+++ b/src/expression_builders.cpp
@@ -16,9 +16,10 @@ build_expression(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
tokens::Type type = tokens::string_to_type(parser_node.get_type());
- auto maybe_parenthesis = parser_node.next_sibling();
+ auto maybe_parenthesis = parser_node.previous_sibling();
bool is_scoped =
- (!maybe_parenthesis.is_null() && maybe_parenthesis.get_value() == "(");
+ (!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() &&
+ maybe_parenthesis.get_value() == "(");
switch (type) {
// --- flow control
@@ -119,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::EMPTY_LINES:
+ return expression_storage.add_expression(
+ nodes::Expression(build_empty_lines(parser_node), is_scoped));
default:
error_handling::handle_parsing_error("Unexprected expression node type",
parser_node);
@@ -271,7 +275,7 @@ build_comma_expression(parser::ParseTree::Node parser_node,
return nodes::NameExpression(
build_node(parser_node),
nodes::Identifier(
- build_node(parser_node), // can't find more precise location'
+ build_node(parser_node), // can't find more precise location
nodes::Identifier::SIMPLE_NAME, ","),
std::move(arguments), std::nullopt, false, true);
}
@@ -308,7 +312,7 @@ build_container(parser::ParseTree::Node parser_node,
nodes::Container::ContainerType container_type) {
std::vector expressions;
- auto current_node = parser_node.nth_named_child(0).next_named_sibling();
+ auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
expressions.push_back(
diff --git a/src/expression_printers.cpp b/src/expression_printers.cpp
index 84b40e2..d354e25 100644
--- a/src/expression_printers.cpp
+++ b/src/expression_printers.cpp
@@ -2,6 +2,7 @@
#include "basic_nodes.hpp"
#include "basic_printers.hpp"
#include "expression_nodes.hpp"
+#include "tokens.hpp"
#include "type_printers.hpp"
namespace printers {
@@ -60,6 +61,10 @@ void print_expression(const nodes::Expression &expression,
case 12: // Literal
print_literal(*expression.get().value(), printer);
break;
+ // --- empty lines
+ case 13: // EmptyLines
+ print_empty_lines(*expression.get().value(), printer);
+ break;
}
if (expression.is_scoped()) {
@@ -100,9 +105,9 @@ void print_match(const nodes::Match &expression, printers::Printer &printer) {
printer.space();
- size_t previous_indentation_level = printer.get_current_indentation_level();
+ size_t previous_indentation_level = printer.get_indentation_level();
- printer.set_current_indentation_level(printer.current_position());
+ printer.set_indentation_level(printer.current_position());
for (size_t i = 0; i < expression.cases_size(); ++i) {
print_case(*expression.get_case(i), printer);
@@ -112,7 +117,7 @@ void print_match(const nodes::Match &expression, printers::Printer &printer) {
}
}
- printer.set_current_indentation_level(previous_indentation_level);
+ printer.set_indentation_level(previous_indentation_level);
} // IN PROGRESS
@@ -123,17 +128,19 @@ void print_condition(const nodes::Condition &expression,
if (i == 0) {
printer.print(printer.print_words_instead_of_symbols() ? "if " : "?? ");
} else {
+ printer.new_indent_line();
printer.print(printer.print_words_instead_of_symbols() ? "elif " : "!! ");
}
print_expression(*expression.get_case(i).first, printer);
- printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> ");
+ printer.print(printer.print_words_instead_of_symbols() ? " do " : " => ");
print_expression(*expression.get_case(i).second, printer);
}
if (expression.get_else_case().has_value()) {
+ printer.new_indent_line();
printer.print(printer.print_words_instead_of_symbols() ? "else " : "!!=> ");
print_expression(*expression.get_else_case().value(), printer);
}
@@ -163,7 +170,6 @@ void print_loop(const nodes::Loop &expression, printers::Printer &printer) {
printer.print(printer.print_words_instead_of_symbols() ? "do " : "=> ");
print_expression(*expression.get_expression(), printer);
- printer.print(";");
} // IN PROGRESS
// --- containers
@@ -177,16 +183,23 @@ void print_container(const nodes::Container &expression,
} else {
printer.print("{");
printer.indent();
- printer.new_indent_line();
}
for (size_t i = 0; i < expression.expressions_size(); ++i) {
+ bool is_empty_lines_expression = expression.get_expression(i)->get().has_value();
+
+ if (!is_array && !is_empty_lines_expression) {
+ printer.new_indent_line();
+ }
print_expression(*expression.get_expression(i), printer);
if (is_array) {
- printer.space();
+ if (i + 1 < expression.expressions_size()) {
+ printer.space();
+ }
} else {
- printer.print(";");
- printer.new_indent_line();
+ if (!is_empty_lines_expression) {
+ printer.print(";");
+ }
}
}
@@ -194,8 +207,8 @@ void print_container(const nodes::Container &expression,
printer.print("]]");
} else {
printer.deindent();
- printer.print("}");
printer.new_indent_line();
+ printer.print("}");
}
} // IN PROGRESS
@@ -234,10 +247,10 @@ void print_name_definition(const nodes::NameDefinition &expression,
} else {
switch (expression.get_modifier()) {
case nodes::NameDefinition::LET:
- printer.print("% ");
+ printer.print("%");
break;
case nodes::NameDefinition::VAR:
- printer.print("$ ");
+ printer.print("$");
break;
default:
break;
@@ -343,7 +356,7 @@ void print_name_expression(const nodes::NameExpression &expression,
print_expression(*expression.get_argument_value(0), printer);
if (expression.is_point_call()) {
printer.print(".");
- } else {
+ } else if (*expression.get_name()->get() != ",") {
printer.space();
}
} else if (expression.get_prefix().has_value()) {
@@ -351,10 +364,27 @@ void print_name_expression(const nodes::NameExpression &expression,
printer.print(".");
}
- // TODO: properly print operator name
+ //
+
+ bool operator_called_as_function =
+ (!expression.is_operator_call() &&
+ expression.get_name()->get_type() == nodes::Identifier::OPERATOR);
+
+ if (operator_called_as_function) {
+ printer.print("( ");
+ }
+
print_identifier(*expression.get_name(), printer);
- for (size_t i = 0; i < expression.arguments_size(); ++i) {
+ if (operator_called_as_function) {
+ printer.print(" )");
+ }
+
+ //
+
+ for (size_t i =
+ expression.is_operator_call() || expression.is_point_call() ? 1 : 0;
+ i < expression.arguments_size(); ++i) {
printer.space();
if (expression.get_argument_annotation(i).has_value()) {
@@ -384,7 +414,7 @@ void print_constructor(const nodes::Constructor &expression,
} // IN PROGRESS
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer) {
- printer.print(printer.print_words_instead_of_symbols() ? "lambda " : "\\ ");
+ 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);
diff --git a/src/statement_builders.cpp b/src/statement_builders.cpp
index d650d2f..1a843a9 100644
--- a/src/statement_builders.cpp
+++ b/src/statement_builders.cpp
@@ -2,11 +2,13 @@
#include "basic_builders.hpp"
#include "basic_nodes.hpp"
+#include "basic_printers.hpp"
#include "doc_builders.hpp"
#include "doc_nodes.hpp"
#include "error_handling.hpp"
#include "expression_builders.hpp"
#include "statement_nodes.hpp"
+#include "statement_printers.hpp"
#include "tokens.hpp"
#include "tree_sitter_wrapper.hpp"
#include "type_builders.hpp"
@@ -37,18 +39,42 @@ void build_statement(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
tokens::Type type = tokens::string_to_type(parser_node.get_type());
+ printers::Printer printer(std::cout, 2, 80, false);
+
switch (type) {
case tokens::Type::IMPORT:
build_import(parser_node);
+ printers::print_import(build_import(parser_node),
+ printer); // TODO TEMPORARY
+ printer.new_indent_line();
return;
case tokens::Type::TYPE_DEFINITION:
build_type_definition(parser_node, expression_storage, type_storage);
+ printers::print_type_definition(
+ build_type_definition(parser_node, expression_storage, type_storage),
+ printer); // TODO TEMPORARY
+ printer.new_indent_line();
return;
case tokens::Type::FUNCTION_DEFINITION:
build_function_definition(parser_node, expression_storage, type_storage);
+ printers::print_function_definition(
+ build_function_definition(parser_node, expression_storage,
+ type_storage),
+ printer); // TODO TEMPORARY
+ printer.new_indent_line();
return;
case tokens::Type::TYPECLASS_DEFINITION:
build_typeclass_definition(parser_node, expression_storage, type_storage);
+ printers::print_typeclass_definition(
+ build_typeclass_definition(parser_node, expression_storage,
+ type_storage),
+ printer); // TODO TEMPORARY
+ printer.new_indent_line();
+ return;
+ case tokens::Type::EMPTY_LINES:
+ build_empty_lines(parser_node);
+ printers::print_empty_lines(build_empty_lines(parser_node),
+ printer); // TODO TEMPORARY
return;
default:
error_handling::handle_parsing_error("Unexprected statement node type",
@@ -219,7 +245,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
nodes::FunctionDefinition::STATIC;
current_node = name_node.previous_sibling();
- if (!current_node.is_null() && current_node.is_named()) {
+ if (!current_node.is_null() && !current_node.is_named()) {
std::string modifier_str = current_node.get_value();
if (modifier_str == "%" || modifier_str == "let") {
modifier = nodes::FunctionDefinition::LET;
@@ -270,11 +296,11 @@ build_function_definition(parser::ParseTree::Node parser_node,
argument_reference_types.push_back(last_reference_type);
arguments.push_back(build_identifier(current_node));
optional_arguments.push_back(!current_node.next_sibling().is_null() &&
- current_node.next_sibling().is_named() &&
+ !current_node.next_sibling().is_named() &&
current_node.next_sibling().get_value() ==
"?");
result_arguments.push_back(!current_node.next_sibling().is_null() &&
- current_node.next_sibling().is_named() &&
+ !current_node.next_sibling().is_named() &&
current_node.next_sibling().get_value() ==
"!");
if (optional_arguments.back() || result_arguments.back()) {
@@ -306,7 +332,10 @@ build_function_definition(parser::ParseTree::Node parser_node,
std::vector> *annotations = nullptr;
std::vector *reference_types = nullptr;
- if (!at_least_one_argument_annotation_found) {
+ bool is_annotations_same_to_names =
+ (!at_least_one_argument_annotation_found && types.empty());
+
+ if (is_annotations_same_to_names) {
for (size_t i = 0; i < argument_annotations.size(); ++i) {
std::string argument_annotation = *arguments[i].get();
argument_annotations[i] =
@@ -346,6 +375,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
std::move(*annotations), std::move(arguments),
std::move(*reference_types), std::move(types),
std::move(optional_arguments), std::move(result_arguments),
+ is_annotations_same_to_names,
expression_node.has_value()
? build_expression(expression_node.value(), expression_storage,
type_storage)
diff --git a/src/statement_printers.cpp b/src/statement_printers.cpp
index a51e2a1..ce5c368 100644
--- a/src/statement_printers.cpp
+++ b/src/statement_printers.cpp
@@ -28,9 +28,6 @@ void print_import(const nodes::Import &statement, Printer &printer) {
}
}
printer.print(";");
-
- printer.new_indent_line();
- printer.new_indent_line();
} // IN PROGRESS
void print_constraint(const nodes::Constraint &statement, Printer &printer) {
@@ -39,6 +36,28 @@ void print_constraint(const nodes::Constraint &statement, Printer &printer) {
printer.print(";");
}
+template
+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); // TODO
@@ -57,33 +76,16 @@ void print_type_definition(const nodes::TypeDefinition &statement,
if (statement.get_type().has_value()) {
printer.print(" = ");
- size_t previous_indentation_level = printer.get_current_indentation_level();
+ size_t previous_indentation_level = printer.get_indentation_level();
- printer.set_current_indentation_level(printer.get_current_position());
+ printer.set_indentation_level(printer.get_current_position() - 2);
print_variant_type(*statement.get_type().value(), printer);
- printer.set_current_indentation_level(previous_indentation_level);
- }
-
- // TODO: same to typeclass, make separated function
- 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);
- printer.new_indent_line();
- }
-
- printer.deindent();
- printer.new_indent_line();
- printer.print("} ");
- } else {
- printer.print(";");
+ printer.set_indentation_level(previous_indentation_level);
}
+ print_statement_methods(statement, printer);
} // IN PROGRESS
void print_function_definition(const nodes::FunctionDefinition &statement,
@@ -99,22 +101,36 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
case nodes::FunctionDefinition::STATIC:
break;
case nodes::FunctionDefinition::LET:
- printer.print(printer.print_words_instead_of_symbols() ? "let " : "% ");
+ printer.print(printer.print_words_instead_of_symbols() ? "let " : "%");
break;
case nodes::FunctionDefinition::VAR:
- printer.print(printer.print_words_instead_of_symbols() ? "var " : "$ ");
+ printer.print(printer.print_words_instead_of_symbols() ? "var " : "$");
break;
default: // remove ??
break;
}
+ bool operator_called_as_function =
+ (statement.get_name()->get_type() == nodes::Identifier::OPERATOR);
+
+ if (operator_called_as_function) {
+ printer.print("( ");
+ }
+
print_identifier(*statement.get_name(), printer);
+ if (operator_called_as_function) {
+ printer.print(" )");
+ }
+
// TODO: same fragments with function type, maybe better make separated
// function
for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
+ printer.space();
+
if (statement.get_argument_types_size() == 0) {
- if (statement.get_argument_annotation(i).has_value()) {
+ if (!statement.is_annotations_same_to_names() &&
+ statement.get_argument_annotation(i).has_value()) {
print_annotation(*statement.get_argument_annotation(i).value(),
printer);
printer.space();
@@ -154,7 +170,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
}
}
- if (statement.get_argument_types_size() > 0) { // TODO
+ if (statement.get_argument_types_size() > 0) {
printer.print(" :");
for (size_t i = 0; i < statement.get_argument_types_size(); ++i) {
printer.space();
@@ -183,22 +199,18 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
}
print_type(*statement.get_argument_type(i), printer);
-
- // TODO: can't be optional and result in same time
-
- if (statement.is_argument_optional(i)) {
- printer.print("?");
- }
-
- if (statement.is_argument_result(i)) {
- printer.print("!");
- }
}
}
if (statement.get_expression().has_value()) {
printer.print(" = ");
print_expression(*statement.get_expression().value(), printer);
+ if (!statement.get_expression()
+ .value()
+ ->get()
+ .has_value()) {
+ printer.print(";");
+ }
} else {
printer.print(";");
}
@@ -218,25 +230,7 @@ void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
}
}
- 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);
- printer.new_indent_line();
- }
-
- printer.deindent();
- printer.new_indent_line();
- printer.print("} ");
- } else {
- printer.print(";");
- }
-
- printer.new_indent_line();
- printer.new_indent_line();
+ print_statement_methods(statement, printer);
} // IN PROGRESS
} // namespace printers
diff --git a/src/type_printers.cpp b/src/type_printers.cpp
index 75c3034..82e99be 100644
--- a/src/type_printers.cpp
+++ b/src/type_printers.cpp
@@ -19,12 +19,16 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
printer.print("!");
}
- printer.print("[");
- for (size_t i = 0; i < type.get_parametrs_size(); ++i) {
- print_type(*type.get_parameter(i), printer);
- printer.space();
+ if (type.get_parametrs_size() > 0) {
+ printer.print("[");
+ for (size_t i = 0; i < type.get_parametrs_size(); ++i) {
+ print_type(*type.get_parameter(i), printer);
+ if (i + 1 < type.get_parametrs_size()) {
+ printer.space();
+ }
+ }
+ printer.print("]");
}
- printer.print("]");
}
void print_tuple_type(const nodes::TupleType &type,
@@ -37,6 +41,7 @@ void print_tuple_type(const nodes::TupleType &type,
if (annotation.has_value()) {
print_annotation(*annotation.value(), printer);
+ printer.space();
}
print_type(*type.get(i), printer);
@@ -46,7 +51,7 @@ void print_tuple_type(const nodes::TupleType &type,
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) {
+ if (i > 0) {
printer.print("| ");
}
diff --git a/tests/formatting.langexp b/tests/formatting.langexp
index b2f698c..7f54128 100644
--- a/tests/formatting.langexp
+++ b/tests/formatting.langexp
@@ -85,7 +85,7 @@ func
'a
'b
'c
- : A B C -> D
+ : A B C -> D;
func 'a 'b 'c
:
@@ -127,7 +127,7 @@ func = {
// operators, containers, modifiers
-func {
+func = {
x + y;
@@ -167,10 +167,11 @@ func {
<> x;
x?;
+}
// other
-func {
+func = {
x
.func a b c;
diff --git a/tests/test.langexp b/tests/test.langexp
index f76a9f1..da5b29a 100644
--- a/tests/test.langexp
+++ b/tests/test.langexp
@@ -90,7 +90,7 @@ func_2 = {
maybe_something!;
// open optional: if null then return default value (operator)
- %x := maybe_something ?| value
+ %x := maybe_something ?| value;
%y := Fruit @apple ();