mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-07 15:38:49 +00:00
types for typecheck, sources manager
This commit is contained in:
parent
4714a05467
commit
ef88e6af86
9 changed files with 353 additions and 104 deletions
134
include/types.hpp
Normal file
134
include/types.hpp
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue