mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-25 08:18:45 +00:00
bug fixes, tests passed, result modifier (!) added to function arguments and to types
This commit is contained in:
parent
4470454838
commit
3914ff7d8b
16 changed files with 418 additions and 62 deletions
Binary file not shown.
|
|
@ -135,7 +135,7 @@ nodes::Literal build_bool_literal(parser::ParseTree::Node parser_node) {
|
|||
literal == "true" ? true : false);
|
||||
}
|
||||
|
||||
nodes::Literal build_Unit_literal(parser::ParseTree::Node parser_node) {
|
||||
nodes::Literal build_unit_literal(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Literal(build_node(parser_node), nodes::unit{});
|
||||
}
|
||||
|
||||
|
|
@ -161,7 +161,12 @@ nodes::Identifier build_identifier(parser::ParseTree::Node parser_node) {
|
|||
return build_argument_name(parser_node);
|
||||
case tokens::Type::ARGUMENT_TYPE_IDENTIFIER:
|
||||
return build_argument_type(parser_node);
|
||||
// used as string
|
||||
case tokens::Type::OPERATOR:
|
||||
case tokens::Type::OPERATOR_TAIL1:
|
||||
case tokens::Type::OPERATOR_TAIL2:
|
||||
case tokens::Type::OPERATOR_TAIL3:
|
||||
return build_operator(parser_node);
|
||||
// [used as string]
|
||||
// case tokens::Type::ANNOTATION_IDENTIFIER:
|
||||
// return build_annotation(parser_node);
|
||||
default:
|
||||
|
|
@ -226,7 +231,7 @@ nodes::Identifier build_operator(parser::ParseTree::Node parser_node) {
|
|||
identifier);
|
||||
}
|
||||
|
||||
nodes::Identifier buildPlaceholder(parser::ParseTree::Node parser_node) {
|
||||
nodes::Identifier build_placeholder(parser::ParseTree::Node parser_node) {
|
||||
return nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::PLACEHOLDER, "_");
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ nodes::SymbolDocs build_symbol_docs(
|
|||
|
||||
for (auto &annotation_parser_node : annotation_parser_nodes) {
|
||||
std::string annotation =
|
||||
build_annotation(annotation_parser_node.nth_child(0));
|
||||
build_annotation(annotation_parser_node.nth_named_child(0));
|
||||
|
||||
if (annotations.count(annotation) == 0) {
|
||||
error_handling::handle_parsing_error(
|
||||
|
|
@ -45,7 +45,8 @@ nodes::SymbolDocs build_symbol_docs(
|
|||
annotation_parser_node);
|
||||
}
|
||||
|
||||
docs.add_annotation_info(annotation, annotation_parser_node.nth_child(1));
|
||||
docs.add_annotation_info(
|
||||
annotation, annotation_parser_node.nth_named_child(1).get_value());
|
||||
}
|
||||
|
||||
return docs;
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ build_expression(parser::ParseTree::Node parser_node,
|
|||
build_name_expression(parser_node, expression_storage, type_storage)));
|
||||
case tokens::Type::ARGUMENT_NAME_IDENTIFIER:
|
||||
case tokens::Type::SIMPLE_NAME_IDENTIFIER:
|
||||
case tokens::Type::PLACEHOLDER:
|
||||
return expression_storage.add_expression(
|
||||
nodes::Expression(nodes::NameExpression(
|
||||
build_node(parser_node), build_identifier(parser_node))));
|
||||
|
|
@ -501,13 +502,15 @@ nodes::Lambda build_lambda(parser::ParseTree::Node parser_node,
|
|||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::Identifier> arguments;
|
||||
|
||||
auto current_node = parser_node.nth_child(1); // next to '\\'
|
||||
auto current_node =
|
||||
parser_node.nth_child(1); // next to '\\', not null ('=>' should present)
|
||||
|
||||
while (current_node.is_named()) { // until _do_
|
||||
arguments.emplace_back(build_identifier(parser_node));
|
||||
arguments.emplace_back(build_identifier(current_node));
|
||||
current_node = current_node.next_sibling();
|
||||
}
|
||||
|
||||
// skip '=>'
|
||||
current_node = current_node.next_named_sibling();
|
||||
|
||||
return nodes::Lambda(
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -12,24 +12,25 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
|||
auto name_node = parse_node.child_by_field_name("name");
|
||||
|
||||
auto current_node = parse_node.nth_child(0);
|
||||
bool is_on_heap = !current_node.is_null() && current_node.get_value() == "^";
|
||||
bool is_on_heap = (!current_node.is_null() && !current_node.is_named() &&
|
||||
current_node.get_value() == "^");
|
||||
|
||||
current_node = name_node.next_sibling();
|
||||
bool is_optional = !current_node.is_null() && current_node.get_value() == "?";
|
||||
bool is_optional = (!current_node.is_null() && !current_node.is_named() &&
|
||||
current_node.get_value() == "?");
|
||||
|
||||
bool is_result = (!current_node.is_null() && !current_node.is_named() &&
|
||||
current_node.get_value() == "!");
|
||||
|
||||
current_node = name_node.next_named_sibling();
|
||||
while (!current_node.is_null()) {
|
||||
parameters.push_back(build_type(current_node, type_storage));
|
||||
current_node = name_node.next_named_sibling();
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return type_storage.add_type(
|
||||
nodes::Type(build_node(parse_node),
|
||||
tokens::string_to_type(name_node.get_type()) ==
|
||||
tokens::Type::ARGUMENT_TYPE_IDENTIFIER
|
||||
? build_argument_type(name_node)
|
||||
: build_simple_type(name_node),
|
||||
std::move(parameters), is_on_heap, is_optional));
|
||||
nodes::Type(build_node(parse_node), build_identifier(name_node),
|
||||
std::move(parameters), is_on_heap, is_optional, is_result));
|
||||
}
|
||||
|
||||
// '&'? annotation? type ('&' annotation? type)*
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue