mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
type structure change, mostly done
This commit is contained in:
parent
522dd16f79
commit
a7c1e3f658
9 changed files with 183 additions and 66 deletions
|
|
@ -8,12 +8,12 @@ namespace builders {
|
||||||
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
||||||
nodes::TypeStorage &type_storage);
|
nodes::TypeStorage &type_storage);
|
||||||
|
|
||||||
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
|
|
||||||
nodes::TypeStorage &type_storage);
|
|
||||||
|
|
||||||
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
|
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
|
||||||
nodes::TypeStorage &type_storage);
|
nodes::TypeStorage &type_storage);
|
||||||
|
|
||||||
|
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
|
||||||
|
nodes::TypeStorage &type_storage);
|
||||||
|
|
||||||
nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node,
|
nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node,
|
||||||
nodes::TypeStorage &type_storage);
|
nodes::TypeStorage &type_storage);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
39
include/builtin_types.hpp
Normal 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
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "basic_nodes.hpp"
|
#include "basic_nodes.hpp"
|
||||||
|
#include "builtin_types.hpp"
|
||||||
#include "doc_nodes.hpp"
|
#include "doc_nodes.hpp"
|
||||||
#include "expression_nodes.hpp"
|
#include "expression_nodes.hpp"
|
||||||
#include "type_nodes.hpp"
|
#include "type_nodes.hpp"
|
||||||
|
|
@ -92,7 +93,8 @@ public:
|
||||||
Modifier before_modifier = Modifier::NONE)
|
Modifier before_modifier = Modifier::NONE)
|
||||||
: annotation_(annotation), type_(type),
|
: annotation_(annotation), type_(type),
|
||||||
before_modifier_(before_modifier),
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto type_after_modifier =
|
||||||
|
builtin::builtin_to_modifier(type.get()->to_builtin());
|
||||||
|
|
||||||
if (after_modifier_ != Modifier::NONE &&
|
if (after_modifier_ != Modifier::NONE &&
|
||||||
after_modifier_ != type.get()->get_modifier()) {
|
after_modifier_ != type_after_modifier) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
annotation_ = annotation;
|
annotation_ = annotation;
|
||||||
type_ = type;
|
type_ = type;
|
||||||
before_modifier_ = before_modifier;
|
before_modifier_ = before_modifier;
|
||||||
after_modifier_ = type.get()->get_modifier();
|
after_modifier_ = type_after_modifier;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -335,7 +340,7 @@ public:
|
||||||
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
|
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
|
||||||
const Identifier &name, std::vector<Identifier> &&typeclasses,
|
const Identifier &name, std::vector<Identifier> &&typeclasses,
|
||||||
std::vector<Identifier> &&arguments,
|
std::vector<Identifier> &&arguments,
|
||||||
std::optional<TypeProxy> &type)
|
std::optional<TypeProxy> type)
|
||||||
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
|
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
|
||||||
name_(name), typeclasses_(typeclasses),
|
name_(name), typeclasses_(typeclasses),
|
||||||
arguments_(std::move(arguments)), type_(std::move(type)) {}
|
arguments_(std::move(arguments)), type_(std::move(type)) {}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "basic_nodes.hpp"
|
#include "basic_nodes.hpp"
|
||||||
|
#include "builtin_types.hpp"
|
||||||
|
|
||||||
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -34,21 +36,28 @@ private:
|
||||||
// can't have both optional and result modifiers ??
|
// can't have both optional and result modifiers ??
|
||||||
class Type : public Node {
|
class Type : public Node {
|
||||||
public:
|
public:
|
||||||
Type(Node node, Identifier &&identifier, bool is_on_heap = false)
|
Type(Node node, Identifier &&identifier, bool is_on_heap = false,
|
||||||
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap) {}
|
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)
|
Type(Node node, const Identifier &identifier, bool is_on_heap = false,
|
||||||
: Node(node), name_(identifier), is_on_heap_(is_on_heap) {}
|
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> &¶meters,
|
Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &¶meters,
|
||||||
bool is_on_heap = false)
|
bool is_on_heap = false,
|
||||||
|
const std::optional<std::string> &annotation = std::nullopt)
|
||||||
: Node(node), name_(std::move(identifier)),
|
: Node(node), name_(std::move(identifier)),
|
||||||
parameters_(std::move(parameters)), is_on_heap_(is_on_heap) {}
|
parameters_(std::move(parameters)), is_on_heap_(is_on_heap),
|
||||||
|
annotation_(annotation) {}
|
||||||
|
|
||||||
Type(Node node, const Identifier &identifier,
|
Type(Node node, const Identifier &identifier,
|
||||||
std::vector<TypeProxy> &¶meters, bool is_on_heap = false)
|
std::vector<TypeProxy> &¶meters, bool is_on_heap = false,
|
||||||
|
const std::optional<std::string> &annotation = std::nullopt)
|
||||||
: Node(node), name_(identifier), parameters_(std::move(parameters)),
|
: 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 ¶meter : parameters_) {
|
||||||
|
parameter.get()->collect_annotations_recursively(insert_iterator);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
bool operator==(const Type &other_type) const {
|
bool operator==(const Type &other_type) const {
|
||||||
if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ ||
|
if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ ||
|
||||||
parameters_.size() != other_type.parameters_.size()) {
|
parameters_.size() != other_type.parameters_.size()) {
|
||||||
|
|
@ -93,11 +138,33 @@ public:
|
||||||
return !(*this == other_type);
|
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:
|
private:
|
||||||
Identifier name_;
|
Identifier name_;
|
||||||
std::vector<TypeProxy> parameters_;
|
std::vector<TypeProxy> parameters_;
|
||||||
// or use allocator ??
|
// or use allocator ??
|
||||||
bool is_on_heap_ = false;
|
bool is_on_heap_ = false;
|
||||||
|
std::optional<std::string> annotation_;
|
||||||
};
|
};
|
||||||
|
|
||||||
class TypeStorage {
|
class TypeStorage {
|
||||||
|
|
|
||||||
|
|
@ -479,7 +479,18 @@ build_name_expression(parser::ParseTree::Node parser_node,
|
||||||
|
|
||||||
auto current_node = name_node.previous_named_sibling();
|
auto current_node = name_node.previous_named_sibling();
|
||||||
if (!current_node.is_null()) {
|
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;
|
prefix_node = current_node;
|
||||||
} else {
|
} else {
|
||||||
is_point_call = true;
|
is_point_call = true;
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,11 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
|
||||||
arguments.push_back(build_identifier(current_node));
|
arguments.push_back(build_identifier(current_node));
|
||||||
break;
|
break;
|
||||||
case tokens::Type::VARIANT_TYPE:
|
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()) {
|
if (type_node.has_value()) {
|
||||||
error_handling::handle_parsing_error(
|
error_handling::handle_parsing_error(
|
||||||
"More then one type node in type definition", parser_node);
|
"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;
|
std::unordered_set<std::string> annotations;
|
||||||
|
|
||||||
// collect annotations from type
|
|
||||||
if (type.has_value()) {
|
if (type.has_value()) {
|
||||||
for (size_t i = 0; i < type.value().size(); ++i) {
|
type.value().get()->collect_annotations_recursively(
|
||||||
// TODO: deal with annotations
|
std::insert_iterator<std::unordered_set<std::string>>(
|
||||||
auto constructor_annotations = type.value().get(i)->get_all_annotations();
|
annotations, annotations.begin()));
|
||||||
for (auto &annotation : constructor_annotations) {
|
|
||||||
annotations.insert(annotation);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nodes::TypeDefinition(
|
return nodes::TypeDefinition(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
build_symbol_docs(description_node, annotation_nodes, annotations),
|
build_symbol_docs(description_node, annotation_nodes, annotations),
|
||||||
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments),
|
is_on_heap, std::move(name), std::move(typeclasses), std::move(arguments),
|
||||||
std::move(type));
|
type);
|
||||||
}
|
}
|
||||||
|
|
||||||
// definition_info? annotation_info* (constraint ';')* '.'? (simple_name
|
// definition_info? annotation_info* (constraint ';')* '.'? (simple_name
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,11 @@
|
||||||
#include "type_builders.hpp"
|
#include "type_builders.hpp"
|
||||||
#include "basic_builders.hpp"
|
#include "basic_builders.hpp"
|
||||||
#include "basic_nodes.hpp"
|
#include "basic_nodes.hpp"
|
||||||
#include "builtin_identifiers.hpp"
|
#include "builtin_types.hpp"
|
||||||
#include "error_handling.hpp"
|
#include "error_handling.hpp"
|
||||||
#include "tokens.hpp"
|
#include "tokens.hpp"
|
||||||
#include "type_nodes.hpp"
|
#include "type_nodes.hpp"
|
||||||
|
#include "types.hpp"
|
||||||
|
|
||||||
namespace builders {
|
namespace builders {
|
||||||
|
|
||||||
|
|
@ -39,41 +40,47 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
|
||||||
exit(1); // unreachable
|
exit(1); // unreachable
|
||||||
}
|
}
|
||||||
|
|
||||||
// '|'? annotation? type ('|' annotation? type)+
|
nodes::TypeProxy
|
||||||
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node,
|
build_buildin_container_type(parser::ParseTree::Node parser_node,
|
||||||
nodes::TypeStorage &type_storage) {
|
nodes::TypeStorage &type_storage,
|
||||||
|
const std::string &type_name) {
|
||||||
std::vector<nodes::TypeProxy> parameters;
|
std::vector<nodes::TypeProxy> parameters;
|
||||||
|
|
||||||
|
std::optional<std::string> current_annotation;
|
||||||
|
|
||||||
auto current_node = parser_node.nth_named_child(0);
|
auto current_node = parser_node.nth_named_child(0);
|
||||||
;
|
|
||||||
while (!current_node.is_null()) {
|
while (!current_node.is_null()) {
|
||||||
parameters.push_back(build_type(current_node, type_storage));
|
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();
|
current_node = current_node.next_named_sibling();
|
||||||
}
|
}
|
||||||
|
|
||||||
return type_storage.add_type(nodes::Type(
|
return type_storage.add_type(
|
||||||
build_node(parser_node),
|
nodes::Type(build_node(parser_node),
|
||||||
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
|
nodes::Identifier(build_node(parser_node),
|
||||||
builtin::VARIANT_IDENTIFIER),
|
nodes::Identifier::SIMPLE_TYPE, type_name),
|
||||||
std::move(parameters), false));
|
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)+
|
// '&'? annotation? type ('&' annotation? type)+
|
||||||
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
|
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
|
||||||
nodes::TypeStorage &type_storage) {
|
nodes::TypeStorage &type_storage) {
|
||||||
std::vector<nodes::TypeProxy> parameters;
|
return build_buildin_container_type(parser_node, type_storage,
|
||||||
|
builtin::TUPLE_IDENTIFIER);
|
||||||
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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// '[[' type ']]'
|
// '[[' type ']]'
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,11 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
|
||||||
printer.print("^");
|
printer.print("^");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (type.get_annotation().has_value()) {
|
||||||
|
print_annotation(*type.get_annotation().value(), printer);
|
||||||
|
printer.space();
|
||||||
|
}
|
||||||
|
|
||||||
print_identifier(*type.get_name(), printer);
|
print_identifier(*type.get_name(), printer);
|
||||||
|
|
||||||
if (type.get_parametrs_size() > 0) {
|
if (type.get_parametrs_size() > 0) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue