function definition class structure changed, corresponding builders and printers fixes, fixes

This commit is contained in:
ProgramSnail 2023-07-26 13:43:14 +03:00
parent 18d7bdf5c1
commit b4ce56b5f7
13 changed files with 323 additions and 284 deletions

View file

@ -118,6 +118,8 @@ private:
size_t indentation_level_ = 0; size_t indentation_level_ = 0;
}; };
void print_modifier(const nodes::Modifier &modifier, Printer &printer);
void print_literal(const nodes::Literal &literal, Printer &printer); void print_literal(const nodes::Literal &literal, Printer &printer);
void print_identifier(const nodes::Identifier &identifier, Printer &printer); void print_identifier(const nodes::Identifier &identifier, Printer &printer);

View file

@ -24,10 +24,10 @@ public:
private: private:
ExpressionProxy(ExpressionStorage &expression_storage, size_t id) ExpressionProxy(ExpressionStorage &expression_storage, size_t id)
: expression_storage_(expression_storage), id_(id) {} : expression_storage_(&expression_storage), id_(id) {}
private: private:
ExpressionStorage &expression_storage_; ExpressionStorage *expression_storage_;
size_t id_; size_t id_;
}; };

View file

@ -66,24 +66,138 @@ public:
VAR, VAR,
}; };
class Argument {
public:
Argument(const std::optional<std::string> &annotation, Identifier &&name,
Modifier before_modifier = Modifier::NONE,
Modifier after_modifier = Modifier::NONE)
: annotation_(annotation), name_(std::move(name)),
before_modifier_(before_modifier), after_modifier_(after_modifier) {}
Argument(const std::optional<std::string> &annotation,
const Identifier &name, Modifier before_modifier = Modifier::NONE,
Modifier after_modifier = Modifier::NONE)
: annotation_(annotation), name_(name),
before_modifier_(before_modifier), after_modifier_(after_modifier) {}
Argument(const std::optional<std::string> &annotation, TypeProxy type,
Modifier before_modifier = Modifier::NONE)
: annotation_(annotation), type_(type),
before_modifier_(before_modifier),
after_modifier_(type.get()->get_modifier()) {}
//
bool add_type(const std::optional<std::string> &annotation, TypeProxy type,
nodes::Modifier before_modifier = Modifier::NONE) {
if (annotation_.has_value() &&
(!annotation.has_value() ||
annotation_.value() != annotation.value())) {
return false;
}
if (before_modifier_ != Modifier::NONE &&
before_modifier_ != before_modifier) {
return false;
}
if (after_modifier_ != Modifier::NONE &&
after_modifier_ != type.get()->get_modifier()) {
return false;
}
annotation_ = annotation;
type_ = type;
before_modifier_ = before_modifier;
after_modifier_ = type.get()->get_modifier();
return true;
}
bool add_annotation(const std::string &annotation) {
if (annotation_.has_value()) {
return false;
}
annotation_ = annotation;
return true;
}
//
std::optional<std::string *> get_annotation() {
if (annotation_.has_value()) {
return &annotation_.value();
}
return std::nullopt;
}
std::optional<const std::string *> get_annotation() const {
if (annotation_.has_value()) {
return &annotation_.value();
}
return std::nullopt;
}
//
std::optional<Identifier *> get_name() {
if (name_.has_value()) {
return &name_.value();
}
return std::nullopt;
}
std::optional<const Identifier *> get_name() const {
if (name_.has_value()) {
return &name_.value();
}
return std::nullopt;
}
//
std::optional<Type *> get_type() {
if (type_.has_value()) {
return type_.value().get();
}
return std::nullopt;
}
std::optional<const Type *> get_type() const {
if (type_.has_value()) {
return type_.value().get();
}
return std::nullopt;
}
//
Modifier get_before_modifier() const { return before_modifier_; }
Modifier get_after_modifier() const { return after_modifier_; }
private:
std::optional<std::string> annotation_;
std::optional<Identifier> name_; // no name for output arguments
std::optional<TypeProxy> type_; // no type if it is deduced
Modifier before_modifier_ =
Modifier::NONE; // in, out, ref, none // sync with type
Modifier after_modifier_ =
Modifier::NONE; // optional, result, none // sync with type
};
FunctionDefinition(Node node, SymbolDocs &&docs, FunctionDefinition(Node node, SymbolDocs &&docs,
std::vector<Constraint> &&constraints, std::vector<Constraint> &&constraints,
ModifierType modifier, const Identifier &name, ModifierType modifier, const Identifier &name,
std::vector<std::optional<std::string>> &&annotations, std::vector<Argument> &&arguments,
std::vector<Identifier> &&arguments, bool are_annotations_same_to_names,
std::vector<Modifier> &&reference_types,
std::vector<TypeProxy> &&types,
std::vector<bool> &&optional_arguments,
std::vector<bool> &&result_arguments,
bool is_annotations_same_to_names,
std::optional<ExpressionProxy> expression) std::optional<ExpressionProxy> expression)
: Node(node), docs_(std::move(docs)), : Node(node), docs_(std::move(docs)),
constraints_(std::move(constraints)), modifier_(modifier), name_(name), constraints_(std::move(constraints)), modifier_(modifier), name_(name),
annotations_(std::move(annotations)), arguments_(std::move(arguments)), arguments_(std::move(arguments)),
reference_types_(std::move(reference_types)), types_(std::move(types)), are_annotations_same_to_names_(are_annotations_same_to_names),
optional_arguments_(optional_arguments),
result_arguments_(result_arguments),
is_annotations_same_to_names_(is_annotations_same_to_names),
expression_(expression) {} expression_(expression) {}
// //
@ -114,57 +228,11 @@ public:
// //
std::optional<std::string *> get_argument_annotation(size_t id) {
if (annotations_.at(id).has_value()) {
return &annotations_[id].value();
}
return std::nullopt;
}
std::optional<const std::string *> get_argument_annotation(size_t id) const {
if (annotations_.at(id).has_value()) {
return &annotations_[id].value();
}
return std::nullopt;
}
//
size_t get_arguments_size() const { return arguments_.size(); } size_t get_arguments_size() const { return arguments_.size(); }
Identifier *get_argument(size_t id) { return &arguments_.at(id); } Argument *get_argument(size_t id) { return &arguments_.at(id); }
const Identifier *get_argument(size_t id) const { return &arguments_.at(id); } const Argument *get_argument(size_t id) const { return &arguments_.at(id); }
//
Modifier get_argument_reference_type(size_t id) const {
return reference_types_.at(id);
}
//
size_t get_argument_types_size() const { return types_.size(); }
Type *get_argument_type(size_t id) { return types_.at(id).get(); }
const Type *get_argument_type(size_t id) const { return types_.at(id).get(); }
//
bool is_argument_optional(size_t id) const {
return optional_arguments_.at(id);
}
//
bool is_argument_result(size_t id) const { return result_arguments_.at(id); }
//
bool is_annotations_same_to_names() const {
return is_annotations_same_to_names_;
}
// //
@ -182,18 +250,19 @@ public:
return std::nullopt; return std::nullopt;
} }
//
bool are_annotations_same_to_names() const {
return are_annotations_same_to_names_;
}
private: private:
SymbolDocs docs_; SymbolDocs docs_;
std::vector<Constraint> constraints_; std::vector<Constraint> constraints_;
ModifierType modifier_; ModifierType modifier_;
Identifier name_; Identifier name_;
std::vector<std::optional<std::string>> annotations_; std::vector<Argument> arguments_;
std::vector<Identifier> arguments_; bool are_annotations_same_to_names_; // needed for easier prinitng process
std::vector<Modifier> reference_types_;
std::vector<TypeProxy> types_;
std::vector<bool> optional_arguments_;
std::vector<bool> result_arguments_;
bool is_annotations_same_to_names_;
std::optional<ExpressionProxy> expression_; std::optional<ExpressionProxy> expression_;
}; // refactor ?? }; // refactor ??

View file

@ -24,10 +24,10 @@ public:
private: private:
TypeProxy(TypeStorage &type_storage, size_t id) TypeProxy(TypeStorage &type_storage, size_t id)
: type_storage_(type_storage), id_(id) {} : type_storage_(&type_storage), id_(id) {}
private: private:
TypeStorage &type_storage_; TypeStorage *type_storage_;
size_t id_; size_t id_;
}; };
@ -35,28 +35,26 @@ private:
class Type : public Node { class Type : public Node {
public: public:
Type(Node node, Identifier &&identifier, bool is_on_heap = false, Type(Node node, Identifier &&identifier, bool is_on_heap = false,
bool is_optional = false, bool is_result = false) Modifier modifier = Modifier::NONE)
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap), : Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap),
is_optional_(is_optional), is_result_(is_result) {} modifier_(modifier) {}
Type(Node node, const Identifier &identifier, bool is_on_heap = false, Type(Node node, const Identifier &identifier, bool is_on_heap = false,
bool is_optional = false, bool is_result = false) Modifier modifier = Modifier::NONE)
: Node(node), name_(identifier), is_on_heap_(is_on_heap), : Node(node), name_(identifier), is_on_heap_(is_on_heap),
is_optional_(is_optional), is_result_(is_result) {} modifier_(modifier) {}
Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &&parameters, Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &&parameters,
bool is_on_heap = false, bool is_optional = false, bool is_on_heap = false, Modifier modifier = Modifier::NONE)
bool is_result = false)
: Node(node), name_(std::move(identifier)), : Node(node), name_(std::move(identifier)),
parameters_(std::move(parameters)), is_on_heap_(is_on_heap), parameters_(std::move(parameters)), is_on_heap_(is_on_heap),
is_optional_(is_optional), is_result_(is_result) {} modifier_(modifier) {}
Type(Node node, const Identifier &identifier, Type(Node node, const Identifier &identifier,
std::vector<TypeProxy> &&parameters, bool is_on_heap = false, std::vector<TypeProxy> &&parameters, bool is_on_heap = false,
bool is_optional = false, bool is_result = false) Modifier modifier = Modifier::NONE)
: Node(node), name_(identifier), parameters_(std::move(parameters)), : Node(node), name_(identifier), parameters_(std::move(parameters)),
is_on_heap_(is_on_heap), is_optional_(is_optional), is_on_heap_(is_on_heap), modifier_(modifier) {}
is_result_(is_result) {}
Identifier *get_name() { return &name_; } Identifier *get_name() { return &name_; }
@ -72,17 +70,14 @@ public:
bool is_on_heap() const { return is_on_heap_; } bool is_on_heap() const { return is_on_heap_; }
bool is_optional() const { return is_optional_; } Modifier get_modifier() const { return modifier_; }
bool is_result() const { return is_result_; }
private: private:
Identifier name_; Identifier name_;
std::vector<TypeProxy> parameters_; std::vector<TypeProxy> parameters_;
// or use allocator ?? // or use allocator ??
bool is_on_heap_ = false; bool is_on_heap_ = false;
bool is_optional_ = false; Modifier modifier_ = Modifier::NONE; // optional, result or none
bool is_result_ = false;
}; };
class TypeStorage { class TypeStorage {

View file

@ -77,8 +77,7 @@ nodes::Literal build_string_literal(parser::ParseTree::Node parser_node) {
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove " from both sides ("string") // remove " from both sides ("string")
literal.pop_back(); literal = literal.substr(1, literal.size() - 2);
literal = literal.substr(1, literal.size() - 1);
// replace escape sequences with escape characters // replace escape sequences with escape characters
bool is_escape_symbol = false; bool is_escape_symbol = false;
@ -111,9 +110,7 @@ nodes::Literal build_char_literal(parser::ParseTree::Node parser_node) {
std::string literal = parser_node.get_value(); std::string literal = parser_node.get_value();
// remove '' from both sides (''x'') // remove '' from both sides (''x'')
literal.pop_back(); literal = literal.substr(2, literal.size() - 4);
literal.pop_back();
literal = literal.substr(1, literal.size() - 2);
char ch = '\0'; char ch = '\0';

View file

@ -6,6 +6,30 @@
namespace printers { namespace printers {
void print_modifier(const nodes::Modifier &modifier, Printer &printer) {
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_FALSE:
printer.print("?");
break;
case nodes::Modifier::OR_RETURN:
printer.print("!");
break;
case nodes::Modifier::NONE:
break;
default:
break;
}
}
void print_literal(const nodes::Literal &literal, Printer &printer) { void print_literal(const nodes::Literal &literal, Printer &printer) {
switch (literal.get_any()->index()) { switch (literal.get_any()->index()) {
case 0: // double case 0: // double

View file

@ -3,11 +3,11 @@
namespace nodes { namespace nodes {
Expression *ExpressionProxy::get() { Expression *ExpressionProxy::get() {
return expression_storage_.get_expression(id_); return expression_storage_->get_expression(id_);
} }
const Expression *ExpressionProxy::get() const { const Expression *ExpressionProxy::get() const {
return expression_storage_.get_expression(id_); return expression_storage_->get_expression(id_);
} }
}; // namespace nodes }; // namespace nodes

View file

@ -2,7 +2,6 @@
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "basic_printers.hpp" #include "basic_printers.hpp"
#include "expression_nodes.hpp" #include "expression_nodes.hpp"
#include "tokens.hpp"
#include "type_printers.hpp" #include "type_printers.hpp"
#include "utils.hpp" #include "utils.hpp"
@ -331,48 +330,17 @@ void print_loop_control(const nodes::LoopControl &expression,
void print_modifier_expression(const nodes::ModifierExpression &expression, void print_modifier_expression(const nodes::ModifierExpression &expression,
printers::Printer &printer) { printers::Printer &printer) {
if (expression.get_modifier() == nodes::Modifier::OUT ||
if (printer.print_words_instead_of_symbols()) { expression.get_modifier() == nodes::Modifier::IN ||
switch (expression.get_modifier()) { expression.get_modifier() == nodes::Modifier::REF) {
case nodes::Modifier::OUT: print_modifier(expression.get_modifier(), printer);
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); print_expression(*expression.get_expression(), printer);
switch (expression.get_modifier()) { if (expression.get_modifier() == nodes::Modifier::OR_FALSE ||
case nodes::Modifier::OR_FALSE: expression.get_modifier() == nodes::Modifier::OR_RETURN) {
printer.print("?"); print_modifier(expression.get_modifier(), printer);
break;
case nodes::Modifier::OR_RETURN:
printer.print("!");
break;
default:
break;
} }
} }

View file

@ -254,29 +254,32 @@ build_function_definition(parser::ParseTree::Node parser_node,
} }
} }
std::vector<std::optional<std::string>> argument_annotations; std::vector<nodes::FunctionDefinition::Argument> arguments;
std::vector<nodes::Modifier> argument_reference_types; std::vector<nodes::FunctionDefinition::Argument> argument_types;
std::vector<nodes::Identifier> arguments;
std::vector<bool> optional_arguments;
std::vector<bool> result_arguments;
std::vector<std::optional<std::string>> type_annotations;
std::vector<nodes::Modifier> type_reference_types;
std::vector<nodes::TypeProxy> types;
std::optional<parser::ParseTree::Node> expression_node; std::optional<parser::ParseTree::Node> expression_node;
current_node = name_node.next_named_sibling(); current_node = name_node.next_named_sibling();
bool at_least_one_argument_annotation_found = false; bool at_least_one_argument_annotation_found = false;
bool at_least_one_argument_modifier_found = false;
size_t current_type_id = 0;
std::optional<std::string> last_annotation; std::optional<std::string> last_annotation;
nodes::Modifier last_reference_type = nodes::Modifier::NONE; nodes::Modifier last_before_modifier = nodes::Modifier::NONE;
nodes::Modifier last_after_modifier = nodes::Modifier::NONE;
while (!current_node.is_null()) { while (!current_node.is_null()) {
// update last before modifier
auto maybe_reference_node = current_node.previous_sibling(); auto maybe_reference_node = current_node.previous_sibling();
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) { if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
last_reference_type = build_modifier(maybe_reference_node); last_before_modifier = build_modifier(maybe_reference_node);
// only out, in, ref allowed
if (last_before_modifier != nodes::Modifier::OUT &&
last_before_modifier != nodes::Modifier::IN &&
last_before_modifier != nodes::Modifier::REF) {
last_before_modifier = nodes::Modifier::NONE;
}
} }
switch (tokens::string_to_type(current_node.get_type())) { switch (tokens::string_to_type(current_node.get_type())) {
@ -284,38 +287,50 @@ build_function_definition(parser::ParseTree::Node parser_node,
last_annotation = build_annotation(current_node); last_annotation = build_annotation(current_node);
break; break;
case tokens::Type::ARGUMENT_NAME_IDENTIFIER: case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
// update last after modifier
maybe_reference_node = current_node.next_sibling();
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
last_after_modifier = build_modifier(maybe_reference_node);
// only optional, result allowed
if (last_after_modifier != nodes::Modifier::OR_FALSE &&
last_after_modifier != nodes::Modifier::OR_RETURN) {
last_after_modifier = nodes::Modifier::NONE;
}
}
// update conditions
if (last_annotation.has_value()) { if (last_annotation.has_value()) {
at_least_one_argument_annotation_found = true; at_least_one_argument_annotation_found = true;
at_least_one_argument_modifier_found = true;
}
if (last_reference_type != nodes::Modifier::NONE) {
at_least_one_argument_modifier_found = true;
} }
argument_annotations.push_back(last_annotation); arguments.push_back(nodes::FunctionDefinition::Argument(
argument_reference_types.push_back(last_reference_type); last_annotation, build_identifier(current_node), last_before_modifier,
arguments.push_back(build_identifier(current_node)); last_after_modifier));
optional_arguments.push_back(!current_node.next_sibling().is_null() &&
!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().get_value() ==
"!");
if (optional_arguments.back() || result_arguments.back()) {
at_least_one_argument_modifier_found = true;
}
last_reference_type = nodes::Modifier::NONE;
last_annotation = std::nullopt; last_annotation = std::nullopt;
break; break;
case tokens::Type::TYPE: case tokens::Type::TYPE:
type_annotations.push_back(last_annotation); if (current_type_id >= arguments.size()) {
type_reference_types.push_back(last_reference_type); arguments.push_back(nodes::FunctionDefinition::Argument(
types.push_back(build_type(current_node, type_storage)); last_annotation, build_type(current_node, type_storage),
last_reference_type = nodes::Modifier::NONE; last_before_modifier));
} else {
if (!arguments[current_type_id].add_type(
last_annotation, build_type(current_node, type_storage),
last_before_modifier)) {
error_handling::handle_parsing_error(
"It is impossible to use argument modifiers (annotations, "
"references, "
"optional markers, result markers) when types explicitely "
"defined. Use type annotations instead.",
current_node);
}
}
last_annotation = std::nullopt; last_annotation = std::nullopt;
++current_type_id;
break; break;
default: default:
if (expression_node.has_value()) { if (expression_node.has_value()) {
@ -329,38 +344,32 @@ build_function_definition(parser::ParseTree::Node parser_node,
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
std::vector<std::optional<std::string>> *annotations = nullptr; if (current_type_id > 0 && current_type_id < arguments.size()) {
std::vector<nodes::Modifier> *reference_types = nullptr;
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] =
argument_annotation.substr(1, argument_annotation.size() - 1);
}
}
if (types.empty()) {
annotations = &argument_annotations;
reference_types = &argument_reference_types;
} else if (at_least_one_argument_modifier_found) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
"It is impossible to use argument modifiers (annotations, references, " "Less types then arguments in function definition", parser_node);
"optional markers, result markers) when types explicitely " }
"defined. Use type annotations instead.",
parser_node); // automatic annotations
} else { bool are_annotations_same_to_names =
annotations = &type_annotations; (!at_least_one_argument_annotation_found && current_type_id == 0);
reference_types = &type_reference_types;
if (are_annotations_same_to_names) {
for (size_t i = 0; i < arguments.size(); ++i) {
std::string new_annotation = *arguments[i].get_name().value()->get();
if (!arguments[i].add_annotation(
new_annotation.substr(1, new_annotation.size() - 1))) {
error_handling::handle_parsing_error(
"no annotations provided ( => all annotations same to names), but "
"can't add name annotation",
current_node);
}
}
} }
std::unordered_set<std::string> annotations_set; std::unordered_set<std::string> annotations_set;
for (auto &annotation : *annotations) { for (auto &argument : arguments) {
if (annotation.has_value()) { if (argument.get_annotation().has_value()) {
if (!annotations_set.insert(annotation.value()).second) { if (!annotations_set.insert(*argument.get_annotation().value()).second) {
error_handling::handle_parsing_error( error_handling::handle_parsing_error(
"Two or more same annotations found in function definition", "Two or more same annotations found in function definition",
parser_node); parser_node);
@ -372,15 +381,12 @@ build_function_definition(parser::ParseTree::Node parser_node,
build_node(parser_node), build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations_set), build_symbol_docs(description_node, annotation_nodes, annotations_set),
std::move(constraints), modifier, build_identifier(name_node), std::move(constraints), modifier, build_identifier(name_node),
std::move(*annotations), std::move(arguments), std::move(arguments), are_annotations_same_to_names,
std::move(*reference_types), std::move(types),
std::move(optional_arguments), std::move(result_arguments),
is_annotations_same_to_names,
expression_node.has_value() expression_node.has_value()
? build_expression(expression_node.value(), expression_storage, ? build_expression(expression_node.value(), expression_storage,
type_storage) type_storage)
: std::optional<nodes::ExpressionProxy>()); : std::optional<nodes::ExpressionProxy>());
} // TODO: refactor ?? }
// definition_info? annotation_info* typeclass_identifier (':' // definition_info? annotation_info* typeclass_identifier (':'
// typeclass_identifier+)? ('{' function_definition* '}' | ';') // typeclass_identifier+)? ('{' function_definition* '}' | ';')

View file

@ -23,8 +23,19 @@ void print_import(const nodes::Import &statement, Printer &printer) {
printer.print(" :"); printer.print(" :");
for (size_t i = 0; i < statement.symbols_size(); ++i) { for (size_t i = 0; i < statement.symbols_size(); ++i) {
printer.space(); printer.space();
// TODO: properly print operator identifier
bool identifier_is_operator =
(statement.get_symbol(i)->get_type() == nodes::Identifier::OPERATOR);
if (identifier_is_operator) {
printer.print("( ");
}
print_identifier(*statement.get_symbol(i), printer); print_identifier(*statement.get_symbol(i), printer);
if (identifier_is_operator) {
printer.print(" )");
}
} }
} }
printer.print(";"); printer.print(";");
@ -60,7 +71,7 @@ void print_statement_methods(const T &statement, Printer &printer) {
void print_type_definition(const nodes::TypeDefinition &statement, void print_type_definition(const nodes::TypeDefinition &statement,
Printer &printer) { Printer &printer) {
print_docs(*statement.get_docs(), printer); // TODO print_docs(*statement.get_docs(), printer);
if (statement.is_on_heap()) { if (statement.is_on_heap()) {
printer.print("^"); printer.print("^");
@ -90,7 +101,7 @@ void print_type_definition(const nodes::TypeDefinition &statement,
void print_function_definition(const nodes::FunctionDefinition &statement, void print_function_definition(const nodes::FunctionDefinition &statement,
Printer &printer) { Printer &printer) {
print_docs(*statement.get_docs(), printer); // TODO print_docs(*statement.get_docs(), printer);
for (size_t i = 0; i < statement.get_constraints_size(); ++i) { for (size_t i = 0; i < statement.get_constraints_size(); ++i) {
print_constraint(*statement.get_constraint(i), printer); print_constraint(*statement.get_constraint(i), printer);
@ -110,95 +121,65 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
break; break;
} }
bool operator_called_as_function = bool identifier_is_operator =
(statement.get_name()->get_type() == nodes::Identifier::OPERATOR); (statement.get_name()->get_type() == nodes::Identifier::OPERATOR);
if (operator_called_as_function) { if (identifier_is_operator) {
printer.print("( "); printer.print("( ");
} }
print_identifier(*statement.get_name(), printer); print_identifier(*statement.get_name(), printer);
if (operator_called_as_function) { if (identifier_is_operator) {
printer.print(" )"); printer.print(" )");
} }
// TODO: same fragments with function type, maybe better make separated for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
// function if (!statement.get_argument(i)->get_name().has_value()) {
break;
}
printer.space();
// all arguments are typed or are untyped in the same time
if (!statement.get_argument(i)->get_type().has_value()) {
// print annotation
if (!statement.are_annotations_same_to_names() &&
statement.get_argument(i)->get_annotation().has_value()) {
print_annotation(*statement.get_argument(i)->get_annotation().value(),
printer);
printer.space();
}
print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
}
print_identifier(*statement.get_argument(i)->get_name().value(), printer);
// all arguments are typed or are untyped in the same time
if (!statement.get_argument(i)->get_type().has_value()) {
print_modifier(statement.get_argument(i)->get_after_modifier(), printer);
}
}
// all arguments are typed or are untyped in the same time
if (statement.get_arguments_size() > 0 &&
statement.get_argument(0)->get_type().has_value()) {
printer.print(" :");
for (size_t i = 0; i < statement.get_arguments_size(); ++i) { for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
printer.space(); printer.space();
if (statement.get_argument(i)->get_annotation().has_value()) {
if (statement.get_argument_types_size() == 0) { print_annotation(*statement.get_argument(i)->get_annotation().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);
printer.space(); printer.space();
} }
switch (statement.get_argument_reference_type(i)) { print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
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::NONE:
break;
default: // TODO: handle errors ??
break;
}
}
print_identifier(*statement.get_argument(i), printer); print_type(*statement.get_argument(i)->get_type().value(), printer);
if (statement.get_argument_types_size() == 0) {
// 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_argument_types_size() > 0) {
printer.print(" :");
for (size_t i = 0; i < statement.get_argument_types_size(); ++i) {
printer.space();
if (statement.get_argument_annotation(i).has_value()) {
print_annotation(*statement.get_argument_annotation(i).value(),
printer);
printer.space();
}
switch (statement.get_argument_reference_type(i)) {
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::NONE:
break;
default: // TODO: handle errors ??
break;
}
print_type(*statement.get_argument_type(i), printer);
} }
} }
@ -218,7 +199,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
void print_typeclass_definition(const nodes::TypeclassDefinition &statement, void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
Printer &printer) { Printer &printer) {
print_docs(*statement.get_docs(), printer); // TODO print_docs(*statement.get_docs(), printer);
print_identifier(*statement.get_name(), printer); print_identifier(*statement.get_name(), printer);
@ -234,5 +215,3 @@ void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
} // IN PROGRESS } // IN PROGRESS
} // namespace printers } // namespace printers
// TODO: print operator in ()

View file

@ -1,5 +1,6 @@
#include "type_builders.hpp" #include "type_builders.hpp"
#include "basic_builders.hpp" #include "basic_builders.hpp"
#include "basic_nodes.hpp"
#include "tokens.hpp" #include "tokens.hpp"
namespace builders { namespace builders {
@ -15,12 +16,19 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
bool is_on_heap = (!current_node.is_null() && !current_node.is_named() && bool is_on_heap = (!current_node.is_null() && !current_node.is_named() &&
current_node.get_value() == "^"); current_node.get_value() == "^");
current_node = name_node.next_sibling(); nodes::Modifier modifier = nodes::Modifier::NONE;
bool is_optional = (!current_node.is_null() && !current_node.is_named() &&
current_node.get_value() == "?");
bool is_result = (!current_node.is_null() && !current_node.is_named() && current_node = name_node.next_sibling();
current_node.get_value() == "!"); // update last after modifier
if (!current_node.is_null() && !current_node.is_named()) {
modifier = build_modifier(current_node);
// only optional, result allowed
if (modifier != nodes::Modifier::OR_FALSE &&
modifier != nodes::Modifier::OR_RETURN) {
modifier = nodes::Modifier::NONE;
}
}
current_node = name_node.next_named_sibling(); current_node = name_node.next_named_sibling();
while (!current_node.is_null()) { while (!current_node.is_null()) {
@ -30,7 +38,7 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
return type_storage.add_type( return type_storage.add_type(
nodes::Type(build_node(parse_node), build_identifier(name_node), nodes::Type(build_node(parse_node), build_identifier(name_node),
std::move(parameters), is_on_heap, is_optional, is_result)); std::move(parameters), is_on_heap, modifier));
} }
// '&'? annotation? type ('&' annotation? type)* // '&'? annotation? type ('&' annotation? type)*

View file

@ -2,12 +2,8 @@
namespace nodes { namespace nodes {
Type* TypeProxy::get() { Type *TypeProxy::get() { return type_storage_->get_type(id_); }
return type_storage_.get_type(id_);
}
const Type* TypeProxy::get() const { const Type *TypeProxy::get() const { return type_storage_->get_type(id_); }
return type_storage_.get_type(id_);
}
}; // namespace nodes }; // namespace nodes

View file

@ -1,4 +1,5 @@
#include "type_printers.hpp" #include "type_printers.hpp"
#include "basic_nodes.hpp"
#include "basic_printers.hpp" #include "basic_printers.hpp"
#include "type_nodes.hpp" #include "type_nodes.hpp"
@ -11,13 +12,7 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
print_identifier(*type.get_name(), printer); print_identifier(*type.get_name(), printer);
if (type.is_optional()) { print_modifier(type.get_modifier(), printer);
printer.print("?");
}
if (type.is_result()) {
printer.print("!");
}
if (type.get_parametrs_size() > 0) { if (type.get_parametrs_size() > 0) {
printer.print("["); printer.print("[");