mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
refactoring, move type storage functctions to .cpp
This commit is contained in:
parent
555e69a298
commit
fbe486d25a
2 changed files with 214 additions and 174 deletions
|
|
@ -245,77 +245,17 @@ class TypeStorage {
|
||||||
friend TypeProxy;
|
friend TypeProxy;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TypeProxy primitive(builtin::Type type) {
|
TypeProxy primitive(builtin::Type type);
|
||||||
auto iter = primitive_type_ids_.find(type);
|
|
||||||
if (iter != primitive_type_ids_.end()) {
|
|
||||||
return TypeProxy(*this, iter->second);
|
|
||||||
} else {
|
|
||||||
primitive_type_ids_[type] = storage_.size();
|
|
||||||
return add_type(Type(Identifier(Node(), Identifier::SIMPLE_TYPE,
|
|
||||||
builtin::types::to_string(type))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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;
|
TypeProxy add_error_of(TypeProxy type, Node node = Node());
|
||||||
parameters.push_back(type);
|
|
||||||
|
|
||||||
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
|
||||||
builtin::types::ARRAY_IDENTIFIER),
|
|
||||||
std::move(parameters)));
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeProxy add_error_of(TypeProxy type, Node node = Node()) {
|
|
||||||
if (type.type_storage_ != this) {
|
|
||||||
error_handling::handle_general_error(
|
|
||||||
"TypeStorage: Can't add error of type from another type "
|
|
||||||
"storage");
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<nodes::TypeProxy> parameters;
|
|
||||||
parameters.push_back(type);
|
|
||||||
|
|
||||||
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
|
||||||
builtin::types::ERROR_IDENTIFIER),
|
|
||||||
std::move(parameters)));
|
|
||||||
}
|
|
||||||
|
|
||||||
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &¶meters,
|
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &¶meters,
|
||||||
builtin::Type container,
|
builtin::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(
|
nodes::TypeProxy add_modification_of(TypeProxy type, Modifier modifier);
|
||||||
nodes::Type(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
|
||||||
builtin::types::to_string(container)),
|
|
||||||
std::move(parameters)));
|
|
||||||
}
|
|
||||||
|
|
||||||
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_copy.set_modifier(modifier);
|
|
||||||
|
|
||||||
return add_type(std::move(type_copy));
|
|
||||||
}
|
|
||||||
|
|
||||||
TypeProxy add_type(const Type &type) {
|
TypeProxy add_type(const Type &type) {
|
||||||
storage_.push_back(type);
|
storage_.push_back(type);
|
||||||
|
|
@ -329,125 +269,32 @@ public:
|
||||||
|
|
||||||
// -- deal with generic types (variable types in this case)
|
// -- deal with generic types (variable types in this case)
|
||||||
|
|
||||||
bool resolve_all_generic_types() {
|
bool resolve_all_generic_types();
|
||||||
bool are_all_resolved = true;
|
|
||||||
|
|
||||||
bool new_types_resolved = true;
|
|
||||||
|
|
||||||
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 some 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() {
|
TypeProxy add_generic_type() {
|
||||||
return add_type(Type(generate_generic_type_identifier()));
|
return add_type(Type(generate_generic_type_identifier()));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool resolve_generic_name(const std::string &name,
|
bool resolve_generic_name(const std::string &name,
|
||||||
const TypeProxy &actulal_type) {
|
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(); }
|
void clear_resolved_generic_names() { resolved_generic_names_.clear(); }
|
||||||
|
|
||||||
// -- deal with local types
|
// -- deal with local types
|
||||||
|
|
||||||
bool add_local_type(const std::string &name) {
|
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,
|
bool add_local_type_requirement(const std::string &name,
|
||||||
const Identifier &typeclass) {
|
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,
|
bool add_local_type_requirement(const std::string &name,
|
||||||
Identifier &&typeclass) {
|
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> *>
|
std::optional<std::set<Identifier> *>
|
||||||
get_local_type_requirements(const std::string &name) {
|
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> *>
|
std::optional<const std::set<Identifier> *>
|
||||||
get_local_type_requirements(const std::string &name) const {
|
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() {
|
void clear_local_name_typeclasses() {
|
||||||
local_name_ids_.clear();
|
local_name_ids_.clear();
|
||||||
|
|
@ -459,13 +306,7 @@ private:
|
||||||
|
|
||||||
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 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:
|
||||||
// check is builtin type instaniated
|
// check is builtin type instaniated
|
||||||
|
|
|
||||||
|
|
@ -10,4 +10,203 @@ bool TypeProxy::operator==(const TypeProxy& other) const {
|
||||||
return *get() == *other.get();
|
return *get() == *other.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
TypeProxy TypeStorage::primitive(builtin::Type type) {
|
||||||
|
auto iter = primitive_type_ids_.find(type);
|
||||||
|
if (iter != primitive_type_ids_.end()) {
|
||||||
|
return TypeProxy(*this, iter->second);
|
||||||
|
} else {
|
||||||
|
primitive_type_ids_[type] = storage_.size();
|
||||||
|
return add_type(Type(Identifier(Node(), Identifier::SIMPLE_TYPE,
|
||||||
|
builtin::types::to_string(type))));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeProxy TypeStorage::add_array_of(TypeProxy type, 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;
|
||||||
|
parameters.push_back(type);
|
||||||
|
|
||||||
|
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||||
|
builtin::types::ARRAY_IDENTIFIER),
|
||||||
|
std::move(parameters)));
|
||||||
|
}
|
||||||
|
|
||||||
|
TypeProxy TypeStorage::add_error_of(TypeProxy type, Node node) {
|
||||||
|
if (type.type_storage_ != this) {
|
||||||
|
error_handling::handle_general_error(
|
||||||
|
"TypeStorage: Can't add error of type from another type "
|
||||||
|
"storage");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<nodes::TypeProxy> parameters;
|
||||||
|
parameters.push_back(type);
|
||||||
|
|
||||||
|
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||||
|
builtin::types::ERROR_IDENTIFIER),
|
||||||
|
std::move(parameters)));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::TypeProxy
|
||||||
|
TypeStorage::add_container_of(std::vector<TypeProxy> &¶meters,
|
||||||
|
builtin::Type container, 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(
|
||||||
|
nodes::Type(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
||||||
|
builtin::types::to_string(container)),
|
||||||
|
std::move(parameters)));
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::TypeProxy TypeStorage::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_copy.set_modifier(modifier);
|
||||||
|
|
||||||
|
return add_type(std::move(type_copy));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- deal with generic types (variable types in this case)
|
||||||
|
|
||||||
|
bool TypeStorage::resolve_all_generic_types() {
|
||||||
|
bool are_all_resolved = true;
|
||||||
|
|
||||||
|
bool new_types_resolved = true;
|
||||||
|
|
||||||
|
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 some 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool TypeStorage::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;
|
||||||
|
}
|
||||||
|
|
||||||
|
// -- deal with local types
|
||||||
|
|
||||||
|
bool TypeStorage::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 TypeStorage::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 TypeStorage::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> *>
|
||||||
|
TypeStorage::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> *>
|
||||||
|
TypeStorage::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];
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier TypeStorage::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;
|
||||||
|
}
|
||||||
|
|
||||||
}; // namespace nodes
|
}; // namespace nodes
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue