mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
better global_info API, better const/var/static handling, const typeclass requirements, fixes
This commit is contained in:
parent
047ead6fa3
commit
4f54bb4bd7
15 changed files with 381 additions and 213 deletions
|
|
@ -98,7 +98,7 @@ struct Namespace {
|
|||
|
||||
utils::IdType parent_namespace;
|
||||
|
||||
std::optional<utils::IsConstModifier> modifier; // modifier => variable namespace
|
||||
utils::ClassInternalsModifier modifier;
|
||||
std::string type_name;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -23,35 +23,35 @@ inline void PrintPosition(std::ostream& out,
|
|||
inline void HandleParsingError(const std::string& message,
|
||||
std::pair<size_t, size_t> start_position,
|
||||
std::pair<size_t, size_t> end_position) {
|
||||
std::cout << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cout, start_position, end_position);
|
||||
std::cout << ".\n";
|
||||
std::cerr << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cerr, start_position, end_position);
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleGeneralError(const std::string& message) {
|
||||
std::cout << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n";
|
||||
std::cerr << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleInternalError(const std::string& message, const std::string& place) {
|
||||
std::cout << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at " << place << ".\n";
|
||||
std::cerr << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at " << place << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleTypecheckError(const std::string& message,
|
||||
const interpreter::tokens::BaseNode& node) {
|
||||
std::cout << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cout, node.start_position, node.end_position);
|
||||
std::cout << ".\n";
|
||||
std::cerr << "\x1b[1;31mTypecheck Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cerr, node.start_position, node.end_position);
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleRuntimeError(const std::string& message,
|
||||
const interpreter::tokens::BaseNode& node) {
|
||||
std::cout << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cout, node.start_position, node.end_position);
|
||||
std::cout << ".\n";
|
||||
std::cerr << "\x1b[1;31mRuntime Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cerr, node.start_position, node.end_position);
|
||||
std::cerr << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#pragma once
|
||||
|
||||
#include <asm-generic/errno.h>
|
||||
#include <string>
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
|
|
@ -8,6 +7,7 @@
|
|||
// for clangd
|
||||
#include "definitions.hpp"
|
||||
#include "interpreter_tree.hpp"
|
||||
#include "typeclass_graph.hpp"
|
||||
#include "utils.hpp"
|
||||
|
||||
namespace info {
|
||||
|
|
@ -40,11 +40,11 @@ public:
|
|||
void AddImport(definition::Import&& import_info, const std::optional<std::string>& name = std::nullopt);
|
||||
|
||||
void AddEnterNamespace(const std::string& name,
|
||||
std::optional<utils::IsConstModifier> modifier,
|
||||
utils::ClassInternalsModifier modifier,
|
||||
const interpreter::tokens::BaseNode& base_node);
|
||||
|
||||
void EnterNamespace(const std::string& name,
|
||||
std::optional<utils::IsConstModifier> modifier);
|
||||
utils::ClassInternalsModifier modifier);
|
||||
|
||||
void ExitNamespace();
|
||||
|
||||
|
|
@ -77,28 +77,117 @@ public:
|
|||
utils::IdType AddPartition(const std::vector<std::string>& path, // including name
|
||||
interpreter::tokens::PartitionStatement* node);
|
||||
|
||||
std::optional<utils::IdType> FindNamespace(const std::optional<std::vector<std::string>>& path);
|
||||
std::optional<utils::IdType> FindNamespaceId(const std::optional<std::vector<std::string>>& path);
|
||||
|
||||
std::optional<utils::IdType> FindFunction(const std::optional<std::vector<std::string>>& path,
|
||||
std::optional<utils::IdType> FindFunctionId(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& name);
|
||||
|
||||
std::optional<utils::IdType> FindMethod(const std::optional<std::vector<std::string>>& path,
|
||||
std::optional<utils::IdType> FindMethodId(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type,
|
||||
const std::string& name,
|
||||
utils::IsConstModifier modifier);
|
||||
|
||||
std::optional<utils::IdType> FindType(const std::optional<std::vector<std::string>>& path,
|
||||
std::optional<utils::IdType> FindTypeId(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type);
|
||||
|
||||
std::optional<utils::IdType> FindLocalType(const std::string& type);
|
||||
std::optional<utils::IdType> FindLocalTypeId(const std::string& type);
|
||||
|
||||
std::optional<utils::IdType> FindAbstractType(const std::string& abstract_type);
|
||||
std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
|
||||
|
||||
std::optional<utils::IdType> FindTypeclass(const std::string& typeclass);
|
||||
std::optional<utils::IdType> FindTypeclassId(const std::string& typeclass);
|
||||
|
||||
std::optional<utils::IdType> FindConstructor(const std::optional<std::vector<std::string>>& path,
|
||||
std::optional<utils::IdType> FindConstructorId(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& constructor);
|
||||
|
||||
std::optional<definition::Namespace*> FindNamespace(const std::optional<std::vector<std::string>>& path) {
|
||||
std::optional<utils::IdType> id = FindNamespaceId(path);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetNamespaceInfo(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Function*> FindFunction(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& name) {
|
||||
std::optional<utils::IdType> id = FindFunctionId(path, name);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetFunctionInfo(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Function*> FindMethod(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type,
|
||||
const std::string& name,
|
||||
utils::IsConstModifier modifier) {
|
||||
std::optional<utils::IdType> id = FindFunctionId(path, name);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetFunctionInfo(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Type*> FindAnyType(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type) {
|
||||
std::optional<utils::IdType> id = FindTypeId(path, type);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetAnyTypeInfo(id.value());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<T*> FindType(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type) {
|
||||
std::optional<utils::IdType> id = FindTypeId(path, type);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return global_info_.GetTypeInfo<T>(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Type*> FindAnyLocalType(const std::string& type) {
|
||||
std::optional<utils::IdType> id = FindLocalTypeId(type);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetAnyTypeInfo(id.value());
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<T*> FindLocalType(const std::string& type) {
|
||||
std::optional<utils::IdType> id = FindLocalTypeId(type);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return global_info_.GetTypeInfo<T>(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::AbstractType*> FindAbstractType(const std::string& abstract_type) {
|
||||
std::optional<utils::IdType> id = FindAbstractTypeId(abstract_type);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetAbstractTypeInfo(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Typeclass*> FindTypeclass(const std::string& typeclass) {
|
||||
std::optional<utils::IdType> id = FindTypeclassId(typeclass);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetTypeclassInfo(id.value());
|
||||
}
|
||||
|
||||
std::optional<definition::Constructor*> FindConstructor(const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& constructor) {
|
||||
std::optional<utils::IdType> id = FindConstructorId(path, constructor);
|
||||
if (!id.has_value()) {
|
||||
return std::nullopt;
|
||||
}
|
||||
return &global_info_.GetConstructorInfo(id.value());
|
||||
}
|
||||
|
||||
NamespaceVisitor CreateVisitor() {
|
||||
return global_info_.CreateVisitor();
|
||||
}
|
||||
|
|
@ -107,6 +196,10 @@ public:
|
|||
return &global_info_;
|
||||
}
|
||||
|
||||
TypeclassGraph* GetTypeclassGraph() {
|
||||
return global_info_.GetTypeclassGraph();
|
||||
}
|
||||
|
||||
const std::vector<std::string>& GetCurrentPath() {
|
||||
return current_path_;
|
||||
}
|
||||
|
|
@ -128,7 +221,7 @@ public:
|
|||
const std::vector<std::string>& path);
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>*
|
||||
ChooseNamespaces(std::optional<utils::IsConstModifier> modifier,
|
||||
ChooseNamespaces(utils::ClassInternalsModifier modifier,
|
||||
utils::IdType namespace_id);
|
||||
private:
|
||||
GlobalInfo& global_info_;
|
||||
|
|
@ -145,6 +238,10 @@ public:
|
|||
return functions_.at(id);
|
||||
}
|
||||
|
||||
definition::Type& GetAnyTypeInfo(utils::IdType id) {
|
||||
return types_.at(id);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
std::optional<T*> GetTypeInfo(utils::IdType id) {
|
||||
if (!std::holds_alternative<T>(types_.at(id).type)) {
|
||||
|
|
@ -153,8 +250,8 @@ public:
|
|||
return &std::get<T>(types_[id].type);
|
||||
}
|
||||
|
||||
definition::Type& GetAnyTypeInfo(utils::IdType id) {
|
||||
return types_.at(id);
|
||||
definition::AbstractType& GetAbstractTypeInfo(utils::IdType id) {
|
||||
return abstract_types_.at(id);
|
||||
}
|
||||
|
||||
definition::Typeclass& GetTypeclassInfo(utils::IdType id) {
|
||||
|
|
@ -190,6 +287,10 @@ public:
|
|||
return ans;
|
||||
}
|
||||
|
||||
TypeclassGraph* GetTypeclassGraph() {
|
||||
return &typeclass_graph_;
|
||||
}
|
||||
|
||||
private:
|
||||
const utils::IdType GlobalNamespaceId = 0;
|
||||
|
||||
|
|
@ -209,6 +310,8 @@ private:
|
|||
|
||||
std::vector<definition::Import> imports_;
|
||||
std::unordered_map<std::string, definition::Import> usages_;
|
||||
|
||||
TypeclassGraph typeclass_graph_;
|
||||
};
|
||||
|
||||
} // namespace info
|
||||
|
|
|
|||
|
|
@ -240,7 +240,6 @@ struct ParametrizedTypeclass;
|
|||
|
||||
struct ParametrizedType;
|
||||
|
||||
// Comments [IGNORE] -----------------
|
||||
// Identifiers, constants, etc. -----------------
|
||||
|
||||
using Pattern = std::variant<
|
||||
|
|
@ -272,7 +271,7 @@ struct NamespaceSources {
|
|||
struct Namespace {
|
||||
BaseNode base;
|
||||
|
||||
std::optional<utils::IsConstModifier> modifier; // modifier => variable namespace
|
||||
utils::ClassInternalsModifier modifier;
|
||||
TypeIdentifier type;
|
||||
NamespaceSources scope;
|
||||
|
||||
|
|
@ -355,8 +354,8 @@ struct TypeclassDefinitionStatement {
|
|||
BaseNode base;
|
||||
|
||||
std::unique_ptr<TypeDefinition> definition;
|
||||
std::vector<std::unique_ptr<FunctionDeclaration>> method_requirements;
|
||||
std::vector<std::unique_ptr<FunctionDeclaration>> function_requirements;
|
||||
std::vector<std::pair<utils::ClassInternalsModifier,
|
||||
std::unique_ptr<FunctionDeclaration>>> requirements;
|
||||
|
||||
utils::IdType typeclass_id_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@
|
|||
|
||||
#include <algorithm>
|
||||
#include <string>
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <unordered_map>
|
||||
|
||||
// for calngd
|
||||
|
|
@ -22,7 +19,12 @@ public:
|
|||
|
||||
struct ParametrizedTypeclass {
|
||||
std::string typeclass;
|
||||
// TODO: parameters
|
||||
std::vector<std::string> parameters; // only abstract types from owner
|
||||
};
|
||||
|
||||
struct AnnotatedType {
|
||||
std::string name;
|
||||
std::vector<ParametrizedTypeclass> requirements;
|
||||
};
|
||||
|
||||
struct TypeclassVertex {
|
||||
|
|
@ -31,16 +33,48 @@ public:
|
|||
std::unordered_map<std::string, MethodInfo> methods;
|
||||
std::vector<ParametrizedTypeclass> dependencies;
|
||||
|
||||
// TODO: std::vector<std::pair<std::string, std::vector<ParametrizedTypeclass>>> parameters;
|
||||
std::vector<AnnotatedType> parameters;
|
||||
};
|
||||
|
||||
std::optional<utils::IdType> AddTypeclass(
|
||||
// // TODO: write + rewrite
|
||||
// std::optional<utils::IdType> AddTypeclassByNode(interpreter::tokens::TypeclassDefinitionStatement* node) {
|
||||
// std::string name = node->definition->type->type;
|
||||
// std::vector<ParametrizedTypeclass> dependencies;
|
||||
// // std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>> function_declarations;
|
||||
// // std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>> function_definitions;
|
||||
// // std::vector<AnnotatedType> parameters;
|
||||
//
|
||||
// for (auto& dependency_node : node->definition->type->typeclasses) {
|
||||
// ParametrizedTypeclass dependency;
|
||||
// dependency.typeclass = dependency_node->typeclass;
|
||||
// for (auto& dependency_parameter_node : dependency_node->parameters) { // TODO: all types, etc.
|
||||
// dependency.parameters.push_back(dependency_parameter_node->type.type);
|
||||
// if (dependency_parameter_node->type_id_.has_value()) { // TODO: more checks
|
||||
// error_handling::HandleInternalError("Typeclasses with non-abstract parameters unimplemented",
|
||||
// "TypeclassGraph.AddTypeclassByDefinition");
|
||||
// }
|
||||
// }
|
||||
// dependencies.push_back(dependency);
|
||||
// }
|
||||
//
|
||||
// // TODO
|
||||
//
|
||||
// return AddTypeclass(name,
|
||||
// node,
|
||||
// dependencies,
|
||||
// function_declarations,
|
||||
// function_definitions,
|
||||
// parameters);
|
||||
// }
|
||||
|
||||
std::optional<utils::IdType> AddTypeclass( // move parameters ??
|
||||
const std::string& name,
|
||||
interpreter::tokens::TypeclassDefinitionStatement* definition,
|
||||
const std::vector<ParametrizedTypeclass>& dependencies,
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>>& method_declarations,
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>>& method_definitions) {
|
||||
for (auto& method : method_declarations) {
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDeclaration*>>& function_declarations,
|
||||
const std::vector<std::pair<std::string, interpreter::tokens::FunctionDefinition*>>& function_definitions,
|
||||
const std::vector<AnnotatedType>& parameters) {
|
||||
for (auto& method : function_declarations) {
|
||||
if (method_to_typeclass_.count(method.first) != 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -53,14 +87,15 @@ public:
|
|||
typeclass.name = name;
|
||||
typeclass.definition = definition;
|
||||
typeclass.dependencies = dependencies;
|
||||
typeclass.parameters = parameters;
|
||||
|
||||
for (auto& method : method_declarations) {
|
||||
for (auto& method : function_declarations) {
|
||||
method_to_typeclass_[method.first] = typeclasses_.size();
|
||||
typeclass.methods[method.first].declaration = method.second;
|
||||
}
|
||||
name_to_typeclass_[name] = typeclasses_.size() - 1;
|
||||
|
||||
for (auto& method : method_definitions) {
|
||||
for (auto& method : function_definitions) {
|
||||
typeclass.methods[method.first].definition = method.second;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ const size_t MaxOperatorPrecedence = 4;
|
|||
|
||||
enum class ReferenceModifier { Reference = 0, UniqueReference = 1, Dereference = 2 };
|
||||
enum class IsConstModifier { Const = 0, Var = 1 };
|
||||
enum class ClassInternalsModifier { Static = 0, Const = 1, Var = 2};
|
||||
enum class ClassModifier { Struct = 0, Class = 1 };
|
||||
enum class AssignmentModifier { Assign = 0, Move = 1 };
|
||||
enum class AliasModifier { Alias = 0, Type = 1, Let = 2 };
|
||||
|
|
@ -33,8 +34,21 @@ inline ValueType IsConstModifierToValueType(IsConstModifier modifier) {
|
|||
case IsConstModifier::Var:
|
||||
return ValueType::Var;
|
||||
}
|
||||
// unreachable
|
||||
exit(1);
|
||||
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
inline ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
|
||||
switch (modifier) {
|
||||
case ClassInternalsModifier::Const:
|
||||
return ValueType::Const;
|
||||
case ClassInternalsModifier::Var:
|
||||
return ValueType::Var;
|
||||
case ClassInternalsModifier::Static:
|
||||
throw std::bad_cast(); // ??
|
||||
}
|
||||
|
||||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
|
|
@ -214,32 +228,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
|
||||
|
|
|
|||
|
|
@ -1 +1 @@
|
|||
Subproject commit 3610504b4ce142fe30f47851709fef6bc2fc53f1
|
||||
Subproject commit 630eced5368dca21af5eb2b6bea7f90651ce5e30
|
||||
|
|
@ -58,12 +58,14 @@ void BuildVisitor::Visit(Namespace* node) {
|
|||
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
|
||||
std::string modifier = parse_node.NthChild(1).GetValue();
|
||||
if (modifier == "const") {
|
||||
node->modifier = utils::IsConstModifier::Const;
|
||||
node->modifier = utils::ClassInternalsModifier::Const;
|
||||
} else if (modifier == "var") {
|
||||
node->modifier = utils::IsConstModifier::Var;
|
||||
node->modifier = utils::ClassInternalsModifier::Var;
|
||||
} else {
|
||||
error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace");
|
||||
}
|
||||
} else {
|
||||
node->modifier = utils::ClassInternalsModifier::Static;
|
||||
}
|
||||
|
||||
node->type = parse_node.ChildByFieldName("type").GetValue();
|
||||
|
|
@ -273,15 +275,26 @@ void BuildVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
|
||||
size_t child_count = parse_node.NamedChildCount();
|
||||
|
||||
if (child_count > 1) {
|
||||
node->requirements.reserve(child_count - 1);
|
||||
|
||||
for (size_t i = 0; i + 1 < child_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i + 1);
|
||||
if (current_node_.PreviousSibling().GetValue() != "var") {
|
||||
node->function_requirements.push_back(std::make_unique<FunctionDeclaration>());
|
||||
Visit(node->function_requirements.back().get());
|
||||
|
||||
std::string modifier_name = current_node_.PreviousSibling().GetValue();
|
||||
utils::ClassInternalsModifier modifier;
|
||||
if (modifier_name == "const") {
|
||||
modifier = utils::ClassInternalsModifier::Const;
|
||||
} else if (modifier_name == "var") {
|
||||
modifier = utils::ClassInternalsModifier::Var;
|
||||
} else {
|
||||
node->method_requirements.push_back(std::make_unique<FunctionDeclaration>());
|
||||
Visit(node->method_requirements.back().get());
|
||||
modifier = utils::ClassInternalsModifier::Static;
|
||||
}
|
||||
node->requirements.push_back({modifier,
|
||||
std::make_unique<FunctionDeclaration>()});
|
||||
Visit(node->requirements.back().second.get());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
|
|||
|
|
@ -135,17 +135,11 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
current_info_.reset();
|
||||
}
|
||||
|
||||
namespace_visitor_.AddEnterNamespace(type_name, std::nullopt, node->base);
|
||||
for (size_t i = 0; i < node->function_requirements.size(); ++i) {
|
||||
Visit(node->function_requirements[i].get());
|
||||
}
|
||||
for (size_t i = 0; i < node->requirements.size(); ++i) {
|
||||
namespace_visitor_.AddEnterNamespace(type_name, node->requirements[i].first, node->base);
|
||||
Visit(node->requirements[i].second.get());
|
||||
namespace_visitor_.ExitNamespace();
|
||||
|
||||
namespace_visitor_.AddEnterNamespace(type_name, utils::IsConstModifier::Var, node->base);
|
||||
for (size_t i = 0; i < node->method_requirements.size(); ++i) {
|
||||
Visit(node->method_requirements[i].get());
|
||||
}
|
||||
namespace_visitor_.ExitNamespace();
|
||||
|
||||
info.node = node;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ void GlobalInfo::NamespaceVisitor::AddImport(definition::Import&& import_info,
|
|||
}
|
||||
|
||||
void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
||||
std::optional<utils::IsConstModifier> modifier,
|
||||
utils::ClassInternalsModifier modifier,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
if (type::ToInternalType(name).has_value()) {
|
||||
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
|
||||
|
|
@ -38,7 +38,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
}
|
||||
definition::Namespace* namespace_info = &global_info_.namespaces_[id];
|
||||
|
||||
if (modifier.has_value()) {
|
||||
if (modifier != utils::ClassInternalsModifier::Static) {
|
||||
namespace_info->modifier = modifier;
|
||||
}
|
||||
|
||||
|
|
@ -51,7 +51,7 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
}
|
||||
|
||||
void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name,
|
||||
std::optional<utils::IsConstModifier> modifier) {
|
||||
utils::ClassInternalsModifier modifier) {
|
||||
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
auto current_namespaces = ChooseNamespaces(modifier, i);
|
||||
auto namespace_iter = current_namespaces->find(name);
|
||||
|
|
@ -222,6 +222,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
|
|||
return id;
|
||||
}
|
||||
|
||||
// TODO: which info needed ??
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass,
|
||||
definition::Typeclass&& typeclass_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
|
|
@ -237,6 +238,12 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
|
|||
global_info_.name_to_typeclass_[typeclass] = id;
|
||||
global_info_.typeclasses_.push_back(std::move(typeclass_info));
|
||||
|
||||
definition::Typeclass& moved_typeclass_info = global_info_.typeclasses_.back();
|
||||
|
||||
// global_info_.typeclass_graph_.AddTypeclassByNode(moved_typeclass_info.node); // TODO
|
||||
error_handling::HandleInternalError("Typeclasses are not implemented properly yet",
|
||||
"GlobalInfo.NamespaceVisitor.AddTypeclass");
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
|
@ -282,14 +289,14 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddPartition(const std::vector<std::
|
|||
return id;
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespace(const std::optional<std::vector<std::string>>& path) {
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceId(const std::optional<std::vector<std::string>>& path) {
|
||||
return FindSomething<utils::IdType>(path,
|
||||
[] (utils::IdType current_namespace) -> std::optional<utils::IdType> {
|
||||
return current_namespace;
|
||||
});
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction(
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunctionId(
|
||||
const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& name) {
|
||||
return FindSomething<utils::IdType>(path,
|
||||
|
|
@ -304,7 +311,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindFunction(
|
|||
});
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod(
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethodId(
|
||||
const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type,
|
||||
const std::string& name,
|
||||
|
|
@ -335,7 +342,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindMethod(
|
|||
});
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType(
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeId(
|
||||
const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& type) {
|
||||
return FindSomething<utils::IdType>(path,
|
||||
|
|
@ -350,7 +357,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindType(
|
|||
});
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const std::string& type) {
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalTypeId(const std::string& type) {
|
||||
auto type_id_iter = global_info_.namespaces_[namespace_stack_.back()].types.find(type);
|
||||
|
||||
if (type_id_iter != global_info_.namespaces_[namespace_stack_.back()].types.end()) {
|
||||
|
|
@ -360,7 +367,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalType(const s
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(const std::string& abstract_type) {
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& abstract_type) {
|
||||
auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type);
|
||||
|
||||
if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) {
|
||||
|
|
@ -370,7 +377,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractType(cons
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const std::string& typeclass) {
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) {
|
||||
auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass);
|
||||
|
||||
if (typeclass_id_iter != global_info_.name_to_typeclass_.end()) {
|
||||
|
|
@ -380,7 +387,7 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclass(const s
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructor(
|
||||
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindConstructorId(
|
||||
const std::optional<std::vector<std::string>>& path,
|
||||
const std::string& constructor) {
|
||||
return FindSomething<utils::IdType>(path,
|
||||
|
|
@ -439,17 +446,19 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
|
|||
}
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>*
|
||||
GlobalInfo::NamespaceVisitor::ChooseNamespaces(std::optional<utils::IsConstModifier> modifier,
|
||||
GlobalInfo::NamespaceVisitor::ChooseNamespaces(utils::ClassInternalsModifier modifier,
|
||||
utils::IdType namespace_id) {
|
||||
std::unordered_map<std::string, utils::IdType>* current_namespaces = nullptr;
|
||||
if (modifier.has_value()) {
|
||||
if (modifier.value() == utils::IsConstModifier::Const) {
|
||||
switch (modifier) {
|
||||
case utils::ClassInternalsModifier::Const:
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces;
|
||||
} else {
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Var:
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Static:
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
|
||||
break;
|
||||
}
|
||||
|
||||
return current_namespaces;
|
||||
|
|
|
|||
|
|
@ -12,11 +12,11 @@ namespace interpreter {
|
|||
void LinkSymbolsVisitor::Visit(Namespace* node) {
|
||||
// Visitor::Visit(&node->type); // not needed
|
||||
|
||||
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalType(node->type);
|
||||
std::optional<utils::IdType> maybe_type = namespace_visitor_.FindLocalTypeId(node->type);
|
||||
|
||||
std::optional<utils::IdType> maybe_typeclass;
|
||||
if (namespace_visitor_.GetCurrentPath().size() == 0) {
|
||||
maybe_typeclass = namespace_visitor_.FindTypeclass(node->type);
|
||||
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
|
||||
}
|
||||
|
||||
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
|
||||
|
|
@ -49,8 +49,8 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
path.push_back(path_type.type);
|
||||
}
|
||||
|
||||
node->type_id_ = namespace_visitor_.FindType(path, node->type.type);
|
||||
node->constructor_id_ = namespace_visitor_.FindConstructor(path, node->type.type);
|
||||
node->type_id_ = namespace_visitor_.FindTypeId(path, node->type.type);
|
||||
node->constructor_id_ = namespace_visitor_.FindConstructorId(path, node->type.type);
|
||||
|
||||
// internal type
|
||||
if (info::type::ToInternalType(node->type.type).has_value()) {
|
||||
|
|
@ -91,9 +91,9 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
node->type.type_id_ = node->type_id_.value();
|
||||
}
|
||||
|
||||
std::optional<utils::IdType> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
|
||||
std::optional<info::definition::Namespace*> maybe_type_namespace = namespace_visitor_.FindNamespace(path);
|
||||
if (maybe_type_namespace.has_value()) {
|
||||
info::definition::Namespace* type_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(maybe_type_namespace.value());
|
||||
info::definition::Namespace* type_namespace = maybe_type_namespace.value();
|
||||
|
||||
for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) {
|
||||
info::definition::Namespace* parent_namespace = &namespace_visitor_.GetGlobalInfo()->GetNamespaceInfo(type_namespace->parent_namespace);
|
||||
|
|
@ -111,7 +111,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) { // TODO: check
|
|||
// Typeclass
|
||||
|
||||
void LinkSymbolsVisitor::Visit(ParametrizedTypeclass* node) { // TODO: check
|
||||
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclass(node->typeclass);
|
||||
std::optional<utils::IdType> maybe_typeclass = namespace_visitor_.FindTypeclassId(node->typeclass);
|
||||
|
||||
if (maybe_typeclass.has_value()) {
|
||||
node->typeclass_id_ = maybe_typeclass.value();
|
||||
|
|
|
|||
|
|
@ -25,15 +25,15 @@ void PrintVisitor::Visit(NamespaceSources* node) {
|
|||
|
||||
void PrintVisitor::Visit(Namespace* node) {
|
||||
out_ << "[Namespace] ";
|
||||
if (node->modifier.has_value()) {
|
||||
switch (node->modifier.value()) {
|
||||
case utils::IsConstModifier::Const:
|
||||
switch (node->modifier) {
|
||||
case utils::ClassInternalsModifier::Const:
|
||||
out_ << "const ";
|
||||
break;
|
||||
case utils::IsConstModifier::Var:
|
||||
case utils::ClassInternalsModifier::Var:
|
||||
out_ << "var ";
|
||||
break;
|
||||
}
|
||||
case utils::ClassInternalsModifier::Static:
|
||||
break;
|
||||
}
|
||||
Visit(&node->type);
|
||||
out_ << "{\n";
|
||||
|
|
@ -157,20 +157,22 @@ void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|||
void PrintVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
out_ << "[Typeclass] (";
|
||||
Visit(node->definition.get());
|
||||
if (!node->function_requirements.empty()) {
|
||||
if (!node->requirements.empty()) {
|
||||
out_ << ") : (\n";
|
||||
}
|
||||
for (auto& requirement : node->function_requirements) {
|
||||
for (auto& requirement : node->requirements) {
|
||||
out_ << "& ";
|
||||
Visit(requirement.get());
|
||||
out_ << "\n";
|
||||
switch (requirement.first) {
|
||||
case utils::ClassInternalsModifier::Const:
|
||||
out_ << "const ";
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Var:
|
||||
out_ << "var ";
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Static:
|
||||
break;
|
||||
}
|
||||
if (!node->method_requirements.empty()) {
|
||||
out_ << ") : (\n";
|
||||
}
|
||||
for (auto& requirement : node->method_requirements) {
|
||||
out_ << "& var ";
|
||||
Visit(requirement.get());
|
||||
Visit(requirement.second.get());
|
||||
out_ << "\n";
|
||||
}
|
||||
out_ << ")\n";
|
||||
|
|
|
|||
|
|
@ -38,9 +38,9 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()};
|
||||
utils::IdType abstract_type = context_manager_.AddValue(
|
||||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
|
||||
IsConstModifierToValueType(node->modifier.value()));
|
||||
ClassInternalsModifierToValueType(node->modifier));
|
||||
|
||||
if (node->modifier.has_value()) {
|
||||
if (node->modifier != utils::ClassInternalsModifier::Static) {
|
||||
context_manager_.EnterVariableContext(utils::ClassInternalVarName,
|
||||
abstract_type);
|
||||
} else {
|
||||
|
|
@ -48,7 +48,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
}
|
||||
context_manager_.DefineLocalType(node->type, abstract_type);
|
||||
} else if (node->link_type_id_.has_value()) {
|
||||
if (node->modifier.has_value()) {
|
||||
if (node->modifier != utils::ClassInternalsModifier::Static) {
|
||||
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
|
||||
|
||||
if (!maybe_type_info.has_value()) {
|
||||
|
|
@ -64,7 +64,7 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
current_type_,
|
||||
maybe_type_info.value()->modifier,
|
||||
context_manager_.GetValueManager()),
|
||||
IsConstModifierToValueType(node->modifier.value())));
|
||||
ClassInternalsModifierToValueType(node->modifier)));
|
||||
} else {
|
||||
context_manager_.EnterContext();
|
||||
}
|
||||
|
|
@ -599,7 +599,7 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
|||
// TODO: better structure
|
||||
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
||||
// TODO: Check, that type is not abstract ??
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunctionId(std::nullopt, node->operator_name);
|
||||
info::definition::Function* operator_info = nullptr;
|
||||
|
||||
node->is_method_ = false;
|
||||
|
|
@ -621,13 +621,13 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
|
||||
std::string left_type_name = maybe_left_type_info.value()->type.type;
|
||||
|
||||
auto maybe_const_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
||||
auto maybe_const_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
|
||||
left_type_name,
|
||||
node->operator_name,
|
||||
utils::IsConstModifier::Const);
|
||||
|
||||
if (left_value_type != utils::ValueType::Const) {
|
||||
maybe_operator_id = namespace_visitor_.FindMethod(std::nullopt,
|
||||
maybe_operator_id = namespace_visitor_.FindMethodId(std::nullopt,
|
||||
left_type_name,
|
||||
node->operator_name,
|
||||
utils::IsConstModifier::Var);
|
||||
|
|
@ -795,14 +795,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
path.push_back(type_expression.type.type);
|
||||
|
||||
maybe_function_id = namespace_visitor_.FindFunction(path, node->name);
|
||||
maybe_function_id = namespace_visitor_.FindFunctionId(path, node->name);
|
||||
|
||||
CollectTypeExpressionContext(*std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()), context);
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
} else {
|
||||
maybe_function_id = namespace_visitor_.FindFunction(std::nullopt, node->name);
|
||||
maybe_function_id = namespace_visitor_.FindFunctionId(std::nullopt, node->name);
|
||||
}
|
||||
|
||||
if (!maybe_function_id.has_value()) {
|
||||
|
|
|
|||
|
|
@ -43,15 +43,15 @@ void TypedPrintVisitor::Visit(Namespace* node) {
|
|||
}
|
||||
|
||||
out_ << "] ";
|
||||
if (node->modifier.has_value()) {
|
||||
switch (node->modifier.value()) {
|
||||
case utils::IsConstModifier::Const:
|
||||
switch (node->modifier) {
|
||||
case utils::ClassInternalsModifier::Const:
|
||||
out_ << "const ";
|
||||
break;
|
||||
case utils::IsConstModifier::Var:
|
||||
case utils::ClassInternalsModifier::Var:
|
||||
out_ << "var ";
|
||||
break;
|
||||
}
|
||||
case utils::ClassInternalsModifier::Static:
|
||||
break;
|
||||
}
|
||||
Visit(&node->type);
|
||||
out_ << "{\n";
|
||||
|
|
@ -218,20 +218,22 @@ void TypedPrintVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
|
||||
out_ << "] (";
|
||||
Visit(node->definition.get());
|
||||
if (!node->function_requirements.empty()) {
|
||||
if (!node->requirements.empty()) {
|
||||
out_ << ") : (\n";
|
||||
}
|
||||
for (auto& requirement : node->function_requirements) {
|
||||
for (auto& requirement : node->requirements) {
|
||||
out_ << "& ";
|
||||
Visit(requirement.get());
|
||||
out_ << "\n";
|
||||
switch (requirement.first) {
|
||||
case utils::ClassInternalsModifier::Const:
|
||||
out_ << "const ";
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Var:
|
||||
out_ << "var ";
|
||||
break;
|
||||
case utils::ClassInternalsModifier::Static:
|
||||
break;
|
||||
}
|
||||
if (!node->method_requirements.empty()) {
|
||||
out_ << ") : (\n";
|
||||
}
|
||||
for (auto& requirement : node->method_requirements) {
|
||||
out_ << "& var ";
|
||||
Visit(requirement.get());
|
||||
Visit(requirement.second.get());
|
||||
out_ << "\n";
|
||||
}
|
||||
out_ << ")\n";
|
||||
|
|
|
|||
|
|
@ -357,11 +357,8 @@ void Visitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|||
|
||||
void Visitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
Visit(node->definition.get());
|
||||
for (auto& function_requirement : node->function_requirements) {
|
||||
Visit(function_requirement.get());
|
||||
}
|
||||
for (auto& method_requirement : node->method_requirements) {
|
||||
Visit(method_requirement.get());
|
||||
for (auto& function_requirement : node->requirements) {
|
||||
Visit(function_requirement.second.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue