mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-05 22:48:42 +00:00
fixes, parametrized type constructor not fork (segfault)
This commit is contained in:
parent
7f4266821c
commit
91f9affadc
8 changed files with 89 additions and 58 deletions
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue