typeclasses can have required methods and required functions

This commit is contained in:
ProgramSnail 2023-05-13 16:14:02 +03:00
parent 562541087e
commit 4882d458f8
11 changed files with 113 additions and 43 deletions

View file

@ -78,7 +78,8 @@ struct Function {
struct Typeclass { struct Typeclass {
std::vector<Parameter> parameters; std::vector<Parameter> parameters;
std::vector<FunctionDeclaration> requirements; std::vector<FunctionDeclaration> function_requirements;
std::vector<FunctionDeclaration> method_requirements;
}; };
struct Import { struct Import {

View file

@ -355,7 +355,8 @@ struct TypeclassDefinitionStatement {
BaseNode base; BaseNode base;
std::unique_ptr<TypeDefinition> definition; std::unique_ptr<TypeDefinition> definition;
std::vector<std::unique_ptr<FunctionDeclaration>> requirements; std::vector<std::unique_ptr<FunctionDeclaration>> method_requirements;
std::vector<std::unique_ptr<FunctionDeclaration>> function_requirements;
utils::IdType typeclass_id_; utils::IdType typeclass_id_;
}; };

View file

@ -71,6 +71,7 @@ public:
Node NthChild(size_t n) { Node NthChild(size_t n) {
return Node(ts_node_child(node_, n), source_); return Node(ts_node_child(node_, n), source_);
} }
size_t ChildCount() { size_t ChildCount() {
return ts_node_child_count(node_); return ts_node_child_count(node_);
} }
@ -86,6 +87,14 @@ public:
return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), source_); return Node(ts_node_child_by_field_name(node_, name.c_str(), name.size()), source_);
} }
Node PreviousSibling() {
return Node(ts_node_prev_sibling(node_), source_);
}
Node PreviousNamedSibling() {
return Node(ts_node_prev_named_sibling(node_), source_);
}
Node NextSibling() { Node NextSibling() {
return Node(ts_node_next_sibling(node_), source_); return Node(ts_node_next_sibling(node_), source_);
} }

@ -1 +1 @@
Subproject commit 62c8b6193437e0a10d5b605dc002c7db5e3fc256 Subproject commit 3610504b4ce142fe30f47851709fef6bc2fc53f1

View file

@ -269,14 +269,15 @@ void BuildVisitor::Visit(TypeclassDefinitionStatement* node) {
size_t child_count = parse_node.NamedChildCount(); size_t child_count = parse_node.NamedChildCount();
if (child_count > 1) { for (size_t i = 0; i + 1 < child_count; ++i) {
node->requirements.resize(child_count - 1); current_node_ = parse_node.NthNamedChild(i + 1);
if (parse_node.PreviousSibling().GetValue() != "var") {
for (size_t i = 0; i + 1 < child_count; ++i) { node->function_requirements.push_back(std::make_unique<FunctionDeclaration>());
current_node_ = parse_node.NthNamedChild(i + 1); Visit(node->function_requirements.back().get());
node->requirements[i] = std::make_unique<FunctionDeclaration>(); } else {
Visit(node->requirements[i].get()); node->method_requirements.push_back(std::make_unique<FunctionDeclaration>());
} Visit(node->method_requirements.back().get());
}
} }
current_node_ = parse_node; current_node_ = parse_node;

View file

@ -160,10 +160,17 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
current_info_.reset(); current_info_.reset();
} }
info.requirements.reserve(node->requirements.size()); info.function_requirements.reserve(node->function_requirements.size());
for (size_t i = 0; i < node->requirements.size(); ++i) { for (size_t i = 0; i < node->function_requirements.size(); ++i) {
Visit(node->requirements[i].get()); Visit(node->function_requirements[i].get());
info.requirements[i] = std::move(std::any_cast<info::definition::FunctionDeclaration>(current_info_)); info.function_requirements[i] = std::move(std::any_cast<info::definition::FunctionDeclaration>(current_info_));
current_info_.reset();
}
info.method_requirements.reserve(node->method_requirements.size());
for (size_t i = 0; i < node->method_requirements.size(); ++i) {
Visit(node->method_requirements[i].get());
info.method_requirements[i] = std::move(std::any_cast<info::definition::FunctionDeclaration>(current_info_));
current_info_.reset(); current_info_.reset();
} }

View file

@ -157,14 +157,22 @@ void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
void PrintVisitor::Visit(TypeclassDefinitionStatement* node) { void PrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "[Typeclass] ("; out_ << "[Typeclass] (";
Visit(node->definition.get()); Visit(node->definition.get());
if (!node->requirements.empty()) { if (!node->function_requirements.empty()) {
out_ << ") : (\n"; out_ << ") : (\n";
} }
for (auto& requirement : node->requirements) { for (auto& requirement : node->function_requirements) {
out_ << "& "; out_ << "& ";
Visit(requirement.get()); Visit(requirement.get());
out_ << "\n"; out_ << "\n";
} }
if (!node->method_requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
out_ << "\n";
}
out_ << ")\n"; out_ << ")\n";
} }

View file

@ -218,14 +218,22 @@ void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) {
out_ << "] ("; out_ << "] (";
Visit(node->definition.get()); Visit(node->definition.get());
if (!node->requirements.empty()) { if (!node->function_requirements.empty()) {
out_ << ") : (\n"; out_ << ") : (\n";
} }
for (auto& requirement : node->requirements) { for (auto& requirement : node->function_requirements) {
out_ << "& "; out_ << "& ";
Visit(requirement.get()); Visit(requirement.get());
out_ << "\n"; out_ << "\n";
} }
if (!node->method_requirements.empty()) {
out_ << ") : (\n";
}
for (auto& requirement : node->method_requirements) {
out_ << "& var ";
Visit(requirement.get());
out_ << "\n";
}
out_ << ")\n"; out_ << ")\n";
} }

View file

@ -357,8 +357,11 @@ void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
void Visitor::Visit(TypeclassDefinitionStatement* node) { void Visitor::Visit(TypeclassDefinitionStatement* node) {
Visit(node->definition.get()); Visit(node->definition.get());
for (auto& requirement : node->requirements) { for (auto& function_requirement : node->function_requirements) {
Visit(requirement.get()); Visit(function_requirement.get());
}
for (auto& method_requirement : node->method_requirements) {
Visit(method_requirement.get());
} }
} }

View file

@ -5,7 +5,7 @@ basic Char
basic Bool basic Bool
basic Unit basic Unit
// bool functions //
decl not : Bool -> Bool decl not : Bool -> Bool
def not : x = def not : x =
@ -36,14 +36,14 @@ def ( || ) : x y =
// Eq typeclass // Eq typeclass
typeclass Eq = typeclass Eq =
& ( == ) : Eq -> Bool & var ( == ) : Eq -> Bool
& ( != ) : Eq -> Bool & var ( != ) : Eq -> Bool
namespace const Eq { namespace const Eq {
def ( != ) : x = not: (self == x) def var ( != ) : x = not: (self == x)
} }
// Ord typeclass //
struct Order = struct Order =
| EQ | EQ
@ -51,13 +51,13 @@ struct Order =
| GT | GT
typeclass (Ord : #Eq) = typeclass (Ord : #Eq) =
& compare: Ord -> Order & var compare: Ord -> Order
& ( < ) : Ord -> Bool & var ( < ) : Ord -> Bool
& ( >= ) : Ord -> Bool & var ( >= ) : Ord -> Bool
& ( > ) : Ord -> Bool & var ( > ) : Ord -> Bool
& ( <= ) : Ord -> Bool & var ( <= ) : Ord -> Bool
& min : Ord -> Ord & var min : Ord -> Ord
& max : Ord -> Ord & var max : Ord -> Ord
namespace var Ord { namespace var Ord {
def compare : x = def compare : x =
@ -75,23 +75,55 @@ namespace var Ord {
// //
typeclass Show = typeclass Show =
& show : -> String & var show : -> String
typeclass Read = typeclass Read =
& read : String -> Read & var read : String -> Read
typeclass Debug = typeclass Debug =
& debug : -> String & debug : -> String
// //
typeclass Default =
& default : -> Default
//
// Enum typeclass typeclass Bounded =
& min_bound : -> Bounded
& max_bound : -> Bounded
& var is_max_bound : -> Bool
& var is_min_bound : -> Bool
//
typeclass Enum = typeclass Enum =
& succ : Enum -> (Optional Enum) & var succ : -> (Optional Enum)
& pred : Enum -> (Optional Enum) & var pred : -> (Optional Enum)
& toEnum : Int -> Enum
& var fromEnum : -> Int
//
// // bad
// typeclass Functor 'A =
// & fmap 'B ('F : (#Functor 'B)) : ('A -> 'B) -> Functor -> 'F
// typeclass (Iterator : #Eq) =
// & next : -> Unit
// & prev : -> Unit
//
// typeclass Iterable ('Iter : #Iterable) =
// & begin : -> 'Iter
// & end : -> 'Iter
//
class Slice ('Elem : ) ('Structure : (#Iterable)) =
// //

View file

@ -1,14 +1,14 @@
typeclass Copy = typeclass Default =
& copy : Copy -> Copy & default : -> Copy
typeclass (Ord : #Eq) = typeclass (Ord : #Eq) =
& is_less_then : Ord -> Bool & var is_less_then : Ord -> Bool
typeclass (D : #A #B #C) 'A 'B = typeclass (D : #A #B #C) 'A 'B =
& do_something : -> (& 'A & 'B) & var do_something : -> (& 'A & 'B)
typeclass E 'A = typeclass E 'A =
& do_something : -> 'A & var do_something : -> 'A
decl ( == ) ('A : #Ord) : 'A -> 'A -> Bool decl ( == ) ('A : #Ord) : 'A -> 'A -> Bool
def ( == ) : a b = a.is_equal_to: b def ( == ) : a b = a.is_equal_to: b