diff --git a/deps/tree-sitter-lang b/deps/tree-sitter-lang index 1357783..6a25194 160000 --- a/deps/tree-sitter-lang +++ b/deps/tree-sitter-lang @@ -1 +1 @@ -Subproject commit 1357783074e77c2c5ddcec16e90cf59940dabd9d +Subproject commit 6a251945e63587b97fb718b8a090b2da018cb32a diff --git a/include/builders/type_builders.hpp b/include/builders/type_builders.hpp index 1afce88..4a3c958 100644 --- a/include/builders/type_builders.hpp +++ b/include/builders/type_builders.hpp @@ -14,12 +14,6 @@ nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node, nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node, nodes::TypeStorage &type_storage); -nodes::TypeProxy build_function_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); - -nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node, - nodes::TypeStorage &type_storage); - nodes::TypeProxy build_reference_type(parser::ParseTree::Node parse_node, nodes::TypeStorage &type_storage); diff --git a/include/nodes/basic_nodes.hpp b/include/nodes/basic_nodes.hpp index 107de2d..f52e70b 100644 --- a/include/nodes/basic_nodes.hpp +++ b/include/nodes/basic_nodes.hpp @@ -254,8 +254,15 @@ public: void append_before(const std::string &name) { value_ = name + "." + value_; } void append_after(const std::string &name) { - value_ += "."; - value_ += name; + value_ += "." + name; + } + + std::pair split_first() { + const auto pos = value_.find('.'); + if (pos == std::string::npos) { + return {Identifier(*this, type_, ""), *this}; + } + return {Identifier(*this, type_, value_.substr(0, pos)), Identifier(*this, type_, value_.substr(pos + 1))}; // '.' is leaved out } // diff --git a/include/tokens.hpp b/include/tokens.hpp index d64480b..ebaf199 100644 --- a/include/tokens.hpp +++ b/include/tokens.hpp @@ -54,8 +54,6 @@ enum class Type { VARIANT_TYPE, TUPLE_TYPE, - FUNCTION_TYPE, - ARRAY_TYPE, REFERENCE_TYPE, MODIFIED_TYPE, SIMPLE_TYPE, @@ -150,8 +148,6 @@ const static std::string LAMBDA = "lambda"; const static std::string VARIANT_TYPE = "variant_type"; const static std::string TUPLE_TYPE = "tuple_type"; -const static std::string FUNCTION_TYPE = "function_type"; -const static std::string ARRAY_TYPE = "array_type"; const static std::string REFERENCE_TYPE = "reference_type"; const static std::string MODIFIED_TYPE = "modified_type"; const static std::string SIMPLE_TYPE = "simple_type"; @@ -244,10 +240,6 @@ inline Type string_to_type(const std::string &str) { return Type::VARIANT_TYPE; } else if (str == TUPLE_TYPE) { return Type::TUPLE_TYPE; - } else if (str == FUNCTION_TYPE) { - return Type::FUNCTION_TYPE; - } else if (str == ARRAY_TYPE) { - return Type::ARRAY_TYPE; } else if (str == REFERENCE_TYPE) { return Type::REFERENCE_TYPE; } else if (str == MODIFIED_TYPE) { diff --git a/src/builders/expression_builders.cpp b/src/builders/expression_builders.cpp index b1d2e8e..89a2066 100644 --- a/src/builders/expression_builders.cpp +++ b/src/builders/expression_builders.cpp @@ -519,8 +519,6 @@ build_name_expression(parser::ParseTree::Node parser_node, tokens::Type::VARIANT_TYPE || tokens::string_to_type(current_node.get_type()) == tokens::Type::TUPLE_TYPE || - tokens::string_to_type(current_node.get_type()) == - tokens::Type::ARRAY_TYPE || tokens::string_to_type(current_node.get_type()) == tokens::Type::REFERENCE_TYPE || tokens::string_to_type(current_node.get_type()) == diff --git a/src/builders/statement_builders.cpp b/src/builders/statement_builders.cpp index da98fa5..9d7ac6c 100644 --- a/src/builders/statement_builders.cpp +++ b/src/builders/statement_builders.cpp @@ -217,7 +217,6 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node, break; case tokens::Type::VARIANT_TYPE: case tokens::Type::TUPLE_TYPE: - case tokens::Type::ARRAY_TYPE: case tokens::Type::REFERENCE_TYPE: case tokens::Type::MODIFIED_TYPE: case tokens::Type::SIMPLE_TYPE: @@ -274,7 +273,7 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node, // definition_info? annotation_info* (constraint ';')* '.'? (simple_name // | '(' operator ')') (annotation? _reference_? argument_name '?'?)* (: // (annotation? _reference_ type)+)? -// ('=' (block | expression ';') | ';') +// (((block | array) | '=' expression ';') | ';') nodes::FunctionDefinition build_function_definition( parser::ParseTree::Node parser_node, const std::optional &last_defined_type_name, @@ -382,8 +381,6 @@ nodes::FunctionDefinition build_function_definition( break; case tokens::Type::VARIANT_TYPE: case tokens::Type::TUPLE_TYPE: - case tokens::Type::FUNCTION_TYPE: - case tokens::Type::ARRAY_TYPE: case tokens::Type::REFERENCE_TYPE: case tokens::Type::MODIFIED_TYPE: case tokens::Type::SIMPLE_TYPE: diff --git a/src/builders/type_builders.cpp b/src/builders/type_builders.cpp index 1ac9fc7..78dc6d3 100644 --- a/src/builders/type_builders.cpp +++ b/src/builders/type_builders.cpp @@ -23,10 +23,6 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node, return build_variant_type(parser_node, type_storage); case tokens::Type::TUPLE_TYPE: return build_tuple_type(parser_node, type_storage); - case tokens::Type::FUNCTION_TYPE: - return build_function_type(parser_node, type_storage); - case tokens::Type::ARRAY_TYPE: - return build_array_type(parser_node, type_storage); case tokens::Type::REFERENCE_TYPE: return build_reference_type(parser_node, type_storage); case tokens::Type::MODIFIED_TYPE: @@ -41,14 +37,14 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node, exit(1); // unreachable } -nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage, - builtin::types::Type container) { +std::vector +collect_parameters(parser::ParseTree::Node first_node, + nodes::TypeStorage &type_storage) { std::vector parameters; std::optional current_annotation; - auto current_node = parser_node.nth_named_child(0); + auto current_node = first_node; while (!current_node.is_null()) { if (tokens::string_to_type(current_node.get_type()) == tokens::Type::ANNOTATION_IDENTIFIER) { @@ -62,6 +58,15 @@ nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node, current_node = current_node.next_named_sibling(); } + return parameters; +} + +nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node, + nodes::TypeStorage &type_storage, + builtin::types::Type container) { + std::vector parameters = + collect_parameters(parser_node.nth_named_child(0), type_storage); + return type_storage.add_container_of(std::move(parameters), container, build_node(parser_node)); } @@ -80,22 +85,6 @@ nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node, builtin::types::Type::TUPLE); } -// '((' (annotation? type)+ '))' -nodes::TypeProxy build_function_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { - return build_container_type(parser_node, type_storage, - builtin::types::Type::FUNCTION); -} - -// '[[' type ']]' -nodes::TypeProxy build_array_type(parser::ParseTree::Node parser_node, - nodes::TypeStorage &type_storage) { - - return type_storage.add_array_of( - build_type(parser_node.nth_named_child(0), type_storage), - build_node(parser_node)); -} - // _reference_ type nodes::TypeProxy build_reference_type(parser::ParseTree::Node parser_node, nodes::TypeStorage &type_storage) { @@ -136,18 +125,13 @@ nodes::TypeProxy build_modified_type(parser::ParseTree::Node parser_node, std::move(parameters))); } -// type_identifier ('[' type+ ']')? +// type_identifier ('[' (annotation? type)+ ']')? nodes::TypeProxy build_simple_type(parser::ParseTree::Node parser_node, nodes::TypeStorage &type_storage) { - std::vector parameters; - auto name_node = parser_node.child_by_field_name("name"); - auto current_node = name_node.next_named_sibling(); - while (!current_node.is_null()) { - parameters.push_back(build_type(current_node, type_storage)); - current_node = current_node.next_named_sibling(); - } + std::vector parameters = + collect_parameters(name_node.next_named_sibling(), type_storage); return type_storage.add_type( nodes::Type(build_identifier(name_node), std::move(parameters))); diff --git a/src/printers/basic_printers.cpp b/src/printers/basic_printers.cpp index 647785c..8b39a3b 100644 --- a/src/printers/basic_printers.cpp +++ b/src/printers/basic_printers.cpp @@ -127,7 +127,7 @@ void print_literal(const nodes::Literal &literal, Printer &printer) { printer.print("\'\'u"); return; case 9: // bool - printer.print(literal.get().value() ? "true" : "false"); + printer.print(*literal.get().value() ? "true" : "false"); return; case 10: // unit printer.print("()"); diff --git a/src/printers/statement_printers.cpp b/src/printers/statement_printers.cpp index d34852a..3be4d18 100644 --- a/src/printers/statement_printers.cpp +++ b/src/printers/statement_printers.cpp @@ -195,7 +195,7 @@ void print_function_definition(const nodes::FunctionDefinition &statement, bool expression_is_container = statement.get_expression().value()->get().has_value(); - printer.print(" = "); + printer.print(expression_is_container ? " " : " = "); size_t previous_indentation_level = printer.get_indentation_level(); if (!expression_is_container) { diff --git a/src/printers/type_printers.cpp b/src/printers/type_printers.cpp index 6e800cd..79e5c1c 100644 --- a/src/printers/type_printers.cpp +++ b/src/printers/type_printers.cpp @@ -7,15 +7,15 @@ namespace printers { // TODO: better printing format for builtin types void print_type(const nodes::Type &type, printers::Printer &printer) { - if (type.get_modifier() != nodes::Modifier::CONST) { - print_modifier(type.get_modifier(), printer); - } - if (type.get_annotation().has_value()) { print_annotation(*type.get_annotation().value(), printer); printer.space(); } + if (type.get_modifier() != nodes::Modifier::CONST) { + print_modifier(type.get_modifier(), printer); + } + print_identifier(*type.get_name(), printer); if (type.parameters_size() > 0) { diff --git a/tests/test.langexp b/tests/test.lang similarity index 87% rename from tests/test.langexp rename to tests/test.lang index 49ba767..2ddf1fe 100644 --- a/tests/test.langexp +++ b/tests/test.lang @@ -7,7 +7,7 @@ :: module_3 : func1 func2 func3; :: module_namespace = module_4; -func = { +func { @ => { %x := scan; @@ -23,7 +23,7 @@ func = { }; ?? abracadabbra < abracadabra_abracadabra || some_long_name == another_long_name - &&. abracadabra-abracadabra < long_long_long_long_name => io.print x + &&. abracadabra_abracadabra < long_long_long_long_name => io.print x !! x < 0 => { x += 1; io.print y; @@ -51,7 +51,7 @@ fib 'n : @n Int -> Int = 'n =: 0 | 1 => 1 =: _ => fib ('n - 1) + fib 'n; -func_2 = { +func_2 { %variant := x; %val | %err := f x; @@ -108,15 +108,15 @@ func_2 = { : operator definition example ( - ) 'a 'b = 'a + neg 'b; -test.something = { +test.something { do_something a b c; } -exec.something = { +exec.something { do_something a b c; } -example.something = { +example.something { do_something a b c; } @@ -128,8 +128,8 @@ Fruit = @apple Unit | @banana Unit; : function that takes array reference argument -bubble_sort 'arr : <> Array['A] = { - swap_occured := true; +bubble_sort 'arr : <> Array['A] { + $ swap_occured := true; @ swap_occured => { swap_occured = false; @ %i : 0 .. 'arr.size => (?? 'arr[i] > 'arr[i + 1] => swap 'arr[i] 'arr[i + 1], swap_occured = true); @@ -137,7 +137,7 @@ bubble_sort 'arr : <> Array['A] = { } : bubble_sort with names instead of symbols -bubble_sort_2 'arr : ref Array['A] = { +bubble_sort_2 'arr : ref Array['A] { var swap_occured := true; for swap_occured do { swap_occured = false; @@ -162,17 +162,17 @@ bubble_sort_2 'arr : ref Array['A] = { .delete <> 'this 'key = do_something; // var methods -generic_type_name_expressions = { +generic_type_name_expressions { $x := TreeNode[Int Int].new; $y := std.Array[Int].new; } -pipes_example = { +pipes_example { expr |> func_1 a b |> func_2 c d |> print; // print (func_2 (func_1 expr a b) c d) print <| func_1 a b <| func_2 c d <| expr; // print (func_1 a b (func_2 c d expr)) } -test_ref_access_precendence = { +test_ref_access_precendence { %x := <> arr[123]; } @@ -208,7 +208,7 @@ result_example 'a! = 'a =: _? => print "value inside" =: _ => print "error inside"; : function, that returns result -parse_number : Unit! = { +parse_number : Unit! { %number_str := String.scan; %number! := Int.parse number_str; number.print; @@ -228,7 +228,7 @@ tuple_argument_test 'x : (A & B & C) = do_something; // ((A1 & A2) | B | C) same to Variant[Tuple[A1 A2] B C] variant_argument_test 'x : ( (A1 & A2) | B | C) = do_something; -literals_test = { +literals_test { %float_number_literal := 1.0f; %double_number_literal := 1.0; %int_literal := 1i; @@ -243,6 +243,13 @@ literals_test = { %null_literal := null; } -array_argument_test 'x : [[ Int ]] = do_something; +array_argument_test 'x : A[Int] = do_something; -functional_arguments_test 'x 'y : (( Int -> Int )) (( Float <- Float -> Float )) = do_something; +functional_arguments_test 'x 'y : F[Int -> Int] F[Float <- Float -> Float] = do_something; + +type_name_expression_test 'x : Int = A[Int].a.b.c x y z; +array_name_expression_test 'x : Int = [[(A a) b]].a.b.c x y z; +name_expression_test 'x : Int = abacaba.a.b.c x y z; +field_name_expression_test 'x : Int = (abacaba.a).b.c x y z; + +array_function_test 'x : Int [[ 'x (do_something 'x) (T 'x)]]