type structure change, mostly done

This commit is contained in:
ProgramSnail 2023-08-08 12:48:36 +03:00
parent 522dd16f79
commit a7c1e3f658
9 changed files with 183 additions and 66 deletions

View file

@ -8,10 +8,10 @@ namespace builders {
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node,

View file

@ -1,17 +0,0 @@
#pragma once
#include <string>
namespace builtin {
const static std::string TUPLE_IDENTIFIER = "Tuple";
const static std::string VARIANT_IDENTIFIER = "Variant";
const static std::string ARRAY_IDENTIFIER = "Array";
const static std::string OPTIONAL_IDENTIFIER = "Optional";
const static std::string RESULT_IDENTIFIER = "Result";
} // namespace builtin

39
include/builtin_types.hpp Normal file
View file

@ -0,0 +1,39 @@
#pragma once
#include <string>
#include "basic_nodes.hpp"
namespace builtin {
const static std::string TUPLE_IDENTIFIER = "Tuple";
const static std::string VARIANT_IDENTIFIER = "Variant";
const static std::string ARRAY_IDENTIFIER = "Array";
const static std::string OPTIONAL_IDENTIFIER = "Optional";
const static std::string RESULT_IDENTIFIER = "Result";
enum class BuiltinType {
TUPLE,
VARIANT,
ARRAY,
OPTIONAL,
RESULT,
NONE,
};
inline nodes::Modifier builtin_to_modifier(BuiltinType type) {
switch (type) {
case BuiltinType::OPTIONAL:
return nodes::Modifier::OPTIONAL;
case BuiltinType::RESULT:
return nodes::Modifier::RESULT;
default:
return nodes::Modifier::NONE;
}
}
} // namespace builtin

View file

@ -1,6 +1,7 @@
#pragma once
#include "basic_nodes.hpp"
#include "builtin_types.hpp"
#include "doc_nodes.hpp"
#include "expression_nodes.hpp"
#include "type_nodes.hpp"
@ -92,7 +93,8 @@ public:
Modifier before_modifier = Modifier::NONE)
: annotation_(annotation), type_(type),
before_modifier_(before_modifier),
after_modifier_(type.get()->get_modifier()) {}
after_modifier_(
builtin::builtin_to_modifier(type.get()->to_builtin())) {}
//
@ -143,15 +145,18 @@ public:
return false;
}
auto type_after_modifier =
builtin::builtin_to_modifier(type.get()->to_builtin());
if (after_modifier_ != Modifier::NONE &&
after_modifier_ != type.get()->get_modifier()) {
after_modifier_ != type_after_modifier) {
return false;
}
annotation_ = annotation;
type_ = type;
before_modifier_ = before_modifier;
after_modifier_ = type.get()->get_modifier();
after_modifier_ = type_after_modifier;
return true;
}
@ -335,7 +340,7 @@ public:
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
const Identifier &name, std::vector<Identifier> &&typeclasses,
std::vector<Identifier> &&arguments,
std::optional<TypeProxy> &type)
std::optional<TypeProxy> type)
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
name_(name), typeclasses_(typeclasses),
arguments_(std::move(arguments)), type_(std::move(type)) {}

View file

@ -1,7 +1,9 @@
#pragma once
#include "basic_nodes.hpp"
#include "builtin_types.hpp"
#include <iterator>
#include <memory>
#include <optional>
#include <string>
@ -34,21 +36,28 @@ private:
// can't have both optional and result modifiers ??
class Type : public Node {
public:
Type(Node node, Identifier &&identifier, bool is_on_heap = false)
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap) {}
Type(Node node, Identifier &&identifier, bool is_on_heap = false,
const std::optional<std::string> &annotation = std::nullopt)
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap),
annotation_(annotation) {}
Type(Node node, const Identifier &identifier, bool is_on_heap = false)
: Node(node), name_(identifier), is_on_heap_(is_on_heap) {}
Type(Node node, const Identifier &identifier, bool is_on_heap = false,
const std::optional<std::string> &annotation = std::nullopt)
: Node(node), name_(identifier), is_on_heap_(is_on_heap),
annotation_(annotation) {}
Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &&parameters,
bool is_on_heap = false)
bool is_on_heap = false,
const std::optional<std::string> &annotation = std::nullopt)
: Node(node), name_(std::move(identifier)),
parameters_(std::move(parameters)), is_on_heap_(is_on_heap) {}
parameters_(std::move(parameters)), is_on_heap_(is_on_heap),
annotation_(annotation) {}
Type(Node node, const Identifier &identifier,
std::vector<TypeProxy> &&parameters, bool is_on_heap = false)
std::vector<TypeProxy> &&parameters, bool is_on_heap = false,
const std::optional<std::string> &annotation = std::nullopt)
: Node(node), name_(identifier), parameters_(std::move(parameters)),
is_on_heap_(is_on_heap) {}
is_on_heap_(is_on_heap), annotation_(annotation) {}
//
@ -74,6 +83,42 @@ public:
//
std::optional<std::string *> get_annotation() {
if (annotation_.has_value()) {
return &annotation_.value();
}
return std::nullopt;
}
std::optional<const std::string *> get_annotation() const {
if (annotation_.has_value()) {
return &annotation_.value();
}
return std::nullopt;
}
void set_annotation(std::string &&annotation) {
annotation_ = std::move(annotation);
}
void set_annotation(const std::string &annotation) {
annotation_ = annotation;
}
template <typename T>
void collect_annotations_recursively(
std::insert_iterator<T> insert_iterator) const {
if (annotation_.has_value()) {
insert_iterator = annotation_.value();
}
for (auto &parameter : parameters_) {
parameter.get()->collect_annotations_recursively(insert_iterator);
}
}
//
bool operator==(const Type &other_type) const {
if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ ||
parameters_.size() != other_type.parameters_.size()) {
@ -93,11 +138,33 @@ public:
return !(*this == other_type);
}
// is parameters count check necessary ??
builtin::BuiltinType to_builtin() {
if (*name_.get() == builtin::TUPLE_IDENTIFIER && parameters_.size() > 0) {
return builtin::BuiltinType::TUPLE;
} else if (*name_.get() == builtin::VARIANT_IDENTIFIER &&
parameters_.size() > 0) {
return builtin::BuiltinType::VARIANT;
} else if (*name_.get() == builtin::ARRAY_IDENTIFIER &&
parameters_.size() == 1) {
return builtin::BuiltinType::ARRAY;
} else if (*name_.get() == builtin::OPTIONAL_IDENTIFIER &&
parameters_.size() == 1) {
return builtin::BuiltinType::OPTIONAL;
} else if (*name_.get() == builtin::RESULT_IDENTIFIER &&
parameters_.size() == 1) {
return builtin::BuiltinType::RESULT;
} else {
return builtin::BuiltinType::NONE;
}
}
private:
Identifier name_;
std::vector<TypeProxy> parameters_;
// or use allocator ??
bool is_on_heap_ = false;
std::optional<std::string> annotation_;
};
class TypeStorage {

View file

@ -479,7 +479,18 @@ build_name_expression(parser::ParseTree::Node parser_node,
auto current_node = name_node.previous_named_sibling();
if (!current_node.is_null()) {
if (tokens::string_to_type(current_node.get_type()) == tokens::Type::TYPE) {
if (tokens::string_to_type(current_node.get_type()) ==
tokens::Type::VARIANT_TYPE ||
tokens::string_to_type(current_node.get_type()) ==
tokens::Type::TUPLE_TYPE ||
tokens::string_to_type(current_node.get_type()) ==
tokens::Type::ARRAY_TYPE ||
tokens::string_to_type(current_node.get_type()) ==
tokens::Type::REFERENCE_TYPE ||
tokens::string_to_type(current_node.get_type()) ==
tokens::Type::MODIFIED_TYPE ||
tokens::string_to_type(current_node.get_type()) ==
tokens::Type::SIMPLE_TYPE) {
prefix_node = current_node;
} else {
is_point_call = true;

View file

@ -209,6 +209,11 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
arguments.push_back(build_identifier(current_node));
break;
case tokens::Type::VARIANT_TYPE:
case tokens::Type::TUPLE_TYPE:
case tokens::Type::ARRAY_TYPE:
case tokens::Type::REFERENCE_TYPE:
case tokens::Type::MODIFIED_TYPE:
case tokens::Type::SIMPLE_TYPE:
if (type_node.has_value()) {
error_handling::handle_parsing_error(
"More then one type node in type definition", parser_node);
@ -246,22 +251,17 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
std::unordered_set<std::string> annotations;
// collect annotations from type
if (type.has_value()) {
for (size_t i = 0; i < type.value().size(); ++i) {
// TODO: deal with annotations
auto constructor_annotations = type.value().get(i)->get_all_annotations();
for (auto &annotation : constructor_annotations) {
annotations.insert(annotation);
}
}
type.value().get()->collect_annotations_recursively(
std::insert_iterator<std::unordered_set<std::string>>(
annotations, annotations.begin()));
}
return nodes::TypeDefinition(
build_node(parser_node),
build_symbol_docs(description_node, annotation_nodes, annotations),
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments),
std::move(type));
type);
}
// definition_info? annotation_info* (constraint ';')* '.'? (simple_name

View file

@ -1,10 +1,11 @@
#include "type_builders.hpp"
#include "basic_builders.hpp"
#include "basic_nodes.hpp"
#include "builtin_identifiers.hpp"
#include "builtin_types.hpp"
#include "error_handling.hpp"
#include "tokens.hpp"
#include "type_nodes.hpp"
#include "types.hpp"
namespace builders {
@ -39,41 +40,47 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
exit(1); // unreachable
}
// '|'? annotation? type ('|' annotation? type)+
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
nodes::TypeProxy
build_buildin_container_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage,
const std::string &type_name) {
std::vector<nodes::TypeProxy> parameters;
std::optional<std::string> current_annotation;
auto current_node = parser_node.nth_named_child(0);
;
while (!current_node.is_null()) {
if (tokens::string_to_type(current_node.get_type()) ==
tokens::Type::ANNOTATION_IDENTIFIER) {
current_annotation = build_annotation(current_node);
} else {
parameters.push_back(build_type(current_node, type_storage));
if (current_annotation.has_value()) {
parameters.back().get()->set_annotation(current_annotation.value());
}
}
current_node = current_node.next_named_sibling();
}
return type_storage.add_type(nodes::Type(
build_node(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::VARIANT_IDENTIFIER),
return type_storage.add_type(
nodes::Type(build_node(parser_node),
nodes::Identifier(build_node(parser_node),
nodes::Identifier::SIMPLE_TYPE, type_name),
std::move(parameters), false));
}
// '|'? annotation? type ('|' annotation? type)+
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
return build_buildin_container_type(parser_node, type_storage,
builtin::VARIANT_IDENTIFIER);
}
// '&'? annotation? type ('&' annotation? type)+
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
parameters.push_back(build_type(current_node, type_storage));
current_node = current_node.next_named_sibling();
}
return type_storage.add_type(nodes::Type(
build_node(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::TUPLE_IDENTIFIER),
std::move(parameters), false));
return build_buildin_container_type(parser_node, type_storage,
builtin::TUPLE_IDENTIFIER);
}
// '[[' type ']]'

View file

@ -11,6 +11,11 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
printer.print("^");
}
if (type.get_annotation().has_value()) {
print_annotation(*type.get_annotation().value(), printer);
printer.space();
}
print_identifier(*type.get_name(), printer);
if (type.get_parametrs_size() > 0) {