mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
statement builders finished
This commit is contained in:
parent
64a91299ff
commit
4470454838
19 changed files with 682 additions and 255 deletions
|
|
@ -12,8 +12,13 @@ include_directories(include
|
|||
|
||||
|
||||
add_executable(lang src/main.cpp
|
||||
src/type_nodes.cpp
|
||||
src/expression_nodes.cpp
|
||||
src/basic_builders.cpp
|
||||
src/type_builders.cpp
|
||||
src/expression_builders.cpp
|
||||
src/statement_builders.cpp
|
||||
include/tree_sitter_wrapper.hpp
|
||||
include/name_tree.hpp
|
||||
deps/tree-sitter-lang/src/tree_sitter/parser.h
|
||||
deps/tree-sitter-lang/src/parser.c
|
||||
deps/tree-sitter/lib/src/lib.c)
|
||||
|
|
|
|||
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
|||
Subproject commit df305457c82a7a9d6e9791ae12a75c7cd16fe663
|
||||
Subproject commit 4a553f24fbd468755c103d64e1c3090dd4c2c7e0
|
||||
|
|
@ -5,6 +5,9 @@
|
|||
|
||||
namespace builders {
|
||||
|
||||
// returns Modifier::NONE for incorrecnt input
|
||||
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Node build_node(parser::ParseTree::Node parser_node);
|
||||
|
||||
// --- literals
|
||||
|
|
@ -25,6 +28,8 @@ nodes::Literal build_null_literal(parser::ParseTree::Node parser_node);
|
|||
|
||||
// --- identifiers
|
||||
|
||||
nodes::Identifier build_identifier(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Identifier build_simple_type(parser::ParseTree::Node parser_node);
|
||||
|
|
|
|||
|
|
@ -7,7 +7,14 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
enum class ReferenceType { REF, IN, OUT, NONE };
|
||||
enum class Modifier {
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
OR_FALSE, // x?
|
||||
OR_PANIC, // x!
|
||||
NONE,
|
||||
};
|
||||
|
||||
class Node {
|
||||
public:
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@
|
|||
namespace builders {
|
||||
|
||||
nodes::SymbolDocs build_symbol_docs(
|
||||
parser::ParseTree::Node description_parser_node,
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes,
|
||||
const std::unordered_set<std::string> &annotations);
|
||||
std::optional<parser::ParseTree::Node> description_parser_node,
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes = {},
|
||||
const std::unordered_set<std::string> &annotations = {});
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -8,6 +8,8 @@ namespace nodes {
|
|||
|
||||
class SymbolDocs {
|
||||
public:
|
||||
SymbolDocs() {}
|
||||
|
||||
SymbolDocs(std::string &&description)
|
||||
: description_(std::move(description)) {}
|
||||
|
||||
|
|
@ -22,9 +24,19 @@ public:
|
|||
return false;
|
||||
}
|
||||
|
||||
std::string *get_description() { return &description_; }
|
||||
std::optional<std::string *> get_description() {
|
||||
if (description_.has_value()) {
|
||||
return &description_.value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
const std::string *get_description() const { return &description_; }
|
||||
std::optional<const std::string *> get_description() const {
|
||||
if (description_.has_value()) {
|
||||
return &description_.value();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<std::string *>
|
||||
get_annotation_info(const std::string &annotation) {
|
||||
|
|
@ -45,7 +57,7 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
std::string description_;
|
||||
std::optional<std::string> description_;
|
||||
std::unordered_map<std::string, std::string> annotations_info_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
#pragma once
|
||||
|
||||
#include "basic_nodes.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
|
||||
#include <iostream>
|
||||
|
||||
namespace error_handling {
|
||||
|
|
|
|||
|
|
@ -8,85 +8,86 @@ namespace builders {
|
|||
// --- flow control
|
||||
|
||||
nodes::ExpressionProxy
|
||||
build_expression(parser::ParseTree::Node parse_node,
|
||||
build_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Match build_match(parser::ParseTree::Node parse_node,
|
||||
nodes::Match build_match(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parse_node,
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parse_node,
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
// --- operators
|
||||
|
||||
nodes::NameExpression
|
||||
build_comma_expression(parser::ParseTree::Node parse_node,
|
||||
build_comma_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::NameExpression
|
||||
build_operator_expression(parser::ParseTree::Node parse_node,
|
||||
build_operator_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
// --- continers
|
||||
|
||||
nodes::Container build_block(parser::ParseTree::Node parse_node,
|
||||
nodes::Container build_block(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Container build_array(parser::ParseTree::Node parse_node,
|
||||
nodes::Container build_array(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
// --- modifiers
|
||||
|
||||
nodes::Return build_return(parser::ParseTree::Node parse_node,
|
||||
nodes::Return build_return(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::NameDefinition build_name_definition(parser::ParseTree::Node parse_node);
|
||||
nodes::NameDefinition
|
||||
build_name_definition(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parse_node,
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parse_node,
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parse_node);
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_reference_expression(parser::ParseTree::Node parse_node,
|
||||
build_reference_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_suffix_expression(parser::ParseTree::Node parse_node,
|
||||
build_suffix_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
// --- other
|
||||
|
||||
nodes::NameExpression
|
||||
build_name_expression(parser::ParseTree::Node parse_node,
|
||||
build_name_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Constructor
|
||||
build_constructor(parser::ParseTree::Node parse_node,
|
||||
build_constructor(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parse_node,
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
|
|
|
|||
|
|
@ -344,14 +344,6 @@ private:
|
|||
|
||||
class ModifierExpression : public Node {
|
||||
public:
|
||||
enum Modifier {
|
||||
OUT, // -> x
|
||||
IN, // <- x
|
||||
REF, // <> x
|
||||
OR_FALSE, // x?
|
||||
OR_PANIC, // x!
|
||||
};
|
||||
|
||||
ModifierExpression(Node node, Modifier modifier, ExpressionProxy expression)
|
||||
: Node(node), modifier_(modifier), expression_(expression) {}
|
||||
|
||||
|
|
@ -372,15 +364,16 @@ private:
|
|||
class NameExpression : public Node {
|
||||
public:
|
||||
template <typename T>
|
||||
NameExpression(Node node, T &&name)
|
||||
NameExpression(Node node, Identifier &&name)
|
||||
: Node(node), name_(std::forward<T>(name)) {}
|
||||
|
||||
template <typename T, typename U, typename V>
|
||||
NameExpression(Node node, T &&name, U &&arguments, V &&prefix,
|
||||
bool is_point_call = false)
|
||||
: Node(node), name_(std::forward<T>(name)),
|
||||
arguments_(std::forward<U>(arguments)),
|
||||
prefix_(std::forward<V>(prefix)), is_point_call_(is_point_call) {}
|
||||
NameExpression(
|
||||
Node node, Identifier &&name,
|
||||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>>
|
||||
&&arguments,
|
||||
std::optional<const Type> &&prefix, bool is_point_call = false)
|
||||
: Node(node), name_(std::move(name)), arguments_(std::move(arguments)),
|
||||
prefix_(std::move(prefix)), is_point_call_(is_point_call) {}
|
||||
|
||||
std::string *get_name() { return name_.get(); }
|
||||
|
||||
|
|
@ -436,12 +429,6 @@ private:
|
|||
bool is_point_call_ = false; // x.f ... or f x ...
|
||||
};
|
||||
|
||||
// explicit instantiation
|
||||
template NameExpression::NameExpression(
|
||||
Node, Identifier &&,
|
||||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>> &&,
|
||||
std::optional<const Type> &&, bool);
|
||||
|
||||
class Constructor : public Node {
|
||||
public:
|
||||
Constructor(
|
||||
|
|
|
|||
|
|
@ -6,35 +6,33 @@
|
|||
namespace builders {
|
||||
|
||||
// IN PROGRESS: return type, etc.
|
||||
void build_source_file(parser::ParseTree::Node parse_node,
|
||||
void build_source_file(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
// IN PROGRESS: return type, etc.
|
||||
void build_statement(parser::ParseTree::Node parse_node,
|
||||
void build_statement(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::Import build_import(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
nodes::Import build_import(parser::ParseTree::Node parser_node);
|
||||
|
||||
nodes::Constraint build_constraint(parser::ParseTree::Node parse_node,
|
||||
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 parse_node,
|
||||
build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::FunctionDefinition
|
||||
build_function_definition(parser::ParseTree::Node parse_node,
|
||||
build_function_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeclassDefinition
|
||||
build_typeclass_definition(parser::ParseTree::Node parse_node,
|
||||
build_typeclass_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
|
|
|
|||
|
|
@ -57,25 +57,27 @@ public:
|
|||
FunctionDefinition(Node node, SymbolDocs &&docs,
|
||||
std::vector<Constraint> &&constraints,
|
||||
ModifierType modifier, const Identifier &name,
|
||||
std::vector<std::string> &&annotations,
|
||||
std::vector<std::optional<std::string>> &&annotations,
|
||||
std::vector<Identifier> &&arguments,
|
||||
std::vector<ReferenceType> &&reference_types,
|
||||
std::vector<TypeProxy> &&types)
|
||||
std::vector<Modifier> &&reference_types,
|
||||
std::vector<std::optional<TypeProxy>> &&types,
|
||||
std::optional<ExpressionProxy> expression)
|
||||
: Node(node), docs_(std::move(docs)),
|
||||
constraints_(std::move(constraints)), modifier_(modifier), name_(name),
|
||||
annotations_(std::move(annotations)), arguments_(std::move(arguments)),
|
||||
reference_types_(std::move(reference_types)), types_(std::move(types)) {
|
||||
}
|
||||
reference_types_(std::move(reference_types)), types_(std::move(types)),
|
||||
expression_(expression) {}
|
||||
|
||||
private:
|
||||
SymbolDocs docs_;
|
||||
std::vector<Constraint> constraints_;
|
||||
ModifierType modifier_;
|
||||
Identifier name_;
|
||||
std::vector<std::string> annotations_;
|
||||
std::vector<std::optional<std::string>> annotations_;
|
||||
std::vector<Identifier> arguments_;
|
||||
std::vector<ReferenceType> reference_types_;
|
||||
std::vector<TypeProxy> types_;
|
||||
std::vector<Modifier> reference_types_;
|
||||
std::vector<std::optional<TypeProxy>> types_;
|
||||
std::optional<ExpressionProxy> expression_;
|
||||
// std::vector<bool> optional_arguments_; // ??
|
||||
}; // IN PROGRESS
|
||||
|
||||
|
|
@ -83,7 +85,8 @@ class TypeDefinition : public Node {
|
|||
public:
|
||||
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
|
||||
const Identifier &name, std::vector<Identifier> &&arguments,
|
||||
VariantType &&type, std::vector<FunctionDefinition> &&methods)
|
||||
std::optional<VariantType> &&type,
|
||||
std::vector<FunctionDefinition> &&methods)
|
||||
: 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)) {}
|
||||
|
|
@ -93,7 +96,7 @@ private:
|
|||
bool is_on_heap_;
|
||||
Identifier name_;
|
||||
std::vector<Identifier> arguments_;
|
||||
VariantType type_; // TupleType is VariantType with one variant
|
||||
std::optional<VariantType> type_; // TupleType is VariantType with one variant
|
||||
std::vector<FunctionDefinition> methods_;
|
||||
}; // IN PROGRESS
|
||||
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ public:
|
|||
fields_.reserve(fields.size());
|
||||
for (auto &field : fields) {
|
||||
if (field.first.has_value()) {
|
||||
annotation_ids_[field.first.value()] = fields_.size();
|
||||
annotation_fields_[field.first.value()] = fields_.size();
|
||||
}
|
||||
fields_.push_back(field.second);
|
||||
}
|
||||
|
|
@ -124,15 +124,26 @@ public:
|
|||
const Type *get(size_t id) const { return fields_.at(id).get(); }
|
||||
|
||||
Type *get(const std::string &annotation) {
|
||||
return fields_.at(annotation_ids_.at(annotation)).get();
|
||||
return fields_.at(annotation_fields_.at(annotation)).get();
|
||||
}
|
||||
|
||||
const Type *get(const std::string &annotation) const {
|
||||
return fields_.at(annotation_ids_.at(annotation)).get();
|
||||
return fields_.at(annotation_fields_.at(annotation)).get();
|
||||
}
|
||||
|
||||
std::vector<std::string> get_all_annotations() {
|
||||
std::vector<std::string> annotations;
|
||||
|
||||
annotations.reserve(annotation_fields_.size());
|
||||
for (auto &annotation_with_field : annotation_fields_) {
|
||||
annotations.push_back(annotation_with_field.first);
|
||||
}
|
||||
|
||||
return annotations;
|
||||
}
|
||||
|
||||
private:
|
||||
std::unordered_map<std::string, size_t> annotation_ids_; // Annotations
|
||||
std::unordered_map<std::string, size_t> annotation_fields_;
|
||||
std::vector<TypeProxy> fields_;
|
||||
};
|
||||
|
||||
|
|
|
|||
BIN
src/.type_nodes.cpp.kate-swp
Normal file
BIN
src/.type_nodes.cpp.kate-swp
Normal file
Binary file not shown.
|
|
@ -1,6 +1,9 @@
|
|||
#include "../include/basic_builders.hpp"
|
||||
#include "basic_builders.hpp"
|
||||
|
||||
#include "basic_nodes.hpp"
|
||||
#include "error_handling.hpp"
|
||||
#include "tokens.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
|
|
@ -32,6 +35,23 @@ std::optional<char> to_escape_symbol(char symbol) {
|
|||
|
||||
} // namespace utils
|
||||
|
||||
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
|
||||
std::string modifier = parser_node.get_value();
|
||||
|
||||
if (modifier == "?") {
|
||||
return nodes::Modifier::OR_FALSE;
|
||||
} else if (modifier == "!") {
|
||||
return nodes::Modifier::OR_PANIC;
|
||||
} 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;
|
||||
}
|
||||
return nodes::Modifier::NONE;
|
||||
}
|
||||
|
||||
nodes::Node build_node(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Node(parser_node.get_start_point(),
|
||||
parser_node.get_end_point());
|
||||
|
|
@ -125,6 +145,33 @@ nodes::Literal build_null_literal(parser::ParseTree::Node parser_node) {
|
|||
|
||||
// --- identifiers
|
||||
|
||||
nodes::Identifier build_identifier(parser::ParseTree::Node parser_node) {
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
switch (type) {
|
||||
case tokens::Type::PLACEHOLDER:
|
||||
return build_placeholder(parser_node);
|
||||
case tokens::Type::SIMPLE_NAME_IDENTIFIER:
|
||||
return build_simple_name(parser_node);
|
||||
case tokens::Type::SIMPLE_TYPE_IDENTIFIER:
|
||||
return build_simple_type(parser_node);
|
||||
case tokens::Type::TYPECLASS_IDENTIFIER:
|
||||
return build_typeclass(parser_node);
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
return build_argument_name(parser_node);
|
||||
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
|
||||
return build_argument_type(parser_node);
|
||||
// used as string
|
||||
// case tokens::Type::ANNOTATION_IDENTIFIER:
|
||||
// return build_annotation(parser_node);
|
||||
default:
|
||||
error_handling::handle_parsing_error("Unexprected identifier node type",
|
||||
parser_node);
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
nodes::Identifier build_simple_name(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::SIMPLE_NAME,
|
||||
|
|
|
|||
|
|
@ -1,30 +1,38 @@
|
|||
#include "../include/doc_builders.hpp"
|
||||
#include "doc_builders.hpp"
|
||||
#include "basic_builders.hpp"
|
||||
#include "doc_nodes.hpp"
|
||||
#include "error_handling.hpp"
|
||||
|
||||
namespace builders {
|
||||
|
||||
// TODO: check, that all annotations are exist in function definition
|
||||
nodes::SymbolDocs build_symbol_docs(
|
||||
parser::ParseTree::Node description_parser_node,
|
||||
std::optional<parser::ParseTree::Node> description_parser_node,
|
||||
const std::vector<parser::ParseTree::Node> &annotation_parser_nodes,
|
||||
const std::unordered_set<std::string> &annotations) {
|
||||
std::string description = description_parser_node.get_value();
|
||||
|
||||
// remove newline delimeters (": " at each new line
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < description.size(); ++i, ++j) {
|
||||
if (j != i) {
|
||||
description[j] = description[i];
|
||||
}
|
||||
std::optional<std::string> description;
|
||||
|
||||
if (description[i] == '\n') {
|
||||
i += 2;
|
||||
if (description_parser_node.has_value()) {
|
||||
description = description_parser_node.value().get_value();
|
||||
|
||||
// remove newline delimeters (": " at each new line
|
||||
size_t j = 0;
|
||||
for (size_t i = 0; i < description.value().size(); ++i, ++j) {
|
||||
if (j != i) {
|
||||
description.value()[j] = description.value()[i];
|
||||
}
|
||||
|
||||
if (description.value()[i] == '\n') {
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
description.value().resize(j);
|
||||
}
|
||||
description.resize(j);
|
||||
|
||||
nodes::SymbolDocs docs(description);
|
||||
nodes::SymbolDocs docs = description.has_value()
|
||||
? nodes::SymbolDocs(description.value())
|
||||
: nodes::SymbolDocs();
|
||||
|
||||
for (auto &annotation_parser_node : annotation_parser_nodes) {
|
||||
std::string annotation =
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "../include/expression_builders.hpp"
|
||||
#include "expression_builders.hpp"
|
||||
|
||||
#include "basic_builders.hpp"
|
||||
#include "basic_nodes.hpp"
|
||||
|
|
@ -11,103 +11,101 @@
|
|||
namespace builders {
|
||||
|
||||
nodes::ExpressionProxy
|
||||
build_expression(parser::ParseTree::Node parse_node,
|
||||
build_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
tokens::Type type = tokens::string_to_type(parse_node.get_type());
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
switch (type) {
|
||||
// --- flow control
|
||||
case tokens::Type::MATCH:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_match(parse_node, expression_storage, type_storage)));
|
||||
build_match(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::CONDITION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_condition(parse_node, expression_storage, type_storage)));
|
||||
build_condition(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::LOOP:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_loop(parse_node, expression_storage, type_storage)));
|
||||
build_loop(parser_node, expression_storage, type_storage)));
|
||||
// --- operators
|
||||
case tokens::Type::COMMA_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_comma_expression(parse_node, expression_storage, type_storage)));
|
||||
build_comma_expression(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::OPERATOR_EXPRESSION:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_operator_expression(
|
||||
parse_node, expression_storage, type_storage)));
|
||||
parser_node, expression_storage, type_storage)));
|
||||
// --- containers
|
||||
case tokens::Type::BLOCK:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_block(parse_node, expression_storage, type_storage)));
|
||||
build_block(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::ARRAY:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_array(parse_node, expression_storage, type_storage)));
|
||||
build_array(parser_node, expression_storage, type_storage)));
|
||||
// --- modifiers
|
||||
case tokens::Type::RETURN:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_return(parse_node, expression_storage, type_storage)));
|
||||
build_return(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::NAME_DEFINITION:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_name_definition(parse_node)));
|
||||
nodes::Expression(build_name_definition(parser_node)));
|
||||
case tokens::Type::ARRAY_ACCESS:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_array_access(parse_node, expression_storage, type_storage)));
|
||||
build_array_access(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::TUPLE_ACCESS:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_tuple_access(parse_node, expression_storage, type_storage)));
|
||||
build_tuple_access(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::LOOP_CONTROL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_loop_control(parse_node)));
|
||||
nodes::Expression(build_loop_control(parser_node)));
|
||||
case tokens::Type::REFERENCE_EXPRESSION:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_reference_expression(
|
||||
parse_node, expression_storage, type_storage)));
|
||||
parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::SUFFIX_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_suffix_expression(parse_node, expression_storage, type_storage)));
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_suffix_expression(
|
||||
parser_node, expression_storage, type_storage)));
|
||||
// --- other
|
||||
case tokens::Type::NAME_EXPRESSION:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_name_expression(parse_node, expression_storage, type_storage)));
|
||||
build_name_expression(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(nodes::NameExpression(
|
||||
build_node(parse_node), build_argument_name(parse_node))));
|
||||
case tokens::Type::SIMPLE_NAME_IDENTIFIER:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(nodes::NameExpression(
|
||||
build_node(parse_node), build_simple_name(parse_node))));
|
||||
build_node(parser_node), build_identifier(parser_node))));
|
||||
case tokens::Type::CONSTRUCTOR:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_constructor(parse_node, expression_storage, type_storage)));
|
||||
build_constructor(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::LAMBDA:
|
||||
return expression_storage.add_expression(nodes::Expression(
|
||||
build_lambda(parse_node, expression_storage, type_storage)));
|
||||
build_lambda(parser_node, expression_storage, type_storage)));
|
||||
// --- literals
|
||||
case tokens::Type::FLOAT_NUMBER_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_float_number_literal(parse_node)));
|
||||
nodes::Expression(build_float_number_literal(parser_node)));
|
||||
case tokens::Type::NUMBER_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_number_literal(parse_node)));
|
||||
nodes::Expression(build_number_literal(parser_node)));
|
||||
case tokens::Type::STRING_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_string_literal(parse_node)));
|
||||
nodes::Expression(build_string_literal(parser_node)));
|
||||
case tokens::Type::CHAR_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_char_literal(parse_node)));
|
||||
nodes::Expression(build_char_literal(parser_node)));
|
||||
case tokens::Type::BOOL_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_bool_literal(parse_node)));
|
||||
nodes::Expression(build_bool_literal(parser_node)));
|
||||
case tokens::Type::UNIT_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_unit_literal(parse_node)));
|
||||
nodes::Expression(build_unit_literal(parser_node)));
|
||||
case tokens::Type::NULL_LITERAL:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(build_null_literal(parse_node)));
|
||||
nodes::Expression(build_null_literal(parser_node)));
|
||||
default:
|
||||
error_handling::handle_parsing_error("Unexprected expression node type",
|
||||
parse_node);
|
||||
parser_node);
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable
|
||||
|
|
@ -116,18 +114,18 @@ build_expression(parser::ParseTree::Node parse_node,
|
|||
// --- flow control
|
||||
|
||||
// (':=' | '=:') expression (('??' | 'if') expression)? (_do_ expression)?
|
||||
nodes::Match::Case build_case(parser::ParseTree::Node parse_node,
|
||||
nodes::Match::Case build_case(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::string case_type = parse_node.nth_child(0).get_value();
|
||||
std::string case_type = parser_node.nth_child(0).get_value();
|
||||
|
||||
std::optional<parser::ParseTree::Node> condition_node;
|
||||
std::optional<parser::ParseTree::Node> expression_node;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(1);
|
||||
auto current_node = parser_node.nth_named_child(1);
|
||||
|
||||
if (!current_node.is_null()) {
|
||||
if (parse_node.child_by_field_name("condition").is_null()) {
|
||||
if (parser_node.child_by_field_name("condition").is_null()) {
|
||||
expression_node = current_node;
|
||||
} else {
|
||||
condition_node = current_node;
|
||||
|
|
@ -139,10 +137,10 @@ nodes::Match::Case build_case(parser::ParseTree::Node parse_node,
|
|||
}
|
||||
|
||||
return nodes::Match::Case(
|
||||
build_node(parse_node),
|
||||
build_node(parser_node),
|
||||
case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE
|
||||
: nodes::Match::Case::VALUE_PATTERN,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage,
|
||||
build_expression(parser_node.nth_named_child(0), expression_storage,
|
||||
type_storage),
|
||||
condition_node.has_value()
|
||||
? build_expression(condition_node.value(), expression_storage,
|
||||
|
|
@ -155,33 +153,33 @@ nodes::Match::Case build_case(parser::ParseTree::Node parse_node,
|
|||
}
|
||||
|
||||
// expression case+
|
||||
nodes::Match build_match(parser::ParseTree::Node parse_node,
|
||||
nodes::Match build_match(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::Match::Case> cases;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(1);
|
||||
auto current_node = parser_node.nth_named_child(1);
|
||||
while (!current_node.is_null()) {
|
||||
cases.push_back(build_case(current_node, expression_storage, type_storage));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Match(build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
return nodes::Match(build_node(parser_node),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage),
|
||||
std::move(cases));
|
||||
}
|
||||
|
||||
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
|
||||
// expression)* (('!!=>', 'else') expression)?
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parse_node,
|
||||
nodes::Condition build_condition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
size_t named_child_count = parse_node.named_child_count();
|
||||
size_t named_child_count = parser_node.named_child_count();
|
||||
|
||||
std::vector<std::pair<nodes::ExpressionProxy, nodes::ExpressionProxy>> cases;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(0);
|
||||
auto current_node = parser_node.nth_named_child(0);
|
||||
auto next_node = current_node.next_named_sibling();
|
||||
|
||||
while (!current_node.is_null() && !next_node.is_null()) {
|
||||
|
|
@ -196,40 +194,40 @@ nodes::Condition build_condition(parser::ParseTree::Node parse_node,
|
|||
}
|
||||
|
||||
return nodes::Condition(
|
||||
build_node(parse_node), std::move(cases),
|
||||
build_node(parser_node), std::move(cases),
|
||||
named_child_count % 2 == 1
|
||||
? build_expression(parse_node.nth_named_child(named_child_count - 1),
|
||||
? build_expression(parser_node.nth_named_child(named_child_count - 1),
|
||||
expression_storage, type_storage)
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
}
|
||||
|
||||
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parse_node,
|
||||
nodes::Loop build_loop(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
size_t named_child_count = parse_node.named_child_count();
|
||||
size_t named_child_count = parser_node.named_child_count();
|
||||
|
||||
if (named_child_count == 1) { // body
|
||||
return nodes::Loop(build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage));
|
||||
} else if (named_child_count == 2) { // condition, body
|
||||
return nodes::Loop(build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage),
|
||||
build_expression(parse_node.nth_named_child(1),
|
||||
build_expression(parser_node.nth_named_child(1),
|
||||
expression_storage, type_storage));
|
||||
} else if (named_child_count == 3) { // variable, interval, body
|
||||
return nodes::Loop(build_node(parse_node),
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage),
|
||||
build_expression(parse_node.nth_named_child(1),
|
||||
build_expression(parser_node.nth_named_child(1),
|
||||
expression_storage, type_storage),
|
||||
build_expression(parse_node.nth_named_child(2),
|
||||
build_expression(parser_node.nth_named_child(2),
|
||||
expression_storage, type_storage));
|
||||
} else {
|
||||
error_handling::handle_parsing_error(
|
||||
"Unexprected named expression amount in loop", parse_node);
|
||||
"Unexprected named expression amount in loop", parser_node);
|
||||
}
|
||||
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
|
|
@ -240,34 +238,34 @@ nodes::Loop build_loop(parser::ParseTree::Node parse_node,
|
|||
|
||||
// expression ',' expression
|
||||
nodes::NameExpression
|
||||
build_comma_expression(parser::ParseTree::Node parse_node,
|
||||
build_comma_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
arguments.emplace_back(std::nullopt,
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage));
|
||||
|
||||
arguments.emplace_back(std::nullopt,
|
||||
build_expression(parse_node.nth_named_child(1),
|
||||
build_expression(parser_node.nth_named_child(1),
|
||||
expression_storage, type_storage));
|
||||
|
||||
return nodes::NameExpression(
|
||||
build_node(parse_node),
|
||||
build_node(parser_node),
|
||||
nodes::Identifier(
|
||||
build_node(parse_node), // can't find more precise location'
|
||||
build_node(parser_node), // can't find more precise location'
|
||||
nodes::Identifier::SIMPLE_NAME, ","),
|
||||
std::move(arguments), std::nullopt, false);
|
||||
}
|
||||
|
||||
// expression operator expression
|
||||
nodes::NameExpression
|
||||
build_operator_expression(parser::ParseTree::Node parse_node,
|
||||
build_operator_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
auto name_node = parse_node.child_by_field_name("name");
|
||||
auto name_node = parser_node.child_by_field_name("name");
|
||||
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
|
@ -280,7 +278,7 @@ build_operator_expression(parser::ParseTree::Node parse_node,
|
|||
build_expression(name_node.next_named_sibling(),
|
||||
expression_storage, type_storage));
|
||||
|
||||
return nodes::NameExpression(build_node(parse_node),
|
||||
return nodes::NameExpression(build_node(parser_node),
|
||||
build_operator(name_node), std::move(arguments),
|
||||
std::nullopt, false);
|
||||
}
|
||||
|
|
@ -288,13 +286,13 @@ build_operator_expression(parser::ParseTree::Node parse_node,
|
|||
// --- continers
|
||||
|
||||
nodes::Container
|
||||
build_container(parser::ParseTree::Node parse_node,
|
||||
build_container(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage,
|
||||
nodes::Container::ContainerType container_type) {
|
||||
std::vector<nodes::ExpressionProxy> expressions;
|
||||
|
||||
auto current_node = parse_node.nth_named_child(0).next_named_sibling();
|
||||
auto current_node = parser_node.nth_named_child(0).next_named_sibling();
|
||||
|
||||
while (!current_node.is_null()) {
|
||||
expressions.push_back(
|
||||
|
|
@ -302,138 +300,115 @@ build_container(parser::ParseTree::Node parse_node,
|
|||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Container(build_node(parse_node), container_type,
|
||||
return nodes::Container(build_node(parser_node), container_type,
|
||||
std::move(expressions));
|
||||
}
|
||||
|
||||
// '{' (expression ';')* '}'
|
||||
nodes::Container build_block(parser::ParseTree::Node parse_node,
|
||||
nodes::Container build_block(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_container(parse_node, expression_storage, type_storage,
|
||||
return build_container(parser_node, expression_storage, type_storage,
|
||||
nodes::Container::BLOCK);
|
||||
}
|
||||
|
||||
// '[[' expression+ ']]'
|
||||
nodes::Container build_array(parser::ParseTree::Node parse_node,
|
||||
nodes::Container build_array(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_container(parse_node, expression_storage, type_storage,
|
||||
return build_container(parser_node, expression_storage, type_storage,
|
||||
nodes::Container::ARRAY);
|
||||
}
|
||||
|
||||
// --- modifiers
|
||||
|
||||
// ('return' | 'bring') expression
|
||||
nodes::Return build_return(parser::ParseTree::Node parse_node,
|
||||
nodes::Return build_return(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::string modifier = parse_node.nth_child(0).get_value();
|
||||
std::string modifier = parser_node.nth_child(0).get_value();
|
||||
|
||||
return nodes::Return(build_node(parse_node),
|
||||
return nodes::Return(build_node(parser_node),
|
||||
modifier == "return" ? nodes::Return::RETURN
|
||||
: nodes::Return::BRING,
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage));
|
||||
}
|
||||
|
||||
// _var_let_ (simple_name_identifier | placeholder)
|
||||
nodes::NameDefinition
|
||||
build_name_definition(parser::ParseTree::Node parse_node) {
|
||||
std::string modifier = parse_node.nth_child(0).get_value();
|
||||
build_name_definition(parser::ParseTree::Node parser_node) {
|
||||
std::string modifier = parser_node.nth_child(0).get_value();
|
||||
|
||||
auto name_node = parse_node.nth_named_child(0);
|
||||
auto name_node = parser_node.nth_named_child(0);
|
||||
|
||||
return nodes::NameDefinition(build_node(parse_node),
|
||||
return nodes::NameDefinition(build_node(parser_node),
|
||||
(modifier == "%" || modifier == "let")
|
||||
? nodes::NameDefinition::LET
|
||||
: nodes::NameDefinition::VAR,
|
||||
tokens::string_to_type(name_node.get_type()) ==
|
||||
tokens::Type::SIMPLE_NAME_IDENTIFIER
|
||||
? build_simple_name(name_node)
|
||||
: build_placeholder(name_node));
|
||||
build_identifier(name_node));
|
||||
} // IN PROGRESS
|
||||
|
||||
// expression '[' expression ']'
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parse_node,
|
||||
nodes::Access build_array_access(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return nodes::Access(build_node(parse_node), nodes::Access::ARRAY,
|
||||
build_expression(parse_node.nth_named_child(0),
|
||||
return nodes::Access(build_node(parser_node), nodes::Access::ARRAY,
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage),
|
||||
build_expression(parse_node.nth_named_child(1),
|
||||
build_expression(parser_node.nth_named_child(1),
|
||||
expression_storage, type_storage));
|
||||
}
|
||||
|
||||
// expression '.' number_literal
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parse_node,
|
||||
nodes::Access build_tuple_access(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return nodes::Access(
|
||||
build_node(parse_node), nodes::Access::TUPLE,
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage,
|
||||
build_node(parser_node), nodes::Access::TUPLE,
|
||||
build_expression(parser_node.nth_named_child(0), expression_storage,
|
||||
type_storage),
|
||||
expression_storage.add_expression(nodes::Expression(
|
||||
build_number_literal(parse_node.nth_named_child(1)))));
|
||||
build_number_literal(parser_node.nth_named_child(1)))));
|
||||
}
|
||||
|
||||
// 'break' | 'continue'
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parse_node) {
|
||||
return nodes::LoopControl(build_node(parse_node),
|
||||
parse_node.get_value() == "break"
|
||||
nodes::LoopControl build_loop_control(parser::ParseTree::Node parser_node) {
|
||||
return nodes::LoopControl(build_node(parser_node),
|
||||
parser_node.get_value() == "break"
|
||||
? nodes::LoopControl::BREAK
|
||||
: nodes::LoopControl::CONTINUE);
|
||||
}
|
||||
|
||||
nodes::ModifierExpression::Modifier
|
||||
string_to_modifier(const std::string &modifier) {
|
||||
if (modifier == "?") {
|
||||
return nodes::ModifierExpression::OR_FALSE;
|
||||
} else if (modifier == "!") {
|
||||
return nodes::ModifierExpression::OR_PANIC;
|
||||
} else if (modifier == "->" || modifier == "out") {
|
||||
return nodes::ModifierExpression::OUT;
|
||||
} else if (modifier == "<-" || modifier == "in") {
|
||||
return nodes::ModifierExpression::IN;
|
||||
} else if (modifier == "<>" || modifier == "ref") {
|
||||
return nodes::ModifierExpression::REF;
|
||||
} else {
|
||||
error_handling::handle_internal_error("Unrecognized modifier",
|
||||
"builders::modifier_by_string");
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
nodes::ModifierExpression
|
||||
build_modifier_expression(parser::ParseTree::Node parse_node,
|
||||
build_modifier_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage,
|
||||
size_t modifier_position) {
|
||||
std::string modifier = parse_node.nth_child(modifier_position).get_value();
|
||||
|
||||
return nodes::ModifierExpression(
|
||||
build_node(parse_node), string_to_modifier(modifier),
|
||||
build_expression(parse_node.nth_named_child(0), expression_storage,
|
||||
build_node(parser_node),
|
||||
build_modifier(parser_node.nth_child(modifier_position)),
|
||||
build_expression(parser_node.nth_named_child(0), expression_storage,
|
||||
type_storage));
|
||||
}
|
||||
|
||||
// _reference_ expression
|
||||
nodes::ModifierExpression
|
||||
build_reference_expression(parser::ParseTree::Node parse_node,
|
||||
build_reference_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_modifier_expression(parse_node, expression_storage, type_storage,
|
||||
0);
|
||||
return build_modifier_expression(parser_node, expression_storage,
|
||||
type_storage, 0);
|
||||
}
|
||||
|
||||
// expression ('?' | '!')
|
||||
nodes::ModifierExpression
|
||||
build_suffix_expression(parser::ParseTree::Node parse_node,
|
||||
build_suffix_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_modifier_expression(parse_node, expression_storage, type_storage,
|
||||
parse_node.child_count() - 1);
|
||||
return build_modifier_expression(parser_node, expression_storage,
|
||||
type_storage, parser_node.child_count() - 1);
|
||||
}
|
||||
|
||||
// --- other
|
||||
|
|
@ -465,7 +440,7 @@ void build_arguments_until_end(
|
|||
// (type '.' simple_name | expression '.' simple_name | name | '(' operator
|
||||
// ')') (annotation? expression)*
|
||||
nodes::NameExpression
|
||||
build_name_expression(parser::ParseTree::Node parse_node,
|
||||
build_name_expression(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
|
|
@ -475,7 +450,7 @@ build_name_expression(parser::ParseTree::Node parse_node,
|
|||
|
||||
bool is_point_call = false;
|
||||
|
||||
auto name_node = parse_node.child_by_field_name("name");
|
||||
auto name_node = parser_node.child_by_field_name("name");
|
||||
|
||||
std::optional<parser::ParseTree::Node> prefix_node;
|
||||
|
||||
|
|
@ -495,11 +470,7 @@ build_name_expression(parser::ParseTree::Node parse_node,
|
|||
type_storage, arguments);
|
||||
|
||||
return nodes::NameExpression(
|
||||
build_node(parse_node),
|
||||
tokens::string_to_type(name_node.get_type()) ==
|
||||
tokens::Type::ARGUMENT_NAME_IDENTIFIER
|
||||
? build_argument_name(name_node)
|
||||
: build_simple_name(name_node),
|
||||
build_node(parser_node), build_identifier(name_node),
|
||||
std::move(arguments),
|
||||
prefix_node.has_value() ? build_type(prefix_node.value(), type_storage)
|
||||
: std::optional<nodes::TypeProxy>(),
|
||||
|
|
@ -508,39 +479,39 @@ build_name_expression(parser::ParseTree::Node parse_node,
|
|||
|
||||
// type (annotation? expression)*
|
||||
nodes::Constructor
|
||||
build_constructor(parser::ParseTree::Node parse_node,
|
||||
build_constructor(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
|
||||
build_arguments_until_end(
|
||||
parse_node.child_by_field_name("type").next_named_sibling(),
|
||||
parser_node.child_by_field_name("type").next_named_sibling(),
|
||||
expression_storage, type_storage, arguments);
|
||||
|
||||
return nodes::Constructor(
|
||||
build_node(parse_node),
|
||||
build_type(parse_node.child_by_field_name("type"), type_storage),
|
||||
build_node(parser_node),
|
||||
build_type(parser_node.child_by_field_name("type"), type_storage),
|
||||
std::move(arguments));
|
||||
}
|
||||
|
||||
// '\\' argument_name* _do_ expression
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parse_node,
|
||||
nodes::Lambda build_lambda(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::Identifier> arguments;
|
||||
|
||||
auto current_node = parse_node.nth_child(1); // next to '\\'
|
||||
auto current_node = parser_node.nth_child(1); // next to '\\'
|
||||
|
||||
while (current_node.is_named()) { // until _do_
|
||||
arguments.emplace_back(build_argument_name(parse_node));
|
||||
arguments.emplace_back(build_identifier(parser_node));
|
||||
current_node = current_node.next_sibling();
|
||||
}
|
||||
|
||||
current_node = current_node.next_named_sibling();
|
||||
|
||||
return nodes::Lambda(
|
||||
build_node(parse_node), std::move(arguments),
|
||||
build_node(parser_node), std::move(arguments),
|
||||
build_expression(current_node, expression_storage, type_storage));
|
||||
}
|
||||
|
||||
|
|
|
|||
43
src/main.cpp
43
src/main.cpp
|
|
@ -1,3 +1,42 @@
|
|||
int main() {
|
||||
return 0;
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <sstream>
|
||||
|
||||
#include "error_handling.hpp"
|
||||
#include "expression_nodes.hpp"
|
||||
#include "statement_builders.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
if (argc < 2 || argc > 2) {
|
||||
std::cout << "Wrong argument count (one argument should be provided - "
|
||||
"source file)\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string filename = argv[1];
|
||||
|
||||
std::ifstream in;
|
||||
in.open(filename);
|
||||
|
||||
std::stringstream source_stream;
|
||||
|
||||
source_stream << in.rdbuf();
|
||||
|
||||
in.close();
|
||||
|
||||
std::string source = source_stream.str();
|
||||
|
||||
parser::ParseTree parse_tree(source);
|
||||
|
||||
if (!parse_tree.is_properly_parsed()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"There are some parsing errors in file", parse_tree.get_root());
|
||||
}
|
||||
|
||||
nodes::ExpressionStorage expression_storage;
|
||||
nodes::TypeStorage type_storage;
|
||||
|
||||
builders::build_source_file(parse_tree.get_root(), expression_storage,
|
||||
type_storage);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,54 +1,385 @@
|
|||
#include "../include/statement_builders.hpp"
|
||||
#include "statement_builders.hpp"
|
||||
|
||||
#include "basic_builders.hpp"
|
||||
#include "basic_nodes.hpp"
|
||||
#include "doc_builders.hpp"
|
||||
#include "doc_nodes.hpp"
|
||||
#include "error_handling.hpp"
|
||||
#include "expression_builders.hpp"
|
||||
#include "statement_nodes.hpp"
|
||||
#include "tokens.hpp"
|
||||
#include "tree_sitter_wrapper.hpp"
|
||||
#include "type_builders.hpp"
|
||||
#include "type_nodes.hpp"
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <vector>
|
||||
|
||||
namespace builders {
|
||||
|
||||
// IN PROGRESS: return type, etc.
|
||||
void build_source_file(parser::ParseTree::Node parse_node,
|
||||
// TODO: return some info ??
|
||||
// statement+
|
||||
void build_source_file(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
nodes::TypeStorage &type_storage) {
|
||||
auto current_node = parser_node.nth_named_child(0);
|
||||
while (!current_node.is_null()) {
|
||||
build_statement(current_node, expression_storage, type_storage);
|
||||
// TODO: do something with statement
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
}
|
||||
|
||||
// IN PROGRESS: return type, etc.
|
||||
void build_statement(parser::ParseTree::Node parse_node,
|
||||
// TODO: return some info ??
|
||||
// import | type_definition | function_definition | typeclass_definition
|
||||
void build_statement(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
nodes::TypeStorage &type_storage) {
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
switch (type) {
|
||||
case tokens::Type::IMPORT:
|
||||
build_import(parser_node);
|
||||
return;
|
||||
case tokens::Type::TYPE_DEFINITION:
|
||||
build_type_definition(parser_node, expression_storage, type_storage);
|
||||
return;
|
||||
case tokens::Type::FUNCTION_DEFINITION:
|
||||
build_function_definition(parser_node, expression_storage, type_storage);
|
||||
return;
|
||||
case tokens::Type::TYPECLASS_DEFINITION:
|
||||
build_typeclass_definition(parser_node, expression_storage, type_storage);
|
||||
return;
|
||||
default:
|
||||
error_handling::handle_parsing_error("Unexprected statement node type",
|
||||
parser_node);
|
||||
}
|
||||
error_handling::handle_general_error("Unreachable");
|
||||
exit(1); // unreachable} // IN PROCESS
|
||||
}
|
||||
|
||||
// ('::' | 'import') simple_name ('=' simple_name)? (':' identifier*)?
|
||||
nodes::Import build_import(parser::ParseTree::Node parse_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
nodes::Import build_import(parser::ParseTree::Node parser_node) {
|
||||
|
||||
auto name_node = parser_node.child_by_field_name("name");
|
||||
auto module_node = parser_node.child_by_field_name("module");
|
||||
if (module_node.is_null()) {
|
||||
module_node = name_node;
|
||||
}
|
||||
|
||||
std::vector<nodes::Identifier> symbols;
|
||||
|
||||
auto current_node = module_node.next_named_sibling();
|
||||
while (!current_node.is_null()) {
|
||||
symbols.push_back(build_identifier(current_node));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Import(build_node(parser_node), build_identifier(name_node),
|
||||
build_identifier(module_node), std::move(symbols));
|
||||
}
|
||||
|
||||
// '?' expression
|
||||
nodes::Constraint build_constraint(parser::ParseTree::Node parse_node,
|
||||
nodes::Constraint build_constraint(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
} // IN PROCESS
|
||||
return nodes::Constraint(build_node(parser_node),
|
||||
build_expression(parser_node.nth_named_child(0),
|
||||
expression_storage, type_storage));
|
||||
}
|
||||
|
||||
parser::ParseTree::Node collect_symbol_doc_nodes(
|
||||
parser::ParseTree::Node start_parser_node,
|
||||
std::optional<parser::ParseTree::Node> &description_node,
|
||||
std::vector<parser::ParseTree::Node> &annotation_nodes) {
|
||||
auto current_node = start_parser_node;
|
||||
|
||||
description_node = std::nullopt;
|
||||
annotation_nodes.clear();
|
||||
|
||||
if (current_node.is_null()) {
|
||||
return current_node;
|
||||
}
|
||||
|
||||
if (tokens::string_to_type(current_node.get_type()) ==
|
||||
tokens::Type::DEFINITION_INFO) {
|
||||
description_node = current_node;
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
while (!current_node.is_null() &&
|
||||
tokens::string_to_type(current_node.get_type()) ==
|
||||
tokens::Type::ANNOTATION_INFO) {
|
||||
annotation_nodes.push_back(current_node);
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return current_node;
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* '^'? simple_type (argument_type* '='
|
||||
// (variant_type | tuple_type))? ('{' function_definition* '}' | ';')
|
||||
// variant_type)? ('{' function_definition* '}' | ';')
|
||||
nodes::TypeDefinition
|
||||
build_type_definition(parser::ParseTree::Node parse_node,
|
||||
build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
nodes::TypeStorage &type_storage) {
|
||||
bool is_on_heap = parser_node.nth_child(0).get_value() == "^";
|
||||
|
||||
// TODO: make references possible only at one place at once
|
||||
std::optional<parser::ParseTree::Node> description_node;
|
||||
std::vector<parser::ParseTree::Node> annotation_nodes;
|
||||
|
||||
// definition_info? annotation_info* (constraint ';')* (simple_name | '('
|
||||
// operator ')') (annotation? _reference_? argument_name '?'?)* (: (annotation?
|
||||
// _reference_ type)+)?
|
||||
auto name_node = collect_symbol_doc_nodes(parser_node.nth_named_child(0),
|
||||
description_node, annotation_nodes);
|
||||
|
||||
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::ARGUMENT_TYPE_IDENTIFIER:
|
||||
arguments.push_back(build_identifier(current_node));
|
||||
break;
|
||||
case tokens::Type::VARIANT_TYPE:
|
||||
if (type_node.has_value()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"More then one type node in type definition", 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);
|
||||
}
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
if (!type_node.has_value() && !annotation_nodes.empty()) {
|
||||
error_handling::handle_parsing_error("", parser_node);
|
||||
}
|
||||
|
||||
std::optional<nodes::VariantType> type =
|
||||
type_node.has_value()
|
||||
? build_variant_type(type_node.value(), type_storage)
|
||||
: std::optional<nodes::VariantType>();
|
||||
|
||||
std::unordered_set<std::string> annotations;
|
||||
|
||||
// collect annotations from type
|
||||
if (type.has_value()) {
|
||||
for (size_t i = 0; i < type.value().size(); ++i) {
|
||||
auto constructor_annotations = type.value().get(i)->get_all_annotations();
|
||||
for (auto &annotation : constructor_annotations) {
|
||||
annotations.insert(annotation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
// 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 parse_node,
|
||||
build_function_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
nodes::TypeStorage &type_storage) {
|
||||
|
||||
std::optional<parser::ParseTree::Node> description_node;
|
||||
std::vector<parser::ParseTree::Node> annotation_nodes;
|
||||
|
||||
std::vector<nodes::Constraint> constraints;
|
||||
|
||||
auto current_node = collect_symbol_doc_nodes(
|
||||
parser_node.nth_named_child(0), description_node, annotation_nodes);
|
||||
|
||||
while (!current_node.is_null() &&
|
||||
tokens::string_to_type(current_node.get_type()) ==
|
||||
tokens::Type::CONSTRAINT) {
|
||||
constraints.push_back(
|
||||
build_constraint(current_node, expression_storage, type_storage));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
auto name_node = current_node;
|
||||
|
||||
nodes::FunctionDefinition::ModifierType modifier =
|
||||
nodes::FunctionDefinition::STATIC;
|
||||
|
||||
current_node = name_node.previous_sibling();
|
||||
if (current_node.is_named()) {
|
||||
std::string modifier_str = current_node.get_value();
|
||||
if (modifier_str == "%" || modifier_str == "let") {
|
||||
modifier = nodes::FunctionDefinition::LET;
|
||||
} else if (modifier_str == "$" || modifier_str == "var") {
|
||||
modifier = nodes::FunctionDefinition::VAR;
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<std::optional<std::string>> argument_annotations;
|
||||
std::vector<nodes::Modifier> argument_reference_types;
|
||||
std::vector<nodes::Identifier> arguments;
|
||||
|
||||
std::vector<std::optional<std::string>> type_annotations;
|
||||
std::vector<nodes::Modifier> type_reference_types;
|
||||
std::vector<std::optional<nodes::TypeProxy>> types;
|
||||
|
||||
std::optional<parser::ParseTree::Node> expression_node;
|
||||
|
||||
current_node = name_node.next_named_sibling();
|
||||
|
||||
bool at_least_one_argument_annotation_found = false;
|
||||
bool at_least_one_argument_reference_type_found = false;
|
||||
|
||||
std::optional<std::string> last_annotation;
|
||||
nodes::Modifier last_reference_type = nodes::Modifier::NONE;
|
||||
while (!current_node.is_null()) {
|
||||
auto maybe_reference_node = current_node.previous_sibling();
|
||||
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
|
||||
last_reference_type = build_modifier(maybe_reference_node);
|
||||
}
|
||||
|
||||
switch (tokens::string_to_type(current_node.get_type())) {
|
||||
case tokens::Type::ANNOTATION_IDENTIFIER:
|
||||
last_annotation = build_annotation(current_node);
|
||||
break;
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
if (last_annotation.has_value()) {
|
||||
at_least_one_argument_annotation_found = true;
|
||||
}
|
||||
if (last_reference_type != nodes::Modifier::NONE) {
|
||||
at_least_one_argument_reference_type_found = true;
|
||||
}
|
||||
|
||||
argument_annotations.push_back(last_annotation);
|
||||
argument_reference_types.push_back(last_reference_type);
|
||||
arguments.push_back(build_identifier(current_node));
|
||||
last_reference_type = nodes::Modifier::NONE;
|
||||
last_annotation = std::nullopt;
|
||||
break;
|
||||
case tokens::Type::TYPE:
|
||||
type_annotations.push_back(last_annotation);
|
||||
type_reference_types.push_back(last_reference_type);
|
||||
types.push_back(build_type(current_node, type_storage));
|
||||
last_reference_type = nodes::Modifier::NONE;
|
||||
last_annotation = std::nullopt;
|
||||
break;
|
||||
default:
|
||||
if (expression_node.has_value()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"More then one expression found in function definition",
|
||||
parser_node);
|
||||
}
|
||||
expression_node = current_node;
|
||||
break;
|
||||
}
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
std::vector<std::optional<std::string>> *annotations = nullptr;
|
||||
std::vector<nodes::Modifier> *reference_types = nullptr;
|
||||
|
||||
if (!at_least_one_argument_annotation_found) {
|
||||
for (size_t i = 0; i < argument_annotations.size(); ++i) {
|
||||
argument_annotations[i] = *arguments[i].get();
|
||||
}
|
||||
}
|
||||
|
||||
if (types.empty()) {
|
||||
annotations = &argument_annotations;
|
||||
reference_types = &argument_reference_types;
|
||||
} else if (at_least_one_argument_annotation_found) {
|
||||
error_handling::handle_parsing_error(
|
||||
"It is impossible to use argument annotations when types explicitely "
|
||||
"defined. Use type annotations instead.",
|
||||
parser_node);
|
||||
} else if (at_least_one_argument_reference_type_found) {
|
||||
error_handling::handle_parsing_error(
|
||||
"It is impossible to use argument reference types when types "
|
||||
"explicitely defined. Use type reference types instead.",
|
||||
parser_node);
|
||||
} else {
|
||||
annotations = &type_annotations;
|
||||
reference_types = &type_reference_types;
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> annotations_set;
|
||||
for (auto &annotation : *annotations) {
|
||||
if (annotation.has_value()) {
|
||||
if (!annotations_set.insert(annotation.value()).second) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Two or more same annotations found in function definition",
|
||||
parser_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nodes::FunctionDefinition(
|
||||
build_node(parser_node),
|
||||
build_symbol_docs(description_node, annotation_nodes, annotations_set),
|
||||
std::move(constraints), modifier, build_identifier(name_node),
|
||||
std::move(*annotations), std::move(arguments),
|
||||
std::move(*reference_types), std::move(types),
|
||||
expression_node.has_value()
|
||||
? build_expression(expression_node.value(), expression_storage,
|
||||
type_storage)
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
} // TODO: refactor ??
|
||||
|
||||
// definition_info? annotation_info* typeclass_identifier (':'
|
||||
// typeclass_identifier+)? ('{' function_definition* '}' | ';')
|
||||
nodes::TypeclassDefinition
|
||||
build_typeclass_definition(parser::ParseTree::Node parse_node,
|
||||
build_typeclass_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::ExpressionStorage &expression_storage,
|
||||
nodes::TypeStorage &type_storage) {} // IN PROCESS
|
||||
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
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#include "../include/type_builders.hpp"
|
||||
#include "type_builders.hpp"
|
||||
#include "basic_builders.hpp"
|
||||
#include "tokens.hpp"
|
||||
|
||||
|
|
@ -55,7 +55,7 @@ nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node,
|
|||
return nodes::TupleType(build_node(parse_node), std::move(fields));
|
||||
}
|
||||
|
||||
// '|'? tuple_type ('|' tuple_type)+
|
||||
// '|'? tuple_type ('|' tuple_type)*
|
||||
nodes::VariantType build_variant_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::TupleType> constructors;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue