mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
TypeProxy changed to handle modifiers internally
This commit is contained in:
parent
5f8d5c5569
commit
fe6507ae12
7 changed files with 222 additions and 114 deletions
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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> &¶meters,
|
Type(Identifier &&identifier, std::vector<TypeProxy> &¶meters,
|
||||||
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> &¶meters,
|
Type(const Identifier &identifier, std::vector<TypeProxy> &¶meters,
|
||||||
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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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("^");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue