folder structure refactoring

This commit is contained in:
ProgramSnail 2023-08-02 18:19:11 +03:00
parent ef88e6af86
commit 78c696b99a
30 changed files with 40 additions and 22 deletions

View file

@ -0,0 +1,13 @@
#include "expression_nodes.hpp"
namespace nodes {
Expression *ExpressionProxy::get() {
return expression_storage_->get_expression(id_);
}
const Expression *ExpressionProxy::get() const {
return expression_storage_->get_expression(id_);
}
}; // namespace nodes

View file

@ -0,0 +1,313 @@
#include "statement_nodes.hpp"
#include "error_handling.hpp"
#include "utils.hpp"
#include <algorithm>
namespace nodes {
bool FunctionDefinition::is_same_to(
const FunctionDefinition &other_function_definition) const {
if (name_ != other_function_definition.name_) {
return false;
}
return true;
}
// TODO
// possible configurations:
// name 'arg1 'arg2 'arg3 : Type1 Type2 Type3 -> Type4; // function declaration
// name 'arg1 'arg2 'arg3 : Type1 Type2 Type3 -> Type4 = ... // function
// definition (with types)
// name 'arg1 'arg2 -> 'arg3 = ... // function definition (without types)
CombineResult
FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
// names should be the same
if (name_ != other_function_definition.name_) {
return CombineResult::DIFFERENT_NAME_ERROR;
}
// modifiers should be the same
if (return_modifier_ != other_function_definition.return_modifier_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
}
if (is_method_ != other_function_definition.is_method_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ??
}
if (are_annotations_same_to_names_ !=
other_function_definition.are_annotations_same_to_names_) {
return CombineResult::ARGUMENTS_ERROR;
}
// only one definition should have constraints
if (!constraints_.empty() &&
!other_function_definition.constraints_.empty()) {
return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR;
}
// only one definition should have expression (body)
if (expression_.has_value() &&
other_function_definition.expression_.has_value()) {
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
}
// only one definition should have documentation
if (docs_.get_description().has_value() &&
other_function_definition.docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
if (docs_.get_annotations_info_size() > 0 &&
other_function_definition.docs_.get_annotations_info_size() > 0) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
// check, that function definitions have same named arguments
for (size_t i = 0; i < std::max(arguments_.size(),
other_function_definition.arguments_.size());
++i) {
if (i < arguments_.size() &&
i < other_function_definition.arguments_.size()) {
// annotations should be the same
if ((!arguments_[i].get_annotation().has_value() &&
!other_function_definition.arguments_[i]
.get_annotation()
.has_value()) ||
(arguments_[i].get_annotation().has_value() &&
other_function_definition.arguments_[i]
.get_annotation()
.has_value() &&
*arguments_[i].get_annotation().value() !=
*other_function_definition.arguments_[i]
.get_annotation()
.value())) {
return CombineResult::ARGUMENTS_ERROR;
}
// argument names should be the same
if ((!arguments_[i].get_name().has_value() &&
!other_function_definition.arguments_[i].get_name().has_value()) ||
(arguments_[i].get_name().has_value() &&
other_function_definition.arguments_[i].get_name().has_value() &&
arguments_[i].get_name().value() !=
other_function_definition.arguments_[i].get_name().value())) {
return CombineResult::ARGUMENTS_ERROR;
}
// types should be the same (if present in both definitions)
if (arguments_[i].get_type().has_value() &&
other_function_definition.arguments_[i].get_type().has_value() &&
*arguments_[i].get_type().value() !=
*other_function_definition.arguments_[i].get_type().value()) {
return CombineResult::ARGUMENTS_ERROR;
}
// argument modifiers should be the same
if (arguments_[i].get_before_modifier() !=
other_function_definition.arguments_[i].get_before_modifier() ||
arguments_[i].get_after_modifier() !=
other_function_definition.arguments_[i].get_after_modifier()) {
return CombineResult::ARGUMENTS_ERROR;
}
} else if (i < arguments_.size()) {
// annotations should be the same
if (arguments_[i].get_annotation().has_value()) {
return CombineResult::ARGUMENTS_ERROR;
}
// names should be the same
if (arguments_[i].get_name().has_value()) {
return CombineResult::ARGUMENTS_ERROR;
}
} else { // i < other_function_definition.size()
// annotations should be the same
if (other_function_definition.arguments_[i]
.get_annotation()
.has_value()) {
return CombineResult::ARGUMENTS_ERROR;
}
// names should be the same
if (other_function_definition.arguments_[i].get_name().has_value()) {
return CombineResult::ARGUMENTS_ERROR;
}
}
}
// combine docs
// all docs should be in one definition
if (other_function_definition.docs_.get_description().has_value() ||
other_function_definition.docs_.get_annotations_info_size() > 0) {
if (docs_.get_annotations_info_size() > 0 ||
docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
docs_ = std::move(other_function_definition.docs_);
}
if (!other_function_definition.constraints_.empty()) {
constraints_ = std::move(other_function_definition.constraints_);
}
if (other_function_definition.expression_.has_value()) {
expression_ = other_function_definition.expression_;
}
for (size_t i = 0; i < other_function_definition.arguments_.size(); ++i) {
if (i < arguments_.size()) {
if (other_function_definition.arguments_[i].get_type().has_value()) {
if (arguments_[i].update_type_from(
other_function_definition.arguments_[i])) {
error_handling::handle_internal_error(
"Function arguments are not properly checked before merging "
"during combination",
*this);
}
}
} else {
arguments_.push_back(std::move(other_function_definition.arguments_[i]));
}
}
return CombineResult::OK;
}
bool TypeDefinition::is_same_to(
const TypeDefinition &other_type_definition) const {
if (name_ != other_type_definition.name_) {
return false;
}
return true;
}
// possible configurations:
// Type[...] 'A 'B 'C; // declare type / define typeclass (statement without
// args in this case)
// Type[...] 'A 'B 'C = ... // define type
CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
// name should be same
if (name_ != other_type_definition.name_) {
return CombineResult::DIFFERENT_NAME_ERROR;
}
// modifier should be the same
if (is_on_heap_ != other_type_definition.is_on_heap_) {
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
}
// typeclasses should be the same
if (typeclasses_.size() != other_type_definition.typeclasses_.size()) {
return CombineResult::ARGUMENTS_ERROR;
}
for (size_t i = 0; i < typeclasses_.size(); ++i) {
if (typeclasses_[i] != other_type_definition.typeclasses_[i]) {
return CombineResult::ARGUMENTS_ERROR;
}
}
// arguments should be the same
if (arguments_.size() != other_type_definition.arguments_.size()) {
return CombineResult::ARGUMENTS_ERROR;
}
for (size_t i = 0; i < arguments_.size(); ++i) {
if (arguments_[i] != other_type_definition.arguments_[i]) {
return CombineResult::ARGUMENTS_ERROR;
}
}
// only one definition should have documentation
if (docs_.get_description().has_value() &&
other_type_definition.docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
if (docs_.get_annotations_info_size() > 0 &&
other_type_definition.docs_.get_annotations_info_size() > 0) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
// only one type should define type / body
if (type_.has_value() && other_type_definition.type_.has_value()) {
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
}
// combine docs
// all docs should be in one definition
if (other_type_definition.docs_.get_description().has_value() ||
other_type_definition.docs_.get_annotations_info_size() > 0) {
if (docs_.get_annotations_info_size() > 0 ||
docs_.get_description().has_value()) {
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
}
docs_ = std::move(other_type_definition.docs_);
}
if (other_type_definition.type_.has_value()) {
type_ = std::move(other_type_definition.type_);
}
return CombineResult::OK;
}
bool Statement::is_same_to(const Statement &other_statement) const {
if (expression_.index() != other_statement.expression_.index()) {
return false;
}
switch (expression_.index()) {
case 0: // Import
return false;
case 1: // TypeDefinition
return std::get<TypeDefinition>(expression_)
.is_same_to(
std::move(std::get<TypeDefinition>(other_statement.expression_)));
case 2: // FunctionDefinition
return std::get<FunctionDefinition>(expression_)
.is_same_to(std::move(
std::get<FunctionDefinition>(other_statement.expression_)));
case 3: // Extra
return false;
case 4: // EmptyLines
return false;
default:
error_handling::handle_general_error(
"Unexpected statement type in is_same_to");
break;
}
error_handling::handle_general_error("Unreachable");
exit(1);
}
CombineResult Statement::combine(Statement &&other_statement) {
if (expression_.index() != other_statement.expression_.index()) {
return CombineResult::DIFFERENT_STATEMENT_TYPES;
}
switch (expression_.index()) {
case 0: // Import
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
case 1: // TypeDefinition
return std::get<TypeDefinition>(expression_)
.combine(
std::move(std::get<TypeDefinition>(other_statement.expression_)));
case 2: // FunctionDefinition
return std::get<FunctionDefinition>(expression_)
.combine(std::move(
std::get<FunctionDefinition>(other_statement.expression_)));
case 3: // Extra
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
case 4: // EmptyLines
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
default:
error_handling::handle_general_error(
"Unexpected statement type in combine");
break;
}
error_handling::handle_general_error("Unreachable");
exit(1);
}
} // namespace nodes

9
src/nodes/type_nodes.cpp Normal file
View file

@ -0,0 +1,9 @@
#include "type_nodes.hpp"
namespace nodes {
Type *TypeProxy::get() { return type_storage_->get_type(id_); }
const Type *TypeProxy::get() const { return type_storage_->get_type(id_); }
}; // namespace nodes