TypeProxy changed to handle modifiers internally

This commit is contained in:
ProgramSnail 2023-08-13 12:47:32 +03:00
parent 5f8d5c5569
commit fe6507ae12
7 changed files with 222 additions and 114 deletions

View file

@ -8,11 +8,10 @@
namespace nodes {
// replace enum with structure ??
enum class Modifier {
IN, // <- x
REF, // <> x
CONST, // -- x (or nothing sometimes)
CONST, // -- x (or x sometimes)
OUT, // -> x
//
IN_OR_REF, // <-|<> x
@ -37,9 +36,114 @@ enum class Modifier {
namespace utils {
inline bool is_suffix_modifier(nodes::Modifier modifier) {
return modifier == nodes::Modifier::OPTIONAL ||
modifier == nodes::Modifier::RESULT;
inline bool is_suffix_modifier(Modifier modifier) {
return modifier == Modifier::OPTIONAL || modifier == Modifier::RESULT;
}
inline bool modifier_contains_IN(Modifier modifier) {
return modifier == Modifier::IN || //
modifier == Modifier::IN_OR_REF || //
modifier == Modifier::IN_OR_CONST || //
modifier == Modifier::IN_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_OUT || //
modifier == Modifier::IN_OR_CONST_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST || //
modifier == Modifier::IN_OR_REF_OR_CONST_OR_OUT; //
}
inline bool modifier_contains_REF(Modifier modifier) {
return modifier == Modifier::REF || //
modifier == Modifier::IN_OR_REF || //
modifier == Modifier::REF_OR_OUT || //
modifier == Modifier::REF_OR_CONST || //
modifier == Modifier::IN_OR_REF_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST || //
modifier == Modifier::REF_OR_CONST_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST_OR_OUT; //
}
inline bool modifier_contains_CONST(Modifier modifier) {
return modifier == Modifier::CONST || //
modifier == Modifier::IN_OR_CONST || //
modifier == Modifier::CONST_OR_OUT || //
modifier == Modifier::REF_OR_CONST || //
modifier == Modifier::IN_OR_CONST_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST || //
modifier == Modifier::REF_OR_CONST_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST_OR_OUT; //
}
inline bool modifier_contains_OUT(Modifier modifier) {
return modifier == Modifier::OUT || //
modifier == Modifier::REF_OR_OUT || //
modifier == Modifier::CONST_OR_OUT || //
modifier == Modifier::IN_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_OUT || //
modifier == Modifier::IN_OR_CONST_OR_OUT || //
modifier == Modifier::REF_OR_CONST_OR_OUT || //
modifier == Modifier::IN_OR_REF_OR_CONST_OR_OUT; //
}
// possible casts:
// <> => ->
// <> => <-
// <> => --
inline bool can_cast_modifier(Modifier from, Modifier to) {
if (is_suffix_modifier(from) || is_suffix_modifier(to) ||
from == Modifier::NONE || to == Modifier::NONE) {
return false;
}
switch (from) {
case Modifier::IN: // // <- x
return modifier_contains_IN(to); //
case Modifier::REF: // // <> x
return true; //
case Modifier::CONST: // // -- x (or x sometimes)
return modifier_contains_CONST(to); //
case Modifier::OUT: // // -> x
return modifier_contains_OUT(to); //
//
case Modifier::IN_OR_REF: // // <-|<> x
return modifier_contains_IN(to); //
case Modifier::IN_OR_CONST: // // <-|-- x
return modifier_contains_IN(to) && //
modifier_contains_CONST(to); //
case Modifier::REF_OR_OUT: // // <>|-> x
return modifier_contains_OUT(to); //
case Modifier::CONST_OR_OUT: // // --|-> x
return modifier_contains_CONST(to) && //
modifier_contains_OUT(to); //
case Modifier::REF_OR_CONST: // // <>|-- x
return modifier_contains_CONST(to); //
case Modifier::IN_OR_OUT: // // <-|-> x
return modifier_contains_IN(to) && //
modifier_contains_OUT(to); //
//
case Modifier::IN_OR_REF_OR_OUT: // // <-|<>|-> x
return modifier_contains_IN(to) && //
modifier_contains_OUT(to); //
case Modifier::IN_OR_CONST_OR_OUT: // // <-|--|-> x
return modifier_contains_IN(to) && //
modifier_contains_CONST(to) && //
modifier_contains_OUT(to); //
case Modifier::IN_OR_REF_OR_CONST: // // <-|<>|-- x
return modifier_contains_IN(to) && //
modifier_contains_CONST(to); //
case Modifier::REF_OR_CONST_OR_OUT: // // <>|--|-> x
return modifier_contains_CONST(to) && //
modifier_contains_OUT(to); //
//
case Modifier::IN_OR_REF_OR_CONST_OR_OUT: // // <-|<>|--|-> x
return modifier_contains_IN(to) && //
modifier_contains_CONST(to) && //
modifier_contains_OUT(to); //
default:
break;
}
error_handling::handle_general_error("Unreachable");
exit(1); // unreachable
}
} // namespace utils

View file

@ -49,26 +49,26 @@ private:
class Type {
public:
Type(Identifier &&identifier, bool is_on_heap = false,
Type(Identifier &&identifier, Modifier modifier = nodes::Modifier::CONST,
const std::optional<std::string> &annotation = std::nullopt)
: name_(std::move(identifier)), is_on_heap_(is_on_heap),
: name_(std::move(identifier)), modifier_(modifier),
annotation_(annotation) {}
Type(const Identifier &identifier, bool is_on_heap = false,
Type(const Identifier &identifier, Modifier modifier = nodes::Modifier::CONST,
const std::optional<std::string> &annotation = std::nullopt)
: name_(identifier), is_on_heap_(is_on_heap), annotation_(annotation) {}
: name_(identifier), modifier_(modifier), annotation_(annotation) {}
Type(Identifier &&identifier, std::vector<TypeProxy> &&parameters,
bool is_on_heap = false,
Modifier modifier = nodes::Modifier::CONST,
const std::optional<std::string> &annotation = std::nullopt)
: name_(std::move(identifier)), parameters_(std::move(parameters)),
is_on_heap_(is_on_heap), annotation_(annotation) {}
modifier_(modifier), annotation_(annotation) {}
Type(const Identifier &identifier, std::vector<TypeProxy> &&parameters,
bool is_on_heap = false,
Modifier modifier = nodes::Modifier::CONST,
const std::optional<std::string> &annotation = std::nullopt)
: name_(identifier), parameters_(std::move(parameters)),
is_on_heap_(is_on_heap), annotation_(annotation) {}
modifier_(modifier), annotation_(annotation) {}
//
@ -90,9 +90,9 @@ public:
//
bool is_on_heap() const { return is_on_heap_; }
Modifier get_modifier() const { return modifier_; }
void set_is_on_heap(bool is_on_heap) { is_on_heap_ = is_on_heap; }
void set_modifier(Modifier modifier) { modifier_ = modifier; }
//
@ -133,7 +133,7 @@ public:
//
bool operator==(const Type &other) const {
if (name_ != other.name_ || is_on_heap_ != other.is_on_heap_ ||
if (name_ != other.name_ || modifier_ != other.modifier_ ||
parameters_.size() != other.parameters_.size()) {
return false;
}
@ -156,8 +156,8 @@ public:
return *name_.get() < *other.name_.get();
}
if (is_on_heap_ != other.is_on_heap_) {
return is_on_heap_ < other.is_on_heap_;
if (modifier_ != other.modifier_) {
return modifier_ < other.modifier_;
}
if (parameters_.size() != other.parameters_.size()) {
@ -198,8 +198,7 @@ public:
private:
Identifier name_;
std::vector<TypeProxy> parameters_;
// or use allocator ??
bool is_on_heap_ = false;
Modifier modifier_ = Modifier::NONE;
std::optional<std::string> annotation_;
};
@ -207,12 +206,12 @@ class TypeStorage {
friend TypeProxy;
public:
TypeProxy primitive_type(builtin::types::Type type, Node node = Node()) {
TypeProxy primitive_type(builtin::types::Type type) {
if (unit_type_id.has_value()) {
return TypeProxy(*this, unit_type_id.value());
} else {
unit_type_id = storage_.size();
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
return add_type(Type(Identifier(Node(), Identifier::SIMPLE_TYPE,
builtin::types::to_string(type))));
}
}
@ -235,6 +234,13 @@ public:
std::move(parameters)));
}
nodes::TypeProxy add_modification_of(TypeProxy type, Modifier modifier) {
Type type_copy = *type.get();
type_copy.set_modifier(modifier);
return add_type(std::move(type_copy));
}
TypeProxy add_type(const Type &type) {
storage_.push_back(type);
return TypeProxy(*this, storage_.size() - 1);
@ -256,57 +262,60 @@ private:
std::vector<Type> storage_;
};
class ModifiedTypeProxy {
public:
ModifiedTypeProxy(nodes::TypeProxy type,
nodes::Modifier modifier = nodes::Modifier::NONE)
: type_(type), modifier_(modifier) {}
//
nodes::Modifier get_modifier() const { return modifier_; }
void set_modifier(nodes::Modifier modifier) { modifier_ = modifier; }
//
nodes::Type *get_type() { return type_.get(); }
const nodes::Type *get_type() const { return type_.get(); }
const nodes::TypeProxy get_type_proxy() const { return type_; }
//
bool operator==(const ModifiedTypeProxy &other) const {
return *type_.get() == *other.type_.get() && modifier_ == other.modifier_;
}
bool operator!=(const ModifiedTypeProxy &other) const {
return !(*this == other);
}
//
bool operator<(const ModifiedTypeProxy &other) const {
return *type_.get() < *other.type_.get() ||
(*type_.get() == *other.type_.get() && modifier_ < other.modifier_);
}
bool operator>(const ModifiedTypeProxy &other) const { return other < *this; }
bool operator<=(const ModifiedTypeProxy &other) const {
return !operator>(other);
}
bool operator>=(const ModifiedTypeProxy &other) const {
return !operator<(other);
}
private:
nodes::TypeProxy type_;
nodes::Modifier modifier_;
};
// class ModifiedTypeProxy {
// public:
// ModifiedTypeProxy(nodes::TypeProxy type,
// nodes::Modifier modifier = nodes::Modifier::NONE)
// : type_(type), modifier_(modifier) {}
//
// //
//
// nodes::Modifier get_modifier() const { return modifier_; }
//
// void set_modifier(nodes::Modifier modifier) { modifier_ = modifier; }
//
// //
//
// nodes::Type *get_type() { return type_.get(); }
//
// const nodes::Type *get_type() const { return type_.get(); }
//
// const nodes::TypeProxy get_type_proxy() const { return type_; }
//
// //
//
// bool operator==(const ModifiedTypeProxy &other) const {
// return *type_.get() == *other.type_.get() && modifier_ ==
// other.modifier_;
// }
//
// bool operator!=(const ModifiedTypeProxy &other) const {
// return !(*this == other);
// }
//
// //
//
// bool operator<(const ModifiedTypeProxy &other) const {
// return *type_.get() < *other.type_.get() ||
// (*type_.get() == *other.type_.get() && modifier_ <
// other.modifier_);
// }
//
// bool operator>(const ModifiedTypeProxy &other) const { return other <
// *this; }
//
// bool operator<=(const ModifiedTypeProxy &other) const {
// return !operator>(other);
// }
//
// bool operator>=(const ModifiedTypeProxy &other) const {
// return !operator<(other);
// }
//
// private:
// nodes::TypeProxy type_;
// nodes::Modifier modifier_;
// };
class TypeCheckResult {
public:
@ -315,12 +324,11 @@ public:
return TypeCheckResult();
}
explicit TypeCheckResult(std::optional<ModifiedTypeProxy> type)
: type_(type) {}
explicit TypeCheckResult(std::optional<TypeProxy> type) : type_(type) {}
//
ModifiedTypeProxy &get() {
TypeProxy &get() {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
@ -329,7 +337,7 @@ public:
return type_.value();
}
const ModifiedTypeProxy &get() const {
const TypeProxy &get() const {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
@ -338,7 +346,7 @@ public:
return type_.value();
}
void set(ModifiedTypeProxy type) { type_ = type; }
void set(TypeProxy type) { type_ = type; }
//
@ -348,7 +356,7 @@ private:
TypeCheckResult() = default;
private:
std::optional<ModifiedTypeProxy> type_;
std::optional<TypeProxy> type_;
};
} // namespace nodes