es_builtin for type, type utils state fixes

This commit is contained in:
ProgramSnail 2024-01-03 21:55:24 +03:00
parent f03f77191f
commit ffa9c47107
3 changed files with 63 additions and 27 deletions

View file

@ -26,7 +26,7 @@ public:
const Type *get() const; const Type *get() const;
bool operator==(const TypeProxy& other) const; bool operator==(const TypeProxy &other) const;
private: private:
TypeProxy(TypeStorage &type_storage, size_t id) TypeProxy(TypeStorage &type_storage, size_t id)
@ -191,6 +191,8 @@ public:
return builtin_type; return builtin_type;
} }
bool is_builtin(builtin::types::Type type) { return to_builtin() == type; }
private: private:
Identifier name_; Identifier name_;
std::vector<TypeProxy> parameters_; std::vector<TypeProxy> parameters_;

View file

@ -42,8 +42,8 @@ public:
"Set brought type to contexts_ with zero elements in State"); "Set brought type to contexts_ with zero elements in State");
} }
auto &brought_type = contexts_.back().brought_type; auto &brought_type = contexts_.back().brought_type;
if (brought_type.has_value() &&) { if (brought_type.has_value() &&
// TODO type != brought_type.value()) { // check inheritance, etc ??
return false; return false;
} }
brought_type = type; brought_type = type;
@ -56,8 +56,8 @@ public:
"Set returned type to contexts_ with zero elements in State"); "Set returned type to contexts_ with zero elements in State");
} }
auto &returned_type = contexts_.back().returned_type; auto &returned_type = contexts_.back().returned_type;
if (returned_type.has_value() &&) { if (returned_type.has_value() &&
// TODO type != returned_type.value()) { // check inheritance, etc ??
return false; return false;
} }
returned_type = type; returned_type = type;
@ -65,7 +65,10 @@ public:
} }
private: private:
void enter_context(const nodes::Node &node) { contexts_.emplace_back(node); } void enter_context(const nodes::Node &node,
error_handling::ErrorLog &error_log) {
contexts_.emplace_back(node, error_log);
}
// returns brought type, return type is merged with next context or with // returns brought type, return type is merged with next context or with
// brought type in last context // brought type in last context
@ -75,14 +78,33 @@ private:
"Pop from contexts_ with zero elements in State"); "Pop from contexts_ with zero elements in State");
} }
const auto brought_type = contexts_.back().brought_type; auto context = std::move(contexts_.back());
const auto returned_type = contexts_.back().returned_type;
contexts_.pop_back(); contexts_.pop_back();
auto &brought_type = context.brought_type;
const auto &returned_type = context.returned_type;
if (returned_type.has_value()) {
if (contexts_.empty()) { if (contexts_.empty()) {
// TODO: merge returned and brought types if (brought_type.has_value()) {
if (returned_type.value() != brought_type.value()) {
context.log_typecheck_error(
"Different returned and brought type in last context");
}
} else { } else {
// TODO: merge to previous brought_type = returned_type.value();
}
} else {
auto &previous_returned_type = contexts_.back().returned_type;
if (previous_returned_type.has_value()) {
if (returned_type.value() != previous_returned_type.value()) {
context.log_typecheck_error(
"Different returned type in this context and previous one");
}
} else {
previous_returned_type = returned_type.value();
}
}
} }
return brought_type; return brought_type;
@ -91,16 +113,25 @@ private:
public: public:
class Context { class Context {
public: public:
Context(const nodes::Node &node) : node(node) {} Context(const nodes::Node &node, error_handling::ErrorLog &error_log)
: node(node), error_log(error_log) {}
void log_typecheck_error(
const std::string &message = "Context typecheck error") {
error_log.add_error(error_handling::ErrorLog::ErrorMessage(
node, message, error_handling::ErrorType::TYPE_CHECK));
}
public: public:
nodes::MaybeTypeProxy brought_type; nodes::MaybeTypeProxy brought_type;
nodes::MaybeTypeProxy returned_type; nodes::MaybeTypeProxy returned_type;
std::unordered_map<std::string, nodes::TypeProxy> variables; std::unordered_map<std::string, nodes::TypeProxy> variables;
private:
const nodes::Node &node; const nodes::Node &node;
error_handling::ErrorLog &error_log;
}; };
private:
std::vector<Context> contexts_ = {{}}; std::vector<Context> contexts_ = {{}};
}; };
@ -111,8 +142,10 @@ public:
class ContextHolder { class ContextHolder {
public: public:
ContextHolder(State &state, const nodes::Node &node) : state(state) { ContextHolder(State &state, const nodes::Node &node,
state.enter_context(node); error_handling::ErrorLog &error_log)
: state(state) {
state.enter_context(node, error_log);
} }
ContextHolder(const ContextHolder &) = delete; ContextHolder(const ContextHolder &) = delete;

View file

@ -120,8 +120,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
return condition_result.value(); return condition_result.value();
} }
if (condition_result.value().get().get()->to_builtin() != if (!condition_result.value().get().get()->is_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(
*expression.get_condition().value(), *expression.get_condition().value(),
@ -145,8 +145,9 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
} }
// // TODO ?? // // TODO ??
// if (variable_result.value().get().get_type()->to_builtin() != // if
// builtin::types::Type::BOOL) { // (!variable_result.value().get().get_type()->is_builtin(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(
// *expression.get_condition().value(), // *expression.get_condition().value(),
@ -156,8 +157,8 @@ nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
// } // }
// TODO: ranges ?? // TODO: ranges ??
if (condition_result.value().get().get()->to_builtin() != if (!condition_result.value().get().get()->is_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.get_condition().value(), *expression.get_condition().value(),
@ -231,10 +232,10 @@ nodes::TypeCheckResult type_check_container(const nodes::Container &expression,
const Arguments &arguments) { const Arguments &arguments) {
switch (expression.get_type()) { switch (expression.get_type()) {
case nodes::Container::ARRAY: case nodes::Container::ARRAY:
return type_check_array(expression, sources_manager, state); return type_check_array(expression, sources_manager, state, arguments);
case nodes::Container::BLOCK: case nodes::Container::BLOCK:
return type_check_block(expression, sources_manager, return type_check_block(expression, sources_manager,
state); // TODO: check that expression brought state, arguments); // TODO: check that expression brought
// type are same, -> brought_type // type are same, -> brought_type
} }
} // IN PROGRESS } // IN PROGRESS
@ -303,7 +304,7 @@ nodes::TypeCheckResult type_check_array_access(const nodes::Access &expression,
return value_result; return value_result;
} }
if (index_result.get().get()->to_builtin() != builtin::types::Type::INDEX) { if (!index_result.get().get()->is_builtin(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",
@ -311,7 +312,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()->to_builtin() != builtin::types::Type::ARRAY) { if (!value_result.get().get()->is_builtin(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",
@ -342,7 +343,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()->to_builtin() != builtin::types::Type::TUPLE) { if (!value_result.get().get()->is_builtin(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",