mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2026-01-25 13:07:13 +00:00
type_check_visitor first iteration, value, execution_visitor started
This commit is contained in:
parent
173d50672a
commit
890bd90eba
22 changed files with 481 additions and 452 deletions
Binary file not shown.
|
|
@ -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
134
include/execute_visitor.hpp
Normal 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
|
||||
|
|
@ -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_;
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
143
include/values.hpp
Normal 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
|
||||
Loading…
Add table
Add a link
Reference in a new issue