mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
fixes, colored errors
This commit is contained in:
parent
4b4756b657
commit
047ead6fa3
11 changed files with 166 additions and 195 deletions
|
|
@ -79,8 +79,7 @@ struct Function {
|
|||
|
||||
struct Typeclass {
|
||||
std::vector<Parameter> parameters;
|
||||
std::vector<FunctionDeclaration> function_requirements;
|
||||
std::vector<FunctionDeclaration> method_requirements;
|
||||
interpreter::tokens::TypeclassDefinitionStatement* node;
|
||||
};
|
||||
|
||||
struct Import {
|
||||
|
|
|
|||
|
|
@ -23,38 +23,36 @@ 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 << "Parsing Error: " << message << " at ";
|
||||
std::cout << "\x1b[1;31mParsing Error:\x1b[0m " << message << " at ";
|
||||
PrintPosition(std::cout, start_position, end_position);
|
||||
std::cout << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleGeneralError(const std::string& message) {
|
||||
std::cout << "General Error: " << message << ".\n";
|
||||
std::cout << "\x1b[1;31mGeneral Error:\x1b[0m " << message << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleInternalError(const std::string& message, const std::string& place) {
|
||||
std::cout << "Internal Error: " << message << " at " << place << ".\n";
|
||||
std::cout << "\x1b[1;31mInternal Error:\x1b[0m " << message << " at " << place << ".\n";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleTypecheckError(const std::string& message,
|
||||
const interpreter::tokens::BaseNode& node) { // TODO: place in code
|
||||
std::cout << "Typecheck Error: " << message << " at ";
|
||||
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";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
inline void HandleRuntimeError(const std::string& message,
|
||||
const interpreter::tokens::BaseNode& node) { // TODO: place in code
|
||||
std::cout << "Runtime Error: " << message << " at ";
|
||||
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";
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// ...
|
||||
|
||||
} // namespace error_handling
|
||||
|
|
|
|||
|
|
@ -165,7 +165,7 @@ private:
|
|||
|
||||
utils::IdType current_value_;
|
||||
std::optional<LoopControlExpression> active_loop_control_expression_;
|
||||
std::optional<utils::IdType> return_value_; // TODO: work outside block ??
|
||||
std::optional<utils::IdType> returned_value_; // TODO: work outside block ??
|
||||
std::optional<utils::IsConstModifier> is_const_definition_;
|
||||
bool case_matched_;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -121,7 +121,6 @@ private:
|
|||
private:
|
||||
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
||||
|
||||
bool is_in_statement_ = false;
|
||||
std::any current_info_;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -51,10 +51,12 @@ public:
|
|||
void ToGlobalNamespace();
|
||||
|
||||
utils::IdType AddFunctionDeclaration(const std::string& name,
|
||||
definition::FunctionDeclaration&& function_declaration_info);
|
||||
definition::FunctionDeclaration&& function_declaration_info,
|
||||
const interpreter::tokens::BaseNode& base_node);
|
||||
|
||||
utils::IdType AddFunctionDefinition(const std::string& name,
|
||||
definition::FunctionDefinition&& function_definition_info);
|
||||
definition::FunctionDefinition&& function_definition_info,
|
||||
const interpreter::tokens::BaseNode& base_node);
|
||||
|
||||
utils::IdType AddType(const std::string& type,
|
||||
definition::Type&& type_info,
|
||||
|
|
@ -124,6 +126,10 @@ public:
|
|||
std::optional<utils::IdType> FindNamespaceIn(
|
||||
utils::IdType current_namespace,
|
||||
const std::vector<std::string>& path);
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>*
|
||||
ChooseNamespaces(std::optional<utils::IsConstModifier> modifier,
|
||||
utils::IdType namespace_id);
|
||||
private:
|
||||
GlobalInfo& global_info_;
|
||||
|
||||
|
|
@ -135,7 +141,6 @@ public:
|
|||
return NamespaceVisitor(*this);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
definition::Function& GetFunctionInfo(utils::IdType id) {
|
||||
return functions_.at(id);
|
||||
}
|
||||
|
|
@ -148,27 +153,22 @@ public:
|
|||
return &std::get<T>(types_[id].type);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
definition::Type& GetAnyTypeInfo(utils::IdType id) {
|
||||
return types_.at(id);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
definition::Typeclass& GetTypeclassInfo(utils::IdType id) {
|
||||
return typeclasses_.at(id);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
definition::Constructor& GetConstructorInfo(utils::IdType id) {
|
||||
return constructors_.at(id);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
definition::Namespace& GetNamespaceInfo(utils::IdType id) {
|
||||
return namespaces_.at(id);
|
||||
}
|
||||
|
||||
// remember about vector realloc
|
||||
PartitionInfo& GetPartitionInfo(utils::IdType id) {
|
||||
return partitions_.at(id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,3 @@
|
|||
#include <iostream>
|
||||
|
||||
#include <memory>
|
||||
#include <variant>
|
||||
|
||||
|
|
@ -63,6 +61,8 @@ void BuildVisitor::Visit(Namespace* node) {
|
|||
node->modifier = utils::IsConstModifier::Const;
|
||||
} else if (modifier == "var") {
|
||||
node->modifier = utils::IsConstModifier::Var;
|
||||
} else {
|
||||
error_handling::HandleInternalError("Can't parse namespace modifier", "BuildVisitor.Namespace");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -150,6 +150,8 @@ void BuildVisitor::Visit(VariableDefinitionStatement* node) {
|
|||
node->modifier = utils::IsConstModifier::Const;
|
||||
} else if (modifier == "var") {
|
||||
node->modifier = utils::IsConstModifier::Var;
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
||||
current_node_ = parse_node.ChildByFieldName("name");
|
||||
|
|
@ -163,6 +165,8 @@ void BuildVisitor::Visit(VariableDefinitionStatement* node) {
|
|||
node->assignment_modifier = utils::AssignmentModifier::Assign;
|
||||
} else if (assignment_modifier == "<-") {
|
||||
node->assignment_modifier = utils::AssignmentModifier::Move;
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
|
|||
|
|
@ -131,14 +131,18 @@ void ExecuteVisitor::Visit(Match* node) {
|
|||
context_manager_.ExitContext();
|
||||
}
|
||||
|
||||
if (statement_visited) {
|
||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
|
||||
utils::ValueType::Tmp);
|
||||
} else {
|
||||
current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
|
||||
utils::ValueType::Tmp);
|
||||
// --- instead of optional return value or throw runtime error ---
|
||||
// if (statement_visited) {
|
||||
// current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
// info::value::OptionalValue(current_value_, context_manager_.GetValueManager()),
|
||||
// utils::ValueType::Tmp);
|
||||
// } else {
|
||||
// current_value_ = context_manager_.AddValue<info::value::OptionalValue>(
|
||||
// info::value::OptionalValue(std::nullopt, context_manager_.GetValueManager()),
|
||||
// utils::ValueType::Tmp);
|
||||
// }
|
||||
if (!statement_visited) {
|
||||
error_handling::HandleRuntimeError("Value match option not found", node->base);
|
||||
}
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
|
@ -283,10 +287,11 @@ void ExecuteVisitor::Visit(Block* node) {
|
|||
context_manager_.EnterContext();
|
||||
|
||||
for (auto& statement : node->statements) {
|
||||
return_value_ = std::nullopt;
|
||||
returned_value_ = std::nullopt;
|
||||
Visitor::Visit(statement);
|
||||
if (return_value_.has_value()) {
|
||||
current_value_ = return_value_.value();
|
||||
if (returned_value_.has_value()) {
|
||||
current_value_ = returned_value_.value();
|
||||
returned_value_ = std::nullopt; // ??
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -457,7 +462,7 @@ void ExecuteVisitor::Visit(VariantExpression* node) {
|
|||
|
||||
void ExecuteVisitor::Visit(ReturnExpression* node) {
|
||||
Visitor::Visit(node->expression);
|
||||
return_value_ = current_value_;
|
||||
returned_value_ = current_value_;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,3 +1,5 @@
|
|||
#include <iostream>
|
||||
|
||||
// for clangd
|
||||
#include "../include/find_symbols_visitor.hpp"
|
||||
|
||||
|
|
@ -19,27 +21,19 @@ void FindSymbolsVisitor::Visit(Namespace* node) {
|
|||
|
||||
// TODO: add imported symbols to symbol table (global info)
|
||||
void FindSymbolsVisitor::Visit(ImportStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::Import info;
|
||||
info.module_name = node->module_name;
|
||||
info.symbols = node->symbols;
|
||||
namespace_visitor_.AddImport(std::move(info), node->name);
|
||||
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::Type info;
|
||||
|
||||
info::definition::AliasType alias_info;
|
||||
|
||||
alias_info.modifier = node->modifier;
|
||||
|
||||
// TODO: deduce parameter requirements
|
||||
|
||||
alias_info.parameters = node->parameters;
|
||||
alias_info.value.node = node->value.get();
|
||||
alias_info.node = node;
|
||||
|
|
@ -47,14 +41,9 @@ void FindSymbolsVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
info.type = std::move(alias_info);
|
||||
|
||||
node->type_id_ = namespace_visitor_.AddType(node->type, std::move(info), node->base);
|
||||
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
||||
bool was_in_statement = is_in_statement_;
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::FunctionDeclaration info;
|
||||
|
||||
info.parameters.resize(node->parameters.size());
|
||||
|
|
@ -71,17 +60,10 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|||
|
||||
info.node = node;
|
||||
|
||||
if (was_in_statement) {
|
||||
current_info_ = std::move(info);
|
||||
} else {
|
||||
node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info));
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
node->function_id_ = namespace_visitor_.AddFunctionDeclaration(node->name, std::move(info), node->base);
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::FunctionDefinition info;
|
||||
|
||||
auto definition = node->definition.get();
|
||||
|
|
@ -93,14 +75,10 @@ void FindSymbolsVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
|
||||
info.node = node;
|
||||
|
||||
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info));
|
||||
|
||||
is_in_statement_ = false;
|
||||
node->function_id_ = namespace_visitor_.AddFunctionDefinition(definition->name, std::move(info), node->base);
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::Type info;
|
||||
|
||||
auto definition = node->definition.get();
|
||||
|
|
@ -127,13 +105,9 @@ void FindSymbolsVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
info.type = std::move(any_type_info);
|
||||
|
||||
node->type_id_ = namespace_visitor_.AddType(type, std::move(info), node->base);
|
||||
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::AbstractType info;
|
||||
|
||||
Visit(node->type.get());
|
||||
|
|
@ -145,17 +119,15 @@ void FindSymbolsVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
|||
std::string type = info.type.type;
|
||||
|
||||
node->type_id_ = namespace_visitor_.AddAbstractType(type, std::move(info), node->base);
|
||||
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
info::definition::Typeclass info;
|
||||
|
||||
auto definition = node->definition.get();
|
||||
|
||||
std::string& type_name = definition->type.get()->type;
|
||||
|
||||
info.parameters.resize(definition->parameters.size());
|
||||
for (size_t i = 0; i < definition->parameters.size(); ++i) {
|
||||
Visit(definition->parameters[i].get());
|
||||
|
|
@ -163,32 +135,25 @@ void FindSymbolsVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
current_info_.reset();
|
||||
}
|
||||
|
||||
info.function_requirements.resize(node->function_requirements.size());
|
||||
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());
|
||||
info.function_requirements[i] = std::move(std::any_cast<info::definition::FunctionDeclaration>(current_info_));
|
||||
current_info_.reset();
|
||||
}
|
||||
namespace_visitor_.ExitNamespace();
|
||||
|
||||
info.method_requirements.resize(node->method_requirements.size());
|
||||
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());
|
||||
info.method_requirements[i] = std::move(std::any_cast<info::definition::FunctionDeclaration>(current_info_));
|
||||
current_info_.reset();
|
||||
}
|
||||
namespace_visitor_.ExitNamespace();
|
||||
|
||||
node->typeclass_id_ = namespace_visitor_.AddTypeclass(definition->type.get()->type, std::move(info), node->base);
|
||||
info.node = node;
|
||||
|
||||
is_in_statement_ = false;
|
||||
node->typeclass_id_ = namespace_visitor_.AddTypeclass(type_name, std::move(info), node->base);
|
||||
}
|
||||
|
||||
void FindSymbolsVisitor::Visit(PartitionStatement* node) {
|
||||
is_in_statement_ = true;
|
||||
|
||||
node->executable_id_ = namespace_visitor_.AddPartition(node->name.path, node);
|
||||
// TODO: typecheck error on same tests
|
||||
|
||||
is_in_statement_ = false;
|
||||
}
|
||||
|
||||
// Definition parts
|
||||
|
|
|
|||
|
|
@ -24,20 +24,22 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
error_handling::HandleTypecheckError("Can't define basic type namespace", base_node);
|
||||
}
|
||||
|
||||
size_t id = global_info_.namespaces_.size();
|
||||
auto current_namespaces = ChooseNamespaces(modifier, namespace_stack_.back());
|
||||
|
||||
utils::IdType id = 0;
|
||||
|
||||
auto namespace_iter = current_namespaces->find(name);
|
||||
if (namespace_iter == current_namespaces->end()) {
|
||||
id = global_info_.namespaces_.size();
|
||||
(*current_namespaces)[name] = id;
|
||||
global_info_.namespaces_.emplace_back();
|
||||
definition::Namespace* namespace_info = &global_info_.namespaces_.back();
|
||||
} else {
|
||||
id = namespace_iter->second;
|
||||
}
|
||||
definition::Namespace* namespace_info = &global_info_.namespaces_[id];
|
||||
|
||||
if (modifier.has_value()) {
|
||||
if (modifier.value() == utils::IsConstModifier::Const) {
|
||||
global_info_.namespaces_[namespace_stack_.back()].const_namespaces[name] = id;
|
||||
} else {
|
||||
global_info_.namespaces_[namespace_stack_.back()].var_namespaces[name] = id;
|
||||
}
|
||||
|
||||
namespace_info->modifier = modifier;
|
||||
} else {
|
||||
global_info_.namespaces_[namespace_stack_.back()].namespaces[name] = id;
|
||||
}
|
||||
|
||||
namespace_info->parent_namespace = namespace_stack_.back();
|
||||
|
|
@ -48,38 +50,17 @@ void GlobalInfo::NamespaceVisitor::AddEnterNamespace(const std::string& name,
|
|||
current_path_.push_back(name);
|
||||
}
|
||||
|
||||
// better code ??
|
||||
void GlobalInfo::NamespaceVisitor::EnterNamespace(const std::string& name,
|
||||
std::optional<utils::IsConstModifier> modifier) {
|
||||
|
||||
if (!modifier.has_value()) {
|
||||
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
auto namespace_iter = global_info_.namespaces_[namespace_stack_[i]].namespaces.find(name);
|
||||
if (namespace_iter != global_info_.namespaces_[namespace_stack_[i]].namespaces.end()) {
|
||||
auto current_namespaces = ChooseNamespaces(modifier, i);
|
||||
auto namespace_iter = current_namespaces->find(name);
|
||||
if (namespace_iter != current_namespaces->end()) {
|
||||
namespace_stack_.push_back(namespace_iter->second);
|
||||
current_path_.push_back(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (modifier.has_value() && modifier.value() == utils::IsConstModifier::Const) {
|
||||
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
auto const_namespace_iter = global_info_.namespaces_[namespace_stack_[i]].const_namespaces.find(name);
|
||||
if (const_namespace_iter != global_info_.namespaces_[namespace_stack_[i]].const_namespaces.end()) {
|
||||
namespace_stack_.push_back(const_namespace_iter->second);
|
||||
current_path_.push_back(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
auto var_namespace_iter = global_info_.namespaces_[namespace_stack_[i]].var_namespaces.find(name);
|
||||
if (var_namespace_iter != global_info_.namespaces_[namespace_stack_[i]].var_namespaces.end()) {
|
||||
namespace_stack_.push_back(var_namespace_iter->second);
|
||||
current_path_.push_back(name);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
error_handling::HandleInternalError("Can't find namespace " + name,
|
||||
"GlobalInfo.NamespaceVisitor.EnterNamespace");
|
||||
|
|
@ -105,49 +86,54 @@ void GlobalInfo::NamespaceVisitor::ToGlobalNamespace() {
|
|||
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDeclaration(
|
||||
const std::string& name,
|
||||
definition::FunctionDeclaration&& function_declaration_info) {
|
||||
|
||||
size_t id = 0;
|
||||
definition::FunctionDeclaration&& function_declaration_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
utils::IdType id = 0;
|
||||
|
||||
auto function_id_iter = global_info_.namespaces_[namespace_stack_.back()].functions.find(name);
|
||||
|
||||
if (function_id_iter == global_info_.namespaces_[namespace_stack_.back()].functions.end()) {
|
||||
id = global_info_.functions_.size();
|
||||
global_info_.namespaces_[namespace_stack_.back()].functions[name] = id;
|
||||
global_info_.functions_.emplace_back();
|
||||
global_info_.functions_.back().argument_count = function_declaration_info.argument_types.size(); // add return type
|
||||
global_info_.functions_.back().declaration = std::move(function_declaration_info);
|
||||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_.back().argument_count != function_declaration_info.argument_types.size()) {
|
||||
error_handling::HandleInternalError("Not same argument count in function definition and declaration",
|
||||
"GlobalInfo.NamespaceVisitor. AddFunctionDeclaration");
|
||||
if (global_info_.functions_[id].argument_count != function_declaration_info.argument_types.size()) {
|
||||
error_handling::HandleTypecheckError("Function declaration: not same argument count in function definition and declaration", base_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (global_info_.functions_[id].declaration.has_value()) {
|
||||
error_handling::HandleTypecheckError("Second function declaration", base_node);
|
||||
}
|
||||
global_info_.functions_[id].declaration = std::move(function_declaration_info);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(const std::string& name,
|
||||
definition::FunctionDefinition&& function_definition_info) {
|
||||
size_t id = 0;
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddFunctionDefinition(
|
||||
const std::string& name,
|
||||
definition::FunctionDefinition&& function_definition_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
utils::IdType id = 0;
|
||||
|
||||
auto function_id_iter = global_info_.namespaces_[namespace_stack_.back()].functions.find(name);
|
||||
|
||||
if (function_id_iter == global_info_.namespaces_[namespace_stack_.back()].functions.end()) {
|
||||
id = global_info_.functions_.size();
|
||||
global_info_.namespaces_[namespace_stack_.back()].functions[name] = id;
|
||||
global_info_.functions_.emplace_back();
|
||||
global_info_.functions_.back().argument_count = function_definition_info.argument_names.size() + 1;
|
||||
global_info_.functions_.back().definition = std::move(function_definition_info);
|
||||
} else {
|
||||
id = function_id_iter->second;
|
||||
if (global_info_.functions_.back().argument_count != function_definition_info.argument_names.size() + 1) {
|
||||
error_handling::HandleInternalError("Not same argument count in function definition and declaration", "GlobalInfo");
|
||||
if (global_info_.functions_[id].argument_count != function_definition_info.argument_names.size() + 1) {
|
||||
error_handling::HandleTypecheckError("Function definition: not same argument count in function definition and declaration", base_node);
|
||||
}
|
||||
}
|
||||
|
||||
if (global_info_.functions_[id].definition.has_value()) {
|
||||
error_handling::HandleTypecheckError("Second function definition", base_node);
|
||||
}
|
||||
global_info_.functions_[id].definition = std::move(function_definition_info);
|
||||
}
|
||||
|
||||
return id;
|
||||
}
|
||||
|
|
@ -161,7 +147,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
|
|||
error_handling::HandleTypecheckError("Can't redefine basic type", base_node);
|
||||
}
|
||||
|
||||
size_t id = 0;
|
||||
utils::IdType id = 0;
|
||||
|
||||
auto type_id_iter = global_info_.namespaces_[namespace_stack_.back()].types.find(type);
|
||||
|
||||
|
|
@ -224,7 +210,11 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
|
|||
error_handling::HandleTypecheckError("Can't redefine basic type as abstract type", base_node);
|
||||
}
|
||||
|
||||
if (!FindAbstractType(abstract_type).has_value()) {
|
||||
if (FindAbstractType(abstract_type).has_value()) {
|
||||
error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace",
|
||||
base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.abstract_types_.size();
|
||||
global_info_.name_to_abstract_type_[abstract_type] = id;
|
||||
global_info_.abstract_types_.push_back(std::move(abstract_type_info));
|
||||
|
|
@ -232,11 +222,6 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
|
|||
return id;
|
||||
}
|
||||
|
||||
error_handling::HandleTypecheckError("More then one abstract type with the same name in namespace",
|
||||
base_node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& typeclass,
|
||||
definition::Typeclass&& typeclass_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
|
|
@ -244,19 +229,17 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddTypeclass(const std::string& type
|
|||
error_handling::HandleTypecheckError("Can't redefine basic type as typeclass", base_node);
|
||||
}
|
||||
|
||||
if (!FindTypeclass(typeclass).has_value()) {
|
||||
size_t id = global_info_.typeclasses_.size();
|
||||
if (FindTypeclass(typeclass).has_value()) {
|
||||
error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.typeclasses_.size();
|
||||
global_info_.name_to_typeclass_[typeclass] = id;
|
||||
global_info_.typeclasses_.push_back(std::move(typeclass_info));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
error_handling::HandleTypecheckError("More then one typeclass with the same name in namespace", base_node);
|
||||
return 0;
|
||||
}
|
||||
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& constructor,
|
||||
definition::Constructor&& constructor_info,
|
||||
const interpreter::tokens::BaseNode& base_node) {
|
||||
|
|
@ -266,18 +249,17 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddConstructor(const std::string& co
|
|||
|
||||
auto constructor_id_iter = global_info_.namespaces_[namespace_stack_.back()].constructors.find(constructor);
|
||||
|
||||
if (constructor_id_iter == global_info_.namespaces_[namespace_stack_.back()].constructors.end()) {
|
||||
size_t id = global_info_.constructors_.size();
|
||||
if (constructor_id_iter != global_info_.namespaces_[namespace_stack_.back()].constructors.end()) {
|
||||
error_handling::HandleTypecheckError("More then one constructor with the same name in namespace", base_node);
|
||||
}
|
||||
|
||||
utils::IdType id = global_info_.constructors_.size();
|
||||
global_info_.namespaces_[namespace_stack_.back()].constructors[constructor] = id;
|
||||
global_info_.constructors_.push_back(std::move(constructor_info));
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
error_handling::HandleTypecheckError("More then one constructor with the same name in namespace", base_node);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
utils::IdType GlobalInfo::NamespaceVisitor::AddPartition(const std::vector<std::string>& path,
|
||||
interpreter::tokens::PartitionStatement* node) {
|
||||
PartitionInfo partition;
|
||||
|
|
@ -417,8 +399,8 @@ template<typename T>
|
|||
std::optional<T> GlobalInfo::NamespaceVisitor::FindSomething(
|
||||
const std::optional<std::vector<std::string>>& path,
|
||||
std::function<std::optional<T>(utils::IdType)> search_func) {
|
||||
for (ssize_t i = namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
utils::IdType current_namespace;
|
||||
for (ssize_t i = (ssize_t)namespace_stack_.size() - 1; i >= 0; --i) {
|
||||
utils::IdType current_namespace = 0;
|
||||
if (path.has_value()) {
|
||||
auto maybe_namespace = FindNamespaceIn(namespace_stack_[i], path.value());
|
||||
|
||||
|
|
@ -456,4 +438,21 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindNamespaceIn(
|
|||
return next_namespace;
|
||||
}
|
||||
|
||||
std::unordered_map<std::string, utils::IdType>*
|
||||
GlobalInfo::NamespaceVisitor::ChooseNamespaces(std::optional<utils::IsConstModifier> 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) {
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].const_namespaces;
|
||||
} else {
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].var_namespaces;
|
||||
}
|
||||
} else {
|
||||
current_namespaces = &global_info_.namespaces_[namespace_id].namespaces;
|
||||
}
|
||||
|
||||
return current_namespaces;
|
||||
}
|
||||
|
||||
} // namespace info
|
||||
|
|
|
|||
|
|
@ -33,7 +33,6 @@ void TypeCheckVisitor::Visit(NamespaceSources* node) {
|
|||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for class: const and var
|
||||
if (node->modifier.has_value()) {
|
||||
if (node->link_typeclass_id_.has_value()) { // TODO: think about typeclass
|
||||
|
||||
std::vector<utils::IdType> requirements {node->link_typeclass_id_.value()};
|
||||
|
|
@ -41,10 +40,15 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, node->type, requirements),
|
||||
IsConstModifierToValueType(node->modifier.value()));
|
||||
|
||||
if (node->modifier.has_value()) {
|
||||
context_manager_.EnterVariableContext(utils::ClassInternalVarName,
|
||||
abstract_type);
|
||||
} else {
|
||||
context_manager_.EnterContext();
|
||||
}
|
||||
context_manager_.DefineLocalType(node->type, abstract_type);
|
||||
} else if (node->link_type_id_.has_value()) {
|
||||
if (node->modifier.has_value()) {
|
||||
auto maybe_type_info = namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
|
||||
|
||||
if (!maybe_type_info.has_value()) {
|
||||
|
|
@ -61,18 +65,12 @@ void TypeCheckVisitor::Visit(Namespace* node) { // TODO: two var namespces for c
|
|||
maybe_type_info.value()->modifier,
|
||||
context_manager_.GetValueManager()),
|
||||
IsConstModifierToValueType(node->modifier.value())));
|
||||
}
|
||||
} else {
|
||||
if (node->link_typeclass_id_.has_value()) { // TODO
|
||||
error_handling::HandleTypecheckError("Typeclass can't have not variable namespace", node->base);
|
||||
}
|
||||
|
||||
context_manager_.EnterContext();
|
||||
}
|
||||
|
||||
if (node->link_type_id_.has_value()) {
|
||||
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
|
||||
error_handling::HandleTypecheckError("Namespaces of one type one in another", node->base);
|
||||
error_handling::HandleTypecheckError("Namespaces of one type are one in another", node->base);
|
||||
}
|
||||
type_namespaces_.insert(node->link_type_id_.value());
|
||||
}
|
||||
|
|
@ -413,14 +411,16 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO: move value to match
|
|||
}
|
||||
|
||||
if (!is_type_found) {
|
||||
type = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp);
|
||||
error_handling::HandleTypecheckError("Can't find match expression type", node->base);
|
||||
// type = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp);
|
||||
}
|
||||
|
||||
current_type_ = type;
|
||||
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
|
||||
utils::ValueType::Tmp);
|
||||
// --- instead of optional return value or throw runtime error ---
|
||||
// current_type_ = context_manager_.AddValue(
|
||||
// info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
|
||||
// utils::ValueType::Tmp);
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
||||
|
|
|
|||
|
|
@ -39,7 +39,7 @@ typeclass Eq =
|
|||
& var ( == ) : Eq -> Bool
|
||||
& var ( != ) : Eq -> Bool
|
||||
|
||||
namespace const Eq {
|
||||
namespace var Eq {
|
||||
def ( != ) : x = not: (self == x)
|
||||
}
|
||||
|
||||
|
|
@ -56,8 +56,12 @@ typeclass (Ord : #Eq) =
|
|||
& var ( >= ) : Ord -> Bool
|
||||
& var ( > ) : Ord -> Bool
|
||||
& var ( <= ) : Ord -> Bool
|
||||
& var min : Ord -> Ord
|
||||
& var max : Ord -> Ord
|
||||
|
||||
decl min ('A : #Ord) : 'A -> 'A -> 'A
|
||||
def min : x y = if x < y then x else y
|
||||
|
||||
decl max ('A : #Ord) : 'A -> 'A -> 'A
|
||||
def max : x y = if x < y then y else x
|
||||
|
||||
namespace var Ord {
|
||||
def compare : x =
|
||||
|
|
@ -68,8 +72,6 @@ namespace var Ord {
|
|||
def ( >= ) : x = not: (self < x)
|
||||
def ( > ) : x = x < self
|
||||
def ( <= ) : x = not: (x < self)
|
||||
def min : x = if self < x then self else x
|
||||
def max : x = if self < x then x else self
|
||||
}
|
||||
|
||||
//
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue