some fixes, going to fix function_call_expression typeclass argument types search bug

This commit is contained in:
ProgramSnail 2023-05-22 01:25:12 +03:00
parent f2192b5331
commit 0290b5604a
9 changed files with 307 additions and 111 deletions

View file

@ -19,6 +19,7 @@ include_directories(include
add_executable(lang_interpreter src/main.cpp add_executable(lang_interpreter src/main.cpp
src/types.cpp src/types.cpp
src/values.cpp src/values.cpp
src/utils.cpp
src/global_info.cpp src/global_info.cpp
src/typeclass_graph.cpp src/typeclass_graph.cpp
src/visitor.cpp src/visitor.cpp

View file

@ -172,7 +172,14 @@ private:
} }
} }
// void AddGraphIdLocalTypes(utils::IdType graph_id, utils::IdType type) {
std::unordered_set<utils::IdType> requirement_graph_ids = typeclass_graph_.GetDependenciesSet(graph_id);
requirement_graph_ids.insert(graph_id);
for (auto& requirement_graph_id : requirement_graph_ids) {
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(requirement_graph_id).name, type);
}
}
private: private:
info::GlobalInfo::NamespaceVisitor namespace_visitor_; info::GlobalInfo::NamespaceVisitor namespace_visitor_;

View file

@ -50,14 +50,12 @@ public:
} }
bool HasTypeclass(utils::IdType graph_id) { bool HasTypeclass(utils::IdType graph_id) {
error_handling::DebugPrint(name_);
error_handling::DebugPrint(requirement_graph_ids_.size());
for (auto& requirement_graph_id : requirement_graph_ids_) {
error_handling::DebugPrint(requirement_graph_id);
}
return requirement_graph_ids_.count(graph_id) != 0; return requirement_graph_ids_.count(graph_id) != 0;
} }
std::string ToString() {
return "Abstract";
}
private: private:
utils::AbstractTypeModifier modifier_; utils::AbstractTypeModifier modifier_;
std::string name_; std::string name_;
@ -93,6 +91,9 @@ public:
return class_modifier_; return class_modifier_;
} }
std::string ToString() {
return "Defined";
}
private: private:
utils::IdType type_id_; // in defined types utils::IdType type_id_; // in defined types
utils::IdType type_; // in types manager, created using context types (if specific type) utils::IdType type_; // in types manager, created using context types (if specific type)
@ -140,6 +141,32 @@ inline std::optional<InternalType> ToInternalType(const std::string& type) {
return std::nullopt; return std::nullopt;
} }
inline std::string ToString(InternalType type) {
std::string result;
switch (type) {
case InternalType::Float:
result = "Float";
break;
case InternalType::Int:
result = "Int";
break;
case InternalType::String:
result = "String";
break;
case InternalType::Char:
result = "Char";
break;
case InternalType::Bool:
result = "Bool";
break;
case InternalType::Unit:
result = "Unit";
break;
}
return result;
}
class TupleType { class TupleType {
public: public:
TupleType() = default; TupleType() = default;
@ -160,6 +187,7 @@ public:
return fields_; return fields_;
} }
std::string ToString();
private: private:
std::optional<std::string> name_; std::optional<std::string> name_;
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_; std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_;
@ -190,6 +218,7 @@ public:
current_constructor_ = constructor; current_constructor_ = constructor;
} }
std::string ToString();
private: private:
std::optional<std::string> name_; std::optional<std::string> name_;
std::vector<TupleType> constructors_; std::vector<TupleType> constructors_;
@ -211,6 +240,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name, std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const; const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
private: private:
utils::IdType type_; utils::IdType type_;
TypeManager* type_manager_ = nullptr; TypeManager* type_manager_ = nullptr;
@ -232,6 +262,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name, std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const; const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
private: private:
std::vector<utils::ReferenceModifier> references_; std::vector<utils::ReferenceModifier> references_;
utils::IdType type_; utils::IdType type_;
@ -256,6 +287,7 @@ public:
std::optional<utils::IdType> GetFieldType(const std::string& name, std::optional<utils::IdType> GetFieldType(const std::string& name,
const std::unordered_set<utils::IdType>& type_namespaces) const; const std::unordered_set<utils::IdType>& type_namespaces) const;
std::string ToString();
private: private:
std::vector<utils::IdType> argument_types_; std::vector<utils::IdType> argument_types_;
utils::IdType return_type_; utils::IdType return_type_;
@ -282,6 +314,7 @@ public:
return elements_type_; return elements_type_;
} }
std::string ToString();
private: private:
size_t size_; // = 0 for dynamic size_t size_; // = 0 for dynamic
utils::IdType elements_type_; utils::IdType elements_type_;
@ -316,6 +349,8 @@ public:
OptionalType>& GetType() { OptionalType>& GetType() {
return type_; return type_;
} }
std::string ToString();
private: private:
std::variant<AbstractType, std::variant<AbstractType,
DefinedType, DefinedType,

View file

@ -31,62 +31,11 @@ enum class PartitionModifier { Exec = 0, Test = 1 };
enum class ValueType { Const = 0, Var = 1, Tmp = 2 }; enum class ValueType { Const = 0, Var = 1, Tmp = 2 };
inline ValueType IsConstModifierToValueType(IsConstModifier modifier) { ValueType IsConstModifierToValueType(IsConstModifier modifier);
switch (modifier) {
case IsConstModifier::Const:
return ValueType::Const;
case IsConstModifier::Var:
return ValueType::Var;
}
exit(1); // unreachable ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier);
}
inline ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) { bool IsBuiltinFunction(const std::string& name);
switch (modifier) {
case ClassInternalsModifier::Const:
return ValueType::Const;
case ClassInternalsModifier::Var:
return ValueType::Var;
case ClassInternalsModifier::Static:
throw std::bad_cast(); // ??
}
exit(1); // unreachable
}
inline bool IsBuiltinFunction(const std::string& name) { // optimize ??
std::unordered_set<std::string> builtin_functions;
builtin_functions.insert("=");
builtin_functions.insert("<-");
builtin_functions.insert("==");
builtin_functions.insert("!=");
builtin_functions.insert("<");
builtin_functions.insert(">");
builtin_functions.insert("<=");
builtin_functions.insert(">=");
builtin_functions.insert("+=");
builtin_functions.insert("-=");
builtin_functions.insert("*=");
builtin_functions.insert("div");
builtin_functions.insert("mod");
builtin_functions.insert("/=");
// builtin_functions.insert("+");
// builtin_functions.insert("-");
// builtin_functions.insert("*");
// builtin_functions.insert("/");
builtin_functions.insert("&&");
builtin_functions.insert("||");
builtin_functions.insert("size");
builtin_functions.insert("random");
builtin_functions.insert("print");
builtin_functions.insert("scan");
builtin_functions.insert("zero");
builtin_functions.insert("one");
return builtin_functions.count(name) != 0;
}
template<typename T> template<typename T>
class Storage { class Storage {
@ -265,34 +214,12 @@ private:
std::vector<size_t> ranks_; std::vector<size_t> ranks_;
}; };
// move to .cpp ?? void BackVisitDfs(size_t id,
inline void BackVisitDfs(size_t id, std::vector<size_t>& verticles,
std::vector<size_t>& verticles, std::vector<size_t>& marks,
std::vector<size_t>& marks, const std::vector<std::vector<size_t>>& edges,
const std::vector<std::vector<size_t>>& edges, size_t mark);
size_t mark) {
if (marks[id] != 0) {
return;
}
marks[id] = mark; std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_);
verticles.push_back(id);
for (size_t i = 0; i < edges[id].size(); ++i) {
BackVisitDfs(id, verticles, marks, edges, mark);
}
}
// move to .cpp ??
inline 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 } // namespace utils

View file

@ -52,11 +52,9 @@ void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.EnterContext(); context_manager_.EnterContext();
} }
// including namespace typeclass abstract_type = context_manager_.ToModifiedValue(abstract_type, utils::ValueType::Tmp); // ??
// define typeclasses local types as namespace typeclass
for (auto& requirement_graph_id : requirement_graph_ids) { AddGraphIdLocalTypes(graph_id, abstract_type);
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(requirement_graph_id).name, abstract_type);
}
} else if (node->link_type_id_.has_value()) { } else if (node->link_type_id_.has_value()) {
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value()); auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(node->link_type_id_.value());
@ -80,12 +78,7 @@ void TypeCheckVisitor::Visit(Namespace* node) {
context_manager_.EnterContext(); context_manager_.EnterContext();
} }
// better decision ?? AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
// define typeclasses local types as namespace type
auto typeclass_graph_ids = typeclass_graph_.GetDependenciesVector(type_info->type.node->graph_id_);
for (auto& typeclass_graph_id : typeclass_graph_ids) {
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(typeclass_graph_id).name, type);
}
if (type_namespaces_.count(node->link_type_id_.value()) != 0) { if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
error_handling::HandleTypecheckError("Namespaces of one type are one in another", node->base); error_handling::HandleTypecheckError("Namespaces of one type are one in another", node->base);
@ -269,6 +262,8 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
returned_type_ = current_type_; returned_type_ = current_type_;
} }
if (!context_manager_.EqualValues(returned_type, returned_type_.value())) { if (!context_manager_.EqualValues(returned_type, returned_type_.value())) {
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type)->ToString());
error_handling::DebugPrint(context_manager_.GetAnyValue(returned_type_.value())->ToString());
error_handling::HandleTypecheckError("Wrong function return type", node->base); error_handling::HandleTypecheckError("Wrong function return type", node->base);
} }
returned_type_ = std::nullopt; returned_type_ = std::nullopt;
@ -319,7 +314,7 @@ void TypeCheckVisitor::Visit(AbstractTypeDefinitionStatement* node) {
current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements), current_type_ = context_manager_.AddValue(info::type::AbstractType(node->modifier, node->type->type, requirements),
utils::ValueType::Tmp); utils::ValueType::Tmp);
if (!context_manager_.DefineLocalType(node->type->type, current_type_)) { if (!context_manager_.DefineLocalType(node->type->type, current_type_)) {
error_handling::HandleTypecheckError("Can't define basic / astract type: abstract type redefinition", node->base); error_handling::HandleTypecheckError("Can't define basic / abstract type: abstract type redefinition", node->base);
} }
current_type_ = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp); current_type_ = context_manager_.AddValue(info::type::InternalType::Unit, utils::ValueType::Tmp);
@ -731,6 +726,8 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
// TODO: more builtin functions, better handling (??) // TODO: more builtin functions, better handling (??)
void TypeCheckVisitor::Visit(FunctionCallExpression* node) { void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
context_manager_.EnterContext();
std::optional<FunctionDeclaration*> maybe_function_declaration; std::optional<FunctionDeclaration*> maybe_function_declaration;
std::unordered_map<std::string, utils::IdType> context; std::unordered_map<std::string, utils::IdType> context;
@ -749,7 +746,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
if (node->prefix.has_value()) { if (node->prefix.has_value()) {
if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) { if (std::holds_alternative<std::unique_ptr<SubExpressionToken>>(node->prefix.value())) {
Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value())); Visitor::Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
maybe_function_declaration = FindExpressionMethodAndUpdate(node, current_type_); utils::IdType expression_type = current_type_;
maybe_function_declaration = FindExpressionMethodAndUpdate(node, expression_type);
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) { } else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
maybe_function_declaration = FindTypeFunctionAndUpdate( maybe_function_declaration = FindTypeFunctionAndUpdate(
node, node,
@ -843,6 +841,8 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
info::type::TupleType(std::nullopt, fields, context_manager_.GetValueManager()), info::type::TupleType(std::nullopt, fields, context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_; node->base.type_ = current_type_;
} }
@ -988,7 +988,10 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
current_type_ = context_manager_.AddValue( current_type_ = context_manager_.AddValue(
info::type::DefinedType(type_id, current_type_, type_info.modifier, context_manager_.GetValueManager()), info::type::DefinedType(type_id,
current_type_,
type_info.modifier,
context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
node->base.type_ = current_type_; node->base.type_ = current_type_;
@ -1279,7 +1282,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
auto maybe_internal_type = info::type::ToInternalType(node->type.type); auto maybe_internal_type = info::type::ToInternalType(node->type.type);
if (maybe_internal_type.has_value()) { if (maybe_internal_type.has_value()) { // TODO: ???
// checks made in link_symbols_visitor // checks made in link_symbols_visitor
current_type_ = current_type_ =
context_manager_.AddValue<info::type::InternalType>( context_manager_.AddValue<info::type::InternalType>(
@ -1471,6 +1474,18 @@ std::optional<FunctionDeclaration*>
utils::IdType expression_type) { utils::IdType expression_type) {
std::optional<FunctionDeclaration*> maybe_function_declaration; std::optional<FunctionDeclaration*> maybe_function_declaration;
auto maybe_internal_type_info = context_manager_.GetValue<info::type::InternalType>(expression_type);
if (maybe_internal_type_info.has_value()) {
auto maybe_abstract_type_id = context_manager_.FindLocalType(info::type::ToString(*maybe_internal_type_info.value()));
if (maybe_abstract_type_id.has_value()) {
expression_type = maybe_abstract_type_id.value();
} else {
error_handling::HandleInternalError("InternalType local abstract type not found",
"TypeCheckVisitor.FindExpressionMethodAndUpdate",
&node->base);
}
}
auto maybe_abstract_type_info = context_manager_.GetValue<info::type::AbstractType>(expression_type); auto maybe_abstract_type_info = context_manager_.GetValue<info::type::AbstractType>(expression_type);
if (maybe_abstract_type_info.has_value()) { if (maybe_abstract_type_info.has_value()) {
@ -1478,8 +1493,7 @@ std::optional<FunctionDeclaration*>
maybe_abstract_type_info.value(), maybe_abstract_type_info.value(),
true); true);
} else { } else {
auto maybe_defined_type_info = auto maybe_defined_type_info = context_manager_.GetValue<info::type::DefinedType>(expression_type);
context_manager_.GetValue<info::type::DefinedType>(expression_type);
if (!maybe_defined_type_info.has_value()) { if (!maybe_defined_type_info.has_value()) {
error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", node->base); error_handling::HandleTypecheckError("There is no non-builtin methods for not defined type", node->base);
} }
@ -1488,7 +1502,7 @@ std::optional<FunctionDeclaration*>
auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_id); auto maybe_type_info = global_info_.GetTypeInfo<info::definition::AnyType>(type_id);
if (!maybe_type_info.has_value()) { if (!maybe_type_info.has_value()) {
error_handling::HandleInternalError("Functions / Methods implemented only for AnyType", error_handling::HandleInternalError("Functions / Methods implemented only for AnyType",
"TypeCheckVisitor.FunctionCallExpresssion", "TypeCheckVisitor.FindExpressionMethodAndUpdate",
&node->base); &node->base);
} }
info::definition::AnyType* type_info = maybe_type_info.value(); info::definition::AnyType* type_info = maybe_type_info.value();
@ -1645,6 +1659,7 @@ std::optional<FunctionDeclaration*>
} }
node->graph_id_ = maybe_typeclass_graph_id; node->graph_id_ = maybe_typeclass_graph_id;
node->abstract_type_name_ = abstract_type_info->GetName(); node->abstract_type_name_ = abstract_type_info->GetName();
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration; maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
@ -1671,6 +1686,7 @@ std::optional<FunctionDeclaration*>
} }
node->graph_id_ = defined_type->type.node->graph_id_; node->graph_id_ = defined_type->type.node->graph_id_;
// type defined -> abstract type name not needed // type defined -> abstract type name not needed
maybe_function_declaration = maybe_type_function_info.value()->declaration; maybe_function_declaration = maybe_type_function_info.value()->declaration;

View file

@ -128,7 +128,7 @@ void TypeclassGraph::CalculateGraph() {
} }
std::vector<size_t> sorted_verticles = utils::BackTopSort(edges); std::vector<size_t> sorted_verticles = utils::BackTopSort(edges);
std::reverse(sorted_verticles.begin(), sorted_verticles.end()); // std::reverse(sorted_verticles.begin(), sorted_verticles.end());
for (auto& id : sorted_verticles) { for (auto& id : sorted_verticles) {
for (auto& dependency : verticles_[id].dependencies) { for (auto& dependency : verticles_[id].dependencies) {
@ -146,7 +146,7 @@ void TypeclassGraph::CalculateGraph() {
} }
} }
} }
for (auto& inherited_dependency : verticles_[method_to_vertex_[dependency]].dependencies) { for (auto& inherited_dependency : verticles_[name_to_typeclass_[dependency]].dependencies) {
verticles_[id].dependencies.insert(inherited_dependency); verticles_[id].dependencies.insert(inherited_dependency);
} }
} }

View file

@ -124,6 +124,21 @@ std::optional<utils::IdType> TupleType::GetFieldType(const std::string& name,
return std::nullopt; return std::nullopt;
} }
std::string TupleType::ToString() {
std::string result;
result += "(";
for (auto& field : fields_) {
result += "& ";
result += type_manager_->GetAnyValue(field.second)->ToString();
}
result += ")";
return result;
}
// //
std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -174,6 +189,21 @@ std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
return std::nullopt; return std::nullopt;
} }
std::string VariantType::ToString() {
std::string result;
result += "(";
for (auto& constructor : constructors_) {
result += "& ";
result += constructor.ToString();
}
result += ")";
return result;
}
// //
std::optional<utils::IdType> OptionalType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> OptionalType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -203,6 +233,10 @@ std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&,
return std::nullopt; return std::nullopt;
} }
std::string OptionalType::ToString() {
return "Optional " + type_manager_->GetAnyValue(type_)->ToString();
}
// //
std::optional<utils::IdType> ReferenceToType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> ReferenceToType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -232,6 +266,29 @@ std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& na
return type_manager_->GetAnyValue(type_)->GetFieldType(name, type_namespaces); return type_manager_->GetAnyValue(type_)->GetFieldType(name, type_namespaces);
} }
std::string ReferenceToType::ToString() {
std::string result;
for (auto& reference : references_) {
switch (reference) {
case utils::ReferenceModifier::Dereference:
result += '~';
break;
case utils::ReferenceModifier::Reference:
result += '^';
break;
case utils::ReferenceModifier::UniqueReference:
result += '@';
break;
}
}
result += type_manager_->GetAnyValue(type_)->ToString();
return result;
}
// //
std::optional<utils::IdType> FunctionType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> FunctionType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -284,6 +341,26 @@ std::optional<utils::IdType> FunctionType::GetFieldType(const std::string&,
return std::nullopt; return std::nullopt;
} }
std::string FunctionType::ToString() {
std::string result;
result += "(";
bool is_first_argument = true;
for (auto& argument_type : argument_types_) {
if (is_first_argument) {
is_first_argument = false;
} else {
result += " -> ";
}
result += type_manager_->GetAnyValue(argument_type)->ToString();
}
result += " -> " + type_manager_->GetAnyValue(return_type_)->ToString() + ")";
return result;
}
// //
std::optional<utils::IdType> ArrayType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> ArrayType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -314,6 +391,10 @@ std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&,
return std::nullopt; return std::nullopt;
} }
std::string ArrayType::ToString() {
return "Array (" + std::to_string(size_) + ") " + type_manager_->GetAnyValue(elements_type_)->ToString();
}
// //
std::optional<utils::IdType> Type::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> Type::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
@ -477,5 +558,35 @@ std::string Type::GetTypeName() const {
return ""; // ?? return ""; // ??
} }
std::string Type::ToString() {
size_t index = type_.index();
switch (index) {
case 0:
return std::get<AbstractType>(type_).ToString();
case 1:
return std::get<DefinedType>(type_).ToString();
case 2:
return ::info::type::ToString(std::get<InternalType>(type_));
case 3:
return std::get<TupleType>(type_).ToString();
case 4:
return std::get<VariantType>(type_).ToString();
case 5:
return std::get<ReferenceToType>(type_).ToString();
case 6:
return std::get<FunctionType>(type_).ToString();
case 7:
return std::get<ArrayType>(type_).ToString();
case 8:
return std::get<OptionalType>(type_).ToString();
default:
// error
break;
}
return "";
}
} // namespace info::type } // namespace info::type

99
src/utils.cpp Normal file
View file

@ -0,0 +1,99 @@
// for clangd
#include "../include/utils.hpp"
#include"../include/error_handling.hpp"
namespace utils {
using std::size_t;
using IdType = size_t;
ValueType IsConstModifierToValueType(IsConstModifier modifier) {
switch (modifier) {
case IsConstModifier::Const:
return ValueType::Const;
case IsConstModifier::Var:
return ValueType::Var;
}
exit(1); // unreachable
}
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
}
bool IsBuiltinFunction(const std::string& name) { // optimize ??
std::unordered_set<std::string> builtin_functions;
builtin_functions.insert("=");
builtin_functions.insert("<-");
builtin_functions.insert("==");
// builtin_functions.insert("!=");
builtin_functions.insert("<");
// builtin_functions.insert(">");
// builtin_functions.insert("<=");
// builtin_functions.insert(">=");
builtin_functions.insert("+=");
builtin_functions.insert("-=");
builtin_functions.insert("*=");
builtin_functions.insert("div");
builtin_functions.insert("mod");
builtin_functions.insert("/=");
// builtin_functions.insert("+");
// builtin_functions.insert("-");
// builtin_functions.insert("*");
// builtin_functions.insert("/");
builtin_functions.insert("&&");
builtin_functions.insert("||");
builtin_functions.insert("size");
builtin_functions.insert("random");
builtin_functions.insert("print");
builtin_functions.insert("scan");
builtin_functions.insert("zero");
builtin_functions.insert("one");
return builtin_functions.count(name) != 0;
}
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;
for (size_t i = 0; i < edges[id].size(); ++i) {
BackVisitDfs(edges[id][i], verticles, marks, edges, mark);
}
verticles.push_back(id);
}
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 < edges_.size(); ++i) {
if (marks[i] == 0) {
BackVisitDfs(i, sorted_verticles, marks, edges_, 1);
}
}
return sorted_verticles;
}
} // namespace utils

View file

@ -77,8 +77,8 @@ namespace var Mult {
} }
typeclass (IDiv : #Mult) = typeclass (IDiv : #Mult) =
& var div : IDiv -> Unit & var div : IDiv -> IDiv
& var mod : IDiv -> Unit & var mod : IDiv -> IDiv
namespace var IDiv { namespace var IDiv {
def mod : x = self -. x * self.div: x def mod : x = self -. x * self.div: x
@ -190,7 +190,7 @@ def ( -- ) : begin end = {
var current = begin var current = begin
return (while current < end do { return (while current < end do {
; current += 1 ; current += 1
return current - 1 bring current - 1
}) })
} }