fixes, parametrized type constructor not fork (segfault)

This commit is contained in:
ProgramSnail 2023-05-23 20:05:48 +03:00
parent 7f4266821c
commit 91f9affadc
8 changed files with 89 additions and 58 deletions

View file

@ -1,6 +1,7 @@
#pragma once #pragma once
// for clangd // for clangd
#include "error_handling.hpp"
#include "interpreter_tree.hpp" #include "interpreter_tree.hpp"
#include "typeclass_graph.hpp" #include "typeclass_graph.hpp"
#include "types.hpp" #include "types.hpp"
@ -211,8 +212,11 @@ private:
void VisitDefinedType(info::definition::AnyType* defined_type, void VisitDefinedType(info::definition::AnyType* defined_type,
const std::unordered_map<std::string, utils::IdType>& context, const std::unordered_map<std::string, utils::IdType>& context,
utils::ValueType modifier) { utils::ValueType modifier,
bool make_scoped) {
if (make_scoped) {
context_manager_.EnterContext(); context_manager_.EnterContext();
}
AddTypeParameterLocalTypes(defined_type); AddTypeParameterLocalTypes(defined_type);
Visitor::Visit(defined_type->node->value); Visitor::Visit(defined_type->node->value);
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
@ -222,8 +226,10 @@ private:
defined_type->modifier, defined_type->modifier,
context_manager_.GetValueManager()), context_manager_.GetValueManager()),
modifier); modifier);
if (make_scoped) {
context_manager_.ExitContext(); context_manager_.ExitContext();
} }
}
void AddTypeParameterLocalTypes(info::definition::AnyType* type_info) { void AddTypeParameterLocalTypes(info::definition::AnyType* type_info) {
for (auto& parameter : type_info->node->definition->parameters) { for (auto& parameter : type_info->node->definition->parameters) {

View file

@ -44,7 +44,7 @@ public:
} }
std::string ToString() const { std::string ToString() const {
return "Abstract " + std::to_string(graph_id_); return "Abstract " + std::to_string(graph_id_) + " ( " + typeclass_graph_.GetVertex(graph_id_).name + " )";
} }
private: private:
utils::AbstractTypeModifier modifier_; utils::AbstractTypeModifier modifier_;
@ -81,9 +81,7 @@ public:
return class_modifier_; return class_modifier_;
} }
std::string ToString() const { std::string ToString() const;
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)
@ -374,7 +372,7 @@ public:
if (!std::holds_alternative<T>(types_.at(type_id).first.GetType())) { if (!std::holds_alternative<T>(types_.at(type_id).first.GetType())) {
return std::nullopt; return std::nullopt;
} }
return &std::get<T>(types_.at(type_id).first.GetType()); return &std::get<T>(types_[type_id].first.GetType());
} }
Type* GetAnyValue(utils::IdType type_id) { Type* GetAnyValue(utils::IdType type_id) {

View file

@ -69,7 +69,7 @@ int main(int argc, char** argv) { // TODO, only test version
try { try {
type_check_visitor.VisitSourceFile(source_file.get()); type_check_visitor.VisitSourceFile(source_file.get());
} catch (...) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); } } catch (bool) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"}); std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"});
@ -80,7 +80,7 @@ int main(int argc, char** argv) { // TODO, only test version
const info::GlobalInfo::PartitionInfo& main_partition = const info::GlobalInfo::PartitionInfo& main_partition =
global_info.GetPartitionInfo(maybe_main_partition_id.value()); global_info.GetPartitionInfo(maybe_main_partition_id.value());
// std::cout << "\n---------------------------------- Execution -------------------------------------\n\n"; std::cout << "\n---------------------------------- Execution -------------------------------------\n\n";
interpreter::ExecuteVisitor execute_visitor(global_info, interpreter::ExecuteVisitor execute_visitor(global_info,
type_context_manager, type_context_manager,

View file

@ -40,15 +40,12 @@ void TypeCheckVisitor::Visit(Namespace* node) {
utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_; utils::IdType graph_id = global_info_.GetTypeclassInfo(node->link_typeclass_id_.value()).graph_id_;
utils::IdType abstract_type = AddGraphIdLocalAbstractTypes(graph_id); utils::IdType abstract_type = AddGraphIdLocalAbstractTypes(graph_id);
abstract_type = context_manager_.ToModifiedValue(abstract_type,
ClassInternalsModifierToValueType(node->modifier));
if (node->modifier != utils::ClassInternalsModifier::Static) { if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.DefineVariable(utils::ClassInternalVarName, context_manager_.DefineVariable(utils::ClassInternalVarName,
abstract_type); context_manager_.ToModifiedValue(abstract_type,
ClassInternalsModifierToValueType(node->modifier)));
} }
AddGraphIdLocalAbstractTypes(graph_id);
} 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());
@ -58,17 +55,14 @@ void TypeCheckVisitor::Visit(Namespace* node) {
info::definition::AnyType* type_info = maybe_type_info.value(); info::definition::AnyType* type_info = maybe_type_info.value();
// make parameter local types VisitDefinedType(type_info, {}, utils::ValueType::Tmp, false);
VisitDefinedType(type_info, {}, ClassInternalsModifierToValueType(node->modifier));
utils::IdType type = current_type_; utils::IdType type = current_type_;
if (node->modifier != utils::ClassInternalsModifier::Static) { if (node->modifier != utils::ClassInternalsModifier::Static) {
context_manager_.DefineVariable(utils::ClassInternalVarName, type); context_manager_.DefineVariable(utils::ClassInternalVarName,
context_manager_.ToModifiedValue(type, ClassInternalsModifierToValueType(node->modifier)));
} }
type = context_manager_.ToModifiedValue(type, utils::ValueType::Tmp);
AddGraphIdLocalTypes(type_info->type.node->graph_id_, type); AddGraphIdLocalTypes(type_info->type.node->graph_id_, type);
if (type_namespaces_.count(node->link_type_id_.value()) != 0) { if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
@ -82,7 +76,9 @@ void TypeCheckVisitor::Visit(Namespace* node) {
Visit(&node->scope); Visit(&node->scope);
namespace_visitor_.ExitNamespace(); namespace_visitor_.ExitNamespace();
context_manager_.ExitContext(); context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
if (node->link_type_id_.has_value()) { if (node->link_type_id_.has_value()) {
@ -134,6 +130,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaratio
} }
context_manager_.EnterContext(); context_manager_.EnterContext();
for (auto& parameter : node->parameters) { for (auto& parameter : node->parameters) {
current_type_ = context_manager_.AddValue( current_type_ = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract, info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
@ -143,7 +140,9 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaratio
context_manager_.DefineLocalType(parameter->type, current_type_); context_manager_.DefineLocalType(parameter->type, current_type_);
} }
Visit(node->type.get()); Visit(node->type.get());
context_manager_.ExitContext(); context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
if (!was_in_statement) { if (!was_in_statement) {
@ -286,6 +285,8 @@ void TypeCheckVisitor::Visit(TypeDefinitionStatement* node) {
} }
} }
// TODO: check that type definition is correct ??
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
is_in_statement_ = false; is_in_statement_ = false;
@ -336,11 +337,13 @@ void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
void TypeCheckVisitor::Visit(PartitionStatement* node) { void TypeCheckVisitor::Visit(PartitionStatement* node) {
is_in_statement_ = true; is_in_statement_ = true;
context_manager_.EnterContext(); context_manager_.EnterContext();
Visitor::Visit(node->value); Visitor::Visit(node->value);
context_manager_.ExitContext(); context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit); current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
is_in_statement_ = false; is_in_statement_ = false;
@ -435,7 +438,7 @@ void TypeCheckVisitor::Visit(TypeConstructorPattern* node) { // TODO: match name
} }
} }
VisitDefinedType(&type_info, context, utils::ValueType::Tmp); VisitDefinedType(&type_info, context, utils::ValueType::Tmp, true);
node->base.type_ = current_type_; node->base.type_ = current_type_;
} }
@ -623,7 +626,7 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
utils::IsConstModifierToValueType(node->variable_modifier)); utils::IsConstModifierToValueType(node->variable_modifier));
is_const_definition_ = node->variable_modifier; is_const_definition_ = node->variable_modifier;
Visitor::Visit(node->variable); // type passed to variable definition throught current_type_ Visitor::Visit(node->variable); // type passed to variable definition through current_type_
is_const_definition_ = std::nullopt; is_const_definition_ = std::nullopt;
Visitor::Visit(node->statement); Visitor::Visit(node->statement);
@ -791,6 +794,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
&node->base); &node->base);
} }
context[parameter_name] = current_type_; context[parameter_name] = current_type_;
context_manager_.DefineLocalType(
function_declaration->parameters[i]->type,
context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
function_declaration->parameters[i]->graph_id_,
typeclass_graph_),
utils::ValueType::Tmp));
} }
size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0); size_t index_shift = (node->is_method_of_first_argument_ ? 1 : 0);
@ -839,6 +850,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
Visitor::Visit(function_declaration->type->types.back()); Visitor::Visit(function_declaration->type->types.back());
current_type_ = TypeInContext(current_type_, context); current_type_ = TypeInContext(current_type_, context);
context_manager_.ExitContext();
node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp); node->base.type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
} }
@ -854,8 +867,6 @@ 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_;
} }
@ -915,6 +926,9 @@ void TypeCheckVisitor::Visit(TypeConstructorParameter*) {} // Handeled in TypeCo
// TODO: check for tuples // TODO: check for tuples
// TODO: move, etc. // TODO: move, etc.
void TypeCheckVisitor::Visit(TypeConstructor* node) { void TypeCheckVisitor::Visit(TypeConstructor* node) {
context_manager_.EnterContext();
if (!node->constructor->constructor_id_.has_value()) { if (!node->constructor->constructor_id_.has_value()) {
error_handling::HandleTypecheckError("Type constructor name not found", node->base); error_handling::HandleTypecheckError("Type constructor name not found", node->base);
} }
@ -945,6 +959,8 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
info::definition::AnyType& type_info = *maybe_type_info.value(); info::definition::AnyType& type_info = *maybe_type_info.value();
AddTypeParameterLocalTypes(&type_info);
if (constructor_info.constructor_tuple_node.has_value()) { if (constructor_info.constructor_tuple_node.has_value()) {
TupleType* constructor_fields = constructor_info.constructor_tuple_node.value(); TupleType* constructor_fields = constructor_info.constructor_tuple_node.value();
@ -968,7 +984,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
Visitor::Visit(constructor_fields->entities[i].second.get()); Visitor::Visit(constructor_fields->entities[i].second.get());
utils::IdType parameter_type = TypeInContext(current_type_, context); utils::IdType parameter_type = TypeInContext(current_type_, context);
Visitor::Visit(node->parameters[i].value); Visitor::Visit(node->parameters[i].value); // TODO: segfault here (??)
if (!context_manager_.EqualValues(parameter_type, current_type_)) { if (!context_manager_.EqualValues(parameter_type, current_type_)) {
error_handling::HandleTypecheckError("Type constructor: wrong parameter type", node->base); error_handling::HandleTypecheckError("Type constructor: wrong parameter type", node->base);
@ -981,8 +997,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
} }
} }
// TODO: replace with VisitDefinedType ??
AddTypeParameterLocalTypes(&type_info);
Visitor::Visit(type_info.node->value); Visitor::Visit(type_info.node->value);
std::optional<info::type::VariantType*> maybe_variant_type = std::optional<info::type::VariantType*> maybe_variant_type =
@ -1008,6 +1022,8 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
context_manager_.GetValueManager()), context_manager_.GetValueManager()),
utils::ValueType::Tmp); utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_; node->base.type_ = current_type_;
} }
@ -1193,9 +1209,9 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
if (!context_manager_.DefineVariable(node->name, type)) { if (!context_manager_.DefineVariable(node->name, type)) {
error_handling::HandleTypecheckError("Variable name already present in context", node->base); error_handling::HandleTypecheckError("Variable name already present in context", node->base);
} }
if (node->type.has_value()) { if (node->type.has_value()) { // TODO: check
Visitor::Visit(node->type.value()); Visitor::Visit(node->type.value());
if (!context_manager_.EqualValues(type, current_type_)) { // TODO ?? if (!context_manager_.EqualValues(type, current_type_)) {
error_handling::HandleTypecheckError("Wrong type annotation in annotated name", node->base); error_handling::HandleTypecheckError("Wrong type annotation in annotated name", node->base);
} }
} }
@ -1293,7 +1309,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
&node->base); &node->base);
} }
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp); VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, true);
} else { } else {
error_handling::HandleTypecheckError("Type not found", node->base); error_handling::HandleTypecheckError("Type not found", node->base);
} }
@ -1542,7 +1558,7 @@ std::optional<FunctionDeclaration*>
&node->base); &node->base);
} }
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp); VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, true);
maybe_function_declaration = maybe_function_declaration =
FindDefinedTypeFunctionAndUpdate(node, FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(), maybe_type_info.value(),
@ -1582,7 +1598,7 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
&node->base); &node->base);
} }
VisitDefinedType(maybe_type_info.value(), {}, utils::ValueType::Tmp); // TODO: context ?? VisitDefinedType(maybe_type_info.value(), {}, utils::ValueType::Tmp, true); // TODO: context ??
maybe_function_declaration = maybe_function_declaration =
FindDefinedTypeFunctionAndUpdate(node, FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(), maybe_type_info.value(),
@ -1635,15 +1651,15 @@ std::optional<FunctionDeclaration*>
error_handling::HandleTypecheckError("Function not present in typeclass (abstract type)", node->base); error_handling::HandleTypecheckError("Function not present in typeclass (abstract type)", node->base);
} }
// TODO: check that const functions not called on var expressions ?? // TODO: check that const functions not called on var expressions
if ((maybe_typeclass_function_info.value()->modifier != utils::ClassInternalsModifier::Static) != is_method) { if ((maybe_typeclass_function_info.value()->modifier != utils::ClassInternalsModifier::Static) != is_method) {
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base); error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
} }
node->graph_id_ = graph_id; node->graph_id_ = graph_id;
AddGraphIdLocalAbstractTypes(node->graph_id_.value()); // check AddGraphIdLocalAbstractTypes(graph_id); // check
node->abstract_type_name_ = typeclass_graph_.GetVertex(node->graph_id_.value()).name; node->abstract_type_name_ = typeclass_graph_.GetVertex(graph_id).name;
maybe_function_declaration = maybe_typeclass_function_info.value()->declaration; maybe_function_declaration = maybe_typeclass_function_info.value()->declaration;
return maybe_function_declaration; return maybe_function_declaration;
@ -1664,14 +1680,14 @@ std::optional<FunctionDeclaration*>
// error_handling::HandleTypecheckError("Function is not declared in type", node->base); // error_handling::HandleTypecheckError("Function is not declared in type", node->base);
} }
// TODO: check that const functions not called on var expressions ?? // TODO: check that const functions not called on var expressions
if ((maybe_type_function_info.value()->modifier != utils::ClassInternalsModifier::Static) != is_method) { if ((maybe_type_function_info.value()->modifier != utils::ClassInternalsModifier::Static) != is_method) {
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base); error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
} }
node->graph_id_ = defined_type->type.node->graph_id_; node->graph_id_ = defined_type->type.node->graph_id_;
AddGraphIdLocalTypes(node->graph_id_.value(), type); AddGraphIdLocalTypes(defined_type->type.node->graph_id_, type);
// type defined -> abstract type name not needed // type defined -> abstract type name not needed

View file

@ -1,5 +1,6 @@
// for clangd // for clangd
#include "../include/types.hpp" #include "../include/types.hpp"
#include <string>
#include <variant> #include <variant>
namespace info::type { namespace info::type {
@ -64,6 +65,10 @@ std::optional<utils::IdType> DefinedType::GetFieldType(const std::string& name,
return std::nullopt; return std::nullopt;
} }
std::string DefinedType::ToString() const {
return "Defined " + std::to_string(type_id_) + " ( " + type_manager_->GetAnyValue(type_)->ToString() + " )";
}
// //
std::optional<utils::IdType> TupleType::InContext(const std::unordered_map<std::string, utils::IdType>& context) { std::optional<utils::IdType> TupleType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {

View file

@ -26,7 +26,13 @@ ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
case ClassInternalsModifier::Var: case ClassInternalsModifier::Var:
return ValueType::Var; return ValueType::Var;
case ClassInternalsModifier::Static: case ClassInternalsModifier::Static:
throw std::bad_cast(); // ?? error_handling::HandleInternalError("Can't cast ClassInternalsModifier",
"ClassInternalsModifierToValueType",
std::nullopt);
break;
default:
// error
break;
} }
exit(1); // unreachable exit(1); // unreachable

View file

@ -9,13 +9,13 @@ def test_arrays = {
var arr6 <- String._new_array: 10 var arr6 <- String._new_array: 10
var arr6_reference = ^arr6 var arr6_reference = ^arr6
//
// const elem1 = arr1`0 const elem1 = arr1`0
// var elem2 = arr1`2 var elem2 = arr1`2
// const ref1 = ^arr1`1 const ref1 = ^arr1`1
// var ref2 = ^arr1`3 var ref2 = ^arr1`3
// ; arr1`1 = 123 ; arr1`1 = 123
//
// ; ~ref1 = arr1`2 // set value ; ~ref1 = arr1`2 // set value
// ; ref1 = ref2 // set pointer / reference ; ref1 = ref2 // set pointer / reference
} }

View file

@ -258,13 +258,13 @@ def print_anything : x = IO.print: (x.show:)
// //
// return a_copy // return a_copy
// } // }
/*
struct Array 'A = & data : 'A_0
namespace Array { struct Array 'A = & 'A // 'A_0
decl of : 'A_0 -> Array
def of: x = $(Array 'A) & data = x // namespace Array {
}*/ // decl of : 'A_0 -> (Array 'A)
// def of : x = $(Array 'A) & data = x
// }
struct ThreeTuple = & String & String & String struct ThreeTuple = & String & String & String
@ -274,11 +274,11 @@ def scan_three_t = $ThreeTuple & IO.scan: & IO.scan: & IO.scan:
decl scan_three : -> (& String & String & String) decl scan_three : -> (& String & String & String)
def scan_three = & IO.scan: & IO.scan: & IO.scan: def scan_three = & IO.scan: & IO.scan: & IO.scan:
// var n = scan_anything Int:
// var a = $(Array Int) & data = (for _ in 0--n do scan_int:)
// ; print_anything Int: n
exec main { exec main {
var n = scan_anything Int:
var x = $(Array Int) & 0 // (for _ in 0--n do scan_int:)
; print_anything Int: n
var & a & b & c = scan_three_t: var & a & b & c = scan_three_t:
; IO.print: b ; IO.print: b
var & d & e & f = scan_three: var & d & e & f = scan_three: