mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
some fixes, going to fix function_call_expression typeclass argument types search bug
This commit is contained in:
parent
f2192b5331
commit
0290b5604a
9 changed files with 307 additions and 111 deletions
|
|
@ -19,6 +19,7 @@ include_directories(include
|
|||
add_executable(lang_interpreter src/main.cpp
|
||||
src/types.cpp
|
||||
src/values.cpp
|
||||
src/utils.cpp
|
||||
src/global_info.cpp
|
||||
src/typeclass_graph.cpp
|
||||
src/visitor.cpp
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
info::GlobalInfo::NamespaceVisitor namespace_visitor_;
|
||||
|
|
|
|||
|
|
@ -50,14 +50,12 @@ public:
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
std::string ToString() {
|
||||
return "Abstract";
|
||||
}
|
||||
private:
|
||||
utils::AbstractTypeModifier modifier_;
|
||||
std::string name_;
|
||||
|
|
@ -93,6 +91,9 @@ public:
|
|||
return class_modifier_;
|
||||
}
|
||||
|
||||
std::string ToString() {
|
||||
return "Defined";
|
||||
}
|
||||
private:
|
||||
utils::IdType type_id_; // in defined types
|
||||
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;
|
||||
}
|
||||
|
||||
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 {
|
||||
public:
|
||||
TupleType() = default;
|
||||
|
|
@ -160,6 +187,7 @@ public:
|
|||
return fields_;
|
||||
}
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::optional<std::string> name_;
|
||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> fields_;
|
||||
|
|
@ -190,6 +218,7 @@ public:
|
|||
current_constructor_ = constructor;
|
||||
}
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::optional<std::string> name_;
|
||||
std::vector<TupleType> constructors_;
|
||||
|
|
@ -211,6 +240,7 @@ public:
|
|||
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
||||
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
utils::IdType type_;
|
||||
TypeManager* type_manager_ = nullptr;
|
||||
|
|
@ -232,6 +262,7 @@ public:
|
|||
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
||||
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::vector<utils::ReferenceModifier> references_;
|
||||
utils::IdType type_;
|
||||
|
|
@ -256,6 +287,7 @@ public:
|
|||
std::optional<utils::IdType> GetFieldType(const std::string& name,
|
||||
const std::unordered_set<utils::IdType>& type_namespaces) const;
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::vector<utils::IdType> argument_types_;
|
||||
utils::IdType return_type_;
|
||||
|
|
@ -282,6 +314,7 @@ public:
|
|||
return elements_type_;
|
||||
}
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
size_t size_; // = 0 for dynamic
|
||||
utils::IdType elements_type_;
|
||||
|
|
@ -316,6 +349,8 @@ public:
|
|||
OptionalType>& GetType() {
|
||||
return type_;
|
||||
}
|
||||
|
||||
std::string ToString();
|
||||
private:
|
||||
std::variant<AbstractType,
|
||||
DefinedType,
|
||||
|
|
|
|||
|
|
@ -31,62 +31,11 @@ enum class PartitionModifier { Exec = 0, Test = 1 };
|
|||
|
||||
enum class ValueType { Const = 0, Var = 1, Tmp = 2 };
|
||||
|
||||
inline ValueType IsConstModifierToValueType(IsConstModifier modifier) {
|
||||
switch (modifier) {
|
||||
case IsConstModifier::Const:
|
||||
return ValueType::Const;
|
||||
case IsConstModifier::Var:
|
||||
return ValueType::Var;
|
||||
}
|
||||
ValueType IsConstModifierToValueType(IsConstModifier modifier);
|
||||
|
||||
exit(1); // unreachable
|
||||
}
|
||||
ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier);
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
bool IsBuiltinFunction(const std::string& name);
|
||||
|
||||
template<typename T>
|
||||
class Storage {
|
||||
|
|
@ -265,34 +214,12 @@ private:
|
|||
std::vector<size_t> ranks_;
|
||||
};
|
||||
|
||||
// move to .cpp ??
|
||||
inline void BackVisitDfs(size_t id,
|
||||
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;
|
||||
}
|
||||
size_t mark);
|
||||
|
||||
marks[id] = mark;
|
||||
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;
|
||||
}
|
||||
std::vector<size_t> BackTopSort(const std::vector<std::vector<size_t>>& edges_);
|
||||
|
||||
} // namespace utils
|
||||
|
|
|
|||
|
|
@ -52,11 +52,9 @@ void TypeCheckVisitor::Visit(Namespace* node) {
|
|||
context_manager_.EnterContext();
|
||||
}
|
||||
|
||||
// including namespace typeclass
|
||||
// define typeclasses local types as namespace typeclass
|
||||
for (auto& requirement_graph_id : requirement_graph_ids) {
|
||||
context_manager_.DefineLocalType(typeclass_graph_.GetVertex(requirement_graph_id).name, abstract_type);
|
||||
}
|
||||
abstract_type = context_manager_.ToModifiedValue(abstract_type, utils::ValueType::Tmp); // ??
|
||||
|
||||
AddGraphIdLocalTypes(graph_id, abstract_type);
|
||||
} else if (node->link_type_id_.has_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();
|
||||
}
|
||||
|
||||
// better decision ??
|
||||
// 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);
|
||||
}
|
||||
AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
|
||||
|
||||
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
|
||||
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_;
|
||||
}
|
||||
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);
|
||||
}
|
||||
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),
|
||||
utils::ValueType::Tmp);
|
||||
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);
|
||||
|
|
@ -731,6 +726,8 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
|
||||
// TODO: more builtin functions, better handling (??)
|
||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||
context_manager_.EnterContext();
|
||||
|
||||
std::optional<FunctionDeclaration*> maybe_function_declaration;
|
||||
|
||||
std::unordered_map<std::string, utils::IdType> context;
|
||||
|
|
@ -749,7 +746,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
if (node->prefix.has_value()) {
|
||||
if (std::holds_alternative<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())) {
|
||||
maybe_function_declaration = FindTypeFunctionAndUpdate(
|
||||
node,
|
||||
|
|
@ -843,6 +841,8 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
|
|||
info::type::TupleType(std::nullopt, fields, context_manager_.GetValueManager()),
|
||||
utils::ValueType::Tmp);
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
}
|
||||
|
||||
|
|
@ -988,7 +988,10 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
|||
current_type_ = TypeInContext(current_type_, context);
|
||||
|
||||
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);
|
||||
|
||||
node->base.type_ = current_type_;
|
||||
|
|
@ -1279,7 +1282,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
|
|||
|
||||
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
|
||||
current_type_ =
|
||||
context_manager_.AddValue<info::type::InternalType>(
|
||||
|
|
@ -1471,6 +1474,18 @@ std::optional<FunctionDeclaration*>
|
|||
utils::IdType expression_type) {
|
||||
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);
|
||||
|
||||
if (maybe_abstract_type_info.has_value()) {
|
||||
|
|
@ -1478,8 +1493,7 @@ std::optional<FunctionDeclaration*>
|
|||
maybe_abstract_type_info.value(),
|
||||
true);
|
||||
} else {
|
||||
auto maybe_defined_type_info =
|
||||
context_manager_.GetValue<info::type::DefinedType>(expression_type);
|
||||
auto maybe_defined_type_info = context_manager_.GetValue<info::type::DefinedType>(expression_type);
|
||||
if (!maybe_defined_type_info.has_value()) {
|
||||
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);
|
||||
if (!maybe_type_info.has_value()) {
|
||||
error_handling::HandleInternalError("Functions / Methods implemented only for AnyType",
|
||||
"TypeCheckVisitor.FunctionCallExpresssion",
|
||||
"TypeCheckVisitor.FindExpressionMethodAndUpdate",
|
||||
&node->base);
|
||||
}
|
||||
info::definition::AnyType* type_info = maybe_type_info.value();
|
||||
|
|
@ -1645,6 +1659,7 @@ std::optional<FunctionDeclaration*>
|
|||
}
|
||||
|
||||
node->graph_id_ = maybe_typeclass_graph_id;
|
||||
|
||||
node->abstract_type_name_ = abstract_type_info->GetName();
|
||||
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_;
|
||||
|
||||
// type defined -> abstract type name not needed
|
||||
maybe_function_declaration = maybe_type_function_info.value()->declaration;
|
||||
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ void TypeclassGraph::CalculateGraph() {
|
|||
}
|
||||
|
||||
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& 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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
111
src/types.cpp
111
src/types.cpp
|
|
@ -124,6 +124,21 @@ std::optional<utils::IdType> TupleType::GetFieldType(const std::string& name,
|
|||
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) {
|
||||
|
|
@ -174,6 +189,21 @@ std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
|
|||
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) {
|
||||
|
|
@ -203,6 +233,10 @@ std::optional<utils::IdType> OptionalType::GetFieldType(const std::string&,
|
|||
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) {
|
||||
|
|
@ -232,6 +266,29 @@ std::optional<utils::IdType> ReferenceToType::GetFieldType(const std::string& na
|
|||
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) {
|
||||
|
|
@ -284,6 +341,26 @@ std::optional<utils::IdType> FunctionType::GetFieldType(const std::string&,
|
|||
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) {
|
||||
|
|
@ -314,6 +391,10 @@ std::optional<utils::IdType> ArrayType::GetFieldType(const std::string&,
|
|||
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) {
|
||||
|
|
@ -477,5 +558,35 @@ std::string Type::GetTypeName() const {
|
|||
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
|
||||
|
||||
|
|
|
|||
99
src/utils.cpp
Normal file
99
src/utils.cpp
Normal 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
|
||||
|
|
@ -77,8 +77,8 @@ namespace var Mult {
|
|||
}
|
||||
|
||||
typeclass (IDiv : #Mult) =
|
||||
& var div : IDiv -> Unit
|
||||
& var mod : IDiv -> Unit
|
||||
& var div : IDiv -> IDiv
|
||||
& var mod : IDiv -> IDiv
|
||||
|
||||
namespace var IDiv {
|
||||
def mod : x = self -. x * self.div: x
|
||||
|
|
@ -190,7 +190,7 @@ def ( -- ) : begin end = {
|
|||
var current = begin
|
||||
return (while current < end do {
|
||||
; current += 1
|
||||
return current - 1
|
||||
bring current - 1
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue