better global_info API, better const/var/static handling, const typeclass requirements, fixes

This commit is contained in:
ProgramSnail 2023-05-14 11:28:37 +03:00
parent 047ead6fa3
commit 4f54bb4bd7
15 changed files with 381 additions and 213 deletions

View file

@ -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;
};

View file

@ -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);
}

View file

@ -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,
const std::string& name);
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,
const std::string& type,
const std::string& name,
utils::IsConstModifier modifier);
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,
const std::string& type);
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

View file

@ -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_;
};

View file

@ -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;
}

View file

@ -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