fixes, refactoring (shorter names, visitor)

This commit is contained in:
ProgramSnail 2024-05-01 14:05:29 +03:00
parent 57b1172a4f
commit f58bfd938c
20 changed files with 564 additions and 764 deletions

View file

@ -7,9 +7,7 @@
namespace type_check {
// IN PROGRESS: modifiers ??
nodes::TypeCheckResult
type_check_literal(const nodes::Literal &literal,
SourcesManager &sources_manager,
const Arguments& arguments);
Result check(const nodes::Literal &literal, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
} // namespace type_check

View file

@ -5,7 +5,33 @@
#include "basic_nodes.hpp"
namespace builtin::types {
namespace builtin {
enum class Type {
// -- containers
TUPLE,
VARIANT,
FUNCTION,
ARRAY,
OPTIONAL,
RESULT,
ERROR,
// -- basic types
FLOAT,
DOUBLE,
INT,
LONG,
INDEX,
CHAR,
UNICODE,
BOOL,
UNIT,
NULL_OPTION,
// -- none
NONE,
};
namespace types {
// -- containers
@ -50,30 +76,6 @@ const static std::string NULL_OPTION_IDENTIFIER = "Null";
//
enum class Type {
// -- containers
TUPLE,
VARIANT,
FUNCTION,
ARRAY,
OPTIONAL,
RESULT,
ERROR,
// -- basic types
FLOAT,
DOUBLE,
INT,
LONG,
INDEX,
CHAR,
UNICODE,
BOOL,
UNIT,
NULL_OPTION,
// -- none
NONE,
};
inline std::string to_string(Type type) {
switch (type) {
// -- containers
@ -202,4 +204,6 @@ inline std::optional<size_t> get_parameters_count(Type type) {
exit(1); // unreachable
}
} // namespace builtin::types
} // namespace types
} // namespace builtin

View file

@ -12,77 +12,66 @@
namespace type_check {
nodes::TypeCheckResult
type_check_expression(const nodes::Expression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::Expression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
// --- flow control
nodes::TypeCheckResult type_check_match(const nodes::Match &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Match &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
nodes::TypeCheckResult type_check_condition(const nodes::Condition &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Condition &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
nodes::TypeCheckResult type_check_loop(const nodes::Loop &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Loop &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
// --- containers
nodes::TypeCheckResult type_check_container(const nodes::Container &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Container &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
// --- modifiers
nodes::TypeCheckResult type_check_return(const nodes::Return &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Return &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
nodes::TypeCheckResult
type_check_name_definition(const nodes::NameDefinition &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::NameDefinition &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
nodes::TypeCheckResult type_check_access(const nodes::Access &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Access &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
nodes::TypeCheckResult
type_check_loop_control(const nodes::LoopControl &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::LoopControl &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
nodes::TypeCheckResult
type_check_modifier_expression(const nodes::ModifierExpression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::ModifierExpression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
// --- other
nodes::TypeCheckResult
type_check_name_expression(const nodes::NameExpression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::NameExpression &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
nodes::TypeCheckResult
type_check_constructor(const nodes::Constructor &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
Result check(const nodes::Constructor &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
nodes::TypeCheckResult type_check_lambda(const nodes::Lambda &expression,
SourcesManager &sources_manager,
State &state,
const Arguments &arguments);
Result check(const nodes::Lambda &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
Result check(const nodes::Extra &expression, SourcesManager &sources_manager,
State &state, const Arguments &arguments);
Result check(const nodes::EmptyLines &expression,
SourcesManager &sources_manager, State &state,
const Arguments &arguments);
} // namespace type_check

View file

@ -217,7 +217,7 @@ public:
bool operator>=(const Type &other) const { return !operator<(other); }
// is parameters count check necessary ??
builtin::types::Type to_builtin() const {
builtin::Type to_builtin() const {
auto builtin_type = builtin::types::to_type(*name_.get());
auto builtin_type_parameters_count =
@ -226,15 +226,13 @@ public:
// for fixed parameter counts
if (builtin_type_parameters_count.has_value() &&
builtin_type_parameters_count.value() != parameters_.size()) {
return builtin::types::Type::NONE;
return builtin::Type::NONE;
}
return builtin_type;
}
bool is_builtin(builtin::types::Type type) const {
return to_builtin() == type;
}
bool is_builtin(builtin::Type type) const { return to_builtin() == type; }
private:
Identifier name_;
@ -247,7 +245,7 @@ class TypeStorage {
friend TypeProxy;
public:
TypeProxy primitive_type(builtin::types::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);
@ -289,7 +287,7 @@ public:
}
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &&parameters,
builtin::types::Type container,
builtin::Type container,
Node node = Node()) {
for (auto &parameter : parameters) {
if (parameter.type_storage_ != this) {
@ -343,7 +341,7 @@ public:
if (type.is_generic()) {
auto iter = resolved_generic_names_.find(*type.get_name()->get());
// because of undefined order sone types can became resolved earlir
// 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()) {
@ -471,7 +469,7 @@ private:
private:
// check is builtin type instaniated
std::unordered_map<builtin::types::Type, size_t> primitive_type_ids_;
std::unordered_map<builtin::Type, size_t> primitive_type_ids_;
// deal with generic types and generic names
std::unordered_map<std::string, size_t> resolved_generic_names_;
@ -485,46 +483,4 @@ private:
std::vector<Type> storage_;
};
class TypeCheckResult {
public:
// for invalid type
static TypeCheckResult construct_invalid_result() {
return TypeCheckResult();
}
explicit TypeCheckResult(nodes::TypeProxy type) : type_(type) {}
//
TypeProxy &get() {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
}
return type_.value();
}
const TypeProxy &get() const {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
}
return type_.value();
}
void set(TypeProxy type) { type_ = type; }
//
bool is_invalid() const { return !type_.has_value(); }
private:
TypeCheckResult() = default;
private:
nodes::MaybeTypeProxy type_;
};
} // namespace nodes

View file

@ -124,17 +124,24 @@ private:
size_t indentation_level_ = 0;
};
void print_modifier(const nodes::Modifier &modifier, Printer &printer,
bool const_is_none = false);
void print(const nodes::Modifier &modifier, Printer &printer,
bool const_is_none = false);
void print_literal(const nodes::Literal &literal, Printer &printer);
void print(const nodes::Literal &literal, Printer &printer);
void print_identifier(const nodes::Identifier &identifier, Printer &printer);
void print(const nodes::Identifier &identifier, Printer &printer);
void print_annotation(const std::string &annotation, Printer &printer);
void print_extra(const nodes::Extra &extra, Printer &printer);
void print(const nodes::Extra &extra, Printer &printer);
void print_empty_lines(const nodes::EmptyLines &empty_lines, Printer &printer);
void print(const nodes::EmptyLines &empty_lines, Printer &printer);
template <typename T>
inline void print(const std::vector<T> &nodes, Printer &printer) {
for (const auto &node : nodes) {
print(node, printer);
}
}
} // namespace printers

View file

@ -5,6 +5,6 @@
namespace printers {
void print_docs(const nodes::SymbolDocs &docs, Printer &printer);
void print(const nodes::SymbolDocs &docs, Printer &printer);
} // namespace printers

View file

@ -4,48 +4,41 @@
#include "expression_nodes.hpp"
namespace printers {
void print_expression(const nodes::Expression &expression,
printers::Printer &printer);
void print(const nodes::Expression &expression, printers::Printer &printer);
// --- flow control
void print_case(const nodes::Match::Case &expression, Printer &printer);
void print(const nodes::Match::Case &expression, Printer &printer);
void print_match(const nodes::Match &expression, printers::Printer &printer);
void print(const nodes::Match &expression, printers::Printer &printer);
void print_condition(const nodes::Condition &expression,
printers::Printer &printer);
void print(const nodes::Condition &expression, printers::Printer &printer);
void print_loop(const nodes::Loop &expression, printers::Printer &printer);
void print(const nodes::Loop &expression, printers::Printer &printer);
// --- containers
void print_container(const nodes::Container &expression,
printers::Printer &printer);
void print(const nodes::Container &expression, printers::Printer &printer);
// --- modifiers
void print_return(const nodes::Return &expression, printers::Printer &printer);
void print(const nodes::Return &expression, printers::Printer &printer);
void print_name_definition(const nodes::NameDefinition &expression,
printers::Printer &printer);
void print(const nodes::NameDefinition &expression, printers::Printer &printer);
void print_access(const nodes::Access &expression, printers::Printer &printer);
void print(const nodes::Access &expression, printers::Printer &printer);
void print_loop_control(const nodes::LoopControl &expression,
printers::Printer &printer);
void print(const nodes::LoopControl &expression, printers::Printer &printer);
void print_modifier_expression(const nodes::ModifierExpression &expression,
printers::Printer &printer);
void print(const nodes::ModifierExpression &expression,
printers::Printer &printer);
// --- other
void print_name_expression(const nodes::NameExpression &expression,
printers::Printer &printer);
void print(const nodes::NameExpression &expression, printers::Printer &printer);
void print_constructor(const nodes::Constructor &expression,
printers::Printer &printer);
void print(const nodes::Constructor &expression, printers::Printer &printer);
void print_lambda(const nodes::Lambda &expression, printers::Printer &printer);
void print(const nodes::Lambda &expression, printers::Printer &printer);
} // namespace printers

View file

@ -7,19 +7,17 @@
namespace printers {
void print_source_file(const std::vector<nodes::Statement> &statements,
Printer &printer);
// void print_source_file(const std::vector<nodes::Statement> &statements,
// Printer &printer);
void print_statement(const nodes::Statement &statements, Printer &printer);
void print(const nodes::Statement &statements, Printer &printer);
void print_import(const nodes::Import &statement, Printer &printer);
void print(const nodes::Import &statement, Printer &printer);
void print_constraint(const nodes::Constraint &statement, Printer &printer);
void print(const nodes::Constraint &statement, Printer &printer);
void print_type_definition(const nodes::TypeDefinition &statement,
Printer &printer);
void print(const nodes::TypeDefinition &statement, Printer &printer);
void print_function_definition(const nodes::FunctionDefinition &statement,
Printer &printer);
void print(const nodes::FunctionDefinition &statement, Printer &printer);
} // namespace printers

View file

@ -5,7 +5,7 @@
namespace printers {
void print_type(const nodes::Type &type, printers::Printer &printer);
void print(const nodes::Type &type, printers::Printer &printer);
// void print_tuple_type(const nodes::TupleType &type, printers::Printer
// &printer);

View file

@ -49,44 +49,42 @@ public:
void print(std::ostream &out) {
printers::Printer printer(out, 2, 80, true);
printers::print_source_file(statements_, printer);
printers::print(statements_, printer);
}
//
nodes::ExpressionStorage *get_expression_storage() {
return &expression_storage_;
}
nodes::ExpressionStorage *expressions() { return &expression_storage_; }
const nodes::ExpressionStorage *get_expression_storage() const {
const nodes::ExpressionStorage *expressions() const {
return &expression_storage_;
}
//
nodes::TypeStorage *get_type_storage() { return &type_storage_; }
nodes::TypeStorage *types() { return &type_storage_; }
const nodes::TypeStorage *get_type_storage() const { return &type_storage_; }
const nodes::TypeStorage *types() const { return &type_storage_; }
//
names::NameTree *get_name_tree() { return &name_tree_; }
names::NameTree *names() { return &name_tree_; }
const names::NameTree *get_name_tree() const { return &name_tree_; }
const names::NameTree *names() const { return &name_tree_; }
//
error_handling::ErrorLog *get_error_log() { return &error_log_; }
error_handling::ErrorLog *errors() { return &error_log_; }
const error_handling::ErrorLog *get_error_log() const { return &error_log_; }
const error_handling::ErrorLog *errors() const { return &error_log_; }
//
size_t statements_size() const { return statements_.size(); }
nodes::Statement *get_statement(size_t id) { return &statements_.at(id); }
nodes::Statement *statement(size_t id) { return &statements_.at(id); }
const nodes::Statement *get_statement(size_t id) const {
const nodes::Statement *statement(size_t id) const {
return &statements_.at(id);
}

View file

@ -145,23 +145,23 @@ public:
std::vector<Context> contexts_ = {{}};
};
//
class Arguments {
public:
Arguments() = default;
Arguments expect_builtin(builtin::types::Type type,
Arguments expect_builtin(builtin::Type type,
SourcesManager &sources_manager) const {
Arguments copy(*this);
copy.expected_types_ = {
sources_manager.get_type_storage()->primitive_type(type)};
copy.expected_types_ = {sources_manager.types()->primitive(type)};
return copy;
}
Arguments pass_builtin(builtin::types::Type type,
Arguments pass_builtin(builtin::Type type,
SourcesManager &sources_manager) const {
Arguments copy(*this);
copy.passed_type_ =
sources_manager.get_type_storage()->primitive_type(type);
copy.passed_type_ = sources_manager.types()->primitive(type);
return copy;
}
@ -208,6 +208,8 @@ private:
nodes::MaybeTypeProxy passed_type_;
};
//
class ContextHolder {
public:
ContextHolder(State &state, const nodes::Node &node,
@ -236,6 +238,52 @@ private:
nodes::MaybeTypeProxy *context_exit_type_;
};
//
class Result {
public:
// for invalid type
static Result invalid() { return Result(); }
explicit Result(nodes::TypeProxy type) : type_(type) {}
//
nodes::TypeProxy &get() {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
}
return type_.value();
}
const nodes::TypeProxy &get() const {
if (!type_.has_value()) {
error_handling::handle_general_error(
"Access to invalid type in TypeCheckResult");
}
return type_.value();
}
void set(nodes::TypeProxy type) { type_ = type; }
//
bool is_invalid() const { return !type_.has_value(); }
private:
Result() = default;
private:
nodes::MaybeTypeProxy type_;
};
using MaybeResult = std::optional<Result>;
//
nodes::TypeProxy check_same_to_pass_type_in_arguments(
nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node,
SourcesManager &sources_manager,
@ -247,15 +295,17 @@ nodes::TypeProxy check_same_to_pass_type_in_arguments(
// SourcesManager &sources_manager,
// const std::string &message = "Type can't be passed to this node");
nodes::TypeCheckResult type_same_to_expected(
Result type_same_to_expected(
nodes::TypeProxy type, const Arguments &argumensr, const nodes::Node &node,
SourcesManager &sources_manager,
const std::string &message = "Different type with expected one",
bool handle_errors = true);
nodes::TypeCheckResult type_check_from_arguments(
nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node,
SourcesManager &sources_manager, bool handle_errors = true);
Result type_check_from_arguments(nodes::TypeProxy type,
const Arguments &arguments,
const nodes::Node &node,
SourcesManager &sources_manager,
bool handle_errors = true);
std::optional<const nodes::TypeDefinition *>
find_type_definition(const std::string &name, const nodes::Node &node,
@ -267,15 +317,16 @@ find_name_definition(const std::string &name, const nodes::Node &node,
SourcesManager &sources_manager,
bool handle_errors = true);
std::optional<nodes::TypeProxy>
unfold_user_defined_type(nodes::TypeProxy type, const nodes::Node &node,
SourcesManager &sources_manager,
bool handle_errors = true);
nodes::MaybeTypeProxy unfold_user_defined_type(nodes::TypeProxy type,
const nodes::Node &node,
SourcesManager &sources_manager,
bool handle_errors = true);
std::optional<nodes::TypeProxy>
get_field_type_by_name(nodes::TypeProxy type, const std::string &field,
const nodes::Node &node, SourcesManager &sources_manager,
bool handle_errors = true);
nodes::MaybeTypeProxy get_field_type_by_name(nodes::TypeProxy type,
const std::string &field,
const nodes::Node &node,
SourcesManager &sources_manager,
bool handle_errors = true);
void type_check_error(const std::string &message, const nodes::Node &node,
SourcesManager &sources_manager,