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

View file

@ -44,7 +44,7 @@ public:
}
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:
utils::AbstractTypeModifier modifier_;
@ -81,9 +81,7 @@ public:
return class_modifier_;
}
std::string ToString() const {
return "Defined";
}
std::string ToString() const;
private:
utils::IdType type_id_; // in defined types
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())) {
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) {

View file

@ -69,7 +69,7 @@ int main(int argc, char** argv) { // TODO, only test version
try {
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"});
@ -80,7 +80,7 @@ int main(int argc, char** argv) { // TODO, only test version
const info::GlobalInfo::PartitionInfo& main_partition =
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,
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 abstract_type = AddGraphIdLocalAbstractTypes(graph_id);
abstract_type = context_manager_.ToModifiedValue(abstract_type,
ClassInternalsModifierToValueType(node->modifier));
if (node->modifier != utils::ClassInternalsModifier::Static) {
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()) {
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();
// make parameter local types
VisitDefinedType(type_info, {}, ClassInternalsModifierToValueType(node->modifier));
VisitDefinedType(type_info, {}, utils::ValueType::Tmp, false);
utils::IdType type = current_type_;
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);
if (type_namespaces_.count(node->link_type_id_.value()) != 0) {
@ -82,7 +76,9 @@ void TypeCheckVisitor::Visit(Namespace* node) {
Visit(&node->scope);
namespace_visitor_.ExitNamespace();
context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
if (node->link_type_id_.has_value()) {
@ -134,6 +130,7 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaratio
}
context_manager_.EnterContext();
for (auto& parameter : node->parameters) {
current_type_ = context_manager_.AddValue(
info::type::AbstractType(utils::AbstractTypeModifier::Abstract,
@ -143,7 +140,9 @@ void TypeCheckVisitor::Visit(FunctionDeclaration* node) { // function declaratio
context_manager_.DefineLocalType(parameter->type, current_type_);
}
Visit(node->type.get());
context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
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);
is_in_statement_ = false;
@ -336,11 +337,13 @@ void TypeCheckVisitor::Visit(TypeclassDefinitionStatement* node) {
void TypeCheckVisitor::Visit(PartitionStatement* node) {
is_in_statement_ = true;
context_manager_.EnterContext();
Visitor::Visit(node->value);
context_manager_.ExitContext();
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
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_;
}
@ -623,7 +626,7 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
utils::IsConstModifierToValueType(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;
Visitor::Visit(node->statement);
@ -791,6 +794,14 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
&node->base);
}
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);
@ -839,6 +850,8 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
Visitor::Visit(function_declaration->type->types.back());
current_type_ = TypeInContext(current_type_, context);
context_manager_.ExitContext();
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()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
@ -915,6 +926,9 @@ void TypeCheckVisitor::Visit(TypeConstructorParameter*) {} // Handeled in TypeCo
// TODO: check for tuples
// TODO: move, etc.
void TypeCheckVisitor::Visit(TypeConstructor* node) {
context_manager_.EnterContext();
if (!node->constructor->constructor_id_.has_value()) {
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();
AddTypeParameterLocalTypes(&type_info);
if (constructor_info.constructor_tuple_node.has_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());
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_)) {
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);
std::optional<info::type::VariantType*> maybe_variant_type =
@ -1008,6 +1022,8 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) {
context_manager_.GetValueManager()),
utils::ValueType::Tmp);
context_manager_.ExitContext();
node->base.type_ = current_type_;
}
@ -1193,9 +1209,9 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
if (!context_manager_.DefineVariable(node->name, type)) {
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());
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);
}
}
@ -1293,7 +1309,7 @@ void TypeCheckVisitor::Visit(TypeExpression* node) {
&node->base);
}
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp);
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, true);
} else {
error_handling::HandleTypecheckError("Type not found", node->base);
}
@ -1542,7 +1558,7 @@ std::optional<FunctionDeclaration*>
&node->base);
}
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp);
VisitDefinedType(maybe_type_info.value(), context, utils::ValueType::Tmp, true);
maybe_function_declaration =
FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(),
@ -1582,7 +1598,7 @@ std::optional<FunctionDeclaration*> TypeCheckVisitor::FindFunctionAndUpdate(Func
&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 =
FindDefinedTypeFunctionAndUpdate(node,
maybe_type_info.value(),
@ -1635,15 +1651,15 @@ std::optional<FunctionDeclaration*>
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) {
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
}
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;
return maybe_function_declaration;
@ -1664,14 +1680,14 @@ std::optional<FunctionDeclaration*>
// 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) {
error_handling::HandleTypecheckError("Typeclass function has wrong modifier (abstract type)", node->base);
}
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

View file

@ -1,5 +1,6 @@
// for clangd
#include "../include/types.hpp"
#include <string>
#include <variant>
namespace info::type {
@ -64,6 +65,10 @@ std::optional<utils::IdType> DefinedType::GetFieldType(const std::string& name,
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) {

View file

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

View file

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

View file

@ -258,13 +258,13 @@ def print_anything : x = IO.print: (x.show:)
//
// return a_copy
// }
/*
struct Array 'A = & data : 'A_0
namespace Array {
decl of : 'A_0 -> Array
def of: x = $(Array 'A) & data = x
}*/
struct Array 'A = & 'A // 'A_0
// namespace Array {
// decl of : 'A_0 -> (Array 'A)
// def of : x = $(Array 'A) & data = x
// }
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)
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 {
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:
; IO.print: b
var & d & e & f = scan_three: