diff --git a/include/abstract_types_contexts.hpp b/archived/abstract_types_contexts.hpp similarity index 100% rename from include/abstract_types_contexts.hpp rename to archived/abstract_types_contexts.hpp diff --git a/archived/symbols_info.hpp b/archived/symbols_info.hpp new file mode 100644 index 0000000..de8f391 --- /dev/null +++ b/archived/symbols_info.hpp @@ -0,0 +1,118 @@ +#pragma once + +#include "interpreter_tree.hpp" +#include +#include +#include +#include +#include +#include + +// for clangd +#include "utils.hpp" + +namespace interpreter { + class Node; +} // namespace interpreter + +namespace info { + +struct VariantTypeInfo; +struct TupleTypeInfo; +struct AliasTypeInfo; + +struct TypeInfo; + +struct TypeclassInfo; + +enum class BuiltInTypeInfo { + StringT, + IntT, + FloatT, + UnitT, +}; + +struct TypeUsageInfo { + interpreter::tokens::TypeExpression* node; + TypeInfo* info = nullptr; +}; + +struct ParameterInfo { + std::string type; + std::vector typeclass_nodes; + std::vector typeclass_types; +}; + +struct AbstractTypeInfo { + enum { Basic, Abstract } modifier; + ParameterInfo type; +}; + +struct AliasTypeInfo { + enum {Alias, Type, Let} modifier; + std::vector parameters; + TypeUsageInfo value; +}; + +struct AnyTypeInfo { + ParameterInfo type; + std::vector parameters; + interpreter::tokens::AnyType* value; +}; + +struct TypeInfo { + std::variant type; +}; + +struct ConstructorInfo { + std::string name; + size_t order; + utils::IdType type_id; +}; + +struct FunctionDeclarationInfo { + std::vector parameters; + std::vector argument_type_nodes; + std::vector argument_types; + interpreter::tokens::FunctionDeclaration* node = nullptr; +}; + +struct FunctionDefinitionInfo { + std::vector parameters; + std::vector argument_names; + interpreter::tokens::FunctionDefinitionStatement* node = nullptr; +}; + +struct FunctionInfo { + size_t argument_count = 0; + std::optional declaration; + std::optional definition; +}; + +struct TypeclassInfo { + std::vector parameters; + std::vector requirements; +}; + +struct ImportInfo { + std::string module_name; + std::vector symbols; +}; + +struct NamespaceInfo { + enum Modifier { Const, Var }; + + std::unordered_map types; + std::unordered_map typeclasses; + std::unordered_map functions; + std::unordered_map constructors; + std::unordered_map namespaces; + std::unordered_map> variable_namespaces; + + std::optional modifier; + std::optional variable; + std::string type_name; + TypeInfo* type_info = nullptr; +}; + +} // namespace info diff --git a/include/type_graph.hpp b/archived/type_graph.hpp similarity index 95% rename from include/type_graph.hpp rename to archived/type_graph.hpp index aa67388..b5cb68b 100644 --- a/include/type_graph.hpp +++ b/archived/type_graph.hpp @@ -1,3 +1,7 @@ +//////////////////////////////////////////////////////////////////////////////////////// +// Temporary frozen, TODO +//////////////////////////////////////////////////////////////////////////////////////// + #pragma once #include @@ -33,6 +37,8 @@ public: edges_.emplace_back(); back_edges_.emplace_back(); + groups_.AddElement(); + return verticles_.size() - 1; } @@ -96,7 +102,7 @@ public: void SetEqual(size_t u, size_t v) { AddEdge(u, v); AddEdge(v, u); - // TODO: set equality + groups_.Unite(u, v); } void Calculate() { @@ -218,6 +224,7 @@ private: std::vector cluster_requirements_; utils::Storage storage_; + utils::GroupsManager groups_; bool is_calculated_ = false; }; diff --git a/include/typeclass_graph.hpp b/archived/typeclass_graph.hpp similarity index 88% rename from include/typeclass_graph.hpp rename to archived/typeclass_graph.hpp index dc50233..7136425 100644 --- a/include/typeclass_graph.hpp +++ b/archived/typeclass_graph.hpp @@ -1,6 +1,12 @@ #pragma once #include +//////////////////////////////////////////////////////////////////////////////////////// +// Temporary frozen, TODO +//////////////////////////////////////////////////////////////////////////////////////// + +#pragma once + #include // for calngd diff --git a/include/global_info.hpp b/include/global_info.hpp index 0537e39..60ba998 100644 --- a/include/global_info.hpp +++ b/include/global_info.hpp @@ -6,7 +6,7 @@ // for clangd #include "symbols_info.hpp" -#include "type_graph.hpp" +#include "type_manager.hpp" #include "utils.hpp" namespace info { @@ -22,8 +22,8 @@ public: void AddImport(ImportInfo&& import_info, const std::optional& name = std::nullopt); void AddEnterNamespace(const std::string& name, - const std::optional& modifier = std::nullopt, - const std::optional& variable = std::nullopt); + const std::optional& modifier = std::nullopt, + const std::optional& variable = std::nullopt); void EnterNamespace(const std::string& name); @@ -60,8 +60,8 @@ public: return global_info_.CreateVisitor(); } - TypeGraph* GetAbstractTypeGraph() { - return global_info_.GetAbstractTypeGraph(); + type::TypeManager* GetTypeManager() { + return global_info_.GetTypeManager(); } GlobalInfo* GetGlobalInfo() { @@ -92,8 +92,8 @@ public: return NamespaceVisitor(*this); } - TypeGraph* GetAbstractTypeGraph() { - return &abstract_type_graph_; + type::TypeManager* GetTypeManager() { + return &type_manager_; } // TODO: remember about vector realloc @@ -116,7 +116,7 @@ private: std::vector types_; std::vector typeclasses_; - info::TypeGraph abstract_type_graph_; + type::TypeManager type_manager_; NamespaceInfo global_namespace_; std::vector imports_; diff --git a/include/interpreter_tree.hpp b/include/interpreter_tree.hpp index f352fee..cd877d1 100644 --- a/include/interpreter_tree.hpp +++ b/include/interpreter_tree.hpp @@ -268,8 +268,7 @@ struct Sources { struct Namespace { enum Modifier { Const, Var }; - std::optional modifier; - std::optional name; + std::optional modifier; // modifier => variable namespace TypeIdentifier type; std::unique_ptr scope; @@ -358,7 +357,6 @@ struct TypeclassDefinitionStatement { struct FunctionDefinition { enum { Operator, Function } modifier; ExtendedName name; - std::vector> parameters; std::vector arguments; }; diff --git a/include/type_manager.hpp b/include/type_manager.hpp new file mode 100644 index 0000000..4d33d4d --- /dev/null +++ b/include/type_manager.hpp @@ -0,0 +1,26 @@ +#pragma once + +#include + +// for clangd +#include "types.hpp" +#include "utils.hpp" + +namespace info::type { + +class TypeManager { +public: + template + void AddType(const T& type) { + types_.emplace(type); + } + + template + T GetType(utils::IdType type_id) { + return std::get(types_.at(type_id)); + } +private: + std::vector types_; +}; + +} // namespace info::type diff --git a/include/types_info.hpp b/include/types.hpp similarity index 79% rename from include/types_info.hpp rename to include/types.hpp index 77931b7..72d546f 100644 --- a/include/types_info.hpp +++ b/include/types.hpp @@ -10,16 +10,16 @@ namespace info::type { -// TODO: differentiate abstract and basic types -struct AbstractType { - utils::IdType graph_id; - std::vector paramaters; -}; +// // Temporary frozen, TODO +// struct AbstractType { +// utils::IdType graph_id; +// std::vector paramaters; +// }; // TODO: check, if defined type is variant, etc. struct DefinedType { - utils::IdType type_id; - std::vector paramaters; + utils::IdType type_id; // in defined types + utils::IdType type; // in types manager, created using context types }; enum class InternalType { @@ -31,7 +31,7 @@ enum class InternalType { Unit, }; -struct TupleType { // +struct TupleType { std::optional type; std::vector, utils::IdType>> fields; }; @@ -60,8 +60,7 @@ struct ArrayType { std::optional elements_type; }; -using Type = std::variant value_to_id_; }; -class Union { // TODO: recall right algorithm name +class GroupsManager { // TODO: recall right algorithm name public: - Union(size_t n) { + GroupsManager() = default; + + explicit GroupsManager(size_t n) { edges_.resize(n); ranks_.resize(n); @@ -52,26 +54,34 @@ public: } } - void Connect(size_t u, size_t v) { // TODO: recall choice algorithm - u = GetRoot(u); - v = GetRoot(v); + void Unite(size_t u, size_t v) { // TODO: recall choice algorithm + u = GetGroupRoot(u); + v = GetGroupRoot(v); if (ranks_[v] >= ranks_[u]) { edges_[u] = v; ranks_[v] = std::max(ranks_[u] + 1, ranks_[v]); } else { edges_[v] = u; + // always ranks_[u] > ranks_[v] } } - bool IsConnected(size_t u, size_t v) { - return GetRoot(u) == GetRoot(v); + bool IsInOneGroup(size_t u, size_t v) { + return GetGroupRoot(u) == GetGroupRoot(v); } - size_t GetRoot(size_t v) { + size_t AddElement() { + size_t id = edges_.size(); + edges_.push_back(id); + ranks_.push_back(1); + return id; + } + + size_t GetGroupRoot(size_t v) { if (edges_[v] == v) { return v; } - return edges_[v] = GetRoot(edges_[v]); + return edges_[v] = GetGroupRoot(edges_[v]); } private: std::vector edges_; diff --git a/src/build_visitor.cpp b/src/build_visitor.cpp index ae3a5cf..ff3fc7f 100644 --- a/src/build_visitor.cpp +++ b/src/build_visitor.cpp @@ -50,20 +50,15 @@ void BuildVisitor::Visit(Sources* node) { void BuildVisitor::Visit(Namespace* node) { auto parse_node = current_node_; - size_t child_count = parse_node.NamedChildCount(); - - if (child_count > 2) { - current_node_ = parse_node.ChildByFieldName("name"); + size_t child_count = parse_node.ChildCount(); + if (child_count > 3) { // "namespace", ["var"/"const",] type, scope std::string modifier = parse_node.NthChild(1).GetValue(); if (modifier == "const") { node->modifier = Namespace::Const; } else if (modifier == "var") { node->modifier = Namespace::Var; } - - node->name = ExtendedName(); - Visit(&node->name.value()); } current_node_ = parse_node.ChildByFieldName("type"); @@ -338,22 +333,10 @@ void BuildVisitor::Visit(FunctionDefinition* node) { size_t child_count = parse_node.NamedChildCount(); if (child_count > 1) { - bool parameters_ended = false; - + node->arguments.resize(child_count - 1); for (size_t i = 0; i + 1 < child_count; ++i) { current_node_ = parse_node.NthNamedChild(i + 1); - - if (current_node_.GetType() != parser::tokens::AnnotatedAbstractType) { - parameters_ended = true; - } - - if (!parameters_ended) { - node->parameters.push_back(std::make_unique()); - Visit(node->parameters.back().get()); - } else { - node->arguments.emplace_back(); - Visit(&node->arguments.back()); - } + Visit(&node->arguments[i]); } } diff --git a/src/print_visitor.cpp b/src/print_visitor.cpp index 3cf27aa..9f71c78 100644 --- a/src/print_visitor.cpp +++ b/src/print_visitor.cpp @@ -49,20 +49,15 @@ void PrintVisitor::Visit(Partition* node) { void PrintVisitor::Visit(Namespace* node) { out_ << "[Namespace] "; - if (node->name.has_value()) { - if (node->modifier.has_value()) { - switch (node->modifier.value()) { - case Namespace::Const: - out_ << "const "; - break; - case Namespace::Var: - out_ << "var "; - break; - } - } else { - // error + if (node->modifier.has_value()) { + switch (node->modifier.value()) { + case Namespace::Const: + out_ << "const "; + break; + case Namespace::Var: + out_ << "var "; + break; } - Visit(&node->name.value()); } Visit(&node->type); out_ << "{\n"; @@ -206,13 +201,6 @@ void PrintVisitor::Visit(FunctionDefinition* node) { out_ << ' '; Visit(&node->name); out_ << "]"; - if (!node->parameters.empty()) { - out_ << " ("; - for (auto& parameter : node->parameters) { - Visit(parameter.get()); - } - out_ << ')'; - } if (!node->arguments.empty()) { out_ << " : ("; for (auto& argument : node->arguments) { diff --git a/src/visitor.cpp b/src/visitor.cpp index 3fee606..b661b1b 100644 --- a/src/visitor.cpp +++ b/src/visitor.cpp @@ -369,9 +369,6 @@ void Visitor::Visit(Partition* node) { } void Visitor::Visit(Namespace* node) { - if (node->name.has_value()) { - Visit(&node->name.value()); - } Visit(&node->type); Visit(node->scope.get()); } @@ -427,9 +424,6 @@ void Visitor::Visit(TypeclassDefinitionStatement* node) { void Visitor::Visit(FunctionDefinition* node) { Visit(&node->name); - for (auto& parameter : node->parameters) { - Visit(parameter.get()); - } for (auto& argument : node->arguments) { Visit(&argument); } diff --git a/tests/functions.lang b/tests/functions.lang index ee40a32..6b954c8 100644 --- a/tests/functions.lang +++ b/tests/functions.lang @@ -16,7 +16,7 @@ def fact : n = | _ -> error "n must be positive" decl find_prefix_hashes ('H : (#AccHash Char)) : String -> (Array 'H) -def find_prefix_hashes 'H : str = { +def find_prefix_hashes : str = { var hashes = (Array 'H).new (str.size () + 1) ; hashes:0 = 'H.of str:0 @@ -38,7 +38,7 @@ def find_substring : str substr = { const substr_hash = Hash.of substr for i in 0..(str_hashes.size () - substr.size ()) do { - const part_hash = Hash.diff str_hashes:(i + substr->size ()) str_hashes:i + const part_hash = Hash.diff str_hashes(i + substr->size ()) str_hashes:i if part_hash == substr_hash then { ; result.push i diff --git a/tests/match.lang b/tests/match.lang index cd738c7..00719f0 100644 --- a/tests/match.lang +++ b/tests/match.lang @@ -1,15 +1,244 @@ +================================================================================ +Match +================================================================================ + def fruit_cost : fruit = { - return (match fruit with - | $Banana -> 11 - | $Apple | $Orange -> 7) + return (match fruit with + | $Banana -> 11 + | $Apple | $Orange -> 7) } def amount_to_string : x is_zero_separated = { const ans = match x with - | 0 ? is_zero_separated () -> "Zero" - | 0 | 1 | 2 | 3 | 4 -> "Few" - | x ? (5..9).contains x -> "Several" - | x ? (10..19).contains x -> "Pack" - | _ -> "Lots" + | 0 ? is_zero_separated () -> "Zero" + | 0 | 1 | 2 | 3 | 4 -> "Few" + | x ? (5..9).contains x -> "Several" + | x ? (10..19).contains x -> "Pack" + | _ -> "Lots" return ans } + +-------------------------------------------------------------------------------- + +(source_file + (source_statement + (function_definition_statement + (function_definition + (extended_name + (name_identifier)) + (extended_name + (name_identifier))) + (superexpression + (expression + (prefixed_expression + (block + (block_statement + (prefixed_expression + (return_expression + (expression + (subexpression + (subexpression_token + (scoped_statement + (superexpression + (flow_control + (match + (expression + (subexpression + (subexpression_token + (name_expression + (extended_name + (name_identifier)))))) + (match_case + (pattern + (type_constructor_pattern + (type_expression + (type_subexpression + (type_identifier))))) + (expression + (subexpression + (subexpression_token + (literal + (number_literal)))))) + (match_case + (pattern + (type_constructor_pattern + (type_expression + (type_subexpression + (type_identifier)))))) + (match_case + (pattern + (type_constructor_pattern + (type_expression + (type_subexpression + (type_identifier))))) + (expression + (subexpression + (subexpression_token + (literal + (number_literal)))))))))))))))))))))) + (source_statement + (function_definition_statement + (function_definition + (extended_name + (name_identifier)) + (extended_name + (name_identifier)) + (extended_name + (name_identifier))) + (superexpression + (expression + (prefixed_expression + (block + (block_statement + (variable_definition_statement + (any_name + (annotated_name + (extended_name + (name_identifier)))) + (superexpression + (flow_control + (match + (expression + (subexpression + (subexpression_token + (name_expression + (extended_name + (name_identifier)))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal)))) + (expression + (subexpression + (function_call_expression + (extended_name + (name_identifier)) + (function_argument + (subexpression_token + (literal + (unit_literal))))))) + (expression + (subexpression + (subexpression_token + (literal + (string_literal)))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal))))) + (match_case + (pattern + (pattern_token + (literal + (number_literal)))) + (expression + (subexpression + (subexpression_token + (literal + (string_literal)))))) + (match_case + (pattern + (pattern_token + (extended_name + (name_identifier)))) + (expression + (subexpression + (function_call_expression + (subexpression_token + (scoped_statement + (superexpression + (expression + (subexpression + (binary_operator_expression + (subexpression + (subexpression_token + (literal + (number_literal)))) + (operator) + (subexpression + (subexpression_token + (literal + (number_literal)))))))))) + (extended_name + (name_identifier)) + (function_argument + (subexpression_token + (name_expression + (extended_name + (name_identifier)))))))) + (expression + (subexpression + (subexpression_token + (literal + (string_literal)))))) + (match_case + (pattern + (pattern_token + (extended_name + (name_identifier)))) + (expression + (subexpression + (function_call_expression + (subexpression_token + (scoped_statement + (superexpression + (expression + (subexpression + (binary_operator_expression + (subexpression + (subexpression_token + (literal + (number_literal)))) + (operator) + (subexpression + (subexpression_token + (literal + (number_literal)))))))))) + (extended_name + (name_identifier)) + (function_argument + (subexpression_token + (name_expression + (extended_name + (name_identifier)))))))) + (expression + (subexpression + (subexpression_token + (literal + (string_literal)))))) + (match_case + (pattern + (pattern_token + (extended_name + (name_identifier)))) + (expression + (subexpression + (subexpression_token + (literal + (string_literal))))))))))) + (block_statement + (prefixed_expression + (return_expression + (expression + (subexpression + (subexpression_token + (name_expression + (extended_name + (name_identifier)))))))))))))))) diff --git a/tests/namespaces.lang b/tests/namespaces.lang index 3dfbb49..ef58a35 100644 --- a/tests/namespaces.lang +++ b/tests/namespaces.lang @@ -10,6 +10,10 @@ namespace Array { decl something : Unit -> Unit } -namespace var a : Array { +namespace var : Array { + decl something : Unit -> Unit +} + +namespace const : Array { decl something : Unit -> Unit } diff --git a/tests/typeclasses.lang b/tests/typeclasses.lang index 8886ac7..e42a7a0 100644 --- a/tests/typeclasses.lang +++ b/tests/typeclasses.lang @@ -2,10 +2,7 @@ typeclass Copy = & copy : Copy -> Copy typeclass (Ord : #Eq) = - & ( < ) : Ord -> Ord -> Bool - & ( > ) : Ord -> Ord -> Bool - & ( <= ) : Ord -> Ord -> Bool - & ( >= ) : Ord -> Ord -> Bool + & is_less_then : Ord -> Bool typeclass (D : #A #B #C) 'A 'B = & do_something : Unit -> (& 'A & 'B) @@ -13,8 +10,17 @@ typeclass (D : #A #B #C) 'A 'B = typeclass E 'A = & do_something : Unit -> 'A -namespace const ord : Ord { - def ( <= ) : a b = (a < b) || (a == b) - def ( > ) : a b = !(a <= b) - def ( >= ) : a b = !(a < b) -} +decl ( == ) ('A : #Ord) : 'A -> 'A -> Bool +def ( == ) : a b = a.is_equal_to b + +decl ( < ) ('A : #Ord) : 'A -> 'A -> Bool +def ( < ) : a b = a.is_less_then b + +decl ( > ) ('A : #Ord) : 'A -> 'A -> Bool +def ( > ) : a b = !(a <= b) + +decl ( <= ) ('A : #Ord) : 'A -> 'A -> Bool +def ( <= ) : a b = (a < b) || (a == b) + +decl ( >= ) ('A : #Ord) : 'A -> 'A -> Bool +def ( >= ) : a b = !(a < b) diff --git a/tests/types.lang b/tests/types.lang index f6ce429..a27b3db 100644 --- a/tests/types.lang +++ b/tests/types.lang @@ -1,3 +1,7 @@ +================================================================================ +Types +================================================================================ + alias T1 = Int abstract (T2 : #A #B #C) @@ -6,3 +10,44 @@ abstract (T2 : #A #B #C) let T2 = Int let T2 = Float let T2 = Complex + +-------------------------------------------------------------------------------- + +(source_file + (source_statement + (alias_definition_statement + (type_identifier) + (type_expression + (type_subexpression + (type_identifier))))) + (source_statement + (abstract_type_definition_statement + (annotated_type + (type_identifier) + (typeclass_expression + (typeclass_subexpression + (typeclass_identifier))) + (typeclass_expression + (typeclass_subexpression + (typeclass_identifier))) + (typeclass_expression + (typeclass_subexpression + (typeclass_identifier)))))) + (source_statement + (alias_definition_statement + (type_identifier) + (type_expression + (type_subexpression + (type_identifier))))) + (source_statement + (alias_definition_statement + (type_identifier) + (type_expression + (type_subexpression + (type_identifier))))) + (source_statement + (alias_definition_statement + (type_identifier) + (type_expression + (type_subexpression + (type_identifier))))))