mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2026-01-25 13:07:13 +00:00
result / optional return type modifiers for functions (one for all returns)
This commit is contained in:
parent
68463509d8
commit
195a26f9b7
10 changed files with 74 additions and 36 deletions
2
deps/tree-sitter-lang
vendored
2
deps/tree-sitter-lang
vendored
|
|
@ -1 +1 @@
|
||||||
Subproject commit 9c44228eec3d81caf1c1708a2f4d181037b85c16
|
Subproject commit 24015fd8df34dfb1c4c3b1d1622b261d01cb5a4c
|
||||||
|
|
@ -40,20 +40,22 @@
|
||||||
<keyword String="controlflow" attribute="Control Flow" context="#stay"/>
|
<keyword String="controlflow" attribute="Control Flow" context="#stay"/>
|
||||||
<keyword String="keywords" attribute="Keyword" context="#stay"/>
|
<keyword String="keywords" attribute="Keyword" context="#stay"/>
|
||||||
<keyword String="constants" attribute="Constant" context="#stay"/>
|
<keyword String="constants" attribute="Constant" context="#stay"/>
|
||||||
<Detect2Chars char="/" char1="/" attribute="Comment" context="Comment"/>
|
|
||||||
<RegExpr String="\b[0-9]+\.[0-9]+\b" attribute="Float" context="#stay"/>
|
|
||||||
|
|
||||||
|
<Detect2Chars char="/" char1="/" attribute="Comment" context="Comment"/>
|
||||||
<RegExpr String="^\: [^\n]*" attribute="Documentation" context="#stay"/>
|
<RegExpr String="^\: [^\n]*" attribute="Documentation" context="#stay"/>
|
||||||
<RegExpr String="^\@[^\n]*" attribute="Documentation" context="#stay"/>
|
<RegExpr String="^\@[^\n]*" attribute="Documentation" context="#stay"/>
|
||||||
|
|
||||||
|
<Detect2Chars char="(" char1=")" attribute="Constant" context="#stay"/>
|
||||||
|
|
||||||
<RegExpr String="^#![^\n]*" attribute="Comment" context="#stay"/>
|
<RegExpr String="^#![^\n]*" attribute="Comment" context="#stay"/>
|
||||||
|
|
||||||
<RegExpr String="\@[a-z_][a-z0-9_]*(?![a-z0-9_])" attribute="Annotation" context="#stay"/>
|
<RegExpr String="\@[a-z_][a-z0-9_]*(?![a-z0-9_])" attribute="Annotation" context="#stay"/>
|
||||||
|
|
||||||
<RegExpr String="(\:\=)|(\=\:)|\%|\\|\$|(\:\:)|(\|?\-\>)|(<\-\|?)|(<\>)|^" attribute="Keyword" context="#stay"/>
|
<RegExpr String="((\:\=)|(\=\:)|\%|\\|\$|(\:\:)|(\|?\-\>)|(<\-\|?)|(<\>)|^)(?![a\+\\\-\*/%\^\!\?\|&,<>=\.])" attribute="Keyword" context="#stay"/>
|
||||||
|
|
||||||
<RegExpr String="\@|\:|(\?\?)|(\!\!)|(\=\>)" attribute="Control Flow" context="#stay"/>
|
<RegExpr String="(\@|\:|(\?\?)|(\!\!)|(\=\>)|(\!\!\=\>))(?![a\+\\\-\*/%\^\!\?\|&,<>=\.])" attribute="Control Flow" context="#stay"/>
|
||||||
|
|
||||||
|
<RegExpr String="\b[0-9]+\.[0-9]+\b" attribute="Float" context="#stay"/>
|
||||||
<RegExpr String="''([^\\\/]|(\\.))''" attribute="Character" context="#stay"/>
|
<RegExpr String="''([^\\\/]|(\\.))''" attribute="Character" context="#stay"/>
|
||||||
|
|
||||||
<RegExpr String="(\.+)|([\+\\\-\*/%\^\!\?\|&,<>=]+\.?\.?\.?)" attribute="Operator" context="#stay"/>
|
<RegExpr String="(\.+)|([\+\\\-\*/%\^\!\?\|&,<>=]+\.?\.?\.?)" attribute="Operator" context="#stay"/>
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,15 @@
|
||||||
|
|
||||||
namespace builders {
|
namespace builders {
|
||||||
|
|
||||||
|
namespace utils {
|
||||||
|
|
||||||
|
inline bool is_suffix_modifier(nodes::Modifier modifier) {
|
||||||
|
return modifier == nodes::Modifier::OPTIONAL ||
|
||||||
|
modifier == nodes::Modifier::RESULT;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace utils
|
||||||
|
|
||||||
// returns Modifier::NONE for incorrecnt input
|
// returns Modifier::NONE for incorrecnt input
|
||||||
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node);
|
nodes::Modifier build_modifier(parser::ParseTree::Node parser_node);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,15 +16,18 @@ inline void print_position(std::ostream &out,
|
||||||
<< ']';
|
<< ']';
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void
|
inline void handle_internal_error(const std::string &message,
|
||||||
handle_internal_error(const std::string &message,
|
const nodes::Node &node) {
|
||||||
std::optional<const nodes::Node *> node = std::nullopt) {
|
std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at ";
|
||||||
std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message;
|
print_position(std::cerr, node.get_start_position(), node.get_end_position());
|
||||||
if (node.has_value()) {
|
std::cerr << ".\n";
|
||||||
std::cerr << " at ";
|
exit(1);
|
||||||
print_position(std::cerr, node.value()->get_start_position(),
|
}
|
||||||
node.value()->get_end_position());
|
|
||||||
}
|
inline void handle_internal_error(const std::string &message,
|
||||||
|
parser::ParseTree::Node node) {
|
||||||
|
std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at ";
|
||||||
|
print_position(std::cerr, node.get_start_point(), node.get_end_point());
|
||||||
std::cerr << ".\n";
|
std::cerr << ".\n";
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ private:
|
||||||
|
|
||||||
class FunctionDefinition : public Node {
|
class FunctionDefinition : public Node {
|
||||||
public:
|
public:
|
||||||
enum ModifierType {
|
enum MethodModifier {
|
||||||
STATIC,
|
STATIC,
|
||||||
LET,
|
LET,
|
||||||
VAR,
|
VAR,
|
||||||
|
|
@ -237,12 +237,13 @@ public:
|
||||||
|
|
||||||
FunctionDefinition(Node node, SymbolDocs &&docs,
|
FunctionDefinition(Node node, SymbolDocs &&docs,
|
||||||
std::vector<Constraint> &&constraints,
|
std::vector<Constraint> &&constraints,
|
||||||
ModifierType modifier, const Identifier &name,
|
Modifier return_modifier, MethodModifier method_modifier,
|
||||||
std::vector<Argument> &&arguments,
|
const Identifier &name, std::vector<Argument> &&arguments,
|
||||||
bool are_annotations_same_to_names,
|
bool are_annotations_same_to_names,
|
||||||
std::optional<ExpressionProxy> expression)
|
std::optional<ExpressionProxy> expression)
|
||||||
: Node(node), docs_(std::move(docs)),
|
: Node(node), docs_(std::move(docs)),
|
||||||
constraints_(std::move(constraints)), modifier_(modifier), name_(name),
|
constraints_(std::move(constraints)), return_modifier_(return_modifier),
|
||||||
|
method_modifier_(method_modifier), name_(name),
|
||||||
arguments_(std::move(arguments)),
|
arguments_(std::move(arguments)),
|
||||||
are_annotations_same_to_names_(are_annotations_same_to_names),
|
are_annotations_same_to_names_(are_annotations_same_to_names),
|
||||||
expression_(expression) {}
|
expression_(expression) {}
|
||||||
|
|
@ -265,7 +266,9 @@ public:
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
ModifierType get_modifier() const { return modifier_; }
|
Modifier get_return_modifier() const { return return_modifier_; }
|
||||||
|
|
||||||
|
MethodModifier get_method_modifier() const { return method_modifier_; }
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
|
|
@ -312,7 +315,8 @@ public:
|
||||||
private:
|
private:
|
||||||
SymbolDocs docs_;
|
SymbolDocs docs_;
|
||||||
std::vector<Constraint> constraints_;
|
std::vector<Constraint> constraints_;
|
||||||
ModifierType modifier_;
|
Modifier return_modifier_;
|
||||||
|
MethodModifier method_modifier_;
|
||||||
Identifier name_;
|
Identifier name_;
|
||||||
std::vector<Argument> arguments_;
|
std::vector<Argument> arguments_;
|
||||||
bool are_annotations_same_to_names_; // needed for easier prinitng process
|
bool are_annotations_same_to_names_; // needed for easier prinitng process
|
||||||
|
|
|
||||||
|
|
@ -263,16 +263,28 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
||||||
|
|
||||||
auto name_node = current_node;
|
auto name_node = current_node;
|
||||||
|
|
||||||
nodes::FunctionDefinition::ModifierType modifier =
|
nodes::FunctionDefinition::MethodModifier method_modifier =
|
||||||
nodes::FunctionDefinition::STATIC;
|
nodes::FunctionDefinition::STATIC;
|
||||||
|
|
||||||
current_node = name_node.previous_sibling();
|
current_node = name_node.previous_sibling();
|
||||||
if (!current_node.is_null() && !current_node.is_named()) {
|
if (!current_node.is_null() && !current_node.is_named()) {
|
||||||
std::string modifier_str = current_node.get_value();
|
std::string modifier_str = current_node.get_value();
|
||||||
if (modifier_str == "%" || modifier_str == "let") {
|
if (modifier_str == "%" || modifier_str == "let") {
|
||||||
modifier = nodes::FunctionDefinition::LET;
|
method_modifier = nodes::FunctionDefinition::LET;
|
||||||
} else if (modifier_str == "$" || modifier_str == "var") {
|
} else if (modifier_str == "$" || modifier_str == "var") {
|
||||||
modifier = nodes::FunctionDefinition::VAR;
|
method_modifier = nodes::FunctionDefinition::VAR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
nodes::Modifier return_modifier = nodes::Modifier::NONE;
|
||||||
|
|
||||||
|
current_node = name_node.next_sibling();
|
||||||
|
if (!current_node.is_null() && !current_node.is_named()) {
|
||||||
|
return_modifier = build_modifier(current_node);
|
||||||
|
|
||||||
|
// only optional, result allowed
|
||||||
|
if (!utils::is_suffix_modifier(return_modifier)) {
|
||||||
|
return_modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -297,8 +309,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
||||||
last_before_modifier = build_modifier(maybe_reference_node);
|
last_before_modifier = build_modifier(maybe_reference_node);
|
||||||
|
|
||||||
// only out, in, ref allowed
|
// only out, in, ref allowed
|
||||||
if (last_before_modifier == nodes::Modifier::OPTIONAL ||
|
if (utils::is_suffix_modifier(last_before_modifier)) {
|
||||||
last_before_modifier == nodes::Modifier::RESULT) {
|
|
||||||
last_before_modifier = nodes::Modifier::NONE;
|
last_before_modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -314,8 +325,7 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
||||||
last_after_modifier = build_modifier(maybe_reference_node);
|
last_after_modifier = build_modifier(maybe_reference_node);
|
||||||
|
|
||||||
// only optional, result allowed
|
// only optional, result allowed
|
||||||
if (last_after_modifier != nodes::Modifier::OPTIONAL &&
|
if (!utils::is_suffix_modifier(last_after_modifier)) {
|
||||||
last_after_modifier != nodes::Modifier::RESULT) {
|
|
||||||
last_after_modifier = nodes::Modifier::NONE;
|
last_after_modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -401,8 +411,9 @@ build_function_definition(parser::ParseTree::Node parser_node,
|
||||||
return nodes::FunctionDefinition(
|
return nodes::FunctionDefinition(
|
||||||
build_node(parser_node),
|
build_node(parser_node),
|
||||||
build_symbol_docs(description_node, annotation_nodes, annotations_set),
|
build_symbol_docs(description_node, annotation_nodes, annotations_set),
|
||||||
std::move(constraints), modifier, build_identifier(name_node),
|
std::move(constraints), return_modifier, method_modifier,
|
||||||
std::move(arguments), are_annotations_same_to_names,
|
build_identifier(name_node), std::move(arguments),
|
||||||
|
are_annotations_same_to_names,
|
||||||
expression_node.has_value()
|
expression_node.has_value()
|
||||||
? build_expression(expression_node.value(), expression_storage,
|
? build_expression(expression_node.value(), expression_storage,
|
||||||
type_storage)
|
type_storage)
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,13 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
||||||
if (*name_.get() != *other_function_definition.name_.get()) {
|
if (*name_.get() != *other_function_definition.name_.get()) {
|
||||||
return CombineResult::DIFFERENT_NAME_ERROR;
|
return CombineResult::DIFFERENT_NAME_ERROR;
|
||||||
}
|
}
|
||||||
if (modifier_ != other_function_definition.modifier_) {
|
if (return_modifier_ != other_function_definition.return_modifier_) {
|
||||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||||
}
|
}
|
||||||
|
if (method_modifier_ != other_function_definition.method_modifier_) {
|
||||||
|
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
if (are_annotations_same_to_names_ !=
|
if (are_annotations_same_to_names_ !=
|
||||||
other_function_definition.are_annotations_same_to_names_) {
|
other_function_definition.are_annotations_same_to_names_) {
|
||||||
return CombineResult::ARGUMENTS_ERROR;
|
return CombineResult::ARGUMENTS_ERROR;
|
||||||
|
|
@ -158,7 +162,7 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
||||||
error_handling::handle_internal_error(
|
error_handling::handle_internal_error(
|
||||||
"Function arguments are not properly checked before merging "
|
"Function arguments are not properly checked before merging "
|
||||||
"during combination",
|
"during combination",
|
||||||
this);
|
*this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
||||||
|
|
@ -143,7 +143,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
||||||
printer.new_indent_line();
|
printer.new_indent_line();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (statement.get_modifier()) {
|
switch (statement.get_method_modifier()) {
|
||||||
case nodes::FunctionDefinition::STATIC:
|
case nodes::FunctionDefinition::STATIC:
|
||||||
break;
|
break;
|
||||||
case nodes::FunctionDefinition::LET:
|
case nodes::FunctionDefinition::LET:
|
||||||
|
|
@ -169,6 +169,8 @@ void print_function_definition(const nodes::FunctionDefinition &statement,
|
||||||
printer.print(" )");
|
printer.print(" )");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
print_modifier(statement.get_return_modifier(), printer);
|
||||||
|
|
||||||
for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
|
for (size_t i = 0; i < statement.get_arguments_size(); ++i) {
|
||||||
if (!statement.get_argument(i)->get_name().has_value()) {
|
if (!statement.get_argument(i)->get_name().has_value()) {
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,7 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
||||||
modifier = build_modifier(current_node);
|
modifier = build_modifier(current_node);
|
||||||
|
|
||||||
// only optional, result allowed
|
// only optional, result allowed
|
||||||
if (modifier != nodes::Modifier::OPTIONAL &&
|
if (!utils::is_suffix_modifier(modifier)) {
|
||||||
modifier != nodes::Modifier::RESULT) {
|
|
||||||
modifier = nodes::Modifier::NONE;
|
modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,5 +215,9 @@ parse_number : Unit! = {
|
||||||
bring ();
|
bring ();
|
||||||
}
|
}
|
||||||
|
|
||||||
: example of or_in and or_out usage for template operators
|
: example of or_in and or_out usage for template operators (tuple input and tuple output)
|
||||||
( & ) |-> 'a |-> 'b <-| 'x <-| 'y = (|-> 'a := <-| 'x) && (|-> 'b := <-| 'y);
|
( & ) |-> 'a |-> 'b <-| 'x <-| 'y = ('a := 'x) && ('b := 'y);
|
||||||
|
|
||||||
|
: function, that return result ('!' not used on calls)
|
||||||
|
: useful when tuples returned
|
||||||
|
result_func! 'a 'b -> 'c -> 'd = ?? 'a == 0 => error "some error" !!=> ('c := 'a, 'd := 'b, ());
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue