mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 15:08:48 +00:00
function definition class structure changed, corresponding builders and printers fixes, fixes
This commit is contained in:
parent
18d7bdf5c1
commit
b4ce56b5f7
13 changed files with 323 additions and 284 deletions
|
|
@ -254,29 +254,32 @@ 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;
|
||||
std::vector<nodes::TypeProxy> types;
|
||||
std::vector<nodes::FunctionDefinition::Argument> arguments;
|
||||
std::vector<nodes::FunctionDefinition::Argument> argument_types;
|
||||
|
||||
std::optional<parser::ParseTree::Node> expression_node;
|
||||
|
||||
current_node = name_node.next_named_sibling();
|
||||
|
||||
bool at_least_one_argument_annotation_found = false;
|
||||
bool at_least_one_argument_modifier_found = false;
|
||||
|
||||
size_t current_type_id = 0;
|
||||
|
||||
std::optional<std::string> last_annotation;
|
||||
nodes::Modifier last_reference_type = nodes::Modifier::NONE;
|
||||
nodes::Modifier last_before_modifier = nodes::Modifier::NONE;
|
||||
nodes::Modifier last_after_modifier = nodes::Modifier::NONE;
|
||||
while (!current_node.is_null()) {
|
||||
// update last before modifier
|
||||
auto maybe_reference_node = current_node.previous_sibling();
|
||||
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
|
||||
last_reference_type = build_modifier(maybe_reference_node);
|
||||
last_before_modifier = build_modifier(maybe_reference_node);
|
||||
|
||||
// only out, in, ref allowed
|
||||
if (last_before_modifier != nodes::Modifier::OUT &&
|
||||
last_before_modifier != nodes::Modifier::IN &&
|
||||
last_before_modifier != nodes::Modifier::REF) {
|
||||
last_before_modifier = nodes::Modifier::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
switch (tokens::string_to_type(current_node.get_type())) {
|
||||
|
|
@ -284,38 +287,50 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
last_annotation = build_annotation(current_node);
|
||||
break;
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
// update last after modifier
|
||||
maybe_reference_node = current_node.next_sibling();
|
||||
if (!maybe_reference_node.is_null() && !maybe_reference_node.is_named()) {
|
||||
last_after_modifier = build_modifier(maybe_reference_node);
|
||||
|
||||
// only optional, result allowed
|
||||
if (last_after_modifier != nodes::Modifier::OR_FALSE &&
|
||||
last_after_modifier != nodes::Modifier::OR_RETURN) {
|
||||
last_after_modifier = nodes::Modifier::NONE;
|
||||
}
|
||||
}
|
||||
|
||||
// update conditions
|
||||
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_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;
|
||||
}
|
||||
arguments.push_back(nodes::FunctionDefinition::Argument(
|
||||
last_annotation, build_identifier(current_node), last_before_modifier,
|
||||
last_after_modifier));
|
||||
|
||||
last_reference_type = nodes::Modifier::NONE;
|
||||
last_annotation = std::nullopt;
|
||||
break;
|
||||
case tokens::Type::TYPE:
|
||||
type_annotations.push_back(last_annotation);
|
||||
type_reference_types.push_back(last_reference_type);
|
||||
types.push_back(build_type(current_node, type_storage));
|
||||
last_reference_type = nodes::Modifier::NONE;
|
||||
if (current_type_id >= arguments.size()) {
|
||||
arguments.push_back(nodes::FunctionDefinition::Argument(
|
||||
last_annotation, build_type(current_node, type_storage),
|
||||
last_before_modifier));
|
||||
} else {
|
||||
if (!arguments[current_type_id].add_type(
|
||||
last_annotation, build_type(current_node, type_storage),
|
||||
last_before_modifier)) {
|
||||
error_handling::handle_parsing_error(
|
||||
"It is impossible to use argument modifiers (annotations, "
|
||||
"references, "
|
||||
"optional markers, result markers) when types explicitely "
|
||||
"defined. Use type annotations instead.",
|
||||
current_node);
|
||||
}
|
||||
}
|
||||
|
||||
last_annotation = std::nullopt;
|
||||
|
||||
++current_type_id;
|
||||
break;
|
||||
default:
|
||||
if (expression_node.has_value()) {
|
||||
|
|
@ -329,38 +344,32 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
std::vector<std::optional<std::string>> *annotations = nullptr;
|
||||
std::vector<nodes::Modifier> *reference_types = nullptr;
|
||||
if (current_type_id > 0 && current_type_id < arguments.size()) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Less types then arguments in function definition", parser_node);
|
||||
}
|
||||
|
||||
bool is_annotations_same_to_names =
|
||||
(!at_least_one_argument_annotation_found && types.empty());
|
||||
// automatic annotations
|
||||
bool are_annotations_same_to_names =
|
||||
(!at_least_one_argument_annotation_found && current_type_id == 0);
|
||||
|
||||
if (is_annotations_same_to_names) {
|
||||
for (size_t i = 0; i < argument_annotations.size(); ++i) {
|
||||
std::string argument_annotation = *arguments[i].get();
|
||||
argument_annotations[i] =
|
||||
argument_annotation.substr(1, argument_annotation.size() - 1);
|
||||
if (are_annotations_same_to_names) {
|
||||
for (size_t i = 0; i < arguments.size(); ++i) {
|
||||
std::string new_annotation = *arguments[i].get_name().value()->get();
|
||||
if (!arguments[i].add_annotation(
|
||||
new_annotation.substr(1, new_annotation.size() - 1))) {
|
||||
error_handling::handle_parsing_error(
|
||||
"no annotations provided ( => all annotations same to names), but "
|
||||
"can't add name annotation",
|
||||
current_node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (types.empty()) {
|
||||
annotations = &argument_annotations;
|
||||
reference_types = &argument_reference_types;
|
||||
} else if (at_least_one_argument_modifier_found) {
|
||||
error_handling::handle_parsing_error(
|
||||
"It is impossible to use argument modifiers (annotations, references, "
|
||||
"optional markers, result markers) when types explicitely "
|
||||
"defined. Use type annotations instead.",
|
||||
parser_node);
|
||||
} else {
|
||||
annotations = &type_annotations;
|
||||
reference_types = &type_reference_types;
|
||||
}
|
||||
|
||||
std::unordered_set<std::string> annotations_set;
|
||||
for (auto &annotation : *annotations) {
|
||||
if (annotation.has_value()) {
|
||||
if (!annotations_set.insert(annotation.value()).second) {
|
||||
for (auto &argument : arguments) {
|
||||
if (argument.get_annotation().has_value()) {
|
||||
if (!annotations_set.insert(*argument.get_annotation().value()).second) {
|
||||
error_handling::handle_parsing_error(
|
||||
"Two or more same annotations found in function definition",
|
||||
parser_node);
|
||||
|
|
@ -372,15 +381,12 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
|||
build_node(parser_node),
|
||||
build_symbol_docs(description_node, annotation_nodes, annotations_set),
|
||||
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),
|
||||
is_annotations_same_to_names,
|
||||
std::move(arguments), are_annotations_same_to_names,
|
||||
expression_node.has_value()
|
||||
? build_expression(expression_node.value(), expression_storage,
|
||||
type_storage)
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
} // TODO: refactor ??
|
||||
}
|
||||
|
||||
// definition_info? annotation_info* typeclass_identifier (':'
|
||||
// typeclass_identifier+)? ('{' function_definition* '}' | ';')
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue