bug fixes, tests passed, result modifier (!) added to function arguments and to types

This commit is contained in:
ProgramSnail 2023-07-24 13:01:34 +03:00
parent 4470454838
commit 3914ff7d8b
16 changed files with 418 additions and 62 deletions

View file

@ -219,7 +219,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
nodes::FunctionDefinition::STATIC;
current_node = name_node.previous_sibling();
if (current_node.is_named()) {
if (!current_node.is_null() && current_node.is_named()) {
std::string modifier_str = current_node.get_value();
if (modifier_str == "%" || modifier_str == "let") {
modifier = nodes::FunctionDefinition::LET;
@ -231,6 +231,8 @@ build_function_definition(parser::ParseTree::Node parser_node,
std::vector<std::optional<std::string>> argument_annotations;
std::vector<nodes::Modifier> argument_reference_types;
std::vector<nodes::Identifier> arguments;
std::vector<bool> optional_arguments;
std::vector<bool> result_arguments;
std::vector<std::optional<std::string>> type_annotations;
std::vector<nodes::Modifier> type_reference_types;
@ -241,7 +243,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
current_node = name_node.next_named_sibling();
bool at_least_one_argument_annotation_found = false;
bool at_least_one_argument_reference_type_found = false;
bool at_least_one_argument_modifier_found = false;
std::optional<std::string> last_annotation;
nodes::Modifier last_reference_type = nodes::Modifier::NONE;
@ -258,14 +260,27 @@ build_function_definition(parser::ParseTree::Node parser_node,
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
if (last_annotation.has_value()) {
at_least_one_argument_annotation_found = true;
at_least_one_argument_modifier_found = true;
}
if (last_reference_type != nodes::Modifier::NONE) {
at_least_one_argument_reference_type_found = true;
at_least_one_argument_modifier_found = true;
}
argument_annotations.push_back(last_annotation);
argument_reference_types.push_back(last_reference_type);
arguments.push_back(build_identifier(current_node));
optional_arguments.push_back(!current_node.next_sibling().is_null() &&
current_node.next_sibling().is_named() &&
current_node.next_sibling().get_value() ==
"?");
result_arguments.push_back(!current_node.next_sibling().is_null() &&
current_node.next_sibling().is_named() &&
current_node.next_sibling().get_value() ==
"!");
if (optional_arguments.back() | result_arguments.back()) {
at_least_one_argument_modifier_found = true;
}
last_reference_type = nodes::Modifier::NONE;
last_annotation = std::nullopt;
break;
@ -293,23 +308,21 @@ build_function_definition(parser::ParseTree::Node parser_node,
if (!at_least_one_argument_annotation_found) {
for (size_t i = 0; i < argument_annotations.size(); ++i) {
argument_annotations[i] = *arguments[i].get();
std::string argument_annotation = *arguments[i].get();
argument_annotations[i] =
argument_annotation.substr(1, argument_annotation.size() - 1);
}
}
if (types.empty()) {
annotations = &argument_annotations;
reference_types = &argument_reference_types;
} else if (at_least_one_argument_annotation_found) {
} else if (at_least_one_argument_modifier_found) {
error_handling::handle_parsing_error(
"It is impossible to use argument annotations when types explicitely "
"It is impossible to use argument modifiers (annotations, references, "
"optional markers, result markers) when types explicitely "
"defined. Use type annotations instead.",
parser_node);
} else if (at_least_one_argument_reference_type_found) {
error_handling::handle_parsing_error(
"It is impossible to use argument reference types when types "
"explicitely defined. Use type reference types instead.",
parser_node);
} else {
annotations = &type_annotations;
reference_types = &type_reference_types;
@ -332,6 +345,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
std::move(constraints), modifier, build_identifier(name_node),
std::move(*annotations), std::move(arguments),
std::move(*reference_types), std::move(types),
std::move(optional_arguments), std::move(result_arguments),
expression_node.has_value()
? build_expression(expression_node.value(), expression_storage,
type_storage)