type_check_visitor first iteration, value, execution_visitor started

This commit is contained in:
ProgramSnail 2023-05-07 19:52:35 +03:00
parent 173d50672a
commit 890bd90eba
22 changed files with 481 additions and 452 deletions

View file

@ -1,6 +1,5 @@
#pragma once
#include "interpreter_tree.hpp"
#include <string>
#include <variant>
#include <vector>
@ -9,6 +8,7 @@
#include <memory>
// for clangd
#include "interpreter_tree.hpp"
#include "utils.hpp"
namespace interpreter {

134
include/execute_visitor.hpp Normal file
View file

@ -0,0 +1,134 @@
#pragma once
#include <ostream>
// for clangd
#include "contexts.hpp"
#include "global_info.hpp"
#include "type_info_contexts.hpp"
#include "visitor.hpp"
namespace interpreter {
class ExecuteVisitor : public Visitor {
public:
explicit ExecuteVisitor(info::GlobalInfo& global_info,
info::TypeInfoContextManager& type_info_context_manager,
info::ContextManager& context_manager)
: namespace_visitor_(global_info.CreateVisitor()),
type_info_context_manager_(type_info_context_manager),
context_manager_(context_manager) {}
private:
// Sources -----------------
void Visit(SourceFile* node) override;
// Namespaces, partitions -----------------
void Visit(PartitionSources* node) override;
void Visit(Partition* node) override;
void Visit(NamespaceSources* node) override;
void Visit(Namespace* node) override;
// Definitions -----------------
void Visit(ImportStatement* node) override;
void Visit(AliasDefinitionStatement* node) override;
void Visit(VariableDefinitionStatement* node) override;
void Visit(FunctionDeclaration* node) override;
void Visit(FunctionDefinitionStatement* node) override;
void Visit(TypeDefinitionStatement* node) override;
void Visit(AbstractTypeDefinitionStatement* node) override;
void Visit(TypeclassDefinitionStatement* node) override;
// Definition parts
void Visit(FunctionDefinition* node) override;
void Visit(TypeDefinition* node) override;
void Visit(AnyAnnotatedType* node) override;
// Flow control -----------------
void Visit(TypeConstructorPatternParameter* node) override;
void Visit(TypeConstructorPattern* node) override;
void Visit(MatchCase* node) override;
void Visit(Match* node) override;
void Visit(Condition* node) override;
void Visit(DoWhileLoop* node) override;
void Visit(WhileLoop* node) override;
void Visit(ForLoop* node) override;
void Visit(LoopLoop* node) override;
// Statements, expressions, blocks, etc. -----------------
void Visit(Block* node) override;
void Visit(ScopedStatement* node) override;
// Operators
void Visit(BinaryOperatorExpression* node) override;
void Visit(UnaryOperatorExpression* node) override;
void Visit(ReferenceExpression* node) override;
void Visit(AccessExpression* node) override;
// Simple Expressions
void Visit(FunctionCallExpression* node) override;
void Visit(TupleExpression* node) override;
void Visit(VariantExpression* node) override;
void Visit(ReturnExpression* node) override;
void Visit(TypeConstructorParameter* node) override;
void Visit(TypeConstructor* node) override;
void Visit(LambdaFunction* node) override;
void Visit(ArrayExpression* node) override;
void Visit(LoopControlExpression& node) override; // enum
// Name
void Visit(NameExpression* node) override;
void Visit(TupleName* node) override;
void Visit(VariantName* node) override;
void Visit(AnnotatedName* node) override;
// Type, typeclass, etc. -----------------
// Type
void Visit(FunctionType* node) override;
void Visit(TupleType* node) override;
void Visit(VariantType* node) override;
void Visit(TypeExpression* node) override;
void Visit(ExtendedScopedAnyType* node) override;
// Typeclass
void Visit(ParametrizedTypeclass* node) override;
// Typeclass & Type
void Visit(ParametrizedType* node) override;
// Identifiers, constants, etc. -----------------
void Visit(ExtendedName* node) override;
void Visit(std::string* node) override; // std::string
void Visit(FloatNumberLiteral* node) override;
void Visit(NumberLiteral* node) override;
void Visit(StringLiteral* node) override;
void Visit(CharLiteral* node) override;
void Visit(UnitLiteral* node) override;
private:
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
info::TypeInfoContextManager& type_info_context_manager_;
info::ContextManager& context_manager_;
};
} // namespace interpreter

View file

@ -107,10 +107,10 @@ public:
definition::Namespace* current_namespace,
const std::vector<std::string>& path);
private:
GlobalInfo& global_info_;
std::vector<definition::Namespace*> namespace_stack_;
std::vector<std::string> current_path_;
GlobalInfo& global_info_;
};
NamespaceVisitor CreateVisitor() {
@ -123,11 +123,11 @@ public:
}
template<typename T>
const std::optional<T>& GetTypeInfo(utils::IdType id) {
std::optional<T*> GetTypeInfo(utils::IdType id) {
if (!std::holds_alternative<T>(types_.at(id).type)) {
return std::nullopt;
}
return std::get<T>(types_[id].type);
return &std::get<T>(types_[id].type);
}
// remember about vector realloc
@ -146,6 +146,7 @@ public:
}
private:
std::vector<definition::Function> functions_;
std::vector<definition::Type> types_;
std::vector<definition::AbstractType> abstract_types_;

View file

@ -40,8 +40,9 @@ const std::string AnnotatedType = "annotated_type";
// Flow control -----------------
const std::string TypeConstructorPatternParameter = "type_constructor_pattern_parameter";
const std::string TypeConstructorPattern = "type_constructor_pattern";
const std::string PatternToken = "pattern_token";
const std::string ScopedPattern = "scoped_pattern";
const std::string Pattern = "pattern";
const std::string MatchCase = "match_case";
const std::string Match = "match";
@ -77,6 +78,7 @@ const std::string FunctionCallExpression = "function_call_expression";
const std::string TupleExpression = "tuple_expression";
const std::string VariantExpression = "variant_expression";
const std::string ReturnExpression = "return_expression";
const std::string TypeConstructorParameter = "type_constructor_parameter";
const std::string TypeConstructor = "type_constructor";
const std::string LambdaFunction = "lambda_function";
const std::string ArrayExpression = "array_expression";
@ -88,7 +90,6 @@ const std::string NameExpression = "name_expression";
const std::string TupleName = "tuple_name";
const std::string VariantName = "variant_name";
const std::string AnnotatedName = "annotated_name";
const std::string NameSubExpression = "name_subexpression";
const std::string AnyName = "any_name";
const std::string ScopedAnyName = "scoped_any_name";

View file

@ -11,7 +11,8 @@ namespace interpreter {
class TypeCheckVisitor : public Visitor {
public:
explicit TypeCheckVisitor(info::GlobalInfo& global_info, info::TypeInfoContextManager& context_manager)
explicit TypeCheckVisitor(info::GlobalInfo& global_info,
info::TypeInfoContextManager& context_manager)
: namespace_visitor_(global_info.CreateVisitor()), context_manager_(context_manager) {}
private:

View file

@ -14,13 +14,17 @@ namespace info {
// TODO: remember about type pointers
class TypeInfoContextManager {
public:
TypeInfoContextManager() {
contexts_.emplace_back();
}
template<typename T>
utils::IdType AddType(T&& type, utils::ValueType value_type) {
return type_manager_.AddType(std::forward(type), value_type);
utils::IdType AddType(const T& type, utils::ValueType value_type) {
return type_manager_.AddType(type, value_type);
}
utils::IdType AddAnyType(type::Type&& type, utils::ValueType value_type) {
return type_manager_.AddType(std::move(type), value_type);
return type_manager_.AddAnyType(std::move(type), value_type);
}
template<typename T>
@ -45,7 +49,8 @@ public:
}
utils::IdType ToModifiedType(utils::IdType type_id, utils::ValueType new_value_type) {
return AddAnyType(type::Type(*GetAnyType(type_id)), new_value_type);
type::Type type = *GetAnyType(type_id);
return AddAnyType(std::move(type), new_value_type);
}
type::TypeManager* GetTypeManager() {
@ -53,7 +58,7 @@ public:
}
void EnterContext() {
contexts_.emplace_back(false);
contexts_.emplace_back();
}
void ExitContext() {
@ -74,11 +79,10 @@ public:
}
bool DefineLocalAbstractType(const std::string& name, utils::IdType type_id) {
if (GetLocalAbstractType(name)) {
if (GetLocalAbstractType(name).has_value()) {
return false;
}
contexts_.back().DefineLocalAbstractType(name, type_id);
return true;
return contexts_.back().DefineLocalAbstractType(name, type_id);
}
@ -124,7 +128,7 @@ private:
Context() = default;
bool DefineVariable(const std::string& name, utils::IdType type_id) {
if (name == "_") { // placeholder // TODO: check in all places
if (name == "_") { // placeholder // TODO: ??
return true;
}

View file

@ -225,7 +225,7 @@ public:
Type() = default;
template<typename T>
explicit Type(T&& type) : type_(std::forward(type)) {}
explicit Type(const T& type) : type_(type) {}
std::optional<utils::IdType> InContext(const std::unordered_map<std::string, utils::IdType>& context);
bool Same(const Type& type) const;
@ -236,6 +236,17 @@ public:
std::string GetTypeName() const;
std::variant<AbstractType,
DefinedType,
InternalType,
TupleType,
VariantType,
ReferenceToType,
FunctionType,
ArrayType,
OptionalType>& GetType() {
return type_;
}
private:
std::variant<AbstractType,
DefinedType,
@ -251,22 +262,42 @@ private:
class TypeManager {
public:
template<typename T>
utils::IdType AddType(T&& type, utils::ValueType value_type);
utils::IdType AddType(const T& type, utils::ValueType value_type) {
types_.push_back(std::pair<Type, utils::ValueType> {type, value_type});
return types_.size() - 1;
}
utils::IdType AddAnyType(Type&& type, utils::ValueType value_type);
utils::IdType AddAnyType(Type&& type, utils::ValueType value_type) {
types_.push_back(std::pair<Type, utils::ValueType> {std::move(type), value_type});
return types_.size() - 1;
}
template<typename T>
std::optional<T*> GetType(utils::IdType type_id);
std::optional<T*> GetType(utils::IdType type_id) {
if (!std::holds_alternative<T>(types_.at(type_id).first.GetType())) {
return std::nullopt;
}
return &std::get<T>(types_.at(type_id).first.GetType());
}
Type* GetAnyType(utils::IdType type_id);
Type* GetAnyType(utils::IdType type_id) {
return &types_.at(type_id).first;
}
utils::ValueType GetValueType(utils::IdType type_id);
utils::ValueType GetValueType(utils::IdType type_id) {
return types_.at(type_id).second;
}
bool AddTypeRequirement(utils::IdType type, utils::IdType requrement);
bool EqualTypes(utils::IdType first_type, utils::IdType second_type);
bool EqualTypes(utils::IdType first_type, utils::IdType second_type) {
return GetAnyType(first_type)->Same(*GetAnyType(second_type));
}
bool AddTypeRequirement(utils::IdType type, utils::IdType requrement) {
return *GetAnyType(requrement) < *GetAnyType(type);
}
private:
std::vector<std::pair<info::type::Type, utils::ValueType>> types_;
std::vector<std::pair<Type, utils::ValueType>> types_;
};
} // namespace info::type

View file

@ -28,6 +28,7 @@ inline ValueType IsConstModifierToValueType(IsConstModifier modifier) {
return ValueType::Var;
}
// unreachable
exit(1);
}
template<typename T>
@ -107,32 +108,32 @@ private:
std::vector<size_t> ranks_;
};
static void BackVisitDfs(size_t id,
std::vector<size_t>& verticles,
std::vector<size_t>& marks,
const std::vector<std::vector<size_t>>& edges,
size_t mark) {
if (marks[id] != 0) {
return;
}
marks[id] = mark;
verticles.push_back(id);
for (size_t i = 0; i < edges[id].size(); ++i) {
BackVisitDfs(id, verticles, marks, edges, mark);
}
}
static std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_) {
std::vector<size_t> sorted_verticles;
std::vector<size_t> marks(edges_.size(), 0);
for (size_t i = 0; i < marks.size(); ++i) {
BackVisitDfs(i, sorted_verticles, marks, edges_, 1);
}
return sorted_verticles;
}
// static void BackVisitDfs(size_t id,
// std::vector<size_t>& verticles,
// std::vector<size_t>& marks,
// const std::vector<std::vector<size_t>>& edges,
// size_t mark) {
// if (marks[id] != 0) {
// return;
// }
//
// marks[id] = mark;
// verticles.push_back(id);
//
// for (size_t i = 0; i < edges[id].size(); ++i) {
// BackVisitDfs(id, verticles, marks, edges, mark);
// }
// }
//
// static std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_) {
// std::vector<size_t> sorted_verticles;
// std::vector<size_t> marks(edges_.size(), 0);
//
// for (size_t i = 0; i < marks.size(); ++i) {
// BackVisitDfs(i, sorted_verticles, marks, edges_, 1);
// }
//
// return sorted_verticles;
// }
} // namespace utils

143
include/values.hpp Normal file
View file

@ -0,0 +1,143 @@
#pragma once
#include <string>
#include <variant>
#include <optional>
#include <unordered_map>
// for clangd
#include "interpreter_tree.hpp"
#include "utils.hpp"
namespace info::value {
struct Unit {};
struct InternalValue {
public:
InternalValue() = default;
InternalValue(std::variant<double,
long long,
std::string,
char,
bool,
Unit>&& value) : value(std::move(value)) {}
public:
std::variant<double,
long long,
std::string,
char,
bool,
Unit> value;
};
struct TupleValue {
public:
TupleValue() = default;
TupleValue(std::unordered_map<std::string, utils::IdType>&& fields) : fields(fields) {}
public:
std::unordered_map<std::string, utils::IdType> fields;
};
struct VariantValue {
public:
VariantValue() = default;
VariantValue(size_t constructor, TupleValue value)
: constructor(constructor), value(value) {}
public:
size_t constructor;
TupleValue value;
};
struct ReferenceToValue {
public:
ReferenceToValue() = default;
ReferenceToValue(const std::vector<utils::ReferenceModifier>& references,
utils::IdType value)
: references(references), value(value) {}
public:
std::vector<utils::ReferenceModifier> references;
utils::IdType value;
};
struct FunctionValue {
public:
FunctionValue() = default;
FunctionValue(std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function)
: function(function) {}
public:
std::variant<interpreter::tokens::FunctionDeclaration*,
interpreter::tokens::LambdaFunction*> function;
};
struct ArrayValue {
public:
ArrayValue() = default;
ArrayValue(const std::vector<utils::IdType>& elements)
: elements(elements) {}
public:
std::vector<utils::IdType> elements;
};
struct OptionalValue {
public:
OptionalValue() = default;
OptionalValue(utils::IdType value) : value(value) {}
public:
std::optional<utils::IdType> value;
};
struct Value { // DefinedValue ??
std::variant<InternalValue,
TupleValue,
VariantValue,
ReferenceToValue,
FunctionValue, // ??
ArrayValue,
OptionalValue> value;
};
class ValueManager {
public:
template<typename T>
utils::IdType AddType(const T& value, utils::ValueType value_type) {
values_.push_back(std::pair<Value, utils::ValueType> {value, value_type});
return values_.size() - 1;
}
utils::IdType AddAnyType(Value&& value, utils::ValueType value_type) {
values_.push_back(std::pair<Value, utils::ValueType> {std::move(value), value_type});
return values_.size() - 1;
}
template<typename T>
std::optional<T*> GetType(utils::IdType value_id) {
if (!std::holds_alternative<T>(values_.at(value_id).first.value)) {
return std::nullopt;
}
return &std::get<T>(values_.at(value_id).first.value);
}
Value* GetAnyType(utils::IdType value_id) {
return &values_.at(value_id).first;
}
utils::ValueType GetValueType(utils::IdType value_id) {
return values_.at(value_id).second;
}
private:
std::vector<std::pair<Value, utils::ValueType>> values_;
};
} // namespace info::value