mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2026-01-25 13:07:13 +00:00
or references, prining improvements, comments now printed, fixes
This commit is contained in:
parent
73263193a9
commit
5e70f0015f
19 changed files with 354 additions and 429 deletions
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit b71b732797ce7fc203322b5ce2b1bbd9333bfb51
|
||||
Subproject commit 8e0cea277edec400aefe29ed7aca9037348b9806
|
||||
|
|
@ -62,7 +62,7 @@
|
|||
<RegExpr String="\b[0-9]+\.[0-9]+\b" attribute="Float" context="#stay"/>
|
||||
<RegExpr String="''([^\\\/]|(\\.))''" attribute="Character" context="#stay"/>
|
||||
|
||||
<RegExpr String="((?<![a\+\\\-\*/%\^\!\?\|&,<>=\.])((\.+)|([\+\\\-\*/%\^\!\?\|&,<>=]+\.?\.?\.?)))|(\|)" attribute="Operator" context="#stay"/>
|
||||
<RegExpr String="((?<![\+\\\-\*/%\^\!\?\|&,<>=\.])((\.+)|([\+\\\-\*/%\^\!\?\|&,<>=]+\.?\.?\.?)))|(\|)" attribute="Operator" context="#stay"/>
|
||||
|
||||
<RegExpr String="([a-z_][a-z0-9_]*\.)*(([a-z_][a-z0-9_]*)|_)(?![a-z0-9_])" attribute="Name" context="#stay"/>
|
||||
|
||||
|
|
|
|||
|
|
@ -56,6 +56,10 @@ nodes::Identifier build_operator(parser::ParseTree::Node parser_node);
|
|||
|
||||
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node);
|
||||
|
||||
// --- extra
|
||||
|
||||
nodes::Extra build_extra(parser::ParseTree::Node parser_node);
|
||||
|
||||
// --- empty lines
|
||||
|
||||
nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node);
|
||||
|
|
|
|||
|
|
@ -7,14 +7,28 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
// replace enum with structure ??
|
||||
enum class Modifier {
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x // IN and OUT
|
||||
OR_OUT, // |-> // OUT or NONE
|
||||
OR_IN, // <-| // IN or NONE
|
||||
OPTIONAL, // x?
|
||||
RESULT, // x!
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
CONST, // -- x (or nothing sometimes)
|
||||
OUT, // -> x
|
||||
//
|
||||
IN_OR_REF, // <-|<> x
|
||||
IN_OR_CONST, // <-|-- x
|
||||
REF_OR_OUT, // <>|-> x
|
||||
CONST_OR_OUT, // --|-> x
|
||||
REF_OR_CONST, // <>|-- x
|
||||
IN_OR_OUT, // <-|-> x
|
||||
//
|
||||
IN_OR_REF_OR_OUT, // <-|<>|-> x
|
||||
IN_OR_CONST_OR_OUT, // <-|--|-> x
|
||||
IN_OR_REF_OR_CONST, // <-|<>|-- x
|
||||
REF_OR_CONST_OR_OUT, //<>|--|-> x
|
||||
//
|
||||
IN_OR_REF_OR_CONST_OR_OUT, //<-|<>|--|-> x
|
||||
OPTIONAL, // x?
|
||||
RESULT, // x!
|
||||
NONE,
|
||||
};
|
||||
|
||||
|
|
@ -86,23 +100,51 @@ public:
|
|||
|
||||
IdentifierType get_type() const { return type_; }
|
||||
|
||||
//
|
||||
|
||||
std::string *get() { return &value_; }
|
||||
|
||||
const std::string *get() const { return &value_; }
|
||||
|
||||
//
|
||||
|
||||
void append_before(const std::string &name) { value_ = name + "." + value_; }
|
||||
|
||||
void append_after(const std::string &name) {
|
||||
value_ += ".";
|
||||
value_ += name;
|
||||
}
|
||||
|
||||
private:
|
||||
IdentifierType type_;
|
||||
std::string value_;
|
||||
};
|
||||
|
||||
class EmptyLines : public Node {
|
||||
class Extra : public Node {
|
||||
public:
|
||||
EmptyLines(Node node, size_t size) : Node(node), size_(size) {}
|
||||
Extra(Node node, std::string &&content)
|
||||
: Node(node), content_(std::move(content)) {}
|
||||
|
||||
size_t size() const { return size_; }
|
||||
Extra(Node node, const std::string &content)
|
||||
: Node(node), content_(content) {}
|
||||
|
||||
std::string *content() { return &content_; }
|
||||
|
||||
const std::string *content() const { return &content_; }
|
||||
|
||||
private:
|
||||
size_t size_;
|
||||
std::string content_;
|
||||
};
|
||||
|
||||
class EmptyLines : public Node {
|
||||
public:
|
||||
EmptyLines(Node node, size_t line_count)
|
||||
: Node(node), line_count_(line_count) {}
|
||||
|
||||
size_t line_count() const { return line_count_; }
|
||||
|
||||
private:
|
||||
size_t line_count_;
|
||||
};
|
||||
|
||||
} // namespace nodes
|
||||
|
|
|
|||
|
|
@ -42,6 +42,12 @@ public:
|
|||
print_spaces(indentation);
|
||||
}
|
||||
|
||||
void to_indentation_level() {
|
||||
if (indentation_level_ > current_position_) {
|
||||
print_spaces(indentation_level_ - current_position_);
|
||||
}
|
||||
}
|
||||
|
||||
void indent() { indentation_level_ += tab_width_; }
|
||||
|
||||
void deindent() { indentation_level_ -= tab_width_; }
|
||||
|
|
@ -118,7 +124,8 @@ private:
|
|||
size_t indentation_level_ = 0;
|
||||
};
|
||||
|
||||
void print_modifier(const nodes::Modifier &modifier, Printer &printer);
|
||||
void print_modifier(const nodes::Modifier &modifier, Printer &printer,
|
||||
bool const_is_none = false);
|
||||
|
||||
void print_literal(const nodes::Literal &literal, Printer &printer);
|
||||
|
||||
|
|
@ -126,6 +133,8 @@ void print_identifier(const nodes::Identifier &identifier, Printer &printer);
|
|||
|
||||
void print_annotation(const std::string &annotation, Printer &printer);
|
||||
|
||||
void print_extra(const nodes::Extra &extra, Printer &printer);
|
||||
|
||||
void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer);
|
||||
|
||||
} // namespace printers
|
||||
|
|
|
|||
|
|
@ -561,6 +561,9 @@ private:
|
|||
// --- literal
|
||||
Literal,
|
||||
|
||||
// --- extra
|
||||
Extra,
|
||||
|
||||
// --- empty lines
|
||||
EmptyLines>
|
||||
expression_;
|
||||
|
|
|
|||
|
|
@ -16,10 +16,11 @@ build_source_file(parser::ParseTree::Node parser_node,
|
|||
nodes::TypeStorage &type_storage, names::NameTree &name_tree);
|
||||
|
||||
// copy of statement inserted into name_tree
|
||||
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage,
|
||||
names::NameTree &name_tree);
|
||||
nodes::Statement
|
||||
build_statement(parser::ParseTree::Node parser_node,
|
||||
std::optional<nodes::Identifier> &previous_defined_type_name,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage, names::NameTree &name_tree);
|
||||
|
||||
nodes::Import build_import(parser::ParseTree::Node parser_node);
|
||||
|
||||
|
|
@ -27,19 +28,12 @@ nodes::Constraint build_constraint(parser::ParseTree::Node parser_node,
|
|||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeDefinition
|
||||
build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::FunctionDefinition
|
||||
build_function_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeclassDefinition
|
||||
build_typeclass_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::FunctionDefinition build_function_definition(
|
||||
parser::ParseTree::Node parser_node,
|
||||
const std::optional<nodes::Identifier> &previous_defined_type_name,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -73,12 +73,6 @@ private:
|
|||
|
||||
class FunctionDefinition : public Node {
|
||||
public:
|
||||
enum MethodModifier {
|
||||
STATIC,
|
||||
LET,
|
||||
VAR,
|
||||
};
|
||||
|
||||
class Argument {
|
||||
public:
|
||||
Argument(const std::optional<std::string> &annotation, Identifier &&name,
|
||||
|
|
@ -237,16 +231,21 @@ public:
|
|||
|
||||
FunctionDefinition(Node node, SymbolDocs &&docs,
|
||||
std::vector<Constraint> &&constraints,
|
||||
Modifier return_modifier, MethodModifier method_modifier,
|
||||
Modifier return_modifier, bool is_method,
|
||||
const std::optional<Identifier> &name_prefix,
|
||||
const Identifier &name, std::vector<Argument> &&arguments,
|
||||
bool are_annotations_same_to_names,
|
||||
std::optional<ExpressionProxy> expression)
|
||||
: Node(node), docs_(std::move(docs)),
|
||||
constraints_(std::move(constraints)), return_modifier_(return_modifier),
|
||||
method_modifier_(method_modifier), name_(name),
|
||||
is_method_(is_method), name_(name), full_name_(name),
|
||||
arguments_(std::move(arguments)),
|
||||
are_annotations_same_to_names_(are_annotations_same_to_names),
|
||||
expression_(expression) {}
|
||||
expression_(expression) {
|
||||
if (name_prefix.has_value()) {
|
||||
full_name_.append_before(*name_prefix.value().get());
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -268,7 +267,7 @@ public:
|
|||
|
||||
Modifier get_return_modifier() const { return return_modifier_; }
|
||||
|
||||
MethodModifier get_method_modifier() const { return method_modifier_; }
|
||||
bool is_method() const { return is_method_; }
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -278,6 +277,12 @@ public:
|
|||
|
||||
//
|
||||
|
||||
Identifier *get_full_name() { return &full_name_; }
|
||||
|
||||
const Identifier *get_full_name() const { return &full_name_; }
|
||||
|
||||
//
|
||||
|
||||
size_t get_arguments_size() const { return arguments_.size(); }
|
||||
|
||||
Argument *get_argument(size_t id) { return &arguments_.at(id); }
|
||||
|
|
@ -316,8 +321,9 @@ private:
|
|||
SymbolDocs docs_;
|
||||
std::vector<Constraint> constraints_;
|
||||
Modifier return_modifier_;
|
||||
MethodModifier method_modifier_;
|
||||
bool is_method_;
|
||||
Identifier name_;
|
||||
Identifier full_name_;
|
||||
std::vector<Argument> arguments_;
|
||||
bool are_annotations_same_to_names_; // needed for easier prinitng process
|
||||
std::optional<ExpressionProxy> expression_;
|
||||
|
|
@ -326,16 +332,12 @@ private:
|
|||
class TypeDefinition : public Node {
|
||||
public:
|
||||
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
|
||||
const Identifier &name, std::vector<Identifier> &&arguments,
|
||||
std::optional<VariantType> &&type,
|
||||
std::vector<FunctionDefinition> &&methods)
|
||||
const Identifier &name, std::vector<Identifier> &&typeclasses,
|
||||
std::vector<Identifier> &&arguments,
|
||||
std::optional<VariantType> &&type)
|
||||
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
|
||||
name_(name), arguments_(std::move(arguments)), type_(std::move(type)),
|
||||
methods_(std::move(methods)) {
|
||||
for (size_t i = 0; i < methods.size(); ++i) {
|
||||
methods_by_name_[*methods_[i].get_name()->get()] = i;
|
||||
}
|
||||
}
|
||||
name_(name), typeclasses_(typeclasses),
|
||||
arguments_(std::move(arguments)), type_(std::move(type)) {}
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -379,13 +381,7 @@ public:
|
|||
|
||||
//
|
||||
|
||||
size_t get_methods_size() const { return methods_.size(); }
|
||||
|
||||
FunctionDefinition *get_method(size_t id) { return &methods_.at(id); }
|
||||
|
||||
const FunctionDefinition *get_method(size_t id) const {
|
||||
return &methods_.at(id);
|
||||
}
|
||||
bool is_typeclass() { return name_.get_type() == Identifier::TYPECLASS; }
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -397,73 +393,9 @@ private:
|
|||
SymbolDocs docs_;
|
||||
bool is_on_heap_;
|
||||
Identifier name_;
|
||||
std::vector<Identifier> typeclasses_;
|
||||
std::vector<Identifier> arguments_;
|
||||
std::optional<VariantType> type_; // TupleType is VariantType with one variant
|
||||
std::unordered_map<std::string, size_t>
|
||||
methods_by_name_; // methods can't be overloaded ??
|
||||
std::vector<FunctionDefinition> methods_;
|
||||
};
|
||||
|
||||
class TypeclassDefinition : public Node {
|
||||
public:
|
||||
TypeclassDefinition(Node node, SymbolDocs &&docs, const Identifier &name,
|
||||
std::vector<Identifier> &&base_typeclasses,
|
||||
std::vector<FunctionDefinition> &&methods)
|
||||
: Node(node), docs_(std::move(docs)), name_(name),
|
||||
base_typeclasses_(std::move(base_typeclasses)),
|
||||
methods_(std::move(methods)) {
|
||||
for (size_t i = 0; i < methods.size(); ++i) {
|
||||
methods_by_name_[*methods_[i].get_name()->get()] = i;
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
SymbolDocs *get_docs() { return &docs_; }
|
||||
|
||||
const SymbolDocs *get_docs() const { return &docs_; }
|
||||
|
||||
//
|
||||
|
||||
Identifier *get_name() { return &name_; }
|
||||
|
||||
const Identifier *get_name() const { return &name_; }
|
||||
|
||||
//
|
||||
|
||||
size_t get_base_typeclasses_size() const { return base_typeclasses_.size(); }
|
||||
|
||||
Identifier *get_base_typeclass(size_t id) {
|
||||
return &base_typeclasses_.at(id);
|
||||
}
|
||||
|
||||
const Identifier *get_base_typeclass(size_t id) const {
|
||||
return &base_typeclasses_.at(id);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
size_t get_methods_size() const { return methods_.size(); }
|
||||
|
||||
FunctionDefinition *get_method(size_t id) { return &methods_.at(id); }
|
||||
|
||||
const FunctionDefinition *get_method(size_t id) const {
|
||||
return &methods_.at(id);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool is_same_to(const TypeclassDefinition &other_typeclass_definition) const;
|
||||
|
||||
CombineResult combine(TypeclassDefinition &&other_typeclass_definition);
|
||||
|
||||
private:
|
||||
SymbolDocs docs_;
|
||||
Identifier name_;
|
||||
std::vector<Identifier> base_typeclasses_;
|
||||
std::unordered_map<std::string, size_t>
|
||||
methods_by_name_; // methods can't be overloaded ??
|
||||
std::vector<FunctionDefinition> methods_;
|
||||
};
|
||||
|
||||
class Statement {
|
||||
|
|
@ -498,8 +430,7 @@ public:
|
|||
CombineResult combine(Statement &&other_statement);
|
||||
|
||||
private:
|
||||
std::variant<Import, TypeDefinition, FunctionDefinition, TypeclassDefinition,
|
||||
EmptyLines>
|
||||
std::variant<Import, TypeDefinition, FunctionDefinition, Extra, EmptyLines>
|
||||
expression_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include "basic_printers.hpp"
|
||||
#include "name_tree.hpp"
|
||||
#include "statement_nodes.hpp"
|
||||
|
||||
#include <vector>
|
||||
|
|
@ -23,7 +22,4 @@ void print_type_definition(const nodes::TypeDefinition &statement,
|
|||
void print_function_definition(const nodes::FunctionDefinition &statement,
|
||||
Printer &printer);
|
||||
|
||||
void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
|
||||
Printer &printer);
|
||||
|
||||
} // namespace printers
|
||||
|
|
|
|||
|
|
@ -14,9 +14,8 @@ enum class Type {
|
|||
|
||||
// --- definitions
|
||||
|
||||
TYPE_DEFINITION,
|
||||
FUNCTION_DEFINITION,
|
||||
TYPECLASS_DEFINITION,
|
||||
TYPE_DEFINITION, // datatype or typeclass
|
||||
|
||||
// --- flow control
|
||||
|
||||
|
|
@ -62,6 +61,8 @@ enum class Type {
|
|||
DEFINITION_INFO,
|
||||
ANNOTATION_INFO,
|
||||
|
||||
EXTRA,
|
||||
|
||||
EMPTY_LINES,
|
||||
|
||||
// --- tokens
|
||||
|
|
@ -100,9 +101,8 @@ const static std::string CONSTRAINT = "constraint";
|
|||
|
||||
// --- definitions
|
||||
|
||||
const static std::string TYPE_DEFINITION = "type_definition";
|
||||
const static std::string FUNCTION_DEFINITION = "function_definition";
|
||||
const static std::string TYPECLASS_DEFINITION = "typeclass_definition";
|
||||
const static std::string TYPE_DEFINITION = "type_definition";
|
||||
|
||||
// --- flow control
|
||||
|
||||
|
|
@ -148,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 EXTRA = "extra";
|
||||
|
||||
const static std::string EMPTY_LINES = "empty_lines";
|
||||
|
||||
// --- tokens
|
||||
|
|
@ -180,12 +182,10 @@ inline Type string_to_type(const std::string &str) {
|
|||
return Type::IMPORT;
|
||||
} else if (str == CONSTRAINT) {
|
||||
return Type::CONSTRAINT;
|
||||
} else if (str == TYPE_DEFINITION) {
|
||||
return Type::TYPE_DEFINITION;
|
||||
} else if (str == FUNCTION_DEFINITION) {
|
||||
return Type::FUNCTION_DEFINITION;
|
||||
} else if (str == TYPECLASS_DEFINITION) {
|
||||
return Type::TYPECLASS_DEFINITION;
|
||||
} else if (str == TYPE_DEFINITION) {
|
||||
return Type::TYPE_DEFINITION;
|
||||
} else if (str == CASE) {
|
||||
return Type::CASE;
|
||||
} else if (str == MATCH) {
|
||||
|
|
@ -232,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 == EXTRA) {
|
||||
return Type::EXTRA;
|
||||
} else if (str == EMPTY_LINES) {
|
||||
return Type::EMPTY_LINES;
|
||||
} else if (str == PLACEHOLDER) {
|
||||
|
|
|
|||
|
|
@ -46,16 +46,36 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
|
|||
return nodes::Modifier::OPTIONAL;
|
||||
} else if (modifier == "!") {
|
||||
return nodes::Modifier::RESULT;
|
||||
} else if (modifier == "->" || modifier == "out") {
|
||||
return nodes::Modifier::OUT;
|
||||
} else if (modifier == "<-" || modifier == "in") {
|
||||
return nodes::Modifier::IN;
|
||||
} else if (modifier == "<>" || modifier == "ref") {
|
||||
return nodes::Modifier::REF;
|
||||
} else if (modifier == "|->" || modifier == "or_out") {
|
||||
return nodes::Modifier::OR_OUT;
|
||||
} else if (modifier == "<-|" || modifier == "or_in") {
|
||||
return nodes::Modifier::OR_IN;
|
||||
} else if (modifier == "--" || modifier == "const") {
|
||||
return nodes::Modifier::CONST;
|
||||
} else if (modifier == "->" || modifier == "out") {
|
||||
return nodes::Modifier::OUT;
|
||||
} else if (modifier == "<-|<>" || modifier == "in|ref") {
|
||||
return nodes::Modifier::IN_OR_REF;
|
||||
} else if (modifier == "<-|--" || modifier == "in|const") {
|
||||
return nodes::Modifier::IN_OR_CONST;
|
||||
} else if (modifier == "<>|->" || modifier == "ref|out") {
|
||||
return nodes::Modifier::REF_OR_OUT;
|
||||
} else if (modifier == "--|->" || modifier == "const|out") {
|
||||
return nodes::Modifier::CONST_OR_OUT;
|
||||
} else if (modifier == "<>|--" || modifier == "ref|const") {
|
||||
return nodes::Modifier::REF_OR_CONST;
|
||||
} else if (modifier == "<-|->" || modifier == "in|out") {
|
||||
return nodes::Modifier::IN_OR_OUT;
|
||||
} else if (modifier == "<-|<>|->" || modifier == "in|ref|out") {
|
||||
return nodes::Modifier::IN_OR_REF_OR_OUT;
|
||||
} else if (modifier == "<-|--|->" || modifier == "in|const|out") {
|
||||
return nodes::Modifier::IN_OR_CONST_OR_OUT;
|
||||
} else if (modifier == "<-|<>|--" || modifier == "in|ref|const") {
|
||||
return nodes::Modifier::IN_OR_REF_OR_CONST;
|
||||
} else if (modifier == "<>|--|->" || modifier == "ref|const|out") {
|
||||
return nodes::Modifier::REF_OR_CONST_OR_OUT;
|
||||
} else if (modifier == "<-|<>|--|->" || modifier == "in|ref|const|out") {
|
||||
return nodes::Modifier::IN_OR_REF_OR_CONST_OR_OUT;
|
||||
} else {
|
||||
return nodes::Modifier::NONE;
|
||||
}
|
||||
|
|
@ -244,11 +264,31 @@ nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) {
|
|||
nodes::Identifier::PLACEHOLDER, "_");
|
||||
}
|
||||
|
||||
// --- extra
|
||||
|
||||
nodes::Extra build_extra(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Extra(build_node(parser_node), parser_node.get_value());
|
||||
}
|
||||
|
||||
// --- empty lines
|
||||
|
||||
nodes::EmptyLines build_empty_lines(parser::ParseTree::Node parser_node) {
|
||||
return nodes::EmptyLines(build_node(parser_node),
|
||||
parser_node.get_value_length() - 1);
|
||||
std::string empty_lines = parser_node.get_value();
|
||||
|
||||
size_t empty_lines_count = 0;
|
||||
|
||||
for (auto &ch : empty_lines) {
|
||||
if (ch == '\n') {
|
||||
++empty_lines_count;
|
||||
}
|
||||
}
|
||||
|
||||
if (empty_lines_count == 0) {
|
||||
error_handling::handle_parsing_error("Empty lines node with zero new lines",
|
||||
parser_node);
|
||||
}
|
||||
|
||||
return nodes::EmptyLines(build_node(parser_node), empty_lines_count - 1);
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -1,29 +1,77 @@
|
|||
#include "basic_printers.hpp"
|
||||
|
||||
#include "error_handling.hpp"
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "basic_nodes.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace printers {
|
||||
|
||||
void print_modifier(const nodes::Modifier &modifier, Printer &printer) {
|
||||
void print_modifier(const nodes::Modifier &modifier, Printer &printer,
|
||||
bool const_is_none) {
|
||||
switch (modifier) {
|
||||
case nodes::Modifier::OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> ");
|
||||
break;
|
||||
case nodes::Modifier::IN:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in " : "<- ");
|
||||
break;
|
||||
case nodes::Modifier::REF:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
|
||||
break;
|
||||
case nodes::Modifier::OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "or_out "
|
||||
: "|-> ");
|
||||
case nodes::Modifier::CONST:
|
||||
if (!const_is_none) {
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
|
||||
}
|
||||
break;
|
||||
case nodes::Modifier::OR_IN:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "or_in " : "<-| ");
|
||||
case nodes::Modifier::OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "out " : "-> ");
|
||||
break;
|
||||
// ---
|
||||
case nodes::Modifier::IN_OR_REF:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|ref "
|
||||
: "<-|<> ");
|
||||
break;
|
||||
case nodes::Modifier::IN_OR_CONST:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|const "
|
||||
: "<-|-- ");
|
||||
break;
|
||||
case nodes::Modifier::REF_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "ref|out "
|
||||
: "<>|-> ");
|
||||
break;
|
||||
case nodes::Modifier::CONST_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "const|out "
|
||||
: "--|-> ");
|
||||
break;
|
||||
case nodes::Modifier::REF_OR_CONST:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "ref|const "
|
||||
: "<>|-- ");
|
||||
break;
|
||||
case nodes::Modifier::IN_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|out "
|
||||
: "<-|-> ");
|
||||
break;
|
||||
// ---
|
||||
case nodes::Modifier::IN_OR_REF_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|out "
|
||||
: "<-|<>|-> ");
|
||||
break;
|
||||
case nodes::Modifier::IN_OR_CONST_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|const|out "
|
||||
: "<-|--|-> ");
|
||||
break;
|
||||
case nodes::Modifier::IN_OR_REF_OR_CONST:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const "
|
||||
: "<-|<>|-- ");
|
||||
break;
|
||||
case nodes::Modifier::REF_OR_CONST_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "ref|const|out "
|
||||
: "<>|--|-> ");
|
||||
break;
|
||||
// ---
|
||||
case nodes::Modifier::IN_OR_REF_OR_CONST_OR_OUT:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "in|ref|const|out "
|
||||
: "<-|<>|--|-> ");
|
||||
break;
|
||||
//
|
||||
case nodes::Modifier::OPTIONAL:
|
||||
printer.print("?");
|
||||
break;
|
||||
|
|
@ -84,8 +132,12 @@ void print_annotation(const std::string &annotation, Printer &printer) {
|
|||
printer.print(annotation);
|
||||
}
|
||||
|
||||
void print_extra(const nodes::Extra &extra, Printer &printer) {
|
||||
printer.print(*extra.content());
|
||||
}
|
||||
|
||||
void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer) {
|
||||
for (size_t i = 0; i < empty_lines.size(); ++i) {
|
||||
for (size_t i = 0; i < empty_lines.line_count(); ++i) {
|
||||
printer.new_indent_line();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -120,6 +120,9 @@ build_expression(parser::ParseTree::Node parser_node,
|
|||
case tokens::Type::NULL_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_null_literal(parser_node), is_scoped));
|
||||
case tokens::Type::EXTRA:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_extra(parser_node), is_scoped));
|
||||
case tokens::Type::EMPTY_LINES:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_empty_lines(parser_node), is_scoped));
|
||||
|
|
|
|||
|
|
@ -71,7 +71,10 @@ void print_expression(const nodes::Expression &expression,
|
|||
print_literal(*expression.get<nodes::Literal>().value(), printer);
|
||||
break;
|
||||
// --- empty lines
|
||||
case 13: // EmptyLines
|
||||
case 13: // Extra
|
||||
print_extra(*expression.get<nodes::Extra>().value(), printer);
|
||||
break;
|
||||
case 14: // EmptyLines
|
||||
print_empty_lines(*expression.get<nodes::EmptyLines>().value(), printer);
|
||||
break;
|
||||
}
|
||||
|
|
@ -212,10 +215,13 @@ void print_container(const nodes::Container &expression,
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < expression.expressions_size(); ++i) {
|
||||
bool is_empty_lines_expression =
|
||||
bool is_empty_lines =
|
||||
expression.get_expression(i)->get<nodes::EmptyLines>().has_value();
|
||||
|
||||
if (!is_array && !is_empty_lines_expression) {
|
||||
bool is_extra =
|
||||
expression.get_expression(i)->get<nodes::Extra>().has_value();
|
||||
|
||||
if (!is_array && !is_empty_lines) {
|
||||
printer.new_indent_line();
|
||||
}
|
||||
print_expression(*expression.get_expression(i), printer);
|
||||
|
|
@ -224,7 +230,7 @@ void print_container(const nodes::Container &expression,
|
|||
printer.space();
|
||||
}
|
||||
} else {
|
||||
if (!is_empty_lines_expression) {
|
||||
if (!is_empty_lines && !is_extra) {
|
||||
printer.print(";");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "name_tree.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
#include "statement_nodes.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace names {
|
||||
|
||||
|
|
@ -88,10 +89,7 @@ void NameTree::add_statement_children_to_tree() {
|
|||
case 2: // TypeDefinition
|
||||
// TODO: link methods + link children to types + connect to typeclasses
|
||||
break;
|
||||
case 3: // TypeclassDefinition
|
||||
// TODO: link methods + connect typeclasses
|
||||
break;
|
||||
case 4: // EmptyLines
|
||||
case 3: // EmptyLines
|
||||
break;
|
||||
default:
|
||||
error_handling::handle_general_error(
|
||||
|
|
|
|||
|
|
@ -27,10 +27,13 @@ build_source_file(parser::ParseTree::Node parser_node,
|
|||
names::NameTree &name_tree) {
|
||||
std::vector<nodes::Statement> statements;
|
||||
|
||||
std::optional<nodes::Identifier> last_defined_type_name;
|
||||
|
||||
auto current_node = parser_node.nth_named_child(0);
|
||||
while (!current_node.is_null()) {
|
||||
statements.push_back(build_statement(current_node, expression_storage,
|
||||
type_storage, name_tree));
|
||||
statements.push_back(build_statement(current_node, last_defined_type_name,
|
||||
expression_storage, type_storage,
|
||||
name_tree));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
|
|
@ -38,10 +41,11 @@ build_source_file(parser::ParseTree::Node parser_node,
|
|||
}
|
||||
|
||||
// import | type_definition | function_definition | typeclass_definition
|
||||
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage,
|
||||
names::NameTree &name_tree) {
|
||||
nodes::Statement
|
||||
build_statement(parser::ParseTree::Node parser_node,
|
||||
std::optional<nodes::Identifier> &last_defined_type_name,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage, names::NameTree &name_tree) {
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
std::optional<std::string> statement_name;
|
||||
|
|
@ -57,8 +61,10 @@ nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
|||
->get();
|
||||
break;
|
||||
case tokens::Type::TYPE_DEFINITION:
|
||||
statement = nodes::Statement(
|
||||
build_type_definition(parser_node, expression_storage, type_storage));
|
||||
statement =
|
||||
nodes::Statement(build_type_definition(parser_node, type_storage));
|
||||
last_defined_type_name =
|
||||
*statement.value().get<nodes::TypeDefinition>().value()->get_name();
|
||||
statement_name = *statement.value()
|
||||
.get<nodes::TypeDefinition>()
|
||||
.value()
|
||||
|
|
@ -67,21 +73,15 @@ nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
|||
break;
|
||||
case tokens::Type::FUNCTION_DEFINITION:
|
||||
statement = nodes::Statement(build_function_definition(
|
||||
parser_node, expression_storage, type_storage));
|
||||
parser_node, last_defined_type_name, expression_storage, type_storage));
|
||||
statement_name = *statement.value()
|
||||
.get<nodes::FunctionDefinition>()
|
||||
.value()
|
||||
->get_name()
|
||||
->get_full_name()
|
||||
->get();
|
||||
break;
|
||||
case tokens::Type::TYPECLASS_DEFINITION:
|
||||
statement = nodes::Statement(build_typeclass_definition(
|
||||
parser_node, expression_storage, type_storage));
|
||||
statement_name = *statement.value()
|
||||
.get<nodes::TypeclassDefinition>()
|
||||
.value()
|
||||
->get_name()
|
||||
->get();
|
||||
case tokens::Type::EXTRA:
|
||||
statement = nodes::Statement(build_extra(parser_node));
|
||||
break;
|
||||
case tokens::Type::EMPTY_LINES:
|
||||
statement = nodes::Statement(build_empty_lines(parser_node));
|
||||
|
|
@ -168,10 +168,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
|
|||
|
||||
// definition_info? annotation_info* '^'? simple_type (argument_type* '='
|
||||
// variant_type)? ('{' function_definition* '}' | ';')
|
||||
nodes::TypeDefinition
|
||||
build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
bool is_on_heap = parser_node.nth_child(0).get_value() == "^";
|
||||
|
||||
std::optional<parser::ParseTree::Node> description_node;
|
||||
|
|
@ -180,14 +178,31 @@ build_type_definition(parser::ParseTree::Node parser_node,
|
|||
auto name_node = collect_symbol_doc_nodes(parser_node.nth_named_child(0),
|
||||
description_node, annotation_nodes);
|
||||
|
||||
nodes::Identifier name = build_identifier(name_node);
|
||||
|
||||
bool is_typeclass = (name.get_type() == nodes::Identifier::TYPECLASS);
|
||||
|
||||
//
|
||||
|
||||
if (is_typeclass && !annotation_nodes.empty()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Typeclass definition can't have annotation documentation",
|
||||
parser_node);
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
std::vector<nodes::Identifier> typeclasses;
|
||||
std::vector<nodes::Identifier> arguments;
|
||||
std::vector<nodes::FunctionDefinition> methods;
|
||||
|
||||
std::optional<parser::ParseTree::Node> type_node;
|
||||
|
||||
auto current_node = name_node.next_named_sibling();
|
||||
while (!current_node.is_null()) {
|
||||
switch (tokens::string_to_type(current_node.get_type())) {
|
||||
case tokens::Type::TYPECLASS_IDENTIFIER:
|
||||
typeclasses.push_back(build_identifier(current_node));
|
||||
break;
|
||||
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
|
||||
arguments.push_back(build_identifier(current_node));
|
||||
break;
|
||||
|
|
@ -198,10 +213,6 @@ build_type_definition(parser::ParseTree::Node parser_node,
|
|||
}
|
||||
type_node = current_node;
|
||||
break;
|
||||
case tokens::Type::FUNCTION_DEFINITION:
|
||||
methods.push_back(build_function_definition(
|
||||
current_node, expression_storage, type_storage));
|
||||
break;
|
||||
default:
|
||||
error_handling::handle_parsing_error(
|
||||
"Unexprected node type in type definition", parser_node);
|
||||
|
|
@ -210,7 +221,21 @@ build_type_definition(parser::ParseTree::Node parser_node,
|
|||
}
|
||||
|
||||
if (!type_node.has_value() && !annotation_nodes.empty()) {
|
||||
error_handling::handle_parsing_error("", parser_node);
|
||||
error_handling::handle_parsing_error(
|
||||
"Type declaration can't contain annotation documentation", parser_node);
|
||||
}
|
||||
|
||||
if (is_typeclass) {
|
||||
if (!arguments.empty()) {
|
||||
error_handling::handle_parsing_error("Typeclass can't have arguments",
|
||||
parser_node);
|
||||
}
|
||||
|
||||
if (type_node.has_value()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Typeclass can't be type (contain constructors / fields)",
|
||||
type_node.value());
|
||||
}
|
||||
}
|
||||
|
||||
std::optional<nodes::VariantType> type =
|
||||
|
|
@ -233,18 +258,19 @@ build_type_definition(parser::ParseTree::Node parser_node,
|
|||
return nodes::TypeDefinition(
|
||||
build_node(parser_node),
|
||||
build_symbol_docs(description_node, annotation_nodes, annotations),
|
||||
is_on_heap, build_identifier(name_node), std::move(arguments),
|
||||
std::move(type), std::move(methods));
|
||||
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments),
|
||||
std::move(type));
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* (constraint ';')* _var_let_? (simple_name
|
||||
// | '(' operator ')') (annotation? _reference_? argument_name '?'?)* (:
|
||||
// (annotation? _reference_ type)+)?
|
||||
// ('=' (block | expression ';') | ';')
|
||||
nodes::FunctionDefinition
|
||||
build_function_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::FunctionDefinition build_function_definition(
|
||||
parser::ParseTree::Node parser_node,
|
||||
const std::optional<nodes::Identifier> &last_defined_type_name,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
|
||||
std::optional<parser::ParseTree::Node> description_node;
|
||||
std::vector<parser::ParseTree::Node> annotation_nodes;
|
||||
|
|
@ -264,17 +290,20 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
|
||||
auto name_node = current_node;
|
||||
|
||||
nodes::FunctionDefinition::MethodModifier method_modifier =
|
||||
nodes::FunctionDefinition::STATIC;
|
||||
bool is_method = false;
|
||||
std::optional<nodes::Identifier> name_prefix;
|
||||
|
||||
current_node = name_node.previous_sibling();
|
||||
if (!current_node.is_null() && !current_node.is_named()) {
|
||||
std::string modifier_str = current_node.get_value();
|
||||
if (modifier_str == "%" || modifier_str == "let") {
|
||||
method_modifier = nodes::FunctionDefinition::LET;
|
||||
} else if (modifier_str == "$" || modifier_str == "var") {
|
||||
method_modifier = nodes::FunctionDefinition::VAR;
|
||||
if (!current_node.is_null() && !current_node.is_named() &&
|
||||
current_node.get_value() == ".") {
|
||||
is_method = true;
|
||||
|
||||
if (!last_defined_type_name.has_value()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Can't define method without associated type", parser_node);
|
||||
}
|
||||
|
||||
name_prefix = last_defined_type_name.value();
|
||||
}
|
||||
|
||||
nodes::Modifier return_modifier = nodes::Modifier::NONE;
|
||||
|
|
@ -412,7 +441,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
return nodes::FunctionDefinition(
|
||||
build_node(parser_node),
|
||||
build_symbol_docs(description_node, annotation_nodes, annotations_set),
|
||||
std::move(constraints), return_modifier, method_modifier,
|
||||
std::move(constraints), return_modifier, is_method, name_prefix,
|
||||
build_identifier(name_node), std::move(arguments),
|
||||
are_annotations_same_to_names,
|
||||
expression_node.has_value()
|
||||
|
|
@ -421,48 +450,4 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
: std::optional<nodes::ExpressionProxy>());
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* typeclass_identifier (':'
|
||||
// typeclass_identifier+)? ('{' function_definition* '}' | ';')
|
||||
nodes::TypeclassDefinition
|
||||
build_typeclass_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
|
||||
std::optional<parser::ParseTree::Node> description_node;
|
||||
std::vector<parser::ParseTree::Node> annotation_nodes;
|
||||
|
||||
auto name_node = collect_symbol_doc_nodes(parser_node.nth_named_child(0),
|
||||
description_node, annotation_nodes);
|
||||
|
||||
if (!annotation_nodes.empty()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Typeclass can't have annotation info nodes", parser_node);
|
||||
}
|
||||
|
||||
std::vector<nodes::Identifier> base_typeclasses;
|
||||
std::vector<nodes::FunctionDefinition> methods;
|
||||
|
||||
auto current_node = name_node.next_named_sibling();
|
||||
while (!current_node.is_null()) {
|
||||
switch (tokens::string_to_type(current_node.get_type())) {
|
||||
case tokens::Type::TYPECLASS_IDENTIFIER:
|
||||
base_typeclasses.push_back(build_identifier(current_node));
|
||||
break;
|
||||
case tokens::Type::FUNCTION_DEFINITION:
|
||||
methods.push_back(build_function_definition(
|
||||
current_node, expression_storage, type_storage));
|
||||
break;
|
||||
default:
|
||||
error_handling::handle_parsing_error(
|
||||
"Unexprected node type in type definition", parser_node);
|
||||
}
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::TypeclassDefinition(
|
||||
build_node(parser_node), build_symbol_docs(description_node),
|
||||
build_identifier(name_node), std::move(base_typeclasses),
|
||||
std::move(methods));
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -25,8 +25,8 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
if (return_modifier_ != other_function_definition.return_modifier_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||
}
|
||||
if (method_modifier_ != other_function_definition.method_modifier_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||
if (is_method_ != other_function_definition.is_method_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ??
|
||||
}
|
||||
|
||||
if (are_annotations_same_to_names_ !=
|
||||
|
|
@ -228,98 +228,6 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
|
|||
type_ = std::move(other_type_definition.type_);
|
||||
}
|
||||
|
||||
// TODO: can be in incorrect state if error occure here
|
||||
// combine methods ??
|
||||
methods_.reserve(methods_.size() + other_type_definition.methods_.size());
|
||||
for (size_t i = 0; i < other_type_definition.methods_.size(); ++i) {
|
||||
auto method_iter = methods_by_name_.find(
|
||||
*other_type_definition.methods_[i].get_name()->get());
|
||||
|
||||
if (method_iter == methods_by_name_.end()) {
|
||||
methods_by_name_[*other_type_definition.methods_[i].get_name()->get()] =
|
||||
methods_.size();
|
||||
methods_.push_back(std::move(other_type_definition.methods_[i]));
|
||||
} else {
|
||||
auto method_combine_result = methods_[method_iter->second].combine(
|
||||
std::move(other_type_definition.methods_[i]));
|
||||
if (method_combine_result != CombineResult::OK) {
|
||||
return method_combine_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CombineResult::OK;
|
||||
}
|
||||
|
||||
bool TypeclassDefinition::is_same_to(
|
||||
const TypeclassDefinition &other_typeclass_definition) const {
|
||||
if (*name_.get() != *other_typeclass_definition.name_.get()) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
CombineResult
|
||||
TypeclassDefinition::combine(TypeclassDefinition &&other_typeclass_definition) {
|
||||
// should be same in all definitions of one typeclass
|
||||
if (*name_.get() != *other_typeclass_definition.name_.get()) {
|
||||
return CombineResult::DIFFERENT_NAME_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should have documentation
|
||||
if (docs_.get_description().has_value() &&
|
||||
other_typeclass_definition.docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
if (docs_.get_annotations_info_size() > 0 &&
|
||||
other_typeclass_definition.docs_.get_annotations_info_size() > 0) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should define base typeclasses
|
||||
if (!base_typeclasses_.empty() &&
|
||||
!other_typeclass_definition.base_typeclasses_.empty()) {
|
||||
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
|
||||
}
|
||||
|
||||
// combine docs
|
||||
// all docs should be in one definition
|
||||
if (other_typeclass_definition.docs_.get_description().has_value() ||
|
||||
other_typeclass_definition.docs_.get_annotations_info_size() > 0) {
|
||||
if (docs_.get_annotations_info_size() > 0 ||
|
||||
docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
docs_ = std::move(other_typeclass_definition.docs_);
|
||||
}
|
||||
|
||||
if (!other_typeclass_definition.base_typeclasses_.empty()) {
|
||||
base_typeclasses_ = std::move(other_typeclass_definition.base_typeclasses_);
|
||||
}
|
||||
|
||||
// TODO: can be in incorrect state if error occure here
|
||||
// combine methods ??
|
||||
methods_.reserve(methods_.size() +
|
||||
other_typeclass_definition.methods_.size());
|
||||
for (size_t i = 0; i < other_typeclass_definition.methods_.size(); ++i) {
|
||||
auto method_iter = methods_by_name_.find(
|
||||
*other_typeclass_definition.methods_[i].get_name()->get());
|
||||
|
||||
if (method_iter == methods_by_name_.end()) {
|
||||
methods_by_name_
|
||||
[*other_typeclass_definition.methods_[i].get_name()->get()] =
|
||||
methods_.size();
|
||||
methods_.push_back(std::move(other_typeclass_definition.methods_[i]));
|
||||
} else {
|
||||
auto method_combine_result = methods_[method_iter->second].combine(
|
||||
std::move(other_typeclass_definition.methods_[i]));
|
||||
if (method_combine_result != CombineResult::OK) {
|
||||
return method_combine_result;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return CombineResult::OK;
|
||||
}
|
||||
|
||||
|
|
@ -339,11 +247,7 @@ bool Statement::is_same_to(const Statement &other_statement) const {
|
|||
return std::get<FunctionDefinition>(expression_)
|
||||
.is_same_to(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
case 3: // TypeclassDefinition
|
||||
return std::get<TypeclassDefinition>(expression_)
|
||||
.is_same_to(std::move(
|
||||
std::get<TypeclassDefinition>(other_statement.expression_)));
|
||||
case 4: // EmptyLines
|
||||
case 3: // EmptyLines
|
||||
return false;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -369,11 +273,7 @@ CombineResult Statement::combine(Statement &&other_statement) {
|
|||
return std::get<FunctionDefinition>(expression_)
|
||||
.combine(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
case 3: // TypeclassDefinition
|
||||
return std::get<TypeclassDefinition>(expression_)
|
||||
.combine(std::move(
|
||||
std::get<TypeclassDefinition>(other_statement.expression_)));
|
||||
case 4: // EmptyLines
|
||||
case 3: // EmptyLines
|
||||
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
|
||||
default:
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "statement_printers.hpp"
|
||||
|
||||
#include "basic_nodes.hpp"
|
||||
#include "basic_printers.hpp"
|
||||
#include "doc_printers.hpp"
|
||||
#include "expression_nodes.hpp"
|
||||
|
|
@ -32,9 +33,8 @@ void print_statement(const nodes::Statement &statement, Printer &printer) {
|
|||
*statement.get<nodes::FunctionDefinition>().value(), printer);
|
||||
printer.new_indent_line();
|
||||
break;
|
||||
case 3: // TypeclassDefinition
|
||||
print_typeclass_definition(
|
||||
*statement.get<nodes::TypeclassDefinition>().value(), printer);
|
||||
case 3: // Extra
|
||||
print_extra(*statement.get<nodes::Extra>().value(), printer);
|
||||
printer.new_indent_line();
|
||||
break;
|
||||
case 4: // EmptyLines
|
||||
|
|
@ -82,28 +82,6 @@ void print_constraint(const nodes::Constraint &statement, Printer &printer) {
|
|||
printer.print(";");
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
void print_statement_methods(const T &statement, Printer &printer) {
|
||||
if (statement.get_methods_size() > 0) {
|
||||
printer.print(" {");
|
||||
printer.indent();
|
||||
|
||||
for (size_t i = 0; i < statement.get_methods_size(); ++i) {
|
||||
printer.new_indent_line();
|
||||
print_function_definition(*statement.get_method(i), printer);
|
||||
if (i + 1 < statement.get_methods_size()) {
|
||||
printer.new_indent_line();
|
||||
}
|
||||
}
|
||||
|
||||
printer.deindent();
|
||||
printer.new_indent_line();
|
||||
printer.print("}");
|
||||
} else {
|
||||
printer.print(";");
|
||||
}
|
||||
}
|
||||
|
||||
void print_type_definition(const nodes::TypeDefinition &statement,
|
||||
Printer &printer) {
|
||||
print_docs(*statement.get_docs(), printer);
|
||||
|
|
@ -130,10 +108,10 @@ void print_type_definition(const nodes::TypeDefinition &statement,
|
|||
|
||||
printer.set_indentation_level(previous_indentation_level);
|
||||
}
|
||||
|
||||
print_statement_methods(statement, printer);
|
||||
printer.print(";");
|
||||
} // IN PROGRESS
|
||||
|
||||
// TODO: do not print prefix type for names
|
||||
void print_function_definition(const nodes::FunctionDefinition &statement,
|
||||
Printer &printer) {
|
||||
print_docs(*statement.get_docs(), printer);
|
||||
|
|
@ -143,17 +121,8 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
|||
printer.new_indent_line();
|
||||
}
|
||||
|
||||
switch (statement.get_method_modifier()) {
|
||||
case nodes::FunctionDefinition::STATIC:
|
||||
break;
|
||||
case nodes::FunctionDefinition::LET:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "let " : "%");
|
||||
break;
|
||||
case nodes::FunctionDefinition::VAR:
|
||||
printer.print(printer.print_words_instead_of_symbols() ? "var " : "$");
|
||||
break;
|
||||
default: // remove ??
|
||||
break;
|
||||
if (statement.is_method()) {
|
||||
printer.print(".");
|
||||
}
|
||||
|
||||
bool identifier_is_operator =
|
||||
|
|
@ -169,7 +138,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
|||
printer.print(" )");
|
||||
}
|
||||
|
||||
print_modifier(statement.get_return_modifier(), printer);
|
||||
print_modifier(statement.get_return_modifier(), printer); // ! or ?
|
||||
|
||||
for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
|
||||
if (!statement.get_argument(i)->get_name().has_value()) {
|
||||
|
|
@ -189,7 +158,8 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
|||
printer.space();
|
||||
}
|
||||
|
||||
print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
|
||||
print_modifier(statement.get_argument(i)->get_before_modifier(), printer,
|
||||
true);
|
||||
}
|
||||
|
||||
print_identifier(*statement.get_argument(i)->get_name().value(), printer);
|
||||
|
|
@ -214,19 +184,26 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
|||
printer.space();
|
||||
}
|
||||
|
||||
print_modifier(statement.get_argument(i)->get_before_modifier(), printer);
|
||||
print_modifier(statement.get_argument(i)->get_before_modifier(), printer,
|
||||
true);
|
||||
|
||||
print_type(*statement.get_argument(i)->get_type().value(), printer);
|
||||
}
|
||||
}
|
||||
|
||||
if (statement.get_expression().has_value()) {
|
||||
bool expression_is_container =
|
||||
statement.get_expression().value()->get<nodes::Container>().has_value();
|
||||
|
||||
printer.print(" = ");
|
||||
|
||||
size_t previous_indentation_level = printer.get_indentation_level();
|
||||
if (!expression_is_container) {
|
||||
printer.set_indentation_level(printer.current_position());
|
||||
}
|
||||
print_expression(*statement.get_expression().value(), printer);
|
||||
if (!statement.get_expression()
|
||||
.value()
|
||||
->get<nodes::Container>()
|
||||
.has_value()) {
|
||||
if (!expression_is_container) {
|
||||
printer.set_indentation_level(previous_indentation_level);
|
||||
printer.print(";");
|
||||
}
|
||||
} else {
|
||||
|
|
@ -234,21 +211,4 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
|||
}
|
||||
} // IN PROGRESS
|
||||
|
||||
void print_typeclass_definition(const nodes::TypeclassDefinition &statement,
|
||||
Printer &printer) {
|
||||
print_docs(*statement.get_docs(), printer);
|
||||
|
||||
print_identifier(*statement.get_name(), printer);
|
||||
|
||||
if (statement.get_base_typeclasses_size() > 0) {
|
||||
printer.print(" :");
|
||||
for (size_t i = 0; i < statement.get_base_typeclasses_size(); ++i) {
|
||||
printer.space();
|
||||
print_identifier(*statement.get_base_typeclass(i), printer);
|
||||
}
|
||||
}
|
||||
|
||||
print_statement_methods(statement, printer);
|
||||
} // IN PROGRESS
|
||||
|
||||
} // namespace printers
|
||||
|
|
|
|||
|
|
@ -151,15 +151,16 @@ bubble_sort_2 'arr : ref Array['A] = {
|
|||
& @key Key
|
||||
& @value Value
|
||||
& @left ^TreeNode['Key 'Value]
|
||||
& @right ^TreeNode['Key 'Value] {
|
||||
new = do_something; // static methods
|
||||
& @right ^TreeNode['Key 'Value];
|
||||
|
||||
$insert 'key = do_something; // const methods
|
||||
.new = do_something; // static methods
|
||||
|
||||
%find 'key = do_something;
|
||||
.insert <> 'this 'key = do_something; // const methods
|
||||
|
||||
.find 'this 'key = do_something;
|
||||
|
||||
.delete <> 'this 'key = do_something; // var methods
|
||||
|
||||
$delete 'key = do_something; // var methods
|
||||
}
|
||||
|
||||
generic_type_name_expressions = {
|
||||
$x := TreeNode[Int Int].new;
|
||||
|
|
@ -199,9 +200,8 @@ move_construct_task 'name 'duration : <- String <- Float -> Task = Task @name 'n
|
|||
arg_deduction_example 'name 'duration : <- String <- Float -> Task = Task 'name 'duration;
|
||||
|
||||
: ord is fundamental typeclass
|
||||
#Ord : #Eq {
|
||||
$is_less_then : Ord -> Bool;
|
||||
}
|
||||
#Ord[#Eq];
|
||||
.is_less_then : Ord -> Bool;
|
||||
|
||||
: function, that takes result argument
|
||||
result_example 'a! = 'a =: _? => print "value inside"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue