mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
TypeStorage extensions: generic types, local types
This commit is contained in:
parent
fa01d36a84
commit
17b409fe51
2 changed files with 173 additions and 24 deletions
|
|
@ -231,6 +231,8 @@ public:
|
||||||
// ANNOTATION, used as std::string
|
// ANNOTATION, used as std::string
|
||||||
OPERATOR,
|
OPERATOR,
|
||||||
PLACEHOLDER,
|
PLACEHOLDER,
|
||||||
|
//
|
||||||
|
GENERIC_TYPE,
|
||||||
};
|
};
|
||||||
|
|
||||||
Identifier(Node node, IdentifierType type, std::string &&value)
|
Identifier(Node node, IdentifierType type, std::string &&value)
|
||||||
|
|
|
||||||
|
|
@ -7,9 +7,9 @@
|
||||||
#include <iterator>
|
#include <iterator>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <optional>
|
#include <optional>
|
||||||
|
#include <set>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <unordered_set>
|
|
||||||
#include <variant>
|
#include <variant>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
|
@ -35,19 +35,6 @@ private:
|
||||||
size_t id_;
|
size_t id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
// // not needed ??
|
|
||||||
// class TypeNode : public Node {
|
|
||||||
// public:
|
|
||||||
// TypeNode(Node node, TypeProxy type) : Node(node), type_(type) {}
|
|
||||||
//
|
|
||||||
// Type *get() { return type_.get(); }
|
|
||||||
//
|
|
||||||
// const Type *get() const { return type_.get(); }
|
|
||||||
//
|
|
||||||
// private:
|
|
||||||
// TypeProxy type_;
|
|
||||||
// };
|
|
||||||
|
|
||||||
class Type {
|
class Type {
|
||||||
public:
|
public:
|
||||||
Type(Identifier &&identifier, Modifier modifier = nodes::Modifier::CONST,
|
Type(Identifier &&identifier, Modifier modifier = nodes::Modifier::CONST,
|
||||||
|
|
@ -133,6 +120,10 @@ public:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
bool is_generic() { return name_.get_type() == Identifier::GENERIC_TYPE; }
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
bool operator==(const Type &other) const {
|
bool operator==(const Type &other) const {
|
||||||
if (name_ != other.name_ || modifier_ != other.modifier_ ||
|
if (name_ != other.name_ || modifier_ != other.modifier_ ||
|
||||||
parameters_.size() != other.parameters_.size()) {
|
parameters_.size() != other.parameters_.size()) {
|
||||||
|
|
@ -219,6 +210,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeProxy add_array_of(TypeProxy type, Node node = Node()) {
|
TypeProxy add_array_of(TypeProxy type, Node node = Node()) {
|
||||||
|
if (type.type_storage_ != this) {
|
||||||
|
error_handling::handle_general_error(
|
||||||
|
"TypeStorage: Can't add array of type from another type "
|
||||||
|
"storage");
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<nodes::TypeProxy> parameters;
|
std::vector<nodes::TypeProxy> parameters;
|
||||||
parameters.push_back(type);
|
parameters.push_back(type);
|
||||||
|
|
||||||
|
|
@ -230,6 +227,15 @@ public:
|
||||||
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &¶meters,
|
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &¶meters,
|
||||||
builtin::types::Type container,
|
builtin::types::Type container,
|
||||||
Node node = Node()) {
|
Node node = Node()) {
|
||||||
|
for (auto ¶meter : parameters) {
|
||||||
|
if (parameter.type_storage_ != this) {
|
||||||
|
error_handling::handle_general_error(
|
||||||
|
"TypeStorage: Can't add container with parameter of type from "
|
||||||
|
"another type "
|
||||||
|
"storage");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return add_type(
|
return add_type(
|
||||||
nodes::Type(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
nodes::Type(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
||||||
builtin::types::to_string(container)),
|
builtin::types::to_string(container)),
|
||||||
|
|
@ -237,6 +243,12 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes::TypeProxy add_modification_of(TypeProxy type, Modifier modifier) {
|
nodes::TypeProxy add_modification_of(TypeProxy type, Modifier modifier) {
|
||||||
|
if (type.type_storage_ != this) {
|
||||||
|
error_handling::handle_general_error(
|
||||||
|
"TypeStorage: Can't add modification of type from another type "
|
||||||
|
"storage");
|
||||||
|
}
|
||||||
|
|
||||||
Type type_copy = *type.get();
|
Type type_copy = *type.get();
|
||||||
type_copy.set_modifier(modifier);
|
type_copy.set_modifier(modifier);
|
||||||
|
|
||||||
|
|
@ -253,24 +265,159 @@ public:
|
||||||
return TypeProxy(*this, storage_.size() - 1);
|
return TypeProxy(*this, storage_.size() - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO:
|
// -- deal with generic types (variable types in this case)
|
||||||
// bool try_resolve_all_generic_names
|
|
||||||
// bool add_generic_type
|
bool resolve_all_generic_types() {
|
||||||
// bool add_local_type
|
bool are_all_resolved = true;
|
||||||
// // add local type requirement
|
|
||||||
// // deduce generic type
|
bool new_types_resolved = true;
|
||||||
// void clear_local_types
|
|
||||||
// ...
|
while (new_types_resolved) {
|
||||||
|
new_types_resolved = false;
|
||||||
|
|
||||||
|
for (auto &type : storage_) {
|
||||||
|
if (type.is_generic()) {
|
||||||
|
auto iter = resolved_generic_names_.find(*type.get_name()->get());
|
||||||
|
|
||||||
|
// because of undefined order sone types can became resolved earlir
|
||||||
|
// wirking correctly because each generic type has <= 1 successor, no
|
||||||
|
// cyclic deps allowed (do check ??)
|
||||||
|
if (iter != resolved_generic_names_.end()) {
|
||||||
|
new_types_resolved = true;
|
||||||
|
type = storage_[iter->second];
|
||||||
|
} else {
|
||||||
|
are_all_resolved = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// this check is not required ??
|
||||||
|
for (auto &type : storage_) {
|
||||||
|
if (!type.is_generic()) {
|
||||||
|
are_all_resolved = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return are_all_resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeProxy add_generic_type() {
|
||||||
|
return add_type(Type(generate_generic_type_identifier()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool resolve_generic_name(const std::string &name,
|
||||||
|
const TypeProxy &actulal_type) {
|
||||||
|
if (actulal_type.type_storage_ != this) {
|
||||||
|
error_handling::handle_general_error(
|
||||||
|
"TypeStorage: Can't resolve generic type to type from another type "
|
||||||
|
"storage");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (resolved_generic_names_.count(name) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
resolved_generic_names_[name] = actulal_type.id_;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_resolved_generic_names() { resolved_generic_names_.clear(); }
|
||||||
|
|
||||||
|
// -- deal with local types
|
||||||
|
|
||||||
|
bool add_local_type(const std::string &name) {
|
||||||
|
if (local_name_ids_.count(name) != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_name_ids_[name] = local_name_typeclasses_.size();
|
||||||
|
local_name_typeclasses_.emplace_back();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_local_type_requirement(const std::string &name,
|
||||||
|
const Identifier &typeclass) {
|
||||||
|
auto iter = local_name_ids_.find(name);
|
||||||
|
|
||||||
|
if (iter == local_name_ids_.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_name_typeclasses_[iter->second].insert(typeclass);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool add_local_type_requirement(const std::string &name,
|
||||||
|
Identifier &&typeclass) {
|
||||||
|
auto iter = local_name_ids_.find(name);
|
||||||
|
|
||||||
|
if (iter == local_name_ids_.end()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
local_name_typeclasses_[iter->second].insert(std::move(typeclass));
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<std::set<Identifier> *>
|
||||||
|
get_local_type_requirements(const std::string &name) {
|
||||||
|
auto iter = local_name_ids_.find(name);
|
||||||
|
|
||||||
|
if (iter == local_name_ids_.end()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &local_name_typeclasses_[iter->second];
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<const std::set<Identifier> *>
|
||||||
|
get_local_type_requirements(const std::string &name) const {
|
||||||
|
auto iter = local_name_ids_.find(name);
|
||||||
|
|
||||||
|
if (iter == local_name_ids_.end()) {
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
||||||
|
|
||||||
|
return &local_name_typeclasses_[iter->second];
|
||||||
|
}
|
||||||
|
|
||||||
|
void clear_local_name_typeclasses() {
|
||||||
|
local_name_ids_.clear();
|
||||||
|
local_name_typeclasses_.clear();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Type *get_type(size_t id) { return &storage_.at(id); }
|
Type *get_type(size_t id) { return &storage_.at(id); }
|
||||||
|
|
||||||
const Type *get_type(size_t id) const { return &storage_.at(id); }
|
const Type *get_type(size_t id) const { return &storage_.at(id); }
|
||||||
|
|
||||||
|
Identifier generate_generic_type_identifier() {
|
||||||
|
Identifier identifier =
|
||||||
|
Identifier(Node(), Identifier::GENERIC_TYPE,
|
||||||
|
"G_" + std::to_string(last_generic_type_id_));
|
||||||
|
++last_generic_type_id_;
|
||||||
|
return identifier;
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
// TODO
|
// check is builtin type instaniated
|
||||||
// std::unordered_map<std::string, size_t> named_local_types_;
|
|
||||||
std::unordered_map<builtin::types::Type, size_t> primitive_type_ids_;
|
std::unordered_map<builtin::types::Type, size_t> primitive_type_ids_;
|
||||||
|
|
||||||
|
// deal with generic types and generic names
|
||||||
|
std::unordered_map<std::string, size_t> resolved_generic_names_;
|
||||||
|
size_t last_generic_type_id_ = 0;
|
||||||
|
|
||||||
|
// deal with local types
|
||||||
|
std::unordered_map<std::string, size_t> local_name_ids_;
|
||||||
|
std::vector<std::set<Identifier>> local_name_typeclasses_;
|
||||||
|
|
||||||
|
// storage for all types
|
||||||
std::vector<Type> storage_;
|
std::vector<Type> storage_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue