mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 15:08:45 +00:00
part of type_check_visitor done
This commit is contained in:
parent
6fc91aafa0
commit
656f58bcde
14 changed files with 891 additions and 539 deletions
|
|
@ -64,6 +64,10 @@ public:
|
||||||
return global_info_.GetAbstractTypeGraph();
|
return global_info_.GetAbstractTypeGraph();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GlobalInfo* GetGlobalInfo() {
|
||||||
|
return &global_info_;
|
||||||
|
}
|
||||||
|
|
||||||
const std::vector<std::string>& GetCurrentPath() {
|
const std::vector<std::string>& GetCurrentPath() {
|
||||||
return current_path_;
|
return current_path_;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -261,7 +261,6 @@ struct Namespace {
|
||||||
std::unique_ptr<Sources> scope;
|
std::unique_ptr<Sources> scope;
|
||||||
|
|
||||||
std::optional<utils::IdType> type_id_;
|
std::optional<utils::IdType> type_id_;
|
||||||
std::optional<info::type::Type> variable_type_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Partition {
|
struct Partition {
|
||||||
|
|
@ -471,6 +470,9 @@ struct LambdaFunction {
|
||||||
std::vector<std::unique_ptr<AnnotatedAbstractType>> parameters;
|
std::vector<std::unique_ptr<AnnotatedAbstractType>> parameters;
|
||||||
std::vector<ExtendedName> arguments;
|
std::vector<ExtendedName> arguments;
|
||||||
Expression expression;
|
Expression expression;
|
||||||
|
|
||||||
|
std::vector<utils::IdType> argument_graph_ids_;
|
||||||
|
utils::IdType return_type_graph_id_;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayExpression {
|
struct ArrayExpression {
|
||||||
|
|
|
||||||
|
|
@ -41,66 +41,65 @@ private:
|
||||||
|
|
||||||
void Visit(FunctionDefinition* node) override;
|
void Visit(FunctionDefinition* node) override;
|
||||||
void Visit(TypeDefinition* node) override;
|
void Visit(TypeDefinition* node) override;
|
||||||
void Visit(AnyAnnotatedType* node) override;
|
// // void Visit(AnyAnnotatedType* node) override;
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
void Visit(MatchCase* node) override;
|
// // void Visit(MatchCase* node) override;
|
||||||
void Visit(Match* node) override;
|
// // void Visit(Match* node) override;
|
||||||
void Visit(Condition* node) override;
|
// // void Visit(Condition* node) override;
|
||||||
void Visit(DoWhileLoop* node) override;
|
// // void Visit(DoWhileLoop* node) override;
|
||||||
void Visit(WhileLoop* node) override;
|
// // void Visit(WhileLoop* node) override;
|
||||||
void Visit(ForLoop* node) override;
|
// // void Visit(ForLoop* node) override;
|
||||||
void Visit(LoopLoop* node) override;
|
// // void Visit(LoopLoop* node) override;
|
||||||
|
|
||||||
// Statements, expressions, blocks, etc. -----------------
|
// Statements, expressions, blocks, etc. -----------------
|
||||||
|
|
||||||
void Visit(Block* node) override;
|
// // void Visit(Block* node) override;
|
||||||
|
// // void Visit(ScopedStatement* node) override;
|
||||||
void Visit(ScopedStatement* node) override;
|
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
void Visit(BinaryOperatorExpression* node) override;
|
// // void Visit(BinaryOperatorExpression* node) override;
|
||||||
void Visit(UnaryOperatorExpression* node) override;
|
// // void Visit(UnaryOperatorExpression* node) override;
|
||||||
void Visit(ReferenceExpression* node) override;
|
// // void Visit(ReferenceExpression* node) override;
|
||||||
void Visit(AccessExpression* node) override;
|
// // void Visit(AccessExpression* node) override;
|
||||||
|
|
||||||
// Simple Expressions
|
// Simple Expressions
|
||||||
|
|
||||||
void Visit(FunctionCallExpression* node) override;
|
// // void Visit(FunctionCallExpression* node) override;
|
||||||
|
|
||||||
void Visit(TupleExpression* node) override;
|
// // void Visit(TupleExpression* node) override;
|
||||||
void Visit(VariantExpression* node) override;
|
// // void Visit(VariantExpression* node) override;
|
||||||
void Visit(ReturnExpression* node) override;
|
// // void Visit(ReturnExpression* node) override;
|
||||||
void Visit(TypeConstructor* node) override;
|
// // void Visit(TypeConstructor* node) override;
|
||||||
void Visit(LambdaFunction* 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
|
// Name
|
||||||
|
|
||||||
void Visit(NameExpression* node) override;
|
// // void Visit(NameExpression* node) override;
|
||||||
void Visit(TupleName* node) override;
|
// // void Visit(TupleName* node) override;
|
||||||
void Visit(VariantName* node) override;
|
// // void Visit(VariantName* node) override;
|
||||||
void Visit(AnnotatedName* node) override;
|
// // void Visit(AnnotatedName* node) override;
|
||||||
|
|
||||||
// Type, typeclass, etc. -----------------
|
// Type, typeclass, etc. -----------------
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
void Visit(FunctionType* node) override;
|
// // void Visit(FunctionType* node) override;
|
||||||
void Visit(TupleType* node) override;
|
// // void Visit(TupleType* node) override;
|
||||||
void Visit(VariantType* node) override;
|
// // void Visit(VariantType* node) override;
|
||||||
void Visit(ParametrizedType* node) override;
|
// // void Visit(ParametrizedType* node) override;
|
||||||
void Visit(TypeExpression* node) override;
|
void Visit(TypeExpression* node) override;
|
||||||
|
|
||||||
void Visit(ExtendedScopedAnyType* node) override;
|
// // void Visit(ExtendedScopedAnyType* node) override;
|
||||||
|
|
||||||
// Typeclass
|
// Typeclass
|
||||||
|
|
||||||
void Visit(ParametrizedTypeclass* node) override;
|
// // void Visit(ParametrizedTypeclass* node) override;
|
||||||
void Visit(TypeclassExpression* node) override;
|
void Visit(TypeclassExpression* node) override;
|
||||||
|
|
||||||
// Identifiers, constants, etc. -----------------
|
// Identifiers, constants, etc. -----------------
|
||||||
|
|
|
||||||
|
|
@ -85,17 +85,19 @@ struct FunctionDeclarationInfo {
|
||||||
std::vector<ParameterInfo> parameters;
|
std::vector<ParameterInfo> parameters;
|
||||||
std::vector<interpreter::tokens::AnyType*> argument_type_nodes;
|
std::vector<interpreter::tokens::AnyType*> argument_type_nodes;
|
||||||
std::vector<AnyTypeInfo*> argument_types;
|
std::vector<AnyTypeInfo*> argument_types;
|
||||||
|
interpreter::tokens::FunctionDeclaration* node = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionDefinitionInfo {
|
struct FunctionDefinitionInfo {
|
||||||
std::vector<ParameterInfo> parameters;
|
std::vector<ParameterInfo> parameters;
|
||||||
std::vector<std::string> argument_names;
|
std::vector<std::string> argument_names;
|
||||||
interpreter::tokens::SuperExpression* expression = nullptr;
|
interpreter::tokens::FunctionDefinitionStatement* node = nullptr;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct FunctionInfo {
|
struct FunctionInfo {
|
||||||
FunctionDeclarationInfo declaration;
|
size_t argument_count = 0;
|
||||||
FunctionDefinitionInfo definition;
|
std::optional<FunctionDeclarationInfo> declaration;
|
||||||
|
std::optional<FunctionDefinitionInfo> definition;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeclassInfo {
|
struct TypeclassInfo {
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,7 @@ private:
|
||||||
info::TypeInfoContextManager context_manager_;
|
info::TypeInfoContextManager context_manager_;
|
||||||
|
|
||||||
utils::IdType current_type_;
|
utils::IdType current_type_;
|
||||||
|
std::optional<utils::IdType> returned_type_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace interpreter
|
} // namespace interpreter
|
||||||
|
|
|
||||||
|
|
@ -23,20 +23,21 @@ public:
|
||||||
return types_[type_id];
|
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,
|
// void CallFunction(const std::vector<std::string>& names,
|
||||||
const std::vector<utils::IdType>& argument_types) {
|
// const std::vector<utils::IdType>& argument_types) {
|
||||||
if (names.size() != argument_types.size()) {
|
// if (names.size() != argument_types.size()) {
|
||||||
// error
|
// // error
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
contexts_.emplace_back(true);
|
// contexts_.emplace_back(true);
|
||||||
|
//
|
||||||
for (size_t i = 0; i < names.size(); ++i) {
|
// for (size_t i = 0; i < names.size(); ++i) {
|
||||||
DefineVariable(names[i], argument_types[i]);
|
// DefineVariable(names[i], argument_types[i]);
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
void EnterContext() {
|
void EnterContext() {
|
||||||
contexts_.emplace_back(false);
|
contexts_.emplace_back(false);
|
||||||
|
|
@ -59,6 +60,15 @@ public:
|
||||||
return contexts_.back().DefineVariable(name, type_id);
|
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,
|
void EnterVariableContext(const std::string& name,
|
||||||
utils::IdType type_id) { // for variable namespaces, for loops
|
utils::IdType type_id) { // for variable namespaces, for loops
|
||||||
contexts_.push_back(false);
|
contexts_.push_back(false);
|
||||||
|
|
@ -67,7 +77,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
std::optional<utils::IdType> GetVariableType(const std::string& name) {
|
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);
|
auto maybe_type = contexts_[i].GetVariableType(name);
|
||||||
if (maybe_type.has_value()) {
|
if (maybe_type.has_value()) {
|
||||||
return maybe_type.value();
|
return maybe_type.value();
|
||||||
|
|
@ -89,6 +99,10 @@ private:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool RemoveVariable(const std::string& name) {
|
||||||
|
return variables_.erase(name);
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<utils::IdType> GetVariableType(const std::string& name) {
|
std::optional<utils::IdType> GetVariableType(const std::string& name) {
|
||||||
auto variable_iter = variables_.find(name);
|
auto variable_iter = variables_.find(name);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "error_handling.hpp"
|
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
|
|
||||||
namespace info::type {
|
namespace info::type {
|
||||||
|
|
@ -37,39 +36,14 @@ struct TupleType { //
|
||||||
};
|
};
|
||||||
|
|
||||||
struct VariantType {
|
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::optional<std::string> type;
|
||||||
std::vector<std::variant<std::string, TupleType>> constructors;
|
std::vector<std::variant<std::string, TupleType>> constructors;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct OptionalType {
|
||||||
|
std::optional<utils::IdType> type; // Can be empty (Some or None)
|
||||||
|
};
|
||||||
|
|
||||||
struct ReferenceToType {
|
struct ReferenceToType {
|
||||||
std::vector<utils::ReferenceType> references;
|
std::vector<utils::ReferenceType> references;
|
||||||
utils::IdType type;
|
utils::IdType type;
|
||||||
|
|
@ -77,10 +51,12 @@ struct ReferenceToType {
|
||||||
|
|
||||||
struct FunctionType {
|
struct FunctionType {
|
||||||
std::vector<utils::IdType> argument_types;
|
std::vector<utils::IdType> argument_types;
|
||||||
|
utils::IdType return_type;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ArrayType {
|
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,
|
using Type = std::variant<AbstractType,
|
||||||
|
|
|
||||||
|
|
@ -16,42 +16,42 @@ public:
|
||||||
protected:
|
protected:
|
||||||
// Sources -----------------
|
// Sources -----------------
|
||||||
|
|
||||||
virtual void Visit(SourceFile* node) {}
|
virtual void Visit(SourceFile* node);
|
||||||
virtual void Visit(Sources* node) {}
|
virtual void Visit(Sources* node);
|
||||||
|
|
||||||
// Namespaces, partitions -----------------
|
// Namespaces, partitions -----------------
|
||||||
|
|
||||||
virtual void Visit(Partition* node) {}
|
virtual void Visit(Partition* node);
|
||||||
virtual void Visit(Namespace* node) {}
|
virtual void Visit(Namespace* node);
|
||||||
|
|
||||||
// Definitions -----------------
|
// Definitions -----------------
|
||||||
|
|
||||||
virtual void Visit(ImportStatement* node) {}
|
virtual void Visit(ImportStatement* node);
|
||||||
virtual void Visit(AliasDefinitionStatement* node) {}
|
virtual void Visit(AliasDefinitionStatement* node);
|
||||||
virtual void Visit(VariableDefinitionStatement* node) {}
|
virtual void Visit(VariableDefinitionStatement* node);
|
||||||
virtual void Visit(FunctionDeclaration* node) {}
|
virtual void Visit(FunctionDeclaration* node);
|
||||||
virtual void Visit(FunctionDefinitionStatement* node) {}
|
virtual void Visit(FunctionDefinitionStatement* node);
|
||||||
virtual void Visit(TypeDefinitionStatement* node) {}
|
virtual void Visit(TypeDefinitionStatement* node);
|
||||||
virtual void Visit(AbstractTypeDefinitionStatement* node) {}
|
virtual void Visit(AbstractTypeDefinitionStatement* node);
|
||||||
virtual void Visit(TypeclassDefinitionStatement* node) {}
|
virtual void Visit(TypeclassDefinitionStatement* node);
|
||||||
|
|
||||||
virtual void Visit(SourceStatement& node); // variant
|
virtual void Visit(SourceStatement& node); // variant
|
||||||
|
|
||||||
// Definition parts
|
// Definition parts
|
||||||
|
|
||||||
virtual void Visit(FunctionDefinition* node) {}
|
virtual void Visit(FunctionDefinition* node);
|
||||||
virtual void Visit(TypeDefinition* node) {}
|
virtual void Visit(TypeDefinition* node);
|
||||||
virtual void Visit(AnyAnnotatedType* node) {}
|
virtual void Visit(AnyAnnotatedType* node);
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
virtual void Visit(MatchCase* node) {}
|
virtual void Visit(MatchCase* node);
|
||||||
virtual void Visit(Match* node) {}
|
virtual void Visit(Match* node);
|
||||||
virtual void Visit(Condition* node) {}
|
virtual void Visit(Condition* node);
|
||||||
virtual void Visit(DoWhileLoop* node) {}
|
virtual void Visit(DoWhileLoop* node);
|
||||||
virtual void Visit(WhileLoop* node) {}
|
virtual void Visit(WhileLoop* node);
|
||||||
virtual void Visit(ForLoop* node) {}
|
virtual void Visit(ForLoop* node);
|
||||||
virtual void Visit(LoopLoop* node) {}
|
virtual void Visit(LoopLoop* node);
|
||||||
|
|
||||||
virtual void Visit(FlowControl& node); // variant
|
virtual void Visit(FlowControl& node); // variant
|
||||||
|
|
||||||
|
|
@ -59,7 +59,7 @@ protected:
|
||||||
|
|
||||||
virtual void Visit(BlockStatement& node); // variant
|
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(SubExpressionToken& node); // variant
|
||||||
virtual void Visit(SubExpression& node); // variant
|
virtual void Visit(SubExpression& node); // variant
|
||||||
|
|
@ -67,36 +67,36 @@ protected:
|
||||||
virtual void Visit(Expression& node); // variant
|
virtual void Visit(Expression& node); // variant
|
||||||
virtual void Visit(SuperExpression& node); // variant
|
virtual void Visit(SuperExpression& node); // variant
|
||||||
|
|
||||||
virtual void Visit(ScopedStatement* node) {}
|
virtual void Visit(ScopedStatement* node);
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
virtual void Visit(BinaryOperatorExpression* node) {}
|
virtual void Visit(BinaryOperatorExpression* node);
|
||||||
virtual void Visit(UnaryOperatorExpression* node) {}
|
virtual void Visit(UnaryOperatorExpression* node);
|
||||||
virtual void Visit(ReferenceExpression* node) {}
|
virtual void Visit(ReferenceExpression* node);
|
||||||
virtual void Visit(AccessExpression* node) {}
|
virtual void Visit(AccessExpression* node);
|
||||||
|
|
||||||
// Simple Expressions
|
// Simple Expressions
|
||||||
|
|
||||||
virtual void Visit(FunctionCallExpression* node) {}
|
virtual void Visit(FunctionCallExpression* node);
|
||||||
|
|
||||||
virtual void Visit(FunctionArgument& node); // variant
|
virtual void Visit(FunctionArgument& node); // variant
|
||||||
|
|
||||||
virtual void Visit(TupleExpression* node) {}
|
virtual void Visit(TupleExpression* node);
|
||||||
virtual void Visit(VariantExpression* node) {}
|
virtual void Visit(VariantExpression* node);
|
||||||
virtual void Visit(ReturnExpression* node) {}
|
virtual void Visit(ReturnExpression* node);
|
||||||
virtual void Visit(TypeConstructor* node) {}
|
virtual void Visit(TypeConstructor* node);
|
||||||
virtual void Visit(LambdaFunction* node) {}
|
virtual void Visit(LambdaFunction* node);
|
||||||
virtual void Visit(ArrayExpression* node) {}
|
virtual void Visit(ArrayExpression* node);
|
||||||
|
|
||||||
virtual void Visit(LoopControlExpression& node) {} // enum
|
virtual void Visit(LoopControlExpression& node); // enum
|
||||||
|
|
||||||
// Name
|
// Name
|
||||||
|
|
||||||
virtual void Visit(NameExpression* node) {}
|
virtual void Visit(NameExpression* node);
|
||||||
virtual void Visit(TupleName* node) {}
|
virtual void Visit(TupleName* node);
|
||||||
virtual void Visit(VariantName* node) {}
|
virtual void Visit(VariantName* node);
|
||||||
virtual void Visit(AnnotatedName* node) {}
|
virtual void Visit(AnnotatedName* node);
|
||||||
|
|
||||||
virtual void Visit(AnyName& node); // variant
|
virtual void Visit(AnyName& node); // variant
|
||||||
|
|
||||||
|
|
@ -104,20 +104,20 @@ protected:
|
||||||
|
|
||||||
// Type
|
// Type
|
||||||
|
|
||||||
virtual void Visit(FunctionType* node) {}
|
virtual void Visit(FunctionType* node);
|
||||||
virtual void Visit(TupleType* node) {}
|
virtual void Visit(TupleType* node);
|
||||||
virtual void Visit(VariantType* node) {}
|
virtual void Visit(VariantType* node);
|
||||||
virtual void Visit(ParametrizedType* node) {}
|
virtual void Visit(ParametrizedType* node);
|
||||||
virtual void Visit(TypeExpression* node) {}
|
virtual void Visit(TypeExpression* node);
|
||||||
|
|
||||||
virtual void Visit(AnyType& node); // variant
|
virtual void Visit(AnyType& node); // variant
|
||||||
|
|
||||||
virtual void Visit(ExtendedScopedAnyType* node) {}
|
virtual void Visit(ExtendedScopedAnyType* node);
|
||||||
|
|
||||||
// Typeclass
|
// Typeclass
|
||||||
|
|
||||||
virtual void Visit(ParametrizedTypeclass* node) {}
|
virtual void Visit(ParametrizedTypeclass* node);
|
||||||
virtual void Visit(TypeclassExpression* node) {}
|
virtual void Visit(TypeclassExpression* node);
|
||||||
|
|
||||||
virtual void Visit(TypeclassUsage& node); // variant
|
virtual void Visit(TypeclassUsage& node); // variant
|
||||||
|
|
||||||
|
|
@ -128,14 +128,14 @@ protected:
|
||||||
|
|
||||||
// Identifiers, constants, etc. -----------------
|
// 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(FloatNumberLiteral* node);
|
||||||
virtual void Visit(NumberLiteral* node) {}
|
virtual void Visit(NumberLiteral* node);
|
||||||
virtual void Visit(StringLiteral* node) {}
|
virtual void Visit(StringLiteral* node);
|
||||||
virtual void Visit(CharLiteral* node) {}
|
virtual void Visit(CharLiteral* node);
|
||||||
|
|
||||||
virtual void Visit(Literal& node); // variant
|
virtual void Visit(Literal& node); // variant
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -117,6 +117,8 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||||
info.argument_type_nodes[i] = &node->type->types[i];
|
info.argument_type_nodes[i] = &node->type->types[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
info.node = node;
|
||||||
|
|
||||||
if (was_in_statement) {
|
if (was_in_statement) {
|
||||||
current_info_ = std::move(info);
|
current_info_ = std::move(info);
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -148,7 +150,7 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||||
|
|
||||||
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
|
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));
|
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info));
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
// for clangd
|
// for clangd
|
||||||
#include "../include/global_info.hpp"
|
#include "../include/global_info.hpp"
|
||||||
|
#include "../include/error_handling.hpp"
|
||||||
|
|
||||||
namespace info {
|
namespace info {
|
||||||
|
|
||||||
|
|
@ -63,9 +64,13 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(const std::st
|
||||||
id = global_info_.functions_.size();
|
id = global_info_.functions_.size();
|
||||||
namespace_stack_.back()->functions[name] = id;
|
namespace_stack_.back()->functions[name] = id;
|
||||||
global_info_.functions_.emplace_back();
|
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);
|
global_info_.functions_.back().declaration = std::move(function_declaration_info);
|
||||||
} else {
|
} else {
|
||||||
id = function_id_iter->second;
|
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);
|
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();
|
id = global_info_.functions_.size();
|
||||||
namespace_stack_.back()->functions[name] = id;
|
namespace_stack_.back()->functions[name] = id;
|
||||||
global_info_.functions_.emplace_back();
|
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);
|
global_info_.functions_.back().definition = std::move(function_definition_info);
|
||||||
} else {
|
} else {
|
||||||
id = function_id_iter->second;
|
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);
|
global_info_.functions_[id].definition = std::move(function_definition_info);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -54,7 +54,7 @@ void LinkSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
||||||
for (size_t i = 0; i <node->parameters.size(); ++i) {
|
for (size_t i = 0; i <node->parameters.size(); ++i) {
|
||||||
abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]);
|
abstract_types_.DefineType(node->parameters[i], node->parameter_graph_ids_[i]);
|
||||||
}
|
}
|
||||||
Visit(node->value.get());
|
Visitor::Visit(node->value.get());
|
||||||
abstract_types_.ExitContext();
|
abstract_types_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -68,10 +68,10 @@ void LinkSymbolsVisitor::Visit(VariableDefinitionStatement* node) {
|
||||||
void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
void LinkSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||||
abstract_types_.EnterContext();
|
abstract_types_.EnterContext();
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(parameter.get());
|
Visitor::Visit(parameter.get());
|
||||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||||
}
|
}
|
||||||
Visit(node->type.get());
|
Visitor::Visit(node->type.get());
|
||||||
abstract_types_.ExitContext();
|
abstract_types_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -90,7 +90,7 @@ void LinkSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
void LinkSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||||
Visit(node->type.get());
|
Visitor::Visit(node->type.get());
|
||||||
// TODO: can't be used before definition
|
// TODO: can't be used before definition
|
||||||
abstract_types_.DefineType(node->type->type, node->type->type_graph_id_);
|
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) {
|
void LinkSymbolsVisitor::Visit(FunctionDefinition* node) {
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(parameter.get());
|
Visitor::Visit(parameter.get());
|
||||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(TypeDefinition* node) {
|
void LinkSymbolsVisitor::Visit(TypeDefinition* node) {
|
||||||
Visit(node->type.get());
|
Visitor::Visit(node->type.get());
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(parameter.get());
|
Visitor::Visit(parameter.get());
|
||||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
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 -----------------
|
// 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. -----------------
|
// 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
|
// 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
|
// Other Expressions
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(FunctionCallExpression* node) {
|
// TODO: move to find_symbols_visitor
|
||||||
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));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(LambdaFunction* node) {
|
void LinkSymbolsVisitor::Visit(LambdaFunction* node) {
|
||||||
abstract_types_.EnterContext();
|
abstract_types_.EnterContext();
|
||||||
for (auto& parameter : node->parameters) {
|
for (auto& parameter : node->parameters) {
|
||||||
Visit(parameter.get());
|
Visitor::Visit(parameter.get());
|
||||||
abstract_types_.DefineType(parameter->type, parameter->type_graph_id_);
|
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);
|
Visitor::Visit(node->expression);
|
||||||
abstract_types_.ExitContext();
|
abstract_types_.ExitContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(ArrayExpression* node) {
|
|
||||||
for (auto& element : node->elements) {
|
|
||||||
Visitor::Visit(element);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Name
|
// 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, typeclass, etc. -----------------
|
||||||
|
|
||||||
// Type
|
// 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) {
|
void LinkSymbolsVisitor::Visit(TypeExpression* node) {
|
||||||
std::vector<std::string> path;
|
std::vector<std::string> path;
|
||||||
path.reserve(node->namespaces.size());
|
path.reserve(node->namespaces.size());
|
||||||
|
|
@ -361,19 +191,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(ExtendedScopedAnyType* node) {
|
|
||||||
Visitor::Visit(node->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Typeclass
|
// Typeclass
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) {
|
|
||||||
Visit(node->typeclass_expression.get());
|
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visitor::Visit(parameter);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void LinkSymbolsVisitor::Visit(TypeclassExpression* node) {
|
void LinkSymbolsVisitor::Visit(TypeclassExpression* node) {
|
||||||
std::vector<std::string> path;
|
std::vector<std::string> path;
|
||||||
path.reserve(node->namespaces.size());
|
path.reserve(node->namespaces.size());
|
||||||
|
|
|
||||||
|
|
@ -250,7 +250,7 @@ void PrintVisitor::Visit(AnyAnnotatedType* node) {
|
||||||
out_ << "[Annotated (Abstract) Type ";
|
out_ << "[Annotated (Abstract) Type ";
|
||||||
Visit(&node->type);
|
Visit(&node->type);
|
||||||
out_ << ']';
|
out_ << ']';
|
||||||
if (!node->typeclasses.empty() > 0) {
|
if (!node->typeclasses.empty()) {
|
||||||
out_ << " (";
|
out_ << " (";
|
||||||
for (auto& typeclass : node->typeclasses) {
|
for (auto& typeclass : node->typeclasses) {
|
||||||
Visitor::Visit(typeclass);
|
Visitor::Visit(typeclass);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,9 @@
|
||||||
#include "../include/type_check_visitor.hpp"
|
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
#include <variant>
|
||||||
|
|
||||||
|
// for clangd
|
||||||
|
#include "../include/type_check_visitor.hpp"
|
||||||
|
#include "../include/error_handling.hpp"
|
||||||
|
|
||||||
// TODO
|
// TODO
|
||||||
|
|
||||||
|
|
@ -17,26 +21,30 @@ void TypeCheckVisitor::Visit(SourceFile* node) {
|
||||||
// error
|
// error
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Sources* node) {
|
void TypeCheckVisitor::Visit(Sources* node) {
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
Visitor::Visit(statement);
|
Visitor::Visit(statement);
|
||||||
}
|
}
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Namespaces, partitions -----------------
|
// Namespaces, partitions -----------------
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Partition* node) {
|
void TypeCheckVisitor::Visit(Partition* node) {
|
||||||
Visit(node->scope.get());
|
Visit(node->scope.get());
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Namespace* node) {
|
void TypeCheckVisitor::Visit(Namespace* node) {
|
||||||
if (node->name.has_value()) {
|
if (node->name.has_value()) {
|
||||||
// TODO: add modifiers
|
// TODO: add modifiers
|
||||||
node->variable_type_ = info::type::Type {info::type::DefinedType {node->type_id_.value()}};
|
|
||||||
context_manager_.EnterVariableContext(node->name.value().name,
|
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);
|
namespace_visitor_.EnterNamespace(node->type);
|
||||||
|
|
@ -44,6 +52,8 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
||||||
Visit(node->scope.get());
|
Visit(node->scope.get());
|
||||||
|
|
||||||
namespace_visitor_.ExitNamespace();
|
namespace_visitor_.ExitNamespace();
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definitions -----------------
|
// Definitions -----------------
|
||||||
|
|
@ -51,364 +61,520 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
||||||
void TypeCheckVisitor::Visit(ImportStatement* node) {}
|
void TypeCheckVisitor::Visit(ImportStatement* node) {}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(AliasDefinitionStatement* 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());
|
Visit(node->value.get());
|
||||||
|
context_manager_.EqualTypes(type, current_type_);
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
|
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
|
||||||
|
// TODO: remove variable on move
|
||||||
// TODO: add modifiers
|
// TODO: add modifiers
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value);
|
||||||
|
// current_type from value automatically passed to name definitions
|
||||||
Visitor::Visit(node->name);
|
Visitor::Visit(node->name);
|
||||||
|
|
||||||
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
|
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) {
|
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);
|
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) {
|
void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
|
||||||
switch (node->modifier) {
|
// TODO: add modifiers
|
||||||
case TypeDefinitionStatement::Struct:
|
// check, that all paramaters used ??
|
||||||
break;
|
// TODO: defined type typeclasses
|
||||||
case TypeDefinitionStatement::Class:
|
|
||||||
break;
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
}
|
|
||||||
Visit(node->definition.get());
|
|
||||||
Visitor::Visit(node->value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||||
switch (node->modifier) {
|
utils::IdType type = context_manager_.AddType(info::type::AbstractType {node->type_graph_id_} );
|
||||||
case AbstractTypeDefinitionStatement::Basic:
|
|
||||||
break;
|
// Visit(node->type.get()); ??
|
||||||
case AbstractTypeDefinitionStatement::Abstract:
|
for (auto& typeclass : node->type->typeclasses) { // TODO
|
||||||
break;
|
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) {
|
void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||||
Visit(node->definition.get());
|
// check, that all paramaters used ??
|
||||||
if (!node->requirements.empty()) {
|
// TODO: needed ??
|
||||||
}
|
|
||||||
for (auto& requirement : node->requirements) {
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
Visit(requirement.get());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Definition parts
|
// Definition parts
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(FunctionDefinition* node) {
|
void TypeCheckVisitor::Visit(FunctionDefinition* node) {
|
||||||
switch (node->modifier) {
|
// TODO: needed ??
|
||||||
case FunctionDefinition::Operator:
|
|
||||||
break;
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(TypeDefinition* node) {
|
void TypeCheckVisitor::Visit(TypeDefinition* node) {
|
||||||
Visit(node->type.get());
|
// TODO: needed ??
|
||||||
if (!node->parameters.empty()) {
|
|
||||||
for (auto& parameter : node->parameters) {
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
Visit(parameter.get());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// used on upper levels
|
||||||
void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
|
void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
|
||||||
Visit(&node->type);
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
if (!node->typeclasses.empty() > 0) {
|
|
||||||
for (auto& typeclass : node->typeclasses) {
|
|
||||||
Visitor::Visit(typeclass);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Flow control -----------------
|
// Flow control -----------------
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(MatchCase* node) {
|
void TypeCheckVisitor::Visit(MatchCase* node) {
|
||||||
Visitor::Visit(node->value);
|
Visitor::Visit(node->value); // TODO: literal & name instead of expression
|
||||||
if (node->condition.has_value()) {
|
if (node->condition.has_value()) {
|
||||||
Visitor::Visit(node->condition.value());
|
Visitor::Visit(node->condition.value());
|
||||||
}
|
}
|
||||||
|
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||||
|
|
||||||
if (node->statement.has_value()) {
|
if (node->statement.has_value()) {
|
||||||
Visitor::Visit(node->statement.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);
|
Visitor::Visit(node->value);
|
||||||
for (auto& match_case : node->matches) {
|
for (size_t i = 0; i < node->matches.size(); ++i) {
|
||||||
Visit(&match_case);
|
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) {
|
void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant type ?? (problem with same types)
|
||||||
Visitor::Visit(node->conditions[0]);
|
// TODO: types can be different in statement
|
||||||
Visitor::Visit(node->statements[0]);
|
utils::IdType type;
|
||||||
for (size_t i = 1; i < node->conditions.size(); ++i) {
|
|
||||||
|
for (size_t i = 0; i < node->conditions.size(); ++i) {
|
||||||
Visitor::Visit(node->conditions[i]);
|
Visitor::Visit(node->conditions[i]);
|
||||||
|
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||||
|
|
||||||
Visitor::Visit(node->statements[i]);
|
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()) {
|
if (node->statements.size() > node->conditions.size()) {
|
||||||
Visitor::Visit(node->statements[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) {
|
void TypeCheckVisitor::Visit(DoWhileLoop* node) {
|
||||||
out_ << "[Do] (\n";
|
|
||||||
Visitor::Visit(node->statement);
|
|
||||||
out_ << ") [while] (";
|
|
||||||
Visitor::Visit(node->condition);
|
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) {
|
void TypeCheckVisitor::Visit(WhileLoop* node) {
|
||||||
out_ << "[While] (";
|
|
||||||
Visitor::Visit(node->statement);
|
|
||||||
out_ << ") [do] (\n";
|
|
||||||
Visitor::Visit(node->condition);
|
Visitor::Visit(node->condition);
|
||||||
out_ << ")\n";
|
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Bool), current_type_);
|
||||||
}
|
|
||||||
void TypeCheckVisitor::Visit(ForLoop* node) {
|
|
||||||
out_ << "[For] (";
|
|
||||||
Visitor::Visit(node->variable);
|
|
||||||
out_ << ") [in] (";
|
|
||||||
Visitor::Visit(node->interval);
|
|
||||||
out_ << ") [do] (\n";
|
|
||||||
Visitor::Visit(node->statement);
|
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) {
|
void TypeCheckVisitor::Visit(LoopLoop* node) {
|
||||||
out_ << "[Loop] (\n";
|
|
||||||
Visitor::Visit(node->statement);
|
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. -----------------
|
// Statements, expressions, blocks, etc. -----------------
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(Block* node) {
|
void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (problem with same types)
|
||||||
out_ << "[Block] {\n";
|
utils::IdType type;
|
||||||
|
|
||||||
|
bool is_first_returned_type = true;
|
||||||
|
|
||||||
for (auto& statement : node->statements) {
|
for (auto& statement : node->statements) {
|
||||||
|
returned_type_ = std::nullopt;
|
||||||
Visitor::Visit(statement);
|
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) {
|
void TypeCheckVisitor::Visit(ScopedStatement* node) {
|
||||||
out_ << "[Scoped] ( ";
|
|
||||||
Visitor::Visit(node->statement);
|
Visitor::Visit(node->statement);
|
||||||
out_ << ")\n";
|
// current_type_ is type of statement
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
||||||
switch (node) {
|
current_type_ = context_manager_.AddType(info::type::InternalType::Unit);
|
||||||
case LoopControlExpression::Break:
|
|
||||||
out_ << "[Break]\n";
|
|
||||||
break;
|
|
||||||
case LoopControlExpression::Continue:
|
|
||||||
out_ << "[Continue]\n";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Operators
|
// Operators
|
||||||
|
|
||||||
|
// -------------------------- TODO --------------------------
|
||||||
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
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);
|
Visitor::Visit(node->left_expression);
|
||||||
out_ << ") [";
|
context_manager_.AddTypeRequirement(current_type_,
|
||||||
Visit(&node->operator_name);
|
context_manager_.AddType(info::type::AbstractType {operator_info->definition.value().node->argument_graph_ids_[0]}));
|
||||||
out_ << "] (";
|
|
||||||
Visitor::Visit(node->right_expression);
|
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) {
|
void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
||||||
out_ << "[UnaryOperator ";
|
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
|
||||||
Visit(&node->operator_name);
|
|
||||||
out_ << "] (";
|
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);
|
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) {
|
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());
|
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
|
void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||||
Visitor::Visit(node->name);
|
|
||||||
Visitor::Visit(node->id);
|
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
|
// Other Expressions
|
||||||
|
|
||||||
|
// -------------------------- TODO --------------------------
|
||||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||||
out_ << "[FunctionCall ";
|
// TODO: add function paramaters
|
||||||
Visit(node->name.get());
|
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) {
|
void TypeCheckVisitor::Visit(TupleExpression* node) {
|
||||||
out_ << "[TupleExpression] (";
|
info::type::TupleType type;
|
||||||
|
|
||||||
|
type.fields.reserve(node->expressions.size());
|
||||||
for (auto& expression : node->expressions) {
|
for (auto& expression : node->expressions) {
|
||||||
out_ << "&";
|
|
||||||
Visitor::Visit(expression);
|
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) {
|
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||||
out_ << "[VariantExpression] (";
|
info::type::VariantType type;
|
||||||
|
|
||||||
for (auto& expression : node->expressions) {
|
for (auto& expression : node->expressions) {
|
||||||
out_ << "|";
|
info::type::TupleType constructor;
|
||||||
|
|
||||||
Visitor::Visit(expression);
|
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) {
|
void TypeCheckVisitor::Visit(ReturnExpression* node) {
|
||||||
Visitor::Visit(node->expression);
|
Visitor::Visit(node->expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
// -------------------------- TODO --------------------------
|
||||||
out_ << "[TypeConstructor ";
|
void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor names, etc.
|
||||||
Visit(node->type.get());
|
utils::IdType type;
|
||||||
out_ << "]\n(";
|
|
||||||
|
|
||||||
bool is_first = true;
|
Visit(node->type.get());
|
||||||
for (auto& parameter : node->parameters) {
|
type = current_type_;
|
||||||
if (!is_first) {
|
|
||||||
out_ << ")\n";
|
info::AnyTypeInfo* type_info = &std::get<info::AnyTypeInfo>(
|
||||||
is_first = false;
|
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));
|
current_type_ = type;
|
||||||
switch (std::get<1>(parameter)) {
|
|
||||||
case TypeConstructor::Assign:
|
|
||||||
out_ << " = ";
|
|
||||||
break;
|
|
||||||
case TypeConstructor::Move:
|
|
||||||
out_ << " <- ";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
Visitor::Visit(std::get<2>(parameter));
|
|
||||||
}
|
|
||||||
out_ << ")\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(LambdaFunction* node) {
|
void TypeCheckVisitor::Visit(LambdaFunction* node) {
|
||||||
out_ << "[LambdaFunction] (";
|
info::type::FunctionType type;
|
||||||
for (auto& parameter : node->parameters) {
|
|
||||||
Visit(parameter.get());
|
// 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_ << ") : (";
|
type.return_type = context_manager_.AddType(info::type::AbstractType {node->return_type_graph_id_});
|
||||||
}
|
|
||||||
for (auto& argument : node->arguments) {
|
|
||||||
Visit(&argument);
|
|
||||||
}
|
|
||||||
out_ << ") -> (\n";
|
|
||||||
Visitor::Visit(node->expression);
|
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) {
|
void TypeCheckVisitor::Visit(ArrayExpression* node) {
|
||||||
out_ << "[ArrayExpression] ([";
|
info::type::ArrayType type;
|
||||||
for (auto& element : node->elements) {
|
|
||||||
Visitor::Visit(element);
|
type.size = node->elements.size();
|
||||||
out_ << ';';
|
|
||||||
|
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
|
// Name
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(NameExpression* node) {
|
// -------------------------- TODO --------------------------
|
||||||
out_ << "[NameExpression] (";
|
void TypeCheckVisitor::Visit(NameExpression* node) { // TODO: ?? functions without arguments ??
|
||||||
for (auto& variable_namespace : node->namespaces) {
|
std::vector<std::string> path;
|
||||||
Visitor::Visit(variable_namespace);
|
std::string type_name;
|
||||||
out_ << '.';
|
|
||||||
|
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) {
|
for (size_t i = 0; i < node->expressions.size(); ++i) {
|
||||||
Visitor::Visit(node->expressions[i]);
|
// Visitor::Visit(node->expressions[i]);
|
||||||
if (i + 1 < node->expressions.size()) {
|
|
||||||
out_ << '.';
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
out_ << ')';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(TupleName* node) {
|
void TypeCheckVisitor::Visit(TupleName* node) {
|
||||||
utils::IdType type = current_type_;
|
utils::IdType type = current_type_;
|
||||||
|
|
||||||
auto type_value = std::get_if<info::type::TupleType>(context_manager_.GetType(type));
|
if (!std::holds_alternative<info::type::TupleType>(context_manager_.GetType(type))) {
|
||||||
|
|
||||||
if (type_value = nullptr) {
|
|
||||||
error_handling::HandleTypecheckError("Mismatched types in tuple variable definition");
|
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");
|
error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition");
|
||||||
}
|
}
|
||||||
for (auto& name : node->names) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
current_type_ = type_value->fields[i];
|
current_type_ = type_value.fields[i].second;
|
||||||
Visitor::Visit(name);
|
Visitor::Visit(node->names[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
current_type_ = type;
|
current_type_ = type;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeCheckVisitor::Visit(VariantName* node) { // TODO
|
void TypeCheckVisitor::Visit(VariantName* node) {
|
||||||
utils::IdType type = current_type_;
|
utils::IdType type = current_type_;
|
||||||
|
|
||||||
auto type_value = std::get_if<info::type::VariantType>(context_manager_.GetType(type));
|
if (!std::holds_alternative<info::type::VariantType>(context_manager_.GetType(type))) {
|
||||||
|
|
||||||
if (type_value = nullptr) {
|
|
||||||
error_handling::HandleTypecheckError("Mismatched types in variant variable definition");
|
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");
|
error_handling::HandleTypecheckError("Mismatched variant count in variant variable definition");
|
||||||
}
|
}
|
||||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||||
current_type_ = info::type::VariantType::MakeOptional(type_value->constructors[i]);
|
if (std::holds_alternative<std::string>(type_value.constructors[i])) {
|
||||||
Visitor::Visit(name);
|
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;
|
current_type_ = type;
|
||||||
|
|
@ -428,9 +594,9 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
|
||||||
void TypeCheckVisitor::Visit(FunctionType* node) {
|
void TypeCheckVisitor::Visit(FunctionType* node) {
|
||||||
info::type::FunctionType type;
|
info::type::FunctionType type;
|
||||||
|
|
||||||
type.argument_type_ids.reserve(node->types.size());
|
type.argument_types.reserve(node->types.size());
|
||||||
for (auto& type : node->types) {
|
for (auto& argument_type : node->types) {
|
||||||
Visitor::Visit(type);
|
Visitor::Visit(argument_type);
|
||||||
type.argument_types.push_back(current_type_);
|
type.argument_types.push_back(current_type_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -474,8 +640,7 @@ void TypeCheckVisitor::Visit(VariantType* node) {
|
||||||
void TypeCheckVisitor::Visit(ParametrizedType* node) {
|
void TypeCheckVisitor::Visit(ParametrizedType* node) {
|
||||||
info::type::DefinedType type;
|
info::type::DefinedType type;
|
||||||
|
|
||||||
Visit(node->type_expression.get());
|
type.type_id = node->type_expression->type_id_;
|
||||||
type.type = current_type_;
|
|
||||||
|
|
||||||
type.paramaters.reserve(node->parameters.size());
|
type.paramaters.reserve(node->parameters.size());
|
||||||
for (auto& paramater : node->parameters) {
|
for (auto& paramater : node->parameters) {
|
||||||
|
|
|
||||||
359
src/visitor.cpp
359
src/visitor.cpp
|
|
@ -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
|
} // namespace interpreter
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue