mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
combine functions fixes
This commit is contained in:
parent
5e70f0015f
commit
4714a05467
5 changed files with 117 additions and 44 deletions
|
|
@ -115,6 +115,16 @@ public:
|
|||
value_ += name;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool operator==(const Identifier &other_identifier) const {
|
||||
return type_ == other_identifier.type_ && value_ == other_identifier.value_;
|
||||
}
|
||||
|
||||
bool operator!=(const Identifier &other_identifier) const {
|
||||
return !(*this == other_identifier);
|
||||
}
|
||||
|
||||
private:
|
||||
IdentifierType type_;
|
||||
std::string value_;
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ enum class CombineResult {
|
|||
MORE_THEN_ONE_DOCS_ERROR,
|
||||
MORE_THEN_ONE_CONSTRAINTS_ERROR,
|
||||
MORE_THEN_ONE_DEFINITION_BODY_ERROR,
|
||||
TYPECLASSES_ERROR,
|
||||
ARGUMENTS_ERROR,
|
||||
DIFFERENT_STATEMENT_TYPES,
|
||||
STATEMENTS_CANT_BE_COMBINED_ERROR,
|
||||
|
|
|
|||
|
|
@ -56,10 +56,14 @@ public:
|
|||
: Node(node), name_(identifier), parameters_(std::move(parameters)),
|
||||
is_on_heap_(is_on_heap), modifier_(modifier) {}
|
||||
|
||||
//
|
||||
|
||||
Identifier *get_name() { return &name_; }
|
||||
|
||||
const Identifier *get_name() const { return &name_; }
|
||||
|
||||
//
|
||||
|
||||
size_t get_parametrs_size() const { return parameters_.size(); }
|
||||
|
||||
Type *get_parameter(size_t id) { return parameters_.at(id).get(); }
|
||||
|
|
@ -68,10 +72,34 @@ public:
|
|||
return parameters_.at(id).get();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
bool is_on_heap() const { return is_on_heap_; }
|
||||
|
||||
Modifier get_modifier() const { return modifier_; }
|
||||
|
||||
//
|
||||
|
||||
bool operator==(const Type &other_type) const {
|
||||
if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ ||
|
||||
modifier_ != other_type.modifier_ ||
|
||||
parameters_.size() != other_type.parameters_.size()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < parameters_.size(); ++i) {
|
||||
if (*parameters_[i].get() != *other_type.parameters_[i].get()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Type &other_type) const {
|
||||
return !(*this == other_type);
|
||||
}
|
||||
|
||||
private:
|
||||
Identifier name_;
|
||||
std::vector<TypeProxy> parameters_;
|
||||
|
|
|
|||
|
|
@ -166,8 +166,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
|
|||
return current_node;
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* '^'? simple_type (argument_type* '='
|
||||
// variant_type)? ('{' function_definition* '}' | ';')
|
||||
// definition_info? annotation_info* '^'? (simple_type | typeclass)
|
||||
// (argument_type* '=' variant_type)? ';'
|
||||
nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
bool is_on_heap = parser_node.nth_child(0).get_value() == "^";
|
||||
|
|
@ -262,7 +262,7 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
|
|||
std::move(type));
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* (constraint ';')* _var_let_? (simple_name
|
||||
// definition_info? annotation_info* (constraint ';')* '.'? (simple_name
|
||||
// | '(' operator ')') (annotation? _reference_? argument_name '?'?)* (:
|
||||
// (annotation? _reference_ type)+)?
|
||||
// ('=' (block | expression ';') | ';')
|
||||
|
|
@ -410,6 +410,13 @@ nodes::FunctionDefinition build_function_definition(
|
|||
"Less types then arguments in function definition", parser_node);
|
||||
}
|
||||
|
||||
if (current_type_id == 0 && !expression_node.has_value()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Can't declare function without types (types or function body should "
|
||||
"be added)",
|
||||
parser_node);
|
||||
}
|
||||
|
||||
// automatic annotations
|
||||
bool are_annotations_same_to_names =
|
||||
(!at_least_one_argument_annotation_found && current_type_id == 0);
|
||||
|
|
|
|||
|
|
@ -6,29 +6,34 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
// TODO: function overloading, etc. ??
|
||||
bool FunctionDefinition::is_same_to(
|
||||
const FunctionDefinition &other_function_definition) const {
|
||||
if (*name_.get() != *other_function_definition.name_.get()) {
|
||||
if (name_ != other_function_definition.name_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: function overloading, etc. ??
|
||||
// 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) {
|
||||
// should be same in all definitions of one function
|
||||
if (*name_.get() != *other_function_definition.name_.get()) {
|
||||
// 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;
|
||||
|
|
@ -40,7 +45,7 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should have expression
|
||||
// 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;
|
||||
|
|
@ -56,15 +61,14 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
// TODO: think about required checks
|
||||
// check, that function definitions have same named arguments count
|
||||
// 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()) {
|
||||
|
||||
// check that all argument annotations are the same
|
||||
// annotations should be the same
|
||||
if ((!arguments_[i].get_annotation().has_value() &&
|
||||
!other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
|
|
@ -80,27 +84,25 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// check that all argument names are the same
|
||||
// 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()->get() !=
|
||||
*other_function_definition.arguments_[i]
|
||||
.get_name()
|
||||
.value()
|
||||
->get())) {
|
||||
arguments_[i].get_name().value() !=
|
||||
other_function_definition.arguments_[i].get_name().value())) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// check that types are are in zero or one set of arguments (TODO: can be
|
||||
// same and in two sets ??)
|
||||
// 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()) {
|
||||
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 same
|
||||
// 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() !=
|
||||
|
|
@ -108,26 +110,24 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
} else if (i < arguments_.size()) {
|
||||
// last arguments shouldn't be annotated (because they are not annotated
|
||||
// in other function definition statement)
|
||||
// annotations should be the same
|
||||
if (arguments_[i].get_annotation().has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// last arguments can only be unnamed arguments (returned values)
|
||||
// names should be the same
|
||||
if (arguments_[i].get_name().has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
} else { // i < other_function_definition.size()
|
||||
// last arguments shouldn't be annotated (because they are not annotated
|
||||
// in other function definition statement)
|
||||
// annotations should be the same
|
||||
if (other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
.has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// last arguments can only be unnamed arguments (returned values)
|
||||
// names should be the same
|
||||
if (other_function_definition.arguments_[i].get_name().has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
|
@ -175,21 +175,47 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
|
||||
bool TypeDefinition::is_same_to(
|
||||
const TypeDefinition &other_type_definition) const {
|
||||
if (*name_.get() != *other_type_definition.name_.get()) {
|
||||
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) {
|
||||
// should be same in all definitions of one type
|
||||
if (*name_.get() != *other_type_definition.name_.get()) {
|
||||
// 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()) {
|
||||
|
|
@ -200,12 +226,9 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
|
|||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should define type and arguments (they should be
|
||||
// defined in one place)
|
||||
if ((other_type_definition.type_.has_value() ||
|
||||
!other_type_definition.arguments_.empty()) &&
|
||||
(type_.has_value() || !arguments_.empty())) {
|
||||
return CombineResult::ARGUMENTS_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
|
||||
|
|
@ -220,10 +243,6 @@ CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
|
|||
docs_ = std::move(other_type_definition.docs_);
|
||||
}
|
||||
|
||||
if (!other_type_definition.arguments_.empty()) {
|
||||
arguments_ = std::move(other_type_definition.arguments_);
|
||||
}
|
||||
|
||||
if (other_type_definition.type_.has_value()) {
|
||||
type_ = std::move(other_type_definition.type_);
|
||||
}
|
||||
|
|
@ -247,9 +266,13 @@ bool Statement::is_same_to(const Statement &other_statement) const {
|
|||
return std::get<FunctionDefinition>(expression_)
|
||||
.is_same_to(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
case 3: // EmptyLines
|
||||
case 3: // Extra
|
||||
return false;
|
||||
case 4: // EmptyLines
|
||||
return false;
|
||||
default:
|
||||
error_handling::handle_general_error(
|
||||
"Unexpected statement type in is_same_to");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -273,9 +296,13 @@ CombineResult Statement::combine(Statement &&other_statement) {
|
|||
return std::get<FunctionDefinition>(expression_)
|
||||
.combine(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
case 3: // EmptyLines
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue