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

@ -11,8 +11,8 @@
namespace type_check { namespace type_check {
struct State { struct State {
std::optional<nodes::ModifiedTypeProxy> brought_type; std::optional<nodes::TypeProxy> brought_type;
std::optional<nodes::ModifiedTypeProxy> returned_type; std::optional<nodes::TypeProxy> returned_type;
}; };
nodes::TypeCheckResult nodes::TypeCheckResult

View file

@ -8,11 +8,10 @@
namespace nodes { namespace nodes {
// replace enum with structure ??
enum class Modifier { enum class Modifier {
IN, // <- x IN, // <- x
REF, // <> x REF, // <> x
CONST, // -- x (or nothing sometimes) CONST, // -- x (or x sometimes)
OUT, // -> x OUT, // -> x
// //
IN_OR_REF, // <-|<> x IN_OR_REF, // <-|<> x
@ -37,9 +36,114 @@ enum class Modifier {
namespace utils { namespace utils {
inline bool is_suffix_modifier(nodes::Modifier modifier) { inline bool is_suffix_modifier(Modifier modifier) {
return modifier == nodes::Modifier::OPTIONAL || return modifier == Modifier::OPTIONAL || modifier == Modifier::RESULT;
modifier == nodes::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 } // namespace utils

View file

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

View file

@ -59,6 +59,6 @@ nodes::TypeCheckResult type_check_literal(const nodes::Literal &literal,
error_handling::handle_general_error("Unreachable"); error_handling::handle_general_error("Unreachable");
exit(1); // unreachable exit(1); // unreachable
} // IN PROGRESS: modifiers ?? }
} // namespace type_check } // namespace type_check

View file

@ -87,12 +87,13 @@ nodes::TypeProxy build_array_type(parser::ParseTree::Node parser_node,
build_node(parser_node)); build_node(parser_node));
} }
// TODO: add different reference types
// '^' type // '^' type
nodes::TypeProxy build_reference_type(parser::ParseTree::Node parser_node, nodes::TypeProxy build_reference_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) { nodes::TypeStorage &type_storage) {
nodes::TypeProxy type = nodes::TypeProxy type =
build_type(parser_node.nth_named_child(0), type_storage); build_type(parser_node.nth_named_child(0), type_storage);
type.get()->set_is_on_heap(true); type.get()->set_modifier(nodes::Modifier::REF);
return type; return type;
} }
@ -124,7 +125,7 @@ nodes::TypeProxy build_modified_type(parser::ParseTree::Node parser_node,
return type_storage.add_type( return type_storage.add_type(
nodes::Type(nodes::Identifier(build_node(parser_node), nodes::Type(nodes::Identifier(build_node(parser_node),
nodes::Identifier::SIMPLE_TYPE, identifier), nodes::Identifier::SIMPLE_TYPE, identifier),
std::move(parameters), false)); std::move(parameters)));
} }
// type_identifier ('[' type+ ']')? // type_identifier ('[' type+ ']')?
@ -141,7 +142,7 @@ nodes::TypeProxy build_simple_type(parser::ParseTree::Node parser_node,
} }
return type_storage.add_type( return type_storage.add_type(
nodes::Type(build_identifier(name_node), std::move(parameters), false)); nodes::Type(build_identifier(name_node), std::move(parameters)));
} }
} // namespace builders } // namespace builders

View file

@ -63,7 +63,7 @@ type_check_expression(const nodes::Expression &expression,
case 12: // Literal case 12: // Literal
// TODO // TODO
return type_check_literal(*expression.get<nodes::Literal>().value(), return type_check_literal(*expression.get<nodes::Literal>().value(),
sources_manager, state); sources_manager);
// --- empty lines // --- empty lines
case 13: // Extra case 13: // Extra
return nodes::TypeCheckResult( return nodes::TypeCheckResult(
@ -113,7 +113,7 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
return condition_result.value(); return condition_result.value();
} }
if (condition_result.value().get().get_type()->to_builtin() != if (condition_result.value().get().get()->to_builtin() !=
builtin::types::Type::BOOL) { builtin::types::Type::BOOL) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
@ -149,7 +149,7 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
// } // }
// TODO: ranges ?? // TODO: ranges ??
if (condition_result.value().get().get_type()->to_builtin() != if (condition_result.value().get().get()->to_builtin() !=
builtin::types::Type::ARRAY) { builtin::types::Type::ARRAY) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
@ -165,12 +165,11 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
return expression_result; return expression_result;
} }
// TODO: modifier checks ?? // TODO: modifier checks ??, modifiers ??
return nodes::TypeCheckResult( return nodes::TypeCheckResult(
nodes::ModifiedTypeProxy(sources_manager.get_type_storage()->add_array_of( sources_manager.get_type_storage()->add_array_of(
expression_result.get().get_type_proxy()), expression_result.get()));
expression_result.get().get_modifier()));
} // IN PROGRESS } // IN PROGRESS
// --- containers // --- containers
@ -187,7 +186,8 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
if (!last_expression_result.has_value()) { if (!last_expression_result.has_value()) {
last_expression_result = expression_result; last_expression_result = expression_result;
} else { } else {
if (last_expression_result.value().get() != expression_result.get()) { if (*last_expression_result.value().get().get() !=
*expression_result.get().get()) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
*expression.get_expression(i), *expression.get_expression(i),
@ -206,10 +206,9 @@ nodes::TypeCheckResult type_check_array(const nodes::Container &expression,
return nodes::TypeCheckResult::construct_invalid_result(); return nodes::TypeCheckResult::construct_invalid_result();
} }
return nodes::TypeCheckResult(nodes::ModifiedTypeProxy( return nodes::TypeCheckResult(
sources_manager.get_type_storage()->add_array_of( sources_manager.get_type_storage()->add_array_of(
last_expression_result.value().get().get_type_proxy()), last_expression_result.value().get()));
last_expression_result.value().get().get_modifier()));
} // IN PROGRESS } // IN PROGRESS
// TODO // TODO
@ -245,8 +244,7 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
switch (expression.get_type()) { switch (expression.get_type()) {
case nodes::Return::BRING: case nodes::Return::BRING:
if (state.brought_type.has_value()) { if (state.brought_type.has_value()) {
if (*state.brought_type.value().get_type() != if (*state.brought_type.value().get() != *returned_result.get().get()) {
*returned_result.get().get_type()) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
expression, "Different brought type to current one", expression, "Different brought type to current one",
@ -259,8 +257,7 @@ nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
break; break;
case nodes::Return::RETURN: case nodes::Return::RETURN:
if (state.returned_type.has_value()) { if (state.returned_type.has_value()) {
if (*state.returned_type.value().get_type() != if (*state.returned_type.value().get() != *returned_result.get().get()) {
*returned_result.get().get_type()) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
expression, "Different returned type to current one", expression, "Different returned type to current one",
@ -301,8 +298,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
return value_result; return value_result;
} }
if (index_result.get().get_type()->to_builtin() != if (index_result.get().get()->to_builtin() != builtin::types::Type::INDEX) {
builtin::types::Type::INDEX) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
expression, "Can access only by Index", expression, "Can access only by Index",
@ -310,8 +306,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
return nodes::TypeCheckResult::construct_invalid_result(); return nodes::TypeCheckResult::construct_invalid_result();
} }
if (value_result.get().get_type()->to_builtin() != if (value_result.get().get()->to_builtin() != builtin::types::Type::ARRAY) {
builtin::types::Type::ARRAY) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
expression, "Can apply array access only to Array", expression, "Can apply array access only to Array",
@ -322,7 +317,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
// TODO: modifier checks ?? // TODO: modifier checks ??
return nodes::TypeCheckResult( return nodes::TypeCheckResult(
value_result.get().get_type()->get_parameter_proxy(0)); value_result.get().get()->get_parameter_proxy(0));
} }
nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression, nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
@ -341,8 +336,7 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
->get<size_t>() // Index type ->get<size_t>() // Index type
.value(); .value();
if (value_result.get().get_type()->to_builtin() != if (value_result.get().get()->to_builtin() != builtin::types::Type::TUPLE) {
builtin::types::Type::TUPLE) {
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
error_handling::ErrorLog::ErrorMessage( error_handling::ErrorLog::ErrorMessage(
expression, "Can apply tuple access only to Tuple", expression, "Can apply tuple access only to Tuple",
@ -353,7 +347,7 @@ nodes::TypeCheckResult type_check_tuple_access(const nodes::Access &expression,
// TODO: modifier checks ?? // TODO: modifier checks ??
return nodes::TypeCheckResult( return nodes::TypeCheckResult(
value_result.get().get_type()->get_parameter_proxy(index)); value_result.get().get()->get_parameter_proxy(index));
} }
nodes::TypeCheckResult type_check_access(const nodes::Access &expression, nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
@ -388,12 +382,11 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression,
// '!' - open optional / result -> value / panic // '!' - open optional / result -> value / panic
switch (modified_result.get().get_type()->to_builtin()) { switch (modified_result.get().get()->to_builtin()) {
case builtin::types::Type::OPTIONAL: case builtin::types::Type::OPTIONAL:
case builtin::types::Type::RESULT: case builtin::types::Type::RESULT:
modified_result.set(nodes::ModifiedTypeProxy( // TODO: how to unwrap external modifier ??
modified_result.get().get_type()->get_parameter_proxy(0), modified_result.set(modified_result.get().get()->get_parameter_proxy(0));
modified_result.get().get_modifier()));
break; break;
default: default:
sources_manager.get_error_log()->add_error( sources_manager.get_error_log()->add_error(
@ -404,7 +397,8 @@ type_check_modifier_expression(const nodes::ModifierExpression &expression,
} }
} else { } else {
// TODO: check that modifier can be applied // TODO: check that modifier can be applied
modified_result.get().set_modifier(expression.get_modifier()); modified_result.set(sources_manager.get_type_storage()->add_modification_of(
modified_result.get(), expression.get_modifier()));
} }
return modified_result; return modified_result;

View file

@ -7,7 +7,8 @@ namespace printers {
// TODO: better printing format for builtin types // TODO: better printing format for builtin types
void print_type(const nodes::Type &type, printers::Printer &printer) { void print_type(const nodes::Type &type, printers::Printer &printer) {
if (type.is_on_heap()) { // TODO: more modifier types
if (type.get_modifier() == nodes::Modifier::REF) {
printer.print("^"); printer.print("^");
} }