types for typecheck, sources manager

This commit is contained in:
ProgramSnail 2023-08-02 17:54:39 +03:00
parent 4714a05467
commit ef88e6af86
9 changed files with 353 additions and 104 deletions

View file

@ -11,28 +11,78 @@
namespace names {
// IN PROGRESS
class NameTree;
class AnyStatementProxy {
friend NameTree;
public:
nodes::Statement *get();
const nodes::Statement *get() const;
//
bool operator==(const AnyStatementProxy &other_any_statement_proxy) const {
return name_tree_ == other_any_statement_proxy.name_tree_ &&
id_ == other_any_statement_proxy.id_;
}
bool operator!=(const AnyStatementProxy &other_any_statement_proxy) const {
return !(*this == other_any_statement_proxy);
}
private:
AnyStatementProxy(NameTree &name_tree, size_t id)
: name_tree_(&name_tree), id_(id) {}
private:
NameTree *name_tree_;
size_t id_;
};
template <typename T> class StatementProxy {
public:
StatementProxy(AnyStatementProxy proxy) : proxy_(proxy) {}
T *get() { proxy_.get()->get<T>().value(); }
const T *get() const { proxy_.get()->get<T>().value(); }
//
bool operator==(const StatementProxy &other_statement_proxy) const {
return proxy_ == other_statement_proxy.proxy_;
}
bool operator!=(const StatementProxy &other_statement_proxy) const {
return !(*this == other_statement_proxy);
}
private:
AnyStatementProxy proxy_;
};
class NameTree {
friend AnyStatementProxy;
public:
NameTree() {
nodes_.emplace_back(); // root
}
bool insert(const std::string &path, nodes::Statement &&statement);
std::optional<AnyStatementProxy> insert(const std::string &path,
nodes::Statement &&statement);
// bool insert(const std::string &path, const nodes::Statement &statement);
std::pair<std::optional<AnyStatementProxy>, nodes::CombineResult>
insert_combine(const std::string &path, nodes::Statement &&statement);
nodes::CombineResult insert_combine(const std::string &path,
nodes::Statement &&statement);
std::optional<nodes::Statement *> find(const std::string &path);
std::optional<const nodes::Statement *> find(const std::string &path) const;
std::optional<AnyStatementProxy> find(const std::string &path);
void print(printers::Printer &printer) const;
// TODO
void add_statement_children_to_tree();
// // TODO
// void add_statement_children_to_tree();
private:
struct Node {

View file

@ -0,0 +1,85 @@
#pragma once
#include "basic_printers.hpp"
#include "error_handling.hpp"
#include "expression_nodes.hpp"
#include "name_tree.hpp"
#include "statement_builders.hpp"
#include "statement_nodes.hpp"
#include "statement_printers.hpp"
#include "tree_sitter_wrapper.hpp"
#include "type_nodes.hpp"
#include <fstream>
#include <iostream>
#include <sstream>
class SourcesManager {
public:
void add_file(const std::string &filename) {
std::ifstream in;
in.open(filename);
std::stringstream source_stream;
source_stream << in.rdbuf();
in.close();
std::string source = source_stream.str();
parser::ParseTree parse_tree(source);
if (!parse_tree.is_properly_parsed()) {
error_handling::handle_parsing_error(
"There are some parsing errors in file", parse_tree.get_root());
}
auto new_statements = builders::build_source_file(
parse_tree.get_root(), expression_storage_, type_storage_, name_tree_);
statements_.reserve(statements_.size() + new_statements.size());
for (auto &new_statement : new_statements) {
statements_.push_back(std::move(new_statement));
}
new_statements.clear();
}
void print(std::ostream &out) {
printers::Printer printer(out, 2, 80, true);
printers::print_source_file(statements_, printer);
}
//
nodes::ExpressionStorage *get_expression_storage() {
return &expression_storage_;
}
const nodes::ExpressionStorage *get_expression_storage() const {
return &expression_storage_;
}
//
nodes::TypeStorage *get_type_storage() { return &type_storage_; }
const nodes::TypeStorage *get_type_storage() const { return &type_storage_; }
//
size_t get_statements_size() const { return statements_.size(); }
nodes::Statement *get_statement(size_t id) { return &statements_.at(id); }
const nodes::Statement *get_statement(size_t id) const {
return &statements_.at(id);
}
private:
nodes::ExpressionStorage expression_storage_;
nodes::TypeStorage type_storage_;
names::NameTree name_tree_;
std::vector<nodes::Statement> statements_;
};

View file

@ -404,6 +404,7 @@ public:
Statement(const Statement &) = default;
Statement(Statement &&) = default;
Statement &operator=(const Statement &) = default;
Statement &operator=(Statement &&) = default;
template <typename T>
explicit Statement(T &&statement) : expression_(std::forward<T>(statement)) {}

134
include/types.hpp Normal file
View file

@ -0,0 +1,134 @@
#pragma once
#include "basic_nodes.hpp"
#include "name_tree.hpp"
#include "statement_nodes.hpp"
#include <vector>
namespace types {
class Type;
class TypeStorage;
class TypeProxy {
friend TypeStorage;
public:
Type *get();
const Type *get() const;
private:
TypeProxy(TypeStorage &type_storage, size_t id)
: type_storage_(&type_storage), id_(id) {}
private:
TypeStorage *type_storage_;
size_t id_;
};
class Defined {
public:
Defined(nodes::Modifier modifier,
names::StatementProxy<nodes::TypeDefinition> definition)
: modifier_(modifier), definition_(definition) {}
nodes::Modifier get_modifier() const { return modifier_; }
nodes::TypeDefinition *get_definition() { return definition_.get(); }
const nodes::TypeDefinition *get_definition() const {
return definition_.get();
}
private:
nodes::Modifier modifier_;
names::StatementProxy<nodes::TypeDefinition> definition_;
};
class Container {
public:
enum ContainerType {
OR,
AND,
};
Container(ContainerType type, std::vector<TypeProxy> &&fields)
: type_(type), fields_(std::move(fields)) {}
Container(ContainerType type, const std::vector<TypeProxy> &fields)
: type_(type), fields_(std::move(fields)) {}
//
ContainerType get_type() const { return type_; }
//
size_t fields_size() const { return fields_.size(); }
Type *get_field(size_t id) { return fields_.at(id).get(); }
const Type *get_field(size_t id) const { return fields_.at(id).get(); }
private:
ContainerType type_;
std::vector<TypeProxy> fields_; // or constructors
};
class Type {
public:
Type(const Type &) = default;
Type(Type &&) = default;
Type &operator=(const Type &) = default;
template <typename T>
explicit Type(T &&type) : type_(std::forward<T>(type)) {}
template <typename T> std::optional<T *> get() {
if (std::holds_alternative<T>(type_)) {
return &std::get<T>(type_);
}
return std::nullopt;
}
template <typename T> std::optional<const T *> get() const {
if (std::holds_alternative<T>(type_)) {
return &std::get<T>(type_);
}
return std::nullopt;
}
auto get_any() { return &type_; }
auto get_any() const { return &type_; }
private:
std::variant<Defined, Container> type_;
};
class TypeStorage {
friend TypeProxy;
public:
TypeProxy add_type(const Type &type) {
storage_.push_back(type);
return TypeProxy(*this, storage_.size() - 1);
}
TypeProxy add_type(Type &&type) {
storage_.push_back(std::move(type));
return TypeProxy(*this, storage_.size() - 1);
}
private:
Type *get_type(size_t id) { return &storage_.at(id); }
const Type *get_type(size_t id) const { return &storage_.at(id); }
private:
std::vector<Type> storage_;
};
}; // namespace types