access syntax changed, sync with grammar, type_chack_visitor in progress

This commit is contained in:
ProgramSnail 2023-04-21 14:27:55 +03:00
parent 3d74b1383e
commit 6fc91aafa0
19 changed files with 110221 additions and 102967 deletions

View file

@ -76,6 +76,7 @@ private:
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;
// Other expressions // Other expressions
@ -139,8 +140,6 @@ private:
void Visit(CharLiteral* node) override; void Visit(CharLiteral* node) override;
void Visit(Literal& node) override; // variant void Visit(Literal& node) override; // variant
void Visit(NameSubExpression& node) override; // variant
private: private:
const parser::ParseTree& parse_tree_; const parser::ParseTree& parse_tree_;
parser::ParseTree::Node current_node_; parser::ParseTree::Node current_node_;

View file

@ -63,6 +63,7 @@ private:
// // 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;
// Simple Expressions // Simple Expressions

View file

@ -8,6 +8,7 @@
// for clangd // for clangd
#include "utils.hpp" #include "utils.hpp"
#include "types_info.hpp"
namespace interpreter::tokens { namespace interpreter::tokens {
@ -87,12 +88,26 @@ using FlowControl = std::variant<
struct Block; struct Block;
struct FloatNumberLiteral;
struct NumberLiteral;
struct StringLiteral;
struct CharLiteral;
using Literal = std::variant<
std::unique_ptr<FloatNumberLiteral>,
std::unique_ptr<NumberLiteral>,
std::unique_ptr<StringLiteral>,
std::unique_ptr<CharLiteral>>;
// //
struct NameExpression; struct NameExpression;
struct ScopedStatement; struct ScopedStatement;
struct AccessExpression;
using SubExpressionToken = std::variant< using SubExpressionToken = std::variant<
std::unique_ptr<NameExpression>, std::unique_ptr<NameExpression>,
std::unique_ptr<ScopedStatement>>; std::unique_ptr<ScopedStatement>,
std::unique_ptr<AccessExpression>,
std::unique_ptr<Literal>>;
// //
struct FunctionCallExpression; struct FunctionCallExpression;
struct BinaryOperatorExpression; struct BinaryOperatorExpression;
@ -224,29 +239,6 @@ struct ExtendedName {
std::string name; std::string name;
}; };
struct FloatNumberLiteral;
struct NumberLiteral;
struct StringLiteral;
struct CharLiteral;
using Literal = std::variant<
std::unique_ptr<FloatNumberLiteral>,
std::unique_ptr<NumberLiteral>,
std::unique_ptr<StringLiteral>,
std::unique_ptr<CharLiteral>>;
//
using NameSubExpression = std::variant<
std::unique_ptr<ExtendedName>,
std::unique_ptr<Literal>,
std::unique_ptr<SuperExpression>>;
enum class ReferenceType {
Reference,
UniqueReference,
};
//////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////
// ----------------- Sources ----------------- // ----------------- Sources -----------------
@ -267,6 +259,9 @@ struct Namespace {
std::optional<ExtendedName> name; std::optional<ExtendedName> name;
TypeIdentifier type; TypeIdentifier type;
std::unique_ptr<Sources> scope; std::unique_ptr<Sources> scope;
std::optional<utils::IdType> type_id_;
std::optional<info::type::Type> variable_type_;
}; };
struct Partition { struct Partition {
@ -323,6 +318,7 @@ struct FunctionDefinitionStatement {
utils::IdType function_id_; utils::IdType function_id_;
std::vector<utils::IdType> argument_graph_ids_; std::vector<utils::IdType> argument_graph_ids_;
utils::IdType return_type_graph_id_;
}; };
struct TypeDefinitionStatement { struct TypeDefinitionStatement {
@ -437,10 +433,15 @@ struct UnaryOperatorExpression {
}; };
struct ReferenceExpression { struct ReferenceExpression {
std::vector<ReferenceType> references; std::vector<utils::ReferenceType> references;
std::unique_ptr<ScopedStatement> expression; std::unique_ptr<ScopedStatement> expression;
}; };
struct AccessExpression {
std::unique_ptr<NameExpression> name;
SubExpressionToken id;
};
// Other Expressions ----------------- // Other Expressions -----------------
struct FunctionCallExpression { struct FunctionCallExpression {
@ -480,7 +481,7 @@ struct ArrayExpression {
struct NameExpression { struct NameExpression {
std::vector<TypeSubExpression> namespaces; std::vector<TypeSubExpression> namespaces;
std::vector<NameSubExpression> expressions; std::vector<ExtendedName> expressions;
}; };
struct TupleName { struct TupleName {
@ -528,7 +529,7 @@ struct TypeExpression {
}; };
struct ExtendedScopedAnyType { struct ExtendedScopedAnyType {
std::vector<ReferenceType> references; std::vector<utils::ReferenceType> references;
AnyType type; AnyType type;
}; };

View file

@ -3,7 +3,7 @@
#include <ostream> #include <ostream>
// for clangd // for clangd
#include "abstract_types_context.hpp" #include "abstract_types_contexts.hpp"
#include "visitor.hpp" #include "visitor.hpp"
#include "global_info.hpp" #include "global_info.hpp"
@ -64,6 +64,7 @@ private:
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;
// Simple Expressions // Simple Expressions

View file

@ -62,6 +62,7 @@ const std::string ScopedStatement = "scoped_statement";
const std::string BinaryOperatorExpression = "binary_operator_expression"; const std::string BinaryOperatorExpression = "binary_operator_expression";
const std::string UnaryOperatorExpression = "unary_operator_expression"; const std::string UnaryOperatorExpression = "unary_operator_expression";
const std::string ReferenceExpression = "reference_expression"; const std::string ReferenceExpression = "reference_expression";
const std::string AccessExpression = "access_expression";
// Other expressions // Other expressions

View file

@ -60,6 +60,7 @@ private:
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;
// Simple Expressions // Simple Expressions

View file

@ -2,7 +2,7 @@
// for clangd // for clangd
#include "type_info_contexts.hpp" #include "type_info_contexts.hpp"
#include "symbols_info.hpp" #include "utils.hpp"
#include "visitor.hpp" #include "visitor.hpp"
#include "global_info.hpp" #include "global_info.hpp"
@ -10,7 +10,8 @@ namespace interpreter {
class TypeCheckVisitor : public Visitor { class TypeCheckVisitor : public Visitor {
public: public:
explicit TypeCheckVisitor(info::GlobalInfo& global_info) : global_info_(global_info) {} explicit TypeCheckVisitor(info::GlobalInfo& global_info)
: namespace_visitor_(global_info.CreateVisitor()) {}
private: private:
// Sources ----------------- // Sources -----------------
@ -61,6 +62,7 @@ private:
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;
// Simple Expressions // Simple Expressions
@ -111,10 +113,10 @@ private:
void Visit(CharLiteral* node) override; void Visit(CharLiteral* node) override;
private: private:
info::GlobalInfo& global_info_; info::GlobalInfo::NamespaceVisitor namespace_visitor_;
info::TypeInfoContextManager context_manager_; info::TypeInfoContextManager context_manager_;
info::TypeInfo current_type_; utils::IdType current_type_;
}; };
} // namespace interpreter } // namespace interpreter

View file

@ -5,22 +5,36 @@
#include <unordered_map> #include <unordered_map>
// for clangd // for clangd
#include "symbols_info.hpp" #include "types_info.hpp"
#include "utils.hpp"
namespace info { namespace info {
// TODO: remember about typespointers
class TypeInfoContextManager { class TypeInfoContextManager {
public: public:
template<typename T>
utils::IdType AddType(T&& type) {
types_.push_back(std::forward(type));
return types_.size() - 1;
}
const info::type::Type& GetType(utils::IdType type_id) {
return types_[type_id];
}
// void AddTypeRequirement(utils::IdType type, utils::IdType requrement); // TODO
void CallFunction(const std::vector<std::string>& names, void CallFunction(const std::vector<std::string>& names,
const std::vector<TypeInfo*>& types) { const std::vector<utils::IdType>& argument_types) {
if (names.size() != 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], types[i]); DefineVariable(names[i], argument_types[i]);
} }
} }
@ -40,18 +54,19 @@ public:
contexts_.clear(); contexts_.clear();
} }
// TODO Variable modifiers // TODO: variable modifiers
bool DefineVariable(const std::string& name, TypeInfo* type) { bool DefineVariable(const std::string& name, utils::IdType type_id) {
return contexts_.back().DefineVariable(name, type); return contexts_.back().DefineVariable(name, type_id);
} }
void EnterVariableContext(const std::string& name, TypeInfo* type) { // for variable namespaces, for loops void EnterVariableContext(const std::string& name,
utils::IdType type_id) { // for variable namespaces, for loops
contexts_.push_back(false); contexts_.push_back(false);
DefineVariable(name, type); DefineVariable(name, type_id);
} }
std::optional<TypeInfo*> 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 = 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()) {
@ -66,15 +81,15 @@ private:
public: public:
Context(bool hide_previous) : hide_previous_(hide_previous) {} Context(bool hide_previous) : hide_previous_(hide_previous) {}
bool DefineVariable(const std::string& name, TypeInfo* type) { bool DefineVariable(const std::string& name, utils::IdType type_id) {
if (variables_.count(name) > 0) { if (variables_.count(name) > 0) {
return false; return false;
} }
variables_[name] = type; variables_[name] = type_id;
return true; return true;
} }
std::optional<TypeInfo*> 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);
if (variable_iter == variables_.end()) { if (variable_iter == variables_.end()) {
@ -87,10 +102,11 @@ private:
bool IsFirst() { return hide_previous_; } bool IsFirst() { return hide_previous_; }
private: private:
bool hide_previous_; bool hide_previous_;
std::unordered_map<std::string, TypeInfo*> variables_; std::unordered_map<std::string, utils::IdType> variables_;
}; };
std::vector<Context> contexts_; std::vector<Context> contexts_;
std::vector<info::type::Type> types_;
}; };
} // namespace info } // namespace info

View file

@ -1,48 +1,95 @@
#pragma once
#include <optional>
#include <string>
#include <variant>
#include <memory>
// for clangd // for clangd
#include "symbols_info.hpp" #include "error_handling.hpp"
#include "utils.hpp"
namespace info { namespace info::type {
struct BasicType {
std::string name;
std::vector<size_t> methods; // ??
std::vector<size_t> typeclasses;
};
// TODO: differentiate abstract and basic types
struct AbstractType { struct AbstractType {
size_t graph_id; utils::IdType graph_id;
std::vector<utils::IdType> paramaters;
}; };
struct TupleType; struct DefinedType {
struct VariantType; utils::IdType type_id;
struct ReferenceType; std::vector<utils::IdType> paramaters;
using AnyType = std::variant<std::unique_ptr<BasicType>, };
std::unique_ptr<AbstractType>,
std::unique_ptr<TupleType>,
std::unique_ptr<VariantType>,
std::unique_ptr<ReferenceType>>;
struct TupleType { enum class InternalType {
std::vector<std::pair<std::optional<std::string>, AnyType>> fields; Float,
Int,
String,
Char,
Bool,
Unit,
};
struct TupleType { //
std::optional<std::string> type;
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields;
}; };
struct VariantType { struct VariantType {
std::vector<std::pair<std::string, TupleType>> constructors; 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 ReferenceType { struct ReferenceToType {
enum { Reference, UniqueReference } reference_type; std::vector<utils::ReferenceType> references;
AnyType type; utils::IdType type;
}; };
struct FunctionalType { struct FunctionType {
std::vector<utils::IdType> argument_types;
}; };
struct Type { struct ArrayType {
size_t graph_id_; std::vector<utils::IdType> element_types;
TypeInfo* info = nullptr;
std::vector<std::string> requrements_;
}; };
} // namespace info using Type = std::variant<AbstractType,
DefinedType,
InternalType,
TupleType,
VariantType,
ReferenceToType,
FunctionType,
ArrayType>;
} // namespace info::type

View file

@ -8,9 +8,13 @@ namespace utils {
using IdType = std::size_t; using IdType = std::size_t;
enum class ReferenceType { Reference, UniqueReference };
template<typename T> template<typename T>
class Storage { class Storage {
public: public:
Storage() = default;
IdType GetId(const T& value) { IdType GetId(const T& value) {
IdType id = 0; IdType id = 0;
auto value_position = value_to_id_.find(value); auto value_position = value_to_id_.find(value);

View file

@ -74,6 +74,7 @@ protected:
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) {}
// Simple Expressions // Simple Expressions
@ -137,8 +138,6 @@ protected:
virtual void Visit(CharLiteral* node) {} virtual void Visit(CharLiteral* node) {}
virtual void Visit(Literal& node); // variant virtual void Visit(Literal& node); // variant
virtual void Visit(NameSubExpression& node); // variant
}; };
} // namespace interpreter } // namespace interpreter

View file

@ -606,6 +606,12 @@ void BuildVisitor::Visit(SubExpressionToken& node) {
} else if (current_node_type == parser::tokens::ScopedStatement) { } else if (current_node_type == parser::tokens::ScopedStatement) {
node = std::make_unique<ScopedStatement>(); node = std::make_unique<ScopedStatement>();
Visit(std::get<std::unique_ptr<ScopedStatement>>(node).get()); Visit(std::get<std::unique_ptr<ScopedStatement>>(node).get());
} if (current_node_type == parser::tokens::AccessExpression) {
node = std::make_unique<AccessExpression>();
Visit(std::get<std::unique_ptr<AccessExpression>>(node).get());
} else if (current_node_type == parser::tokens::Literal) {
node = std::make_unique<Literal>();
Visit(*std::get<std::unique_ptr<Literal>>(node));
} else { } else {
// error // error
} }
@ -766,9 +772,9 @@ void BuildVisitor::Visit(ReferenceExpression* node) {
for (size_t i = 0; i + 1 < child_count; ++i) { for (size_t i = 0; i + 1 < child_count; ++i) {
std::string reference = parse_node.NthChild(i).GetValue(); std::string reference = parse_node.NthChild(i).GetValue();
if (reference == "~") { if (reference == "~") {
node->references[i] = ReferenceType::Reference; node->references[i] = utils::ReferenceType::Reference;
} else if (reference == "@") { } else if (reference == "@") {
node->references[i] = ReferenceType::UniqueReference; node->references[i] = utils::ReferenceType::UniqueReference;
} }
} }
} }
@ -780,6 +786,18 @@ void BuildVisitor::Visit(ReferenceExpression* node) {
current_node_ = parse_node; current_node_ = parse_node;
} }
void BuildVisitor::Visit(AccessExpression* node) {
auto parse_node = current_node_;
current_node_ = parse_node.ChildByFieldName("name");
Visit(node->name.get());
current_node_ = parse_node.ChildByFieldName("id");
Visit(node->id);
current_node_ = parse_node;
}
// Other expressions // Other expressions
void BuildVisitor::Visit(FunctionArgument& node) { void BuildVisitor::Visit(FunctionArgument& node) {
@ -964,25 +982,8 @@ void BuildVisitor::Visit(NameExpression* node) {
current_node_ = parse_node.NthNamedChild(i); current_node_ = parse_node.NthNamedChild(i);
std::string current_node_type = current_node_.GetType(); std::string current_node_type = current_node_.GetType();
if (current_node_type != parser::tokens::TypeSubExpression && !namespaces_ended) { if (current_node_type != parser::tokens::TypeSubExpression) {
namespaces_ended = true; namespaces_ended = true;
if (i + 1 == child_count) {
node->expressions.emplace_back();
if (current_node_type == parser::tokens::ExtendedName) {
node->expressions.back() = std::make_unique<ExtendedName>();
Visit(node->expressions.back());
} else if (current_node_type == parser::tokens::Literal) {
node->expressions.back() = std::make_unique<Literal>();
Visit(*std::get<std::unique_ptr<Literal>>(node->expressions.back()));
} else {
// error
}
break;
} else {
// error
}
} }
if (!namespaces_ended) { if (!namespaces_ended) {
@ -990,7 +991,7 @@ void BuildVisitor::Visit(NameExpression* node) {
Visit(node->namespaces.back()); Visit(node->namespaces.back());
} else { } else {
node->expressions.emplace_back(); node->expressions.emplace_back();
Visit(node->expressions.back()); Visit(&node->expressions.back());
} }
} }
@ -1249,9 +1250,9 @@ void BuildVisitor::Visit(ExtendedScopedAnyType* node) {
for (size_t i = 0; i + 1 < child_count; ++i) { for (size_t i = 0; i + 1 < child_count; ++i) {
std::string reference = parse_node.NthChild(i).GetValue(); std::string reference = parse_node.NthChild(i).GetValue();
if (reference == "~") { if (reference == "~") {
node->references[i] = ReferenceType::Reference; node->references[i] = utils::ReferenceType::Reference;
} else if (reference == "@") { } else if (reference == "@") {
node->references[i] = ReferenceType::UniqueReference; node->references[i] = utils::ReferenceType::UniqueReference;
} }
} }
} }
@ -1428,27 +1429,4 @@ void BuildVisitor::Visit(Literal& node) {
current_node_ = parse_node; current_node_ = parse_node;
} }
void BuildVisitor::Visit(NameSubExpression& node) {
auto parse_node = current_node_;
current_node_ = parse_node.NthNamedChild(0);
std::string current_node_type = current_node_.GetType();
if (current_node_type == parser::tokens::ExtendedName) {
node = std::make_unique<ExtendedName>();
Visit(std::get<std::unique_ptr<ExtendedName>>(node).get());
} else if (current_node_type == parser::tokens::Literal) {
node = std::make_unique<Literal>();
Visit(*std::get<std::unique_ptr<Literal>>(node));
} else if (current_node_type == parser::tokens::SuperExpression) {
node = std::make_unique<SuperExpression>();
Visit(*std::get<std::unique_ptr<SuperExpression>>(node));
} else {
// error
}
current_node_ = parse_node;
}
} // namespace interpreter } // namespace interpreter

View file

@ -146,6 +146,8 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex(); node->argument_graph_ids_[i] = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
} }
node->return_type_graph_id_ = namespace_visitor_.GetAbstractTypeGraph()->AddVertex();
info.expression = &node->value; info.expression = &node->value;
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info)); node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info));

View file

@ -34,6 +34,12 @@ void LinkSymbolsVisitor::Visit(Partition* node) {
} }
void LinkSymbolsVisitor::Visit(Namespace* node) { void LinkSymbolsVisitor::Visit(Namespace* node) {
node->type_id_ = namespace_visitor_.FindType({}, node->type);
if (node->name.has_value() && !node->type_id_.has_value()) {
error_handling::HandleTypecheckError("Variable namespace type not found");
}
namespace_visitor_.EnterNamespace(node->type); namespace_visitor_.EnterNamespace(node->type);
Visit(node->scope.get()); Visit(node->scope.get());
namespace_visitor_.ExitNamespace(); namespace_visitor_.ExitNamespace();
@ -203,6 +209,11 @@ void LinkSymbolsVisitor::Visit(ReferenceExpression* node) {
Visit(node->expression.get()); 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) { void LinkSymbolsVisitor::Visit(FunctionCallExpression* node) {
@ -257,9 +268,9 @@ void LinkSymbolsVisitor::Visit(NameExpression* node) {
for (auto& variable_namespace : node->namespaces) { for (auto& variable_namespace : node->namespaces) {
Visitor::Visit(variable_namespace); Visitor::Visit(variable_namespace);
} }
for (auto& expression : node->expressions) { // for (auto& expression : node->expressions) {
Visitor::Visit(expression); // Visit(expression);
} // }
} }
void LinkSymbolsVisitor::Visit(TupleName* node) { void LinkSymbolsVisitor::Visit(TupleName* node) {

212584
src/parser.c

File diff suppressed because it is too large Load diff

View file

@ -389,10 +389,10 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
out_ << "[ReferenceExpression "; out_ << "[ReferenceExpression ";
for (auto& reference : node->references) { for (auto& reference : node->references) {
switch (reference) { switch (reference) {
case ReferenceType::Reference: case utils::ReferenceType::Reference:
out_ << '~'; out_ << '~';
break; break;
case ReferenceType::UniqueReference: case utils::ReferenceType::UniqueReference:
out_ << '@'; out_ << '@';
break; break;
} }
@ -402,6 +402,14 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
out_ << ')'; out_ << ')';
} }
void PrintVisitor::Visit(AccessExpression* node) {
out_ << "[AccessExpression] (";
Visit(node->name.get());
out_ << ") : (";
Visitor::Visit(node->id);
out_ << ')';
}
// Other Expressions // Other Expressions
void PrintVisitor::Visit(FunctionCallExpression* node) { void PrintVisitor::Visit(FunctionCallExpression* node) {
@ -499,7 +507,7 @@ void PrintVisitor::Visit(NameExpression* node) {
out_ << '.'; out_ << '.';
} }
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]); Visit(&node->expressions[i]);
if (i + 1 < node->expressions.size()) { if (i + 1 < node->expressions.size()) {
out_ << '.'; out_ << '.';
} }
@ -619,10 +627,10 @@ void PrintVisitor::Visit(ExtendedScopedAnyType* node) {
out_ << "[ExtendedScopedAnyType "; out_ << "[ExtendedScopedAnyType ";
for (auto& reference : node->references) { for (auto& reference : node->references) {
switch (reference) { switch (reference) {
case ReferenceType::Reference: case utils::ReferenceType::Reference:
out_ << '~'; out_ << '~';
break; break;
case ReferenceType::UniqueReference: case utils::ReferenceType::UniqueReference:
out_ << '@'; out_ << '@';
break; break;
} }

View file

@ -1,4 +1,5 @@
#include "../include/type_check_visitor.hpp" #include "../include/type_check_visitor.hpp"
#include <memory>
// TODO // TODO
@ -32,75 +33,36 @@ void TypeCheckVisitor::Visit(Partition* node) {
void TypeCheckVisitor::Visit(Namespace* node) { void TypeCheckVisitor::Visit(Namespace* node) {
if (node->name.has_value()) { if (node->name.has_value()) {
if (node->modifier.has_value()) { // TODO: add modifiers
switch (node->modifier.value()) { // TODO node->variable_type_ = info::type::Type {info::type::DefinedType {node->type_id_.value()}};
case Namespace::Const:
// TODO
break;
case Namespace::Var:
// TODO
break;
}
} else {
// error
}
Visit(&node->name.value());
context_manager_.EnterVariableContext(node->name.value().name, context_manager_.EnterVariableContext(node->name.value().name,
global_info_.FindType(std::nullopt, node->type).value()); // TODO ?? &node->variable_type_.value());
} }
// global_info_.FindType(std::nullopt, node->type); // ??
global_info_.EnterNamespace(node->type); namespace_visitor_.EnterNamespace(node->type);
Visit(node->scope.get()); Visit(node->scope.get());
global_info_.ExitNamespace(); namespace_visitor_.ExitNamespace();
} }
// Definitions ----------------- // Definitions -----------------
void TypeCheckVisitor::Visit(ImportStatement* node) { // TODO void TypeCheckVisitor::Visit(ImportStatement* node) {}
// if (node->name.has_value()) {
// }
// if (!node->symbols.empty()) {
// for (auto& symbol : node->symbols) {
// Visit(&symbol);
// }
// }
}
void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) { void TypeCheckVisitor::Visit(AliasDefinitionStatement* node) {
switch (node->modifier) { // TODO check, that all paramaters used
case AliasDefinitionStatement::Alias:
break;
case AliasDefinitionStatement::Type:
break;
case AliasDefinitionStatement::Let:
break;
}
Visit(&node->type);
Visit(node->value.get()); Visit(node->value.get());
} }
void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) { void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
switch (node->modifier) { // TODO: add modifiers
case VariableDefinitionStatement::Const:
break;
case VariableDefinitionStatement::Var:
break;
}
Visitor::Visit(node->name);
Visitor::Visit(node->value); Visitor::Visit(node->value);
Visitor::Visit(node->name);
} }
void TypeCheckVisitor::Visit(FunctionDeclaration* node) { void TypeCheckVisitor::Visit(FunctionDeclaration* node) {
Visit(&node->name); // later check, that function definition requirements are satisfied
for (auto& parameter : node->parameters) {
Visit(parameter.get());
}
Visit(node->type.get());
} }
void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) { void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
@ -304,6 +266,11 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
out_ << ')'; out_ << ')';
} }
void TypeCheckVisitor::Visit(AccessExpression* node) { // TODO
Visitor::Visit(node->name);
Visitor::Visit(node->id);
}
// Other Expressions // Other Expressions
void TypeCheckVisitor::Visit(FunctionCallExpression* node) { void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
@ -315,6 +282,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
out_ << ", "; out_ << ", ";
} }
out_ << ")"; out_ << ")";
} }
void TypeCheckVisitor::Visit(TupleExpression* node) { void TypeCheckVisitor::Visit(TupleExpression* node) {
@ -336,9 +304,7 @@ void TypeCheckVisitor::Visit(VariantExpression* node) {
} }
void TypeCheckVisitor::Visit(ReturnExpression* node) { void TypeCheckVisitor::Visit(ReturnExpression* node) {
out_ << "[Return] (";
Visitor::Visit(node->expression); Visitor::Visit(node->expression);
out_ << ")\n";
} }
void TypeCheckVisitor::Visit(TypeConstructor* node) { void TypeCheckVisitor::Visit(TypeConstructor* node) {
@ -410,31 +376,48 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
} }
void TypeCheckVisitor::Visit(TupleName* node) { void TypeCheckVisitor::Visit(TupleName* node) {
out_ << "[TupleName] ("; utils::IdType type = current_type_;
for (auto& name : node->names) {
out_ << "& "; auto type_value = std::get_if<info::type::TupleType>(context_manager_.GetType(type));
Visitor::Visit(name);
} if (type_value = nullptr) {
out_ << ')'; error_handling::HandleTypecheckError("Mismatched types in tuple variable definition");
} }
void TypeCheckVisitor::Visit(VariantName* node) { if (type_value->constructors.size() != node->names.size()) {
out_ << "[VariantName] ("; error_handling::HandleTypecheckError("Mismatched field count in tuple variable definition");
}
for (auto& name : node->names) { for (auto& name : node->names) {
out_ << "| "; current_type_ = type_value->fields[i];
Visitor::Visit(name); Visitor::Visit(name);
} }
out_ << ')'; current_type_ = type;
}
void TypeCheckVisitor::Visit(VariantName* node) { // TODO
utils::IdType type = current_type_;
auto type_value = std::get_if<info::type::VariantType>(context_manager_.GetType(type));
if (type_value = nullptr) {
error_handling::HandleTypecheckError("Mismatched types in variant variable definition");
}
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);
}
current_type_ = type;
} }
void TypeCheckVisitor::Visit(AnnotatedName* node) { void TypeCheckVisitor::Visit(AnnotatedName* node) {
out_ << "[AnnotatedName "; context_manager_.DefineVariable(node->name, current_type_);
Visit(&node->name);
out_ << ']';
if (node->type.has_value()) { if (node->type.has_value()) {
out_ << " : ("; // TODO: ?? check, that types are equal, add type requirement ??
Visitor::Visit(node->type.value());
out_ << ')';
} }
} }
@ -443,135 +426,104 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
// Type // Type
void TypeCheckVisitor::Visit(FunctionType* node) { void TypeCheckVisitor::Visit(FunctionType* node) {
out_ << "[FunctionType] ("; info::type::FunctionType type;
bool is_first = true;
type.argument_type_ids.reserve(node->types.size());
for (auto& type : node->types) { for (auto& type : node->types) {
if (!is_first) {
out_ << " -> ";
}
is_first = false;
Visitor::Visit(type); Visitor::Visit(type);
type.argument_types.push_back(current_type_);
} }
out_ << ')';
current_type_ = context_manager_.AddType(std::move(type));
} }
void TypeCheckVisitor::Visit(TupleType* node) { void TypeCheckVisitor::Visit(TupleType* node) {
out_ << "[TupleType "; info::type::TupleType type;
if (node->type.has_value()) {
Visit(&node->type.value()); type.type = node->type;
}
out_ << "] ("; type.fields.reserve(node->entities.size());
for (auto& entity : node->entities) { for (auto& entity : node->entities) {
out_ << "& ";
if (entity.first.has_value()) {
Visit(&entity.first.value());
out_ << " : ";
}
Visit(entity.second.get()); Visit(entity.second.get());
type.fields.emplace_back(entity.first, current_type_);
} }
out_ << ')';
current_type_ = context_manager_.AddType(std::move(type));
} }
void TypeCheckVisitor::Visit(VariantType* node) { void TypeCheckVisitor::Visit(VariantType* node) {
out_ << "[VariantType "; info::type::VariantType type;
if (node->type.has_value()) {
Visit(&node->type.value()); type.type = node->type;
}
out_ << "] ("; type.constructors.reserve(node->constructors.size());
for (auto& constructor : node->constructors) { for (auto& constructor : node->constructors) {
out_ << "| ";
if (std::holds_alternative<Constructor>(constructor)) { if (std::holds_alternative<Constructor>(constructor)) {
Visit(&std::get<Constructor>(constructor)); type.constructors.emplace_back(std::get<Constructor>(constructor));
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) { } else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get()); Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
type.constructors.emplace_back(context_manager_.GetType(current_type_));
} else { } else {
// error // error
} }
} }
out_ << ')';
current_type_ = context_manager_.AddType(std::move(type));
} }
void TypeCheckVisitor::Visit(ParametrizedType* node) { void TypeCheckVisitor::Visit(ParametrizedType* node) {
out_ << "[ParametrizedType] ("; info::type::DefinedType type;
Visit(node->type_expression.get()); Visit(node->type_expression.get());
for (auto& parameter : node->parameters) { type.type = current_type_;
out_ << ' ';
Visitor::Visit(parameter); type.paramaters.reserve(node->parameters.size());
for (auto& paramater : node->parameters) {
Visitor::Visit(paramater);
type.paramaters.push_back(current_type_);
} }
out_ << ')';
current_type_ = context_manager_.AddType(std::move(type));
} }
void TypeCheckVisitor::Visit(TypeExpression* node) { void TypeCheckVisitor::Visit(TypeExpression* node) {
out_ << "[TypeExpression "; current_type_ = context_manager_.AddType(info::type::DefinedType {node->type_id_, {}});
if (node->array_size.has_value()) {
out_ << "[array size: " << node->array_size.value() << ']';
}
out_ << "] (";
for (auto& type_namespace : node->namespaces) {
Visitor::Visit(type_namespace);
out_ << '.';
}
Visit(&node->type);
out_ << ')';
} }
void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) { void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) {
out_ << "[ExtendedScopedAnyType "; info::type::ReferenceToType type;
for (auto& reference : node->references) {
switch (reference) { type.references = node->references;
case ReferenceType::Reference:
out_ << '~';
break;
case ReferenceType::UniqueReference:
out_ << '@';
break;
}
}
out_ << "] (";
Visitor::Visit(node->type); Visitor::Visit(node->type);
out_ << ')'; type.type = current_type_;
current_type_ = context_manager_.AddType(std::move(type));
} }
// Typeclass // Typeclass
void TypeCheckVisitor::Visit(ParametrizedTypeclass* node) { void TypeCheckVisitor::Visit(ParametrizedTypeclass* node) {}
out_ << "[ParametrizedTypeclass] (";
Visit(node->typeclass_expression.get());
for (auto& paramater : node->parameters) {
out_ << ' ';
Visitor::Visit(paramater);
}
out_ << ')';
}
void TypeCheckVisitor::Visit(TypeclassExpression* node) { void TypeCheckVisitor::Visit(TypeclassExpression* node) {}
out_ << "[TypeclassExpression] (";
for (auto& typeclass_namespace : node->namespaces) {
Visitor::Visit(typeclass_namespace);
out_ << '.';
}
Visit(&node->typeclass);
out_ << ')';
}
// Identifiers, constants, etc. ----------------- // Identifiers, constants, etc. -----------------
// TODO don't make dublicates of the same types
void TypeCheckVisitor::Visit(FloatNumberLiteral* node) { void TypeCheckVisitor::Visit(FloatNumberLiteral* node) {
current_type_ = info::BuiltInTypeInfo::FloatT; current_type_ = context_manager_.AddType(info::type::InternalType::Float);
} }
void TypeCheckVisitor::Visit(NumberLiteral* node) { void TypeCheckVisitor::Visit(NumberLiteral* node) {
out_ << "[Number " << node->value << "] "; current_type_ = context_manager_.AddType(info::type::InternalType::Int);
} }
void TypeCheckVisitor::Visit(StringLiteral* node) { void TypeCheckVisitor::Visit(StringLiteral* node) {
out_ << "[String " << node->value << "] "; current_type_ = context_manager_.AddType(info::type::InternalType::String);
} }
void TypeCheckVisitor::Visit(CharLiteral* node) { void TypeCheckVisitor::Visit(CharLiteral* node) {
out_ << "[Char " << node->value << "] "; current_type_ = context_manager_.AddType(info::type::InternalType::Char);
} }
} // namespace interpreter } // namespace interpreter

View file

@ -97,6 +97,12 @@ void Visitor::Visit(SubExpressionToken& node) {
case 1: case 1:
Visit(std::get<std::unique_ptr<ScopedStatement>>(node).get()); Visit(std::get<std::unique_ptr<ScopedStatement>>(node).get());
break; break;
case 2:
Visit(std::get<std::unique_ptr<AccessExpression>>(node).get());
break;
case 3:
Visit(*std::get<std::unique_ptr<Literal>>(node));
break;
default: default:
// error // error
break; break;
@ -313,23 +319,4 @@ void Visitor::Visit(Literal& node) {
} }
} }
//
void Visitor::Visit(NameSubExpression& node) {
switch (node.index()) {
case 0:
Visit(std::get<std::unique_ptr<ExtendedName>>(node).get());
break;
case 1:
Visit(*std::get<std::unique_ptr<Literal>>(node));
break;
case 2:
Visit(*std::get<std::unique_ptr<SuperExpression>>(node));
break;
default:
// error
break;
}
}
} // namespace interpreter } // namespace interpreter