mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 15:08:48 +00:00
function definition class structure changed, corresponding builders and printers fixes, fixes
This commit is contained in:
parent
18d7bdf5c1
commit
b4ce56b5f7
13 changed files with 323 additions and 284 deletions
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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 ??
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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> &¶meters,
|
Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &¶meters,
|
||||||
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> &¶meters, bool is_on_heap = false,
|
std::vector<TypeProxy> &¶meters, 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 {
|
||||||
|
|
|
||||||
|
|
@ -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';
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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* '}' | ';')
|
||||||
|
|
|
||||||
|
|
@ -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 ()
|
|
||||||
|
|
|
||||||
|
|
@ -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)*
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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("[");
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue