fixes, optional type name added

This commit is contained in:
ProgramSnail 2023-05-23 00:51:51 +03:00
parent d38d75c9d8
commit 0850e6aa6b
14 changed files with 163 additions and 99 deletions

View file

@ -31,6 +31,11 @@ public:
}; };
void ExecutePartition(interpreter::tokens::PartitionStatement* partition) { void ExecutePartition(interpreter::tokens::PartitionStatement* partition) {
for (size_t i = 0; i < info::type::InternalTypesCount; ++i) {
info::type::InternalType type = static_cast<info::type::InternalType>(i);
std::string type_name = info::type::ToString(type);
context_manager_.DefineLocalType(type_name, global_info_.FindAbstractType(type_name).value()->node->type->graph_id_);
}
Visit(partition); Visit(partition);
} }

View file

@ -93,8 +93,6 @@ public:
std::optional<utils::IdType> FindLocalTypeId(const std::string& type); std::optional<utils::IdType> FindLocalTypeId(const std::string& type);
std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
std::optional<utils::IdType> FindTypeclassId(const std::string& typeclass); std::optional<utils::IdType> FindTypeclassId(const std::string& typeclass);
std::optional<utils::IdType> FindConstructorId(const std::optional<std::vector<std::string>>& path, std::optional<utils::IdType> FindConstructorId(const std::optional<std::vector<std::string>>& path,
@ -164,14 +162,6 @@ public:
return global_info_.GetTypeInfo<T>(id.value()); 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<definition::Typeclass*> FindTypeclass(const std::string& typeclass) {
std::optional<utils::IdType> id = FindTypeclassId(typeclass); std::optional<utils::IdType> id = FindTypeclassId(typeclass);
if (!id.has_value()) { if (!id.has_value()) {
@ -368,6 +358,16 @@ public:
// function declarations & definitions should be added latter // function declarations & definitions should be added latter
std::optional<utils::IdType> AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node); std::optional<utils::IdType> AddAnnotatedTypeToGraph(interpreter::tokens::AnnotatedType* node);
std::optional<utils::IdType> FindAbstractTypeId(const std::string& abstract_type);
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 &GetAbstractTypeInfo(id.value());
}
private: private:
void CollectFunctionInfo( void CollectFunctionInfo(
utils::IdType current_namespace, utils::IdType current_namespace,

View file

@ -654,6 +654,7 @@ struct TypeExpression {
ParametrizedType type; ParametrizedType type;
std::optional<size_t> array_size; // if array; 0 - dynamic size std::optional<size_t> array_size; // if array; 0 - dynamic size
bool is_optional = false; // for optionals
std::optional<utils::IdType> type_id_; std::optional<utils::IdType> type_id_;
std::optional<utils::IdType> constructor_id_; std::optional<utils::IdType> constructor_id_;

View file

@ -27,7 +27,7 @@ public:
// init internal type abstrac types // init internal type abstrac types
for (size_t i = 0; i < info::type::InternalTypesCount; ++i) { for (size_t i = 0; i < info::type::InternalTypesCount; ++i) {
info::type::InternalType type = static_cast<info::type::InternalType>(i); info::type::InternalType type = static_cast<info::type::InternalType>(i);
Visit(namespace_visitor_.FindAbstractType(info::type::ToString(type)).value()->node); Visit(global_info_.FindAbstractType(info::type::ToString(type)).value()->node);
} }
Visit(source_file); Visit(source_file);

@ -1 +1 @@
Subproject commit ddb08e9b65123324800d1126d38764764363c0e5 Subproject commit 5346d008497d93d30db4933dc3744b3de35cebf8

Binary file not shown.

View file

@ -53,19 +53,11 @@ void BuildVisitor::Visit(Namespace* node) {
auto parse_node = current_node_; auto parse_node = current_node_;
size_t child_count = parse_node.ChildCount();
if (child_count > 3) { // "namespace", ["var"/"const",] type, scope
std::string modifier = parse_node.NthChild(1).GetValue(); std::string modifier = parse_node.NthChild(1).GetValue();
if (modifier == "const") { if (modifier == "const") {
node->modifier = utils::ClassInternalsModifier::Const; node->modifier = utils::ClassInternalsModifier::Const;
} else if (modifier == "var") { } else if (modifier == "var") {
node->modifier = utils::ClassInternalsModifier::Var; node->modifier = utils::ClassInternalsModifier::Var;
} else {
error_handling::HandleInternalError("Can't parse namespace modifier",
"BuildVisitor.Namespace",
&node->base);
}
} else { } else {
node->modifier = utils::ClassInternalsModifier::Static; node->modifier = utils::ClassInternalsModifier::Static;
} }
@ -1380,17 +1372,50 @@ void BuildVisitor::Visit(TypeExpression* node) {
Visit(&node->type); Visit(&node->type);
++excluded_child_count; ++excluded_child_count;
current_node_ = current_node_.NextSibling(); auto suffix_node1 = current_node_.NextSibling();
// TODO: better structure // TODO: check
if (!suffix_node1.IsNull()) {
auto suffix_node2 = suffix_node1.NextSibling();
if (!suffix_node2.IsNull()) {
auto suffix_node3 = suffix_node2.NextSibling();
if (!suffix_node3.IsNull()) {
current_node_ = suffix_node2;
NumberLiteral literal;
Visit(&literal);
node->array_size = literal.value;
++excluded_child_count;
node->is_optional = true;
} else {
if (suffix_node1.GetValue() == "_" && suffix_node2.GetValue() == "!") {
node->array_size = 0;
node->is_optional = true;
} else if (suffix_node1.GetValue() == "_") {
current_node_ = suffix_node2;
if (!current_node_.IsNull()) {
current_node_ = current_node_.NextSibling();
if (!current_node_.IsNull()) {
NumberLiteral literal; NumberLiteral literal;
Visit(&literal); Visit(&literal);
node->array_size = literal.value; node->array_size = literal.value;
++excluded_child_count; ++excluded_child_count;
} else { } else {
error_handling::HandleInternalError("Undefined suffix (2 elements)",
"BuildVisitor.TypeExpression",
std::nullopt);
}
}
} else {
if (suffix_node1.GetValue() == "_") {
node->array_size = 0; node->array_size = 0;
} else if (suffix_node1.GetValue() == "!") {
node->is_optional = true;
} else {
error_handling::HandleInternalError("Undefined suffix (1 element)",
"BuildVisitor.TypeExpression",
std::nullopt);
}
} }
} }

View file

@ -235,7 +235,7 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddAbstractType(const std::string& a
// error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node); // error_handling::HandleNamesError("Can't redefine basic type as abstract type", base_node);
// } // }
if (FindAbstractType(abstract_type).has_value()) { if (global_info_.FindAbstractType(abstract_type).has_value()) {
error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node); error_handling::HandleNamesError("More then one abstract type with the same name in namespace", base_node);
} }
@ -385,16 +385,6 @@ std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindLocalTypeId(const
return std::nullopt; return std::nullopt;
} }
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = global_info_.name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != global_info_.name_to_abstract_type_.end()) {
return abstract_type_id_iter->second;
}
return std::nullopt;
}
std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) { std::optional<utils::IdType> GlobalInfo::NamespaceVisitor::FindTypeclassId(const std::string& typeclass) {
auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass); auto typeclass_id_iter = global_info_.name_to_typeclass_.find(typeclass);
@ -578,6 +568,16 @@ std::optional<utils::IdType> GlobalInfo::AddAnnotatedTypeToGraph(interpreter::to
TypeclassGraph::Modifier::Type); TypeclassGraph::Modifier::Type);
} }
std::optional<utils::IdType> GlobalInfo::FindAbstractTypeId(const std::string& abstract_type) {
auto abstract_type_id_iter = name_to_abstract_type_.find(abstract_type);
if (abstract_type_id_iter != name_to_abstract_type_.end()) {
return abstract_type_id_iter->second;
}
return std::nullopt;
}
void GlobalInfo::CollectFunctionInfo( void GlobalInfo::CollectFunctionInfo(
utils::IdType current_namespace, utils::IdType current_namespace,
utils::ClassInternalsModifier modifier, utils::ClassInternalsModifier modifier,

View file

@ -134,7 +134,7 @@ void LinkSymbolsVisitor::Visit(TypeExpression* node) {
if (maybe_type_namespace.has_value()) { if (maybe_type_namespace.has_value()) {
info::definition::Namespace* type_namespace = maybe_type_namespace.value(); info::definition::Namespace* type_namespace = maybe_type_namespace.value();
for (ssize_t i = (ssize_t)node->path.size(); i >= 0; --i) { for (ssize_t i = (ssize_t)node->path.size() - 1; i >= 0; --i) {
info::definition::Namespace* parent_namespace = &global_info_.GetNamespaceInfo(type_namespace->parent_namespace); info::definition::Namespace* parent_namespace = &global_info_.GetNamespaceInfo(type_namespace->parent_namespace);
auto type_iter = parent_namespace->types.find(type_namespace->type_name); auto type_iter = parent_namespace->types.find(type_namespace->type_name);

View file

@ -654,10 +654,14 @@ void PrintVisitor::Visit(VariantType* node) {
} }
void PrintVisitor::Visit(TypeExpression* node) { void PrintVisitor::Visit(TypeExpression* node) {
out_ << "[TypeExpression "; out_ << "[TypeExpression";
if (node->array_size.has_value()) { if (node->array_size.has_value()) {
out_ << "[array size: " << node->array_size.value() << ']'; out_ << " [array size: " << node->array_size.value() << ']';
}
if (node->is_optional) {
out_ << " [optional]";
} }
out_ << "] ("; out_ << "] (";

View file

@ -249,8 +249,6 @@ 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;
@ -284,7 +282,7 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
auto function_iter = type_functions.find(function.first); auto function_iter = type_functions.find(function.first);
if (function_iter == type_functions.end() || !global_info_.GetFunctionInfo(function_iter->second).definition.has_value()) { if (function_iter == type_functions.end() || !global_info_.GetFunctionInfo(function_iter->second).definition.has_value()) {
error_handling::HandleTypecheckError("Type is not satisfy typeclass requirements: " + function.first + " is not defined", node->base); error_handling::HandleTypecheckError("Type not define all required functions: " + function.first + " is not defined", node->base);
} }
} }
@ -1281,16 +1279,6 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
std::unordered_map<std::string, utils::IdType> context; std::unordered_map<std::string, utils::IdType> context;
CollectTypeExpressionContext(*node, context); CollectTypeExpressionContext(*node, context);
// TODO: -------- remove, unneeded ------
// auto maybe_internal_type = info::type::ToInternalType(node->type.type);
//
// if (maybe_internal_type.has_value()) { // TODO: ???
// // checks made in link_symbols_visitor
// current_type_ =
// context_manager_.AddValue<info::type::InternalType>(
// maybe_internal_type.value(),
// utils::ValueType::Tmp);
// } else {
std::optional<utils::IdType> maybe_local_abstract_type = std::optional<utils::IdType> maybe_local_abstract_type =
context_manager_.FindLocalType(node->type.type); context_manager_.FindLocalType(node->type.type);
if (node->path.empty() && maybe_local_abstract_type.has_value()) { if (node->path.empty() && maybe_local_abstract_type.has_value()) {
@ -1309,7 +1297,6 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
} else { } else {
error_handling::HandleTypecheckError("Type not found", node->base); error_handling::HandleTypecheckError("Type not found", node->base);
} }
// }
if (node->array_size.has_value()) { if (node->array_size.has_value()) {
current_type_ = context_manager_.AddValue( current_type_ = context_manager_.AddValue(
@ -1317,6 +1304,12 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
utils::ValueType::Tmp); utils::ValueType::Tmp);
} }
if (node->is_optional) {
current_type_ = context_manager_.AddValue(
info::type::OptionalType(current_type_, context_manager_.GetValueManager()),
utils::ValueType::Tmp);
}
node->base.type_ = current_type_; node->base.type_ = current_type_;
} }
@ -1433,7 +1426,10 @@ void TypeCheckVisitor::CollectTypeExpressionContext(const TypeExpression& type_e
utils::IdType TypeCheckVisitor::TypeInContext(utils::IdType type, utils::IdType TypeCheckVisitor::TypeInContext(utils::IdType type,
const std::unordered_map<std::string, utils::IdType>& context) { const std::unordered_map<std::string, utils::IdType>& context) {
info::type::Type type_in_context = *context_manager_.GetAnyValue(type); info::type::Type type_in_context = *context_manager_.GetAnyValue(type);
type_in_context.InContext(context); auto maybe_new_type = type_in_context.InContext(context);
if (maybe_new_type.has_value()) {
return maybe_new_type.value();
}
return context_manager_.AddValue(std::move(type_in_context), utils::ValueType::Tmp); return context_manager_.AddValue(std::move(type_in_context), utils::ValueType::Tmp);
} }

View file

@ -920,9 +920,13 @@ void TypedPrintVisitor::Visit(TypeExpression* node) {
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName(); out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
} }
out_ << ") "; out_ << ")";
if (node->array_size.has_value()) { if (node->array_size.has_value()) {
out_ << "[array size: " << node->array_size.value() << ']'; out_ << " [array size: " << node->array_size.value() << ']';
}
if (node->is_optional) {
out_ << " [optional]";
} }
out_ << "] ("; out_ << "] (";

View file

@ -17,7 +17,7 @@ struct (Complex : #Value) =
struct Task = struct Task =
& name : String & name : String
& duration : Float & duration : Float!
class Employee = class Employee =
& name : String & name : String

View file

@ -149,7 +149,7 @@ typeclass Show =
& var show : -> String & var show : -> String
typeclass Read = typeclass Read =
& var read : String -> Read & read : String -> Read
typeclass (Str : #Show #Read) typeclass (Str : #Show #Read)
@ -179,9 +179,11 @@ typeclass Enum =
// //
decl print : String -> Unit namespace IO {
decl scan : -> String decl print : String -> Unit
decl random : -> Int // TODO decl scan : -> String
decl random : -> Int // TODO
}
// //
@ -211,19 +213,46 @@ def ( -- ) : begin end = {
}) })
} }
decl func : String -> Int -> Int // decl func : String -> Int -> Int
def func : s i = { // def func : s i = {
; print: s // ; print: s
var x = s // var x = s
; print: (i.show:) // ; print: (i.show:)
return 5 // return 5
} // }
//
// exec main {
// for i in 0--19 do func: "a" (i * 2 +. 3)
// ; print: ({
// if true then bring scan: else { ; print: "aaa" }
// bring "nothing"
// ; print: "aaa"
// })
// }
decl scan_int : -> Int
def scan_int = Int.read: (IO.scan:)
decl print_int : Int -> Unit
def print_int : x = IO.print: (x.show:)
decl scan_anything ('A : #Read) : -> 'A
def scan_anything = 'A.read: (IO.scan:)
decl print_anything ('A : #Show) : 'A -> Unit
def print_anything : x = IO.print: (x.show:)
/*
struct Array 'A = & data : 'A_0
namespace Array {
decl construct : 'A_0 -> Array
def construct: x = $(Array 'A) & data = x
} // TODO: construct decl + default def -> segfault
*/
exec main { exec main {
for i in 0--19 do func: "a" (i * 2 +. 3) var n = scan_anything Int:
; print: ({ var a = for _ in 0--n do scan_int:
if true then bring scan: else { ; print: "aaa" } ; print_anything Int: n
bring "nothing"
; print: "aaa"
})
} }