mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 15:08:45 +00:00
access syntax changed, sync with grammar, type_chack_visitor in progress
This commit is contained in:
parent
3d74b1383e
commit
6fc91aafa0
19 changed files with 110221 additions and 102967 deletions
|
|
@ -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_;
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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));
|
||||||
|
|
|
||||||
|
|
@ -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
212584
src/parser.c
File diff suppressed because it is too large
Load diff
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue