part of type_check_visitor done

This commit is contained in:
ProgramSnail 2023-04-22 19:30:16 +03:00
parent 6fc91aafa0
commit 656f58bcde
14 changed files with 891 additions and 539 deletions

View file

@ -64,6 +64,10 @@ public:
return global_info_.GetAbstractTypeGraph();
}
GlobalInfo* GetGlobalInfo() {
return &global_info_;
}
const std::vector<std::string>& GetCurrentPath() {
return current_path_;
}

View file

@ -261,7 +261,6 @@ struct Namespace {
std::unique_ptr<Sources> scope;
std::optional<utils::IdType> type_id_;
std::optional<info::type::Type> variable_type_;
};
struct Partition {
@ -471,6 +470,9 @@ struct LambdaFunction {
std::vector<std::unique_ptr<AnnotatedAbstractType>> parameters;
std::vector<ExtendedName> arguments;
Expression expression;
std::vector<utils::IdType> argument_graph_ids_;
utils::IdType return_type_graph_id_;
};
struct ArrayExpression {

View file

@ -41,66 +41,65 @@ private:
void Visit(FunctionDefinition* node) override;
void Visit(TypeDefinition* node) override;
void Visit(AnyAnnotatedType* node) override;
// // void Visit(AnyAnnotatedType* node) override;
// Flow control -----------------
void Visit(MatchCase* node) override;
void Visit(Match* node) override;
void Visit(Condition* node) override;
void Visit(DoWhileLoop* node) override;
void Visit(WhileLoop* node) override;
void Visit(ForLoop* node) override;
void Visit(LoopLoop* node) override;
// // void Visit(MatchCase* node) override;
// // void Visit(Match* node) override;
// // void Visit(Condition* node) override;
// // void Visit(DoWhileLoop* node) override;
// // void Visit(WhileLoop* node) override;
// // void Visit(ForLoop* node) override;
// // void Visit(LoopLoop* node) override;
// Statements, expressions, blocks, etc. -----------------
void Visit(Block* node) override;
void Visit(ScopedStatement* node) override;
// // void Visit(Block* node) override;
// // void Visit(ScopedStatement* node) override;
// Operators
void Visit(BinaryOperatorExpression* node) override;
void Visit(UnaryOperatorExpression* node) override;
void Visit(ReferenceExpression* node) override;
void Visit(AccessExpression* node) override;
// // void Visit(BinaryOperatorExpression* node) override;
// // void Visit(UnaryOperatorExpression* node) override;
// // void Visit(ReferenceExpression* node) override;
// // void Visit(AccessExpression* node) override;
// Simple Expressions
void Visit(FunctionCallExpression* node) override;
// // void Visit(FunctionCallExpression* node) override;
void Visit(TupleExpression* node) override;
void Visit(VariantExpression* node) override;
void Visit(ReturnExpression* node) override;
void Visit(TypeConstructor* node) override;
// // void Visit(TupleExpression* node) override;
// // void Visit(VariantExpression* node) override;
// // void Visit(ReturnExpression* node) override;
// // void Visit(TypeConstructor* node) override;
void Visit(LambdaFunction* node) override;
void Visit(ArrayExpression* node) override;
// // void Visit(ArrayExpression* node) override;
void Visit(LoopControlExpression& node) override; // enum
// // void Visit(LoopControlExpression& node) override; // enum
// Name
void Visit(NameExpression* node) override;
void Visit(TupleName* node) override;
void Visit(VariantName* node) override;
void Visit(AnnotatedName* node) override;
// // void Visit(NameExpression* node) override;
// // void Visit(TupleName* node) override;
// // void Visit(VariantName* node) override;
// // void Visit(AnnotatedName* node) override;
// Type, typeclass, etc. -----------------
// Type
void Visit(FunctionType* node) override;
void Visit(TupleType* node) override;
void Visit(VariantType* node) override;
void Visit(ParametrizedType* node) override;
// // void Visit(FunctionType* node) override;
// // void Visit(TupleType* node) override;
// // void Visit(VariantType* node) override;
// // void Visit(ParametrizedType* node) override;
void Visit(TypeExpression* node) override;
void Visit(ExtendedScopedAnyType* node) override;
// // void Visit(ExtendedScopedAnyType* node) override;
// Typeclass
void Visit(ParametrizedTypeclass* node) override;
// // void Visit(ParametrizedTypeclass* node) override;
void Visit(TypeclassExpression* node) override;
// Identifiers, constants, etc. -----------------

View file

@ -85,17 +85,19 @@ struct FunctionDeclarationInfo {
std::vector<ParameterInfo> parameters;
std::vector<interpreter::tokens::AnyType*> argument_type_nodes;
std::vector<AnyTypeInfo*> argument_types;
interpreter::tokens::FunctionDeclaration* node = nullptr;
};
struct FunctionDefinitionInfo {
std::vector<ParameterInfo> parameters;
std::vector<std::string> argument_names;
interpreter::tokens::SuperExpression* expression = nullptr;
interpreter::tokens::FunctionDefinitionStatement* node = nullptr;
};
struct FunctionInfo {
FunctionDeclarationInfo declaration;
FunctionDefinitionInfo definition;
size_t argument_count = 0;
std::optional<FunctionDeclarationInfo> declaration;
std::optional<FunctionDefinitionInfo> definition;
};
struct TypeclassInfo {

View file

@ -117,6 +117,7 @@ private:
info::TypeInfoContextManager context_manager_;
utils::IdType current_type_;
std::optional<utils::IdType> returned_type_;
};
} // namespace interpreter

View file

@ -23,20 +23,21 @@ public:
return types_[type_id];
}
// void AddTypeRequirement(utils::IdType type, utils::IdType requrement); // TODO
void AddTypeRequirement(utils::IdType type, utils::IdType requrement) {} // TODO
void EqualTypes(utils::IdType first_type, utils::IdType second_type) {} // TODO
void CallFunction(const std::vector<std::string>& names,
const std::vector<utils::IdType>& argument_types) {
if (names.size() != argument_types.size()) {
// error
}
contexts_.emplace_back(true);
for (size_t i = 0; i < names.size(); ++i) {
DefineVariable(names[i], argument_types[i]);
}
}
// void CallFunction(const std::vector<std::string>& names,
// const std::vector<utils::IdType>& argument_types) {
// if (names.size() != argument_types.size()) {
// // error
// }
//
// contexts_.emplace_back(true);
//
// for (size_t i = 0; i < names.size(); ++i) {
// DefineVariable(names[i], argument_types[i]);
// }
// }
void EnterContext() {
contexts_.emplace_back(false);
@ -59,6 +60,15 @@ public:
return contexts_.back().DefineVariable(name, type_id);
}
bool RemoveVariable(const std::string& name) {
for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) {
if (contexts_[i].RemoveVariable(name)) {
return true;
}
}
return false;
}
void EnterVariableContext(const std::string& name,
utils::IdType type_id) { // for variable namespaces, for loops
contexts_.push_back(false);
@ -67,7 +77,7 @@ public:
}
std::optional<utils::IdType> GetVariableType(const std::string& name) {
for (ssize_t i = contexts_.size() - 1; i >= 0; --i) {
for (ssize_t i = (ssize_t)contexts_.size() - 1; i >= 0; --i) {
auto maybe_type = contexts_[i].GetVariableType(name);
if (maybe_type.has_value()) {
return maybe_type.value();
@ -89,6 +99,10 @@ private:
return true;
}
bool RemoveVariable(const std::string& name) {
return variables_.erase(name);
}
std::optional<utils::IdType> GetVariableType(const std::string& name) {
auto variable_iter = variables_.find(name);

View file

@ -6,7 +6,6 @@
#include <memory>
// for clangd
#include "error_handling.hpp"
#include "utils.hpp"
namespace info::type {
@ -37,39 +36,14 @@ struct TupleType { //
};
struct VariantType {
static VariantType MakeOptional(const std::variant<std::string, TupleType>& option) {
if (std::holds_alternative<std::string>(option)) {
return MakeOptional(option);
} else if (std::holds_alternative<TupleType>(option)) {
return MakeOptional(std::get<TupleType>(option));
} else {
error_handling::HandleInternalError("Can't construct optional from variant", "info::type::VariantType::MakeOptional");
}
}
static VariantType MakeOptional(TupleType option) { // TODO
VariantType type;
type.type = option.type;
option.type = "\'Some";
type.constructors.emplace_back(option);
type.constructors.emplace_back("\'None");
return type;
}
static VariantType MakeOptional(std::string& option) { // TODO
VariantType type;
type.type = option;
type.constructors.emplace_back("\'Some");
type.constructors.emplace_back("\'None");
return type;
}
std::optional<std::string> type;
std::vector<std::variant<std::string, TupleType>> constructors;
};
struct OptionalType {
std::optional<utils::IdType> type; // Can be empty (Some or None)
};
struct ReferenceToType {
std::vector<utils::ReferenceType> references;
utils::IdType type;
@ -77,10 +51,12 @@ struct ReferenceToType {
struct FunctionType {
std::vector<utils::IdType> argument_types;
utils::IdType return_type;
};
struct ArrayType {
std::vector<utils::IdType> element_types;
size_t size; // ?? = 0 for dynamic ??
std::optional<utils::IdType> elements_type;
};
using Type = std::variant<AbstractType,

View file

@ -16,42 +16,42 @@ public:
protected:
// Sources -----------------
virtual void Visit(SourceFile* node) {}
virtual void Visit(Sources* node) {}
virtual void Visit(SourceFile* node);
virtual void Visit(Sources* node);
// Namespaces, partitions -----------------
virtual void Visit(Partition* node) {}
virtual void Visit(Namespace* node) {}
virtual void Visit(Partition* node);
virtual void Visit(Namespace* node);
// Definitions -----------------
virtual void Visit(ImportStatement* node) {}
virtual void Visit(AliasDefinitionStatement* node) {}
virtual void Visit(VariableDefinitionStatement* node) {}
virtual void Visit(FunctionDeclaration* node) {}
virtual void Visit(FunctionDefinitionStatement* node) {}
virtual void Visit(TypeDefinitionStatement* node) {}
virtual void Visit(AbstractTypeDefinitionStatement* node) {}
virtual void Visit(TypeclassDefinitionStatement* node) {}
virtual void Visit(ImportStatement* node);
virtual void Visit(AliasDefinitionStatement* node);
virtual void Visit(VariableDefinitionStatement* node);
virtual void Visit(FunctionDeclaration* node);
virtual void Visit(FunctionDefinitionStatement* node);
virtual void Visit(TypeDefinitionStatement* node);
virtual void Visit(AbstractTypeDefinitionStatement* node);
virtual void Visit(TypeclassDefinitionStatement* node);
virtual void Visit(SourceStatement& node); // variant
// Definition parts
virtual void Visit(FunctionDefinition* node) {}
virtual void Visit(TypeDefinition* node) {}
virtual void Visit(AnyAnnotatedType* node) {}
virtual void Visit(FunctionDefinition* node);
virtual void Visit(TypeDefinition* node);
virtual void Visit(AnyAnnotatedType* node);
// Flow control -----------------
virtual void Visit(MatchCase* node) {}
virtual void Visit(Match* node) {}
virtual void Visit(Condition* node) {}
virtual void Visit(DoWhileLoop* node) {}
virtual void Visit(WhileLoop* node) {}
virtual void Visit(ForLoop* node) {}
virtual void Visit(LoopLoop* node) {}
virtual void Visit(MatchCase* node);
virtual void Visit(Match* node);
virtual void Visit(Condition* node);
virtual void Visit(DoWhileLoop* node);
virtual void Visit(WhileLoop* node);
virtual void Visit(ForLoop* node);
virtual void Visit(LoopLoop* node);
virtual void Visit(FlowControl& node); // variant
@ -59,7 +59,7 @@ protected:
virtual void Visit(BlockStatement& node); // variant
virtual void Visit(Block* node) {}
virtual void Visit(Block* node);
virtual void Visit(SubExpressionToken& node); // variant
virtual void Visit(SubExpression& node); // variant
@ -67,36 +67,36 @@ protected:
virtual void Visit(Expression& node); // variant
virtual void Visit(SuperExpression& node); // variant
virtual void Visit(ScopedStatement* node) {}
virtual void Visit(ScopedStatement* node);
// Operators
virtual void Visit(BinaryOperatorExpression* node) {}
virtual void Visit(UnaryOperatorExpression* node) {}
virtual void Visit(ReferenceExpression* node) {}
virtual void Visit(AccessExpression* node) {}
virtual void Visit(BinaryOperatorExpression* node);
virtual void Visit(UnaryOperatorExpression* node);
virtual void Visit(ReferenceExpression* node);
virtual void Visit(AccessExpression* node);
// Simple Expressions
virtual void Visit(FunctionCallExpression* node) {}
virtual void Visit(FunctionCallExpression* node);
virtual void Visit(FunctionArgument& node); // variant
virtual void Visit(TupleExpression* node) {}
virtual void Visit(VariantExpression* node) {}
virtual void Visit(ReturnExpression* node) {}
virtual void Visit(TypeConstructor* node) {}
virtual void Visit(LambdaFunction* node) {}
virtual void Visit(ArrayExpression* node) {}
virtual void Visit(TupleExpression* node);
virtual void Visit(VariantExpression* node);
virtual void Visit(ReturnExpression* node);
virtual void Visit(TypeConstructor* node);
virtual void Visit(LambdaFunction* node);
virtual void Visit(ArrayExpression* node);
virtual void Visit(LoopControlExpression& node) {} // enum
virtual void Visit(LoopControlExpression& node); // enum
// Name
virtual void Visit(NameExpression* node) {}
virtual void Visit(TupleName* node) {}
virtual void Visit(VariantName* node) {}
virtual void Visit(AnnotatedName* node) {}
virtual void Visit(NameExpression* node);
virtual void Visit(TupleName* node);
virtual void Visit(VariantName* node);
virtual void Visit(AnnotatedName* node);
virtual void Visit(AnyName& node); // variant
@ -104,20 +104,20 @@ protected:
// Type
virtual void Visit(FunctionType* node) {}
virtual void Visit(TupleType* node) {}
virtual void Visit(VariantType* node) {}
virtual void Visit(ParametrizedType* node) {}
virtual void Visit(TypeExpression* node) {}
virtual void Visit(FunctionType* node);
virtual void Visit(TupleType* node);
virtual void Visit(VariantType* node);
virtual void Visit(ParametrizedType* node);
virtual void Visit(TypeExpression* node);
virtual void Visit(AnyType& node); // variant
virtual void Visit(ExtendedScopedAnyType* node) {}
virtual void Visit(ExtendedScopedAnyType* node);
// Typeclass
virtual void Visit(ParametrizedTypeclass* node) {}
virtual void Visit(TypeclassExpression* node) {}
virtual void Visit(ParametrizedTypeclass* node);
virtual void Visit(TypeclassExpression* node);
virtual void Visit(TypeclassUsage& node); // variant
@ -128,14 +128,14 @@ protected:
// Identifiers, constants, etc. -----------------
virtual void Visit(ExtendedName* node) {}
virtual void Visit(ExtendedName* node);
virtual void Visit(AnyIdentifier* node) {} // std::string
virtual void Visit(AnyIdentifier* node); // std::string
virtual void Visit(FloatNumberLiteral* node) {}
virtual void Visit(NumberLiteral* node) {}
virtual void Visit(StringLiteral* node) {}
virtual void Visit(CharLiteral* node) {}
virtual void Visit(FloatNumberLiteral* node);
virtual void Visit(NumberLiteral* node);
virtual void Visit(StringLiteral* node);
virtual void Visit(CharLiteral* node);
virtual void Visit(Literal& node); // variant
};

View file

@ -117,6 +117,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
info.argument_type_nodes[i] = &node->type->types[i];
}
info.node = node;
if (was_in_statement) {
current_info_ = std::move(info);
} else {
@ -148,7 +150,7 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
info.expression = &node->value;
info.node = node;
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info));

View file

@ -1,5 +1,6 @@
// for clangd
#include "../include/global_info.hpp"
#include "../include/error_handling.hpp"
namespace info {
@ -63,9 +64,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::st
id = global_info_.functions_.size();
namespace_stack_.back()->functions[name] = id;
global_info_.functions_.emplace_back();
global_info_.functions_.back().argument_count = function_declaration_info.argument_types.size();
global_info_.functions_.back().declaration = std::move(function_declaration_info);
} else {
id = function_id_iter->second;
if (global_info_.functions_.back().argument_count != function_declaration_info.argument_types.size()) {
error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo");
}
global_info_.functions_[id].declaration = std::move(function_declaration_info);
}
@ -82,9 +87,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::str
id = global_info_.functions_.size();
namespace_stack_.back()->functions[name] = id;
global_info_.functions_.emplace_back();
global_info_.functions_.back().argument_count = function_definition_info.argument_names.size();
global_info_.functions_.back().definition = std::move(function_definition_info);
} else {
id = function_id_iter->second;
if (global_info_.functions_.back().argument_count != function_definition_info.argument_names.size()) {
error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo");
}
global_info_.functions_[id].definition = std::move(function_definition_info);
}

View file

@ -54,7 +54,7 @@ void LinkSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
for (size_t i = 0; i <node->parameters.size(); ++i) {
abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]);
}
Visit(node->value.get());
Visitor::Visit(node->value.get());
abstract_types_.ExitContext();
}
@ -68,10 +68,10 @@ void LinkSymbolsVisitor::Visit(VariableDefinitionStatement* node) {
void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) {
abstract_types_.EnterContext();
for (auto& parameter : node->parameters) {
Visit(parameter.get());
Visitor::Visit(parameter.get());
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
}
Visit(node->type.get());
Visitor::Visit(node->type.get());
abstract_types_.ExitContext();
}
@ -90,7 +90,7 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
}
void LinkSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
Visit(node->type.get());
Visitor::Visit(node->type.get());
// TODO: can't be used before definition
abstract_types_.DefineType(node->type->type, node->type->type_graph_id_);
}
@ -108,224 +108,54 @@ void LinkSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
void LinkSymbolsVisitor::Visit(FunctionDefinition* node) {
for (auto& parameter : node->parameters) {
Visit(parameter.get());
Visitor::Visit(parameter.get());
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
}
}
void LinkSymbolsVisitor::Visit(TypeDefinition* node) {
Visit(node->type.get());
Visitor::Visit(node->type.get());
for (auto& parameter : node->parameters) {
Visit(parameter.get());
Visitor::Visit(parameter.get());
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
}
}
void LinkSymbolsVisitor::Visit(AnyAnnotatedType* node) {
// TODO check ??
if (!node->typeclasses.empty() > 0) {
for (auto& typeclass : node->typeclasses) {
Visitor::Visit(typeclass);
}
}
}
// Flow control -----------------
void LinkSymbolsVisitor::Visit(MatchCase* node) {
Visitor::Visit(node->value);
if (node->condition.has_value()) {
Visitor::Visit(node->condition.value());
}
if (node->statement.has_value()) {
Visitor::Visit(node->statement.value());
}
}
void LinkSymbolsVisitor::Visit(Match* node) {
Visitor::Visit(node->value);
for (auto& match_case : node->matches) {
Visit(&match_case);
}
}
void LinkSymbolsVisitor::Visit(Condition* node) {
Visitor::Visit(node->conditions[0]);
Visitor::Visit(node->statements[0]);
for (size_t i = 1; i < node->conditions.size(); ++i) {
Visitor::Visit(node->conditions[i]);
Visitor::Visit(node->statements[i]);
}
if (node->statements.size() > node->conditions.size()) {
Visitor::Visit(node->statements[node->conditions.size()]);
}
}
void LinkSymbolsVisitor::Visit(DoWhileLoop* node) {
Visitor::Visit(node->statement);
Visitor::Visit(node->condition);
}
void LinkSymbolsVisitor::Visit(WhileLoop* node) {
Visitor::Visit(node->condition);
Visitor::Visit(node->statement);
}
void LinkSymbolsVisitor::Visit(ForLoop* node) {
Visitor::Visit(node->variable);
Visitor::Visit(node->interval);
Visitor::Visit(node->statement);
}
void LinkSymbolsVisitor::Visit(LoopLoop* node) {
Visitor::Visit(node->statement);
}
// Statements, expressions, blocks, etc. -----------------
void LinkSymbolsVisitor::Visit(Block* node) {
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
}
void LinkSymbolsVisitor::Visit(ScopedStatement* node) {
Visitor::Visit(node->statement);
}
void LinkSymbolsVisitor::Visit(LoopControlExpression& node) {}
// Operators
void LinkSymbolsVisitor::Visit(BinaryOperatorExpression* node) {
Visitor::Visit(node->left_expression);
Visitor::Visit(node->right_expression);
}
void LinkSymbolsVisitor::Visit(UnaryOperatorExpression* node) {
Visitor::Visit(node->expression);
}
void LinkSymbolsVisitor::Visit(ReferenceExpression* node) {
Visit(node->expression.get());
}
void LinkSymbolsVisitor::Visit(AccessExpression* node) {
Visitor::Visit(node->name.get());
Visitor::Visit(node->id);
}
// Other Expressions
void LinkSymbolsVisitor::Visit(FunctionCallExpression* node) {
Visit(node->name.get());
for (auto& argument : node->arguments) {
Visitor::Visit(argument);
}
}
void LinkSymbolsVisitor::Visit(TupleExpression* node) {
for (auto& expression : node->expressions) {
Visitor::Visit(expression);
}
}
void LinkSymbolsVisitor::Visit(VariantExpression* node) {
for (auto& expression : node->expressions) {
Visitor::Visit(expression);
}
}
void LinkSymbolsVisitor::Visit(ReturnExpression* node) {
Visitor::Visit(node->expression);
}
void LinkSymbolsVisitor::Visit(TypeConstructor* node) {
Visit(node->type.get());
for (auto& parameter : node->parameters) {
Visitor::Visit(std::get<2>(parameter));
}
}
// TODO: move to find_symbols_visitor
void LinkSymbolsVisitor::Visit(LambdaFunction* node) {
abstract_types_.EnterContext();
for (auto& parameter : node->parameters) {
Visit(parameter.get());
Visitor::Visit(parameter.get());
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
}
////////////
node->argument_graph_ids_.resize(node->arguments.size());
for (size_t i = 0; i < node->arguments.size(); ++i) {
node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
}
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
///////////
Visitor::Visit(node->expression);
abstract_types_.ExitContext();
}
void LinkSymbolsVisitor::Visit(ArrayExpression* node) {
for (auto& element : node->elements) {
Visitor::Visit(element);
}
}
// Name
void LinkSymbolsVisitor::Visit(NameExpression* node) {
for (auto& variable_namespace : node->namespaces) {
Visitor::Visit(variable_namespace);
}
// for (auto& expression : node->expressions) {
// Visit(expression);
// }
}
void LinkSymbolsVisitor::Visit(TupleName* node) {
for (auto& name : node->names) {
Visitor::Visit(name);
}
}
void LinkSymbolsVisitor::Visit(VariantName* node) {
for (auto& name : node->names) {
Visitor::Visit(name);
}
}
void LinkSymbolsVisitor::Visit(AnnotatedName* node) {
if (node->type.has_value()) {
Visitor::Visit(node->type.value());
}
}
// Type, typeclass, etc. -----------------
// Type
void LinkSymbolsVisitor::Visit(FunctionType* node) {
for (auto& type : node->types) {
Visitor::Visit(type);
}
}
void LinkSymbolsVisitor::Visit(TupleType* node) {
for (auto& entity : node->entities) {
Visit(entity.second.get());
}
}
void LinkSymbolsVisitor::Visit(VariantType* node) {
for (auto& constructor : node->constructors) {
if (std::holds_alternative<Constructor>(constructor)) {
// do nothing
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
} else {
// error
}
}
}
void LinkSymbolsVisitor::Visit(ParametrizedType* node) {
Visit(node->type_expression.get());
for (auto& parameter : node->parameters) {
Visitor::Visit(parameter);
}
}
void LinkSymbolsVisitor::Visit(TypeExpression* node) {
std::vector<std::string> path;
path.reserve(node->namespaces.size());
@ -361,19 +191,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) {
}
}
void LinkSymbolsVisitor::Visit(ExtendedScopedAnyType* node) {
Visitor::Visit(node->type);
}
// Typeclass
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
Visit(node->typeclass_expression.get());
for (auto& parameter : node->parameters) {
Visitor::Visit(parameter);
}
}
void LinkSymbolsVisitor::Visit(TypeclassExpression* node) {
std::vector<std::string> path;
path.reserve(node->namespaces.size());

View file

@ -250,7 +250,7 @@ void PrintVisitor::Visit(AnyAnnotatedType* node) {
out_ << "[Annotated (Abstract) Type ";
Visit(&node->type);
out_ << ']';
if (!node->typeclasses.empty() > 0) {
if (!node->typeclasses.empty()) {
out_ << " (";
for (auto& typeclass : node->typeclasses) {
Visitor::Visit(typeclass);

View file

@ -1,5 +1,9 @@
#include "../include/type_check_visitor.hpp"
#include <memory>
#include <variant>
// for clangd
#include "../include/type_check_visitor.hpp"
#include "../include/error_handling.hpp"
// TODO
@ -17,26 +21,30 @@ void TypeCheckVisitor::Visit(SourceFile* node) {
// error
}
}
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(Sources* node) {
for (auto& statement : node->statements) {
Visitor::Visit(statement);
}
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// Namespaces, partitions -----------------
void TypeCheckVisitor::Visit(Partition* node) {
Visit(node->scope.get());
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(Namespace* node) {
if (node->name.has_value()) {
// TODO: add modifiers
node->variable_type_ = info::type::Type {info::type::DefinedType {node->type_id_.value()}};
context_manager_.EnterVariableContext(node->name.value().name,
&node->variable_type_.value());
context_manager_.AddType(info::type::DefinedType {node->type_id_.value()}));
}
namespace_visitor_.EnterNamespace(node->type);
@ -44,6 +52,8 @@ void TypeCheckVisitor::Visit(Namespace* node) {
Visit(node->scope.get());
namespace_visitor_.ExitNamespace();
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// Definitions -----------------
@ -51,364 +61,520 @@ void TypeCheckVisitor::Visit(Namespace* node) {
void TypeCheckVisitor::Visit(ImportStatement* node) {}
void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
// TODO check, that all paramaters used
// check, that all paramaters used ??
utils::IdType type = context_manager_.AddType(info::type::DefinedType {node->type_id_}); // ??
Visit(node->value.get());
context_manager_.EqualTypes(type, current_type_);
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
// TODO: remove variable on move
// TODO: add modifiers
Visitor::Visit(node->value);
// current_type from value automatically passed to name definitions
Visitor::Visit(node->name);
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
// later check, that function definition requirements are satisfied
// check later that function definition requirements are satisfied
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
Visit(node->definition.get());
// check, that all paramaters used ??
context_manager_.EnterContext();
// Visit(node->definition.get()); // ??
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
context_manager_.DefineVariable(node->definition->arguments[i].name,
context_manager_.AddType(info::type::AbstractType { node->argument_graph_ids_[i] }));
}
Visitor::Visit(node->value);
context_manager_.EqualTypes(
context_manager_.AddType(info::type::AbstractType { node->return_type_graph_id_ }), current_type_);
context_manager_.ExitContext();
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
switch (node->modifier) {
case TypeDefinitionStatement::Struct:
break;
case TypeDefinitionStatement::Class:
break;
}
Visit(node->definition.get());
Visitor::Visit(node->value);
// TODO: add modifiers
// check, that all paramaters used ??
// TODO: defined type typeclasses
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
switch (node->modifier) {
case AbstractTypeDefinitionStatement::Basic:
break;
case AbstractTypeDefinitionStatement::Abstract:
break;
utils::IdType type = context_manager_.AddType(info::type::AbstractType {node->type_graph_id_} );
// Visit(node->type.get()); ??
for (auto& typeclass : node->type->typeclasses) { // TODO
Visitor::Visit(typeclass);
context_manager_.AddTypeRequirement(type, current_type_);
}
Visit(node->type.get());
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
Visit(node->definition.get());
if (!node->requirements.empty()) {
}
for (auto& requirement : node->requirements) {
Visit(requirement.get());
}
// check, that all paramaters used ??
// TODO: needed ??
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// Definition parts
void TypeCheckVisitor::Visit(FunctionDefinition* node) {
switch (node->modifier) {
case FunctionDefinition::Operator:
break;
case FunctionDefinition::Function:
break;
}
Visit(&node->name);
if (!node->parameters.empty()) {
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
}
if (!node->arguments.empty()) {
for (auto& argument : node->arguments) {
Visit(&argument);
}
}
// TODO: needed ??
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
void TypeCheckVisitor::Visit(TypeDefinition* node) {
Visit(node->type.get());
if (!node->parameters.empty()) {
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
}
// TODO: needed ??
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// used on upper levels
void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
Visit(&node->type);
if (!node->typeclasses.empty() > 0) {
for (auto& typeclass : node->typeclasses) {
Visitor::Visit(typeclass);
}
}
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// Flow control -----------------
void TypeCheckVisitor::Visit(MatchCase* node) {
Visitor::Visit(node->value);
Visitor::Visit(node->value); // TODO: literal & name instead of expression
if (node->condition.has_value()) {
Visitor::Visit(node->condition.value());
}
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
if (node->statement.has_value()) {
Visitor::Visit(node->statement.value());
}
// current_type_ from statement is current_type_ for MatchCase
}
void TypeCheckVisitor::Visit(Match* node) {
void TypeCheckVisitor::Visit(Match* node) { // TODO return variant type ?? (problems with same types)
// TODO: types can be different in statement
utils::IdType type;
Visitor::Visit(node->value);
for (auto& match_case : node->matches) {
Visit(&match_case);
for (size_t i = 0; i < node->matches.size(); ++i) {
Visit(&node->matches[i]);
if (i == 0) {
type = current_type_;
} else {
context_manager_.EqualTypes(type, current_type_);
}
}
current_type_ = type;
}
void TypeCheckVisitor::Visit(Condition* node) {
Visitor::Visit(node->conditions[0]);
Visitor::Visit(node->statements[0]);
for (size_t i = 1; i < node->conditions.size(); ++i) {
void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant type ?? (problem with same types)
// TODO: types can be different in statement
utils::IdType type;
for (size_t i = 0; i < node->conditions.size(); ++i) {
Visitor::Visit(node->conditions[i]);
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
Visitor::Visit(node->statements[i]);
if (i == 0) {
type = current_type_;
} else {
context_manager_.EqualTypes(type, current_type_);
}
}
if (node->statements.size() > node->conditions.size()) {
Visitor::Visit(node->statements[node->conditions.size()]);
context_manager_.EqualTypes(type, current_type_);
current_type_ = type;
} else {
current_type_ = context_manager_.AddType(info::type::OptionalType {type});
}
}
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
out_ << "[Do] (\n";
Visitor::Visit(node->statement);
out_ << ") [while] (";
Visitor::Visit(node->condition);
out_ << ")\n";
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
Visitor::Visit(node->statement);
info::type::ArrayType type;
type.size = 0;
type.elements_type = current_type_;
current_type_ = context_manager_.AddType(type);
}
void TypeCheckVisitor::Visit(WhileLoop* node) {
out_ << "[While] (";
Visitor::Visit(node->statement);
out_ << ") [do] (\n";
Visitor::Visit(node->condition);
out_ << ")\n";
}
void TypeCheckVisitor::Visit(ForLoop* node) {
out_ << "[For] (";
Visitor::Visit(node->variable);
out_ << ") [in] (";
Visitor::Visit(node->interval);
out_ << ") [do] (\n";
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
Visitor::Visit(node->statement);
out_ << ")\n";
info::type::ArrayType type;
type.size = 0;
type.elements_type = current_type_;
current_type_ = context_manager_.AddType(type);
}
void TypeCheckVisitor::Visit(ForLoop* node) {
Visitor::Visit(node->interval);
if (!std::holds_alternative<info::type::ArrayType>(context_manager_.GetType(current_type_))) {
error_handling::HandleTypecheckError("For loop interval type mismatch");
}
info::type::ArrayType type_value =
std::get<info::type::ArrayType>(context_manager_.GetType(current_type_));
current_type_ = context_manager_.AddType(type_value.elements_type);
Visitor::Visit(node->variable);
Visitor::Visit(node->statement);
info::type::ArrayType type;
type.size = 0;
type.elements_type = current_type_;
current_type_ = context_manager_.AddType(type);
}
void TypeCheckVisitor::Visit(LoopLoop* node) {
out_ << "[Loop] (\n";
Visitor::Visit(node->statement);
out_ << ")\n";
info::type::ArrayType type;
type.size = 0;
type.elements_type = current_type_;
current_type_ = context_manager_.AddType(type);
}
// Statements, expressions, blocks, etc. -----------------
void TypeCheckVisitor::Visit(Block* node) {
out_ << "[Block] {\n";
void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (problem with same types)
utils::IdType type;
bool is_first_returned_type = true;
for (auto& statement : node->statements) {
returned_type_ = std::nullopt;
Visitor::Visit(statement);
if (returned_type_.has_value()) {
if (is_first_returned_type) {
type = returned_type_.value();
is_first_returned_type = false;
} else {
context_manager_.EqualTypes(type, returned_type_.value());
}
out_ << "}\n";
}
}
if (is_first_returned_type) {
type = context_manager_.AddType(info::type::InternalType::Unit);
}
current_type_ = type;
}
void TypeCheckVisitor::Visit(ScopedStatement* node) {
out_ << "[Scoped] ( ";
Visitor::Visit(node->statement);
out_ << ")\n";
// current_type_ is type of statement
}
void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
switch (node) {
case LoopControlExpression::Break:
out_ << "[Break]\n";
break;
case LoopControlExpression::Continue:
out_ << "[Continue]\n";
break;
}
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
}
// Operators
// -------------------------- TODO --------------------------
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
out_ << "[BinaryOperator] (";
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
if (!maybe_operator_id.has_value()) {
error_handling::HandleTypecheckError("Operator not found");
}
auto operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
if (operator_info->argument_count != 2) {
error_handling::HandleTypecheckError("Operator wrong argument count");
}
if (operator_info->definition.has_value()) {
Visitor::Visit(node->left_expression);
out_ << ") [";
Visit(&node->operator_name);
out_ << "] (";
context_manager_.AddTypeRequirement(current_type_,
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[0]}));
Visitor::Visit(node->right_expression);
out_ << ')';
context_manager_.AddTypeRequirement(current_type_,
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[1]}));
} else if (operator_info->declaration.has_value()) {
// TODO: get argument types
} else {
error_handling::HandleInternalError("Operator definition and declaration both not found", "TypeCheckVisitor");
}
}
// -------------------------- TODO --------------------------
void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
out_ << "[UnaryOperator ";
Visit(&node->operator_name);
out_ << "] (";
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
if (!maybe_operator_id.has_value()) {
error_handling::HandleTypecheckError("Operator not found");
}
auto operator_info = namespace_visitor_.GetGlobalInfo()->GetFunctionInfo(maybe_operator_id.value());
if (operator_info->argument_count != 1) {
error_handling::HandleTypecheckError("Operator wrong argument count");
}
if (operator_info->definition.has_value()) {
Visitor::Visit(node->expression);
out_ << ')';
context_manager_.AddTypeRequirement(current_type_,
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[0]}));
} else if (operator_info->declaration.has_value()) {
// TODO: get argument type
} else {
error_handling::HandleInternalError("Operator definition and declaration both not found", "TypeCheckVisitor");
}
}
void TypeCheckVisitor::Visit(ReferenceExpression* node) {
out_ << "[ReferenceExpression ";
for (auto& reference : node->references) {
switch (reference) {
case ReferenceType::Reference:
out_ << '~';
break;
case ReferenceType::UniqueReference:
out_ << '@';
break;
}
}
out_ << "] (";
Visit(node->expression.get());
out_ << ')';
info::type::ReferenceToType type;
type.references = node->references;
type.type = current_type_;
current_type_ = context_manager_.AddType(type);
}
void TypeCheckVisitor::Visit(AccessExpression* node) { // TODO
Visitor::Visit(node->name);
void TypeCheckVisitor::Visit(AccessExpression* node) {
Visitor::Visit(node->id);
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Int), current_type_);
// TODO: separate type for counting ?
Visitor::Visit(node->name.get());
if (!std::holds_alternative<info::type::ArrayType>(context_manager_.GetType(current_type_))) {
error_handling::HandleTypecheckError("Access type mismatch");
}
info::type::ArrayType type_value =
std::get<info::type::ArrayType>(context_manager_.GetType(current_type_));
current_type_ = context_manager_.AddType(type_value.elements_type);
}
// Other Expressions
// -------------------------- TODO --------------------------
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
out_ << "[FunctionCall ";
// TODO: add function paramaters
Visit(node->name.get());
out_ << "] (";
for (auto& argument : node->arguments) {
Visitor::Visit(argument);
out_ << ", ";
}
out_ << ")";
if (!std::holds_alternative<info::type::FunctionType>(context_manager_.GetType(current_type_))) {
error_handling::HandleTypecheckError("Mismatched types in function call expression");
}
info::type::FunctionType type_value = std::get<info::type::FunctionType>(context_manager_.GetType(current_type_));
if (type_value.argument_types.size() != node->arguments.size()) {
error_handling::HandleTypecheckError("Mismatched argument count in function call expression");
}
for (size_t i = 0; i < node->arguments.size(); ++i) {
Visitor::Visit(node->arguments[i]);
if (std::holds_alternative<std::string>(node->arguments[i])) {
} else if (std::holds_alternative<info::type::TupleType>(node->arguments[i])) {
} else {
// error
}
context_manager_.AddTypeRequirement(current_type_, type_value.argument_types[i]);
}
current_type_ = type_value.return_type;
}
void TypeCheckVisitor::Visit(TupleExpression* node) {
out_ << "[TupleExpression] (";
info::type::TupleType type;
type.fields.reserve(node->expressions.size());
for (auto& expression : node->expressions) {
out_ << "&";
Visitor::Visit(expression);
type.fields.push_back({std::nullopt, current_type_});
}
out_ << ")";
current_type_ = context_manager_.AddType(std::move(type));
}
void TypeCheckVisitor::Visit(VariantExpression* node) {
out_ << "[VariantExpression] (";
info::type::VariantType type;
for (auto& expression : node->expressions) {
out_ << "|";
info::type::TupleType constructor;
Visitor::Visit(expression);
constructor.fields.push_back({std::nullopt, current_type_}); // ??
type.constructors.push_back(constructor);
}
out_ << ")";
current_type_ = context_manager_.AddType(std::move(type));
}
void TypeCheckVisitor::Visit(ReturnExpression* node) {
Visitor::Visit(node->expression);
}
void TypeCheckVisitor::Visit(TypeConstructor* node) {
out_ << "[TypeConstructor ";
Visit(node->type.get());
out_ << "]\n(";
// -------------------------- TODO --------------------------
void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor names, etc.
utils::IdType type;
bool is_first = true;
for (auto& parameter : node->parameters) {
if (!is_first) {
out_ << ")\n";
is_first = false;
Visit(node->type.get());
type = current_type_;
info::AnyTypeInfo* type_info = &std::get<info::AnyTypeInfo>(
namespace_visitor_.GetGlobalInfo()->GetTypeInfo(
std::get<info::type::DefinedType>(context_manager_.GetType(type)).type_id)->type);
for (size_t i = 0; i < node->parameters.size(); ++i) {
//Visit(&std::get<0>(parameter));
// TODO: remove variable on move
Visitor::Visit(std::get<2>(node->parameters[i]));
//context_manager_.EqualTypes(/* TODO type_info->get_field(paramater).type */, current_type_);
}
out_ << '(';
Visit(&std::get<0>(parameter));
switch (std::get<1>(parameter)) {
case TypeConstructor::Assign:
out_ << " = ";
break;
case TypeConstructor::Move:
out_ << " <- ";
break;
}
Visitor::Visit(std::get<2>(parameter));
}
out_ << ")\n";
current_type_ = type;
}
void TypeCheckVisitor::Visit(LambdaFunction* node) {
out_ << "[LambdaFunction] (";
for (auto& parameter : node->parameters) {
Visit(parameter.get());
info::type::FunctionType type;
// for (auto& parameter : node->parameters) {
// Visit(parameter.get());
// }
type.argument_types.reserve(node->argument_graph_ids_.size());
for (auto& argument_graph_id : node->argument_graph_ids_) {
type.argument_types.push_back(context_manager_.AddType(info::type::AbstractType {argument_graph_id}));
}
if (!node->parameters.empty()) {
out_ << ") : (";
}
for (auto& argument : node->arguments) {
Visit(&argument);
}
out_ << ") -> (\n";
type.return_type = context_manager_.AddType(info::type::AbstractType {node->return_type_graph_id_});
Visitor::Visit(node->expression);
out_ << ")\n";
context_manager_.AddTypeRequirement(type.return_type, current_type_); // right order ??
current_type_ = context_manager_.AddType(std::move(type));
}
void TypeCheckVisitor::Visit(ArrayExpression* node) {
out_ << "[ArrayExpression] ([";
for (auto& element : node->elements) {
Visitor::Visit(element);
out_ << ';';
info::type::ArrayType type;
type.size = node->elements.size();
for (size_t i = 0; i < node->elements.size(); ++i) {
Visitor::Visit(node->elements[i]);
if (i == 0) {
type.elements_type = current_type_;
} else {
context_manager_.EqualTypes(type.elements_type.value(), current_type_);
}
out_ << "])";
}
current_type_ = context_manager_.AddType(std::move(type));
}
// Name
void TypeCheckVisitor::Visit(NameExpression* node) {
out_ << "[NameExpression] (";
for (auto& variable_namespace : node->namespaces) {
Visitor::Visit(variable_namespace);
out_ << '.';
// -------------------------- TODO --------------------------
void TypeCheckVisitor::Visit(NameExpression* node) { // TODO: ?? functions without arguments ??
std::vector<std::string> path;
std::string type_name;
path.reserve(node->namespaces.size());
for (size_t i = 0; i < node->namespaces.size(); ++i) {
std::string current_name;
if (std::holds_alternative<std::unique_ptr<std::string>>(node->namespaces[i])) {
current_name = *std::get<std::unique_ptr<std::string>>(node->namespaces[i]);
} else if (std::holds_alternative<std::unique_ptr<ParametrizedType>>(node->namespaces[i])) {
Visit(std::get<std::unique_ptr<ParametrizedType>>(node->namespaces[i]).get());
// TODO: use current_type_
}
if (i + 1 == node->namespaces.size()) {
type_name = std::move(current_name);
} else {
path.push_back(std::move(current_name));
}
}
// auto name_type = namespace_visitor_.FindType();
path.push_back(type_name);
auto name_namespace = namespace_visitor_.FindNamespace(path);
for (size_t i = 0; i < node->expressions.size(); ++i) {
Visitor::Visit(node->expressions[i]);
if (i + 1 < node->expressions.size()) {
out_ << '.';
// Visitor::Visit(node->expressions[i]);
}
}
out_ << ')';
}
void TypeCheckVisitor::Visit(TupleName* node) {
utils::IdType type = current_type_;
auto type_value = std::get_if<info::type::TupleType>(context_manager_.GetType(type));
if (type_value = nullptr) {
if (!std::holds_alternative<info::type::TupleType>(context_manager_.GetType(type))) {
error_handling::HandleTypecheckError("Mismatched types in tuple variable definition");
}
if (type_value->constructors.size() != node->names.size()) {
info::type::TupleType type_value = std::get<info::type::TupleType>(context_manager_.GetType(type));
if (type_value.fields.size() != node->names.size()) {
error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition");
}
for (auto& name : node->names) {
current_type_ = type_value->fields[i];
Visitor::Visit(name);
for (size_t i = 0; i < node->names.size(); ++i) {
current_type_ = type_value.fields[i].second;
Visitor::Visit(node->names[i]);
}
current_type_ = type;
}
void TypeCheckVisitor::Visit(VariantName* node) { // TODO
void TypeCheckVisitor::Visit(VariantName* node) {
utils::IdType type = current_type_;
auto type_value = std::get_if<info::type::VariantType>(context_manager_.GetType(type));
if (type_value = nullptr) {
if (!std::holds_alternative<info::type::VariantType>(context_manager_.GetType(type))) {
error_handling::HandleTypecheckError("Mismatched types in variant variable definition");
}
if (type_value->constructors.size() != node->names.size()) {
info::type::VariantType type_value = std::get<info::type::VariantType>(context_manager_.GetType(type));
if (type_value.constructors.size() != node->names.size()) {
error_handling::HandleTypecheckError("Mismatched variant count in variant variable definition");
}
for (size_t i = 0; i < node->names.size(); ++i) {
current_type_ = info::type::VariantType::MakeOptional(type_value->constructors[i]);
Visitor::Visit(name);
if (std::holds_alternative<std::string>(type_value.constructors[i])) {
current_type_ = context_manager_.AddType(info::type::OptionalType {});
} else if (std::holds_alternative<info::type::TupleType>(type_value.constructors[i])) {
// TODO: optimize
current_type_ = context_manager_.AddType(info::type::OptionalType { context_manager_.AddType(std::get<info::type::TupleType>(type_value.constructors[i])) });
} else {
// error
}
Visitor::Visit(node->names[i]);
}
current_type_ = type;
@ -428,9 +594,9 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
void TypeCheckVisitor::Visit(FunctionType* node) {
info::type::FunctionType type;
type.argument_type_ids.reserve(node->types.size());
for (auto& type : node->types) {
Visitor::Visit(type);
type.argument_types.reserve(node->types.size());
for (auto& argument_type : node->types) {
Visitor::Visit(argument_type);
type.argument_types.push_back(current_type_);
}
@ -474,8 +640,7 @@ void TypeCheckVisitor::Visit(VariantType* node) {
void TypeCheckVisitor::Visit(ParametrizedType* node) {
info::type::DefinedType type;
Visit(node->type_expression.get());
type.type = current_type_;
type.type_id = node->type_expression->type_id_;
type.paramaters.reserve(node->parameters.size());
for (auto& paramater : node->parameters) {

View file

@ -319,4 +319,363 @@ void Visitor::Visit(Literal& node) {
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////
// Sources -----------------
void Visitor::Visit(SourceFile* node) {
for (auto& statement : node->statements) {
if (std::holds_alternative<Partition>(statement)) {
Visit(&std::get<Partition>(statement));
} else if (std::holds_alternative<SourceStatement>(statement)) {
Visit(std::get<SourceStatement>(statement));
} else {
// error
}
}
}
void Visitor::Visit(Sources* node) {
for (auto& statement : node->statements) {
Visit(statement);
}
}
// Namespaces, partitions -----------------
void Visitor::Visit(Partition* node) {
Visit(node->scope.get());
}
void Visitor::Visit(Namespace* node) {
if (node->name.has_value()) {
Visit(&node->name.value());
}
Visit(&node->type);
Visit(node->scope.get());
}
// Definitions -----------------
void Visitor::Visit(ImportStatement* node) {
for (auto& symbol : node->symbols) {
Visit(&symbol);
}
}
void Visitor::Visit(AliasDefinitionStatement* node) {
Visit(&node->type);
Visit(node->value.get());
}
void Visitor::Visit(VariableDefinitionStatement* node) {
Visit(node->name);
Visit(node->value);
}
void Visitor::Visit(FunctionDeclaration* node) {
Visit(&node->name);
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
Visit(node->type.get());
}
void Visitor::Visit(FunctionDefinitionStatement* node) {
Visit(node->definition.get());
Visit(node->value);
}
void Visitor::Visit(TypeDefinitionStatement* node) {
Visit(node->definition.get());
Visit(node->value);
}
void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
Visit(node->type.get());
}
void Visitor::Visit(TypeclassDefinitionStatement* node) {
Visit(node->definition.get());
for (auto& requirement : node->requirements) {
Visit(requirement.get());
}
}
// Definition parts
void Visitor::Visit(FunctionDefinition* node) {
Visit(&node->name);
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
for (auto& argument : node->arguments) {
Visit(&argument);
}
}
void Visitor::Visit(TypeDefinition* node) {
Visit(node->type.get());
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
}
void Visitor::Visit(AnyAnnotatedType* node) {
Visit(&node->type);
for (auto& typeclass : node->typeclasses) {
Visit(typeclass);
}
}
// Flow control -----------------
void Visitor::Visit(MatchCase* node) {
Visit(node->value);
if (node->condition.has_value()) {
Visit(node->condition.value());
}
if (node->statement.has_value()) {
Visit(node->statement.value());
}
}
void Visitor::Visit(Match* node) {
Visit(node->value);
for (auto& match_case : node->matches) {
Visit(&match_case);
}
}
void Visitor::Visit(Condition* node) {
for (size_t i = 0; i < node->conditions.size(); ++i) {
Visit(node->conditions[i]);
Visit(node->statements[i]);
}
if (node->statements.size() > node->conditions.size()) {
Visit(node->statements[node->conditions.size()]);
}
}
void Visitor::Visit(DoWhileLoop* node) {
Visit(node->statement);
Visit(node->condition);
}
void Visitor::Visit(WhileLoop* node) {
Visit(node->condition);
Visit(node->statement);
}
void Visitor::Visit(ForLoop* node) {
Visit(node->variable);
Visit(node->interval);
Visit(node->statement);
}
void Visitor::Visit(LoopLoop* node) {
Visit(node->statement);
}
// Statements, expressions, blocks, etc. -----------------
void Visitor::Visit(Block* node) {
for (auto& statement : node->statements) {
Visit(statement);
}
}
void Visitor::Visit(ScopedStatement* node) {
Visit(node->statement);
}
void Visitor::Visit(LoopControlExpression& node) {} // enum
// Operators
void Visitor::Visit(BinaryOperatorExpression* node) {
Visit(node->left_expression);
Visit(&node->operator_name);
Visit(node->right_expression);
}
void Visitor::Visit(UnaryOperatorExpression* node) {
Visit(&node->operator_name);
Visit(node->expression);
}
void Visitor::Visit(ReferenceExpression* node) {
Visit(node->expression.get());
}
void Visitor::Visit(AccessExpression* node) {
Visit(node->name.get());
Visit(node->id);
}
// Other Expressions
void Visitor::Visit(FunctionCallExpression* node) {
Visit(node->name.get());
for (auto& argument : node->arguments) {
Visit(argument);
}
}
void Visitor::Visit(TupleExpression* node) {
for (auto& expression : node->expressions) {
Visit(expression);
}
}
void Visitor::Visit(VariantExpression* node) {
for (auto& expression : node->expressions) {
Visit(expression);
}
}
void Visitor::Visit(ReturnExpression* node) {
Visit(node->expression);
}
void Visitor::Visit(TypeConstructor* node) {
Visit(node->type.get());
for (auto& parameter : node->parameters) {
Visit(&std::get<0>(parameter));
Visit(std::get<2>(parameter));
}
}
void Visitor::Visit(LambdaFunction* node) {
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
for (auto& argument : node->arguments) {
Visit(&argument);
}
Visit(node->expression);
}
void Visitor::Visit(ArrayExpression* node) {
for (auto& element : node->elements) {
Visit(element);
}
}
// Name
void Visitor::Visit(NameExpression* node) {
for (auto& variable_namespace : node->namespaces) {
Visit(variable_namespace);
}
for (size_t i = 0; i < node->expressions.size(); ++i) {
Visit(&node->expressions[i]);
}
}
void Visitor::Visit(TupleName* node) {
for (auto& name : node->names) {
Visit(name);
}
}
void Visitor::Visit(VariantName* node) {
for (auto& name : node->names) {
Visit(name);
}
}
void Visitor::Visit(AnnotatedName* node) {
Visit(&node->name);
if (node->type.has_value()) {
Visitor::Visit(node->type.value());
}
}
// Type, typeclass, etc. -----------------
// Type
void Visitor::Visit(FunctionType* node) {
for (auto& type : node->types) {
Visitor::Visit(type);
}
}
void Visitor::Visit(TupleType* node) {
if (node->type.has_value()) {
Visit(&node->type.value());
}
for (auto& entity : node->entities) {
if (entity.first.has_value()) {
Visit(&entity.first.value());
}
Visit(entity.second.get());
}
}
void Visitor::Visit(VariantType* node) {
if (node->type.has_value()) {
Visit(&node->type.value());
}
for (auto& constructor : node->constructors) {
if (std::holds_alternative<Constructor>(constructor)) {
Visit(&std::get<Constructor>(constructor));
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
} else {
// error
}
}
}
void Visitor::Visit(ParametrizedType* node) {
Visit(node->type_expression.get());
for (auto& parameter : node->parameters) {
Visit(parameter);
}
}
void Visitor::Visit(TypeExpression* node) {
for (auto& type_namespace : node->namespaces) {
Visit(type_namespace);
}
Visit(&node->type);
}
void Visitor::Visit(ExtendedScopedAnyType* node) {
Visit(node->type);
}
// Typeclass
void Visitor::Visit(ParametrizedTypeclass* node) {
Visit(node->typeclass_expression.get());
for (auto& parameter : node->parameters) {
Visit(parameter);
}
}
void Visitor::Visit(TypeclassExpression* node) {
for (auto& typeclass_namespace : node->namespaces) {
Visit(typeclass_namespace);
}
Visit(&node->typeclass);
}
// Identifiers, constants, etc. -----------------
void Visitor::Visit(ExtendedName* node) {}
void Visitor::Visit(std::string* node) {} // std::string
void Visitor::Visit(FloatNumberLiteral* node) {}
void Visitor::Visit(NumberLiteral* node) {}
void Visitor::Visit(StringLiteral* node) {}
void Visitor::Visit(CharLiteral* node) {}
} // namespace interpreter