mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-06 06:58:45 +00:00
fixes , type check visitor part
This commit is contained in:
parent
634ade6875
commit
6ba31969d2
2 changed files with 178 additions and 90 deletions
|
|
@ -53,10 +53,10 @@ void PrintVisitor::Visit(Namespace* node) {
|
|||
out_ << "[Namespace] ";
|
||||
if (node->modifier.has_value()) {
|
||||
switch (node->modifier.value()) {
|
||||
case Namespace::Const:
|
||||
case utils::IsConstModifier::Const:
|
||||
out_ << "const ";
|
||||
break;
|
||||
case Namespace::Var:
|
||||
case utils::IsConstModifier::Var:
|
||||
out_ << "var ";
|
||||
break;
|
||||
}
|
||||
|
|
@ -88,13 +88,13 @@ void PrintVisitor::Visit(ImportStatement* node) {
|
|||
void PrintVisitor::Visit(AliasDefinitionStatement* node) {
|
||||
out_ << "[Alias ";
|
||||
switch (node->modifier) {
|
||||
case AliasDefinitionStatement::Alias:
|
||||
case utils::AliasModifier::Alias:
|
||||
out_ << "alias";
|
||||
break;
|
||||
case AliasDefinitionStatement::Type:
|
||||
case utils::AliasModifier::Type:
|
||||
out_ << "type";
|
||||
break;
|
||||
case AliasDefinitionStatement::Let:
|
||||
case utils::AliasModifier::Let:
|
||||
out_ << "let";
|
||||
break;
|
||||
}
|
||||
|
|
@ -108,10 +108,10 @@ void PrintVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
void PrintVisitor::Visit(VariableDefinitionStatement* node) {
|
||||
out_ << "[Variable ";
|
||||
switch (node->modifier) {
|
||||
case VariableDefinitionStatement::Const:
|
||||
case utils::IsConstModifier::Const:
|
||||
out_ << "const";
|
||||
break;
|
||||
case VariableDefinitionStatement::Var:
|
||||
case utils::IsConstModifier::Var:
|
||||
out_ << "var";
|
||||
break;
|
||||
}
|
||||
|
|
@ -145,10 +145,10 @@ void PrintVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
void PrintVisitor::Visit(TypeDefinitionStatement* node) {
|
||||
out_ << "[Type ";
|
||||
switch (node->modifier) {
|
||||
case TypeDefinitionStatement::Struct:
|
||||
case utils::ClassModifier::Struct:
|
||||
out_ << "struct";
|
||||
break;
|
||||
case TypeDefinitionStatement::Class:
|
||||
case utils::ClassModifier::Class:
|
||||
out_ << "class";
|
||||
break;
|
||||
}
|
||||
|
|
@ -162,10 +162,10 @@ void PrintVisitor::Visit(TypeDefinitionStatement* node) {
|
|||
void PrintVisitor::Visit(AbstractTypeDefinitionStatement* node) {
|
||||
out_ << "[AbstractType ";
|
||||
switch (node->modifier) {
|
||||
case AbstractTypeDefinitionStatement::Basic:
|
||||
case utils::AbstractTypeModifier::Basic:
|
||||
out_ << "basic";
|
||||
break;
|
||||
case AbstractTypeDefinitionStatement::Abstract:
|
||||
case utils::AbstractTypeModifier::Abstract:
|
||||
out_ << "abstract";
|
||||
break;
|
||||
}
|
||||
|
|
@ -193,10 +193,10 @@ void PrintVisitor::Visit(TypeclassDefinitionStatement* node) {
|
|||
void PrintVisitor::Visit(FunctionDefinition* node) {
|
||||
out_ << "[FunctionDefinition ";
|
||||
switch (node->modifier) {
|
||||
case FunctionDefinition::Operator:
|
||||
case utils::FunctionTypeModifier::Operator:
|
||||
out_ << "operator";
|
||||
break;
|
||||
case FunctionDefinition::Function:
|
||||
case utils::FunctionTypeModifier::Function:
|
||||
out_ << "function";
|
||||
break;
|
||||
}
|
||||
|
|
@ -397,10 +397,10 @@ void PrintVisitor::Visit(ReferenceExpression* node) {
|
|||
out_ << "[ReferenceExpression ";
|
||||
for (auto& reference : node->references) {
|
||||
switch (reference) {
|
||||
case utils::ReferenceType::Reference:
|
||||
case utils::ReferenceModifier::Reference:
|
||||
out_ << '~';
|
||||
break;
|
||||
case utils::ReferenceType::UniqueReference:
|
||||
case utils::ReferenceModifier::UniqueReference:
|
||||
out_ << '@';
|
||||
break;
|
||||
}
|
||||
|
|
@ -481,10 +481,10 @@ void PrintVisitor::Visit(TypeConstructorParameter* node) {
|
|||
if (node->name.has_value()) {
|
||||
Visit(&node->name.value());
|
||||
switch (node->asignment_modifier.value()) {
|
||||
case TypeConstructorParameter::Assign:
|
||||
case utils::AssignmentModifier::Assign:
|
||||
out_ << " = ";
|
||||
break;
|
||||
case TypeConstructorParameter::Move:
|
||||
case utils::AssignmentModifier::Move:
|
||||
out_ << " <- ";
|
||||
break;
|
||||
}
|
||||
|
|
@ -650,10 +650,10 @@ void PrintVisitor::Visit(ExtendedScopedAnyType* node) {
|
|||
out_ << "[ExtendedScopedAnyType ";
|
||||
for (auto& reference : node->references) {
|
||||
switch (reference) {
|
||||
case utils::ReferenceType::Reference:
|
||||
case utils::ReferenceModifier::Reference:
|
||||
out_ << '~';
|
||||
break;
|
||||
case utils::ReferenceType::UniqueReference:
|
||||
case utils::ReferenceModifier::UniqueReference:
|
||||
out_ << '@';
|
||||
break;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -235,13 +235,7 @@ void TypeCheckVisitor::Visit(AnyAnnotatedType* node) {
|
|||
// TODO <----- | current position |
|
||||
|
||||
// TODO
|
||||
void Visitor::Visit(TypeConstructorPatternParameter* node) {
|
||||
if (node->name.has_value()) {
|
||||
Visit(&node->name.value());
|
||||
}
|
||||
node->
|
||||
Visit(node->value);
|
||||
}
|
||||
void Visitor::Visit(TypeConstructorPatternParameter* node) {} // Handled in TypeConstructorPattern
|
||||
|
||||
// TODO
|
||||
void Visitor::Visit(TypeConstructorPattern* node) {
|
||||
|
|
@ -251,10 +245,99 @@ void Visitor::Visit(TypeConstructorPattern* node) {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
||||
if (!node->constructor->constructor_id_.has_value()) {
|
||||
error_handling::HandleTypecheckError("Type constructor name not found", node->base);
|
||||
}
|
||||
|
||||
if (!node->constructor->type_id_.has_value()) {
|
||||
error_handling::HandleInternalError("Type constructor without type", "TypeCheckVisitor.TypeConstructor");
|
||||
}
|
||||
|
||||
utils::IdType constructor_id = node->constructor->constructor_id_.value();
|
||||
|
||||
info::definition::Constructor constructor_info = namespace_visitor_.GetGlobalInfo()->GetConstructorInfo(constructor_id);
|
||||
|
||||
utils::IdType type_id = constructor_info.type_id;
|
||||
|
||||
std::unordered_map<std::string, utils::IdType> context;
|
||||
CollectTypeExpressionContext(*node->constructor, context);
|
||||
|
||||
// TODO: handle alias types
|
||||
const std::optional<info::definition::AnyType>& maybe_type_info =
|
||||
namespace_visitor_.GetGlobalInfo()->GetTypeInfo<info::definition::AnyType>(type_id);
|
||||
|
||||
if (!maybe_type_info.has_value()) { // TODO
|
||||
error_handling::HandleInternalError("Implemented only for AnyType", "TypeCheckVisitor.LambdaFunction");
|
||||
}
|
||||
|
||||
const info::definition::AnyType& type_info = maybe_type_info.value();
|
||||
|
||||
if (constructor_info.constructor_tuple_node.has_value()) {
|
||||
|
||||
TupleType* constructor_fields = constructor_info.constructor_tuple_node.value();
|
||||
|
||||
if (constructor_fields->entities.size() != node->parameters.size()) {
|
||||
error_handling::HandleTypecheckError("Type constructor parameters count mismatch", node->base);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
||||
// TODO: remove variable on move
|
||||
if (node->parameters[i].name.has_value()) {
|
||||
if (!constructor_fields->entities[i].first.has_value()
|
||||
|| constructor_fields->entities[i].first.value().name != node->parameters[i].name.value().name) {
|
||||
error_handling::HandleTypecheckError("Type constructor: name of parameter and name in constructor don't match each other", node->base);
|
||||
}
|
||||
} else {
|
||||
if (constructor_fields->entities[i].first.has_value()) {
|
||||
error_handling::HandleTypecheckError("Type constructor: unnamed pprameter corresponds named field", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
Visitor::Visit(constructor_fields->entities[i].second.get());
|
||||
utils::IdType parameter_type = TypeInContext(current_type_, context);
|
||||
|
||||
Visitor::Visit(node->parameters[i].value);
|
||||
|
||||
context_manager_.EqualTypes(TypeInContext(parameter_type, context), current_type_);
|
||||
}
|
||||
|
||||
} else {
|
||||
if (node->parameters.size() > 0) {
|
||||
error_handling::HandleTypecheckError("Parameters for untyped type constructor", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
Visitor::Visit(*type_info.value);
|
||||
current_type_ = TypeInContext(current_type_, context);
|
||||
}
|
||||
*/
|
||||
|
||||
void TypeCheckVisitor::Visit(MatchCase* node) {
|
||||
// value type passed as current_type_
|
||||
is_const_definition_ = true; // TODO: or var??
|
||||
Visitor::Visit(node->value);
|
||||
|
||||
switch (node->value.index()) {
|
||||
case 0:
|
||||
context_manager_.DefineVariable(std::get<0>(node->value)->name,
|
||||
current_type_,
|
||||
is_const_definition_.value());
|
||||
break;
|
||||
case 1:
|
||||
|
||||
Visitor::Visit(*std::get<1>(node->value).get());
|
||||
|
||||
break;
|
||||
case 2:
|
||||
Visit(std::get<std::unique_ptr<TypeConstructorPattern>>(node->value).get());
|
||||
break;
|
||||
default:
|
||||
// error
|
||||
break;
|
||||
}
|
||||
|
||||
is_const_definition_ = std::nullopt;
|
||||
|
||||
if (node->condition.has_value()) {
|
||||
|
|
@ -270,7 +353,7 @@ void TypeCheckVisitor::Visit(MatchCase* node) {
|
|||
// current_type_ from statement is current_type_ for MatchCase
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Match* node) { // TODO return variant type ?? (problems with same types)
|
||||
void TypeCheckVisitor::Visit(Match* node) {
|
||||
// TODO: types can be different in block statement
|
||||
utils::IdType type;
|
||||
|
||||
|
|
@ -304,7 +387,7 @@ void TypeCheckVisitor::Visit(Match* node) { // TODO return variant type ?? (prob
|
|||
current_type_ = type;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(Condition* node) { // TODO return variant type ?? (problem with same types)
|
||||
void TypeCheckVisitor::Visit(Condition* node) {
|
||||
// TODO: types can be different in statement
|
||||
utils::IdType type;
|
||||
|
||||
|
|
@ -369,7 +452,7 @@ void TypeCheckVisitor::Visit(ForLoop* node) {
|
|||
}
|
||||
|
||||
current_type_ = context_manager_.AddType(maybe_interval_type.value()->GetElementsType());
|
||||
Visitor::Visit(node->variable); // type passed to variable definition
|
||||
Visitor::Visit(node->variable); // type passed to variable definition throught current_type_
|
||||
|
||||
Visitor::Visit(node->statement);
|
||||
|
||||
|
|
@ -386,18 +469,19 @@ void TypeCheckVisitor::Visit(LoopLoop* node) {
|
|||
|
||||
// Statements, expressions, blocks, etc. -----------------
|
||||
|
||||
void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (problem with same types)
|
||||
void TypeCheckVisitor::Visit(Block* node) {
|
||||
// TODO: types can be different in statement
|
||||
utils::IdType type;
|
||||
|
||||
bool is_first_returned_type = true;
|
||||
bool is_type_found = false;
|
||||
|
||||
for (auto& statement : node->statements) {
|
||||
returned_type_ = std::nullopt;
|
||||
Visitor::Visit(statement);
|
||||
if (returned_type_.has_value()) {
|
||||
if (is_first_returned_type) {
|
||||
if (!is_type_found) {
|
||||
type = returned_type_.value();
|
||||
is_first_returned_type = false;
|
||||
is_type_found = true;
|
||||
} else {
|
||||
if (!context_manager_.EqualTypes(type, returned_type_.value())) {
|
||||
error_handling::HandleTypecheckError("Different return types in block", node->base);
|
||||
|
|
@ -406,7 +490,7 @@ void TypeCheckVisitor::Visit(Block* node) { // TODO return variant type ?? (prob
|
|||
}
|
||||
}
|
||||
|
||||
if (is_first_returned_type) {
|
||||
if (!is_type_found) {
|
||||
type = context_manager_.AddType(info::type::InternalType::Unit);
|
||||
}
|
||||
|
||||
|
|
@ -424,9 +508,8 @@ void TypeCheckVisitor::Visit(LoopControlExpression& node) { // enum
|
|||
|
||||
// Operators
|
||||
|
||||
// TODO
|
||||
// TODO: operator parameters (deduction?), etc.
|
||||
void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
||||
// TODO: Check, that type is not abstract ??
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunction(std::nullopt, node->operator_name);
|
||||
|
||||
if (!maybe_operator_id.has_value()) {
|
||||
|
|
@ -439,7 +522,7 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
||||
}
|
||||
|
||||
if (!operator_info.definition.has_value()) { // TODO: builtin
|
||||
if (!operator_info.definition.has_value()) { // TODO: builtin, etc.
|
||||
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
||||
}
|
||||
|
||||
|
|
@ -452,21 +535,24 @@ void TypeCheckVisitor::Visit(BinaryOperatorExpression* node) {
|
|||
}
|
||||
|
||||
Visitor::Visit(*operator_info.declaration.value().argument_types[0]);
|
||||
utils::IdType left_expression_type = current_type_;
|
||||
utils::IdType left_expression_type = current_type_; // TODO: type in context of deduced types
|
||||
|
||||
Visitor::Visit(node->left_expression);
|
||||
context_manager_.AddTypeRequirement(current_type_, left_expression_type); // TODO: ConstructAnyType
|
||||
if (!context_manager_.AddTypeRequirement(current_type_, left_expression_type)) {
|
||||
error_handling::HandleTypecheckError("Operator left expression has wrong type", node->base);
|
||||
}
|
||||
|
||||
Visitor::Visit(*operator_info.declaration.value().argument_types[1]);
|
||||
utils::IdType right_expression_type = current_type_;
|
||||
utils::IdType right_expression_type = current_type_; // TODO: type in context of deduced types
|
||||
|
||||
Visitor::Visit(node->right_expression);
|
||||
context_manager_.AddTypeRequirement(current_type_, right_expression_type); // TODO: ConstructAnyType
|
||||
|
||||
if (!context_manager_.AddTypeRequirement(current_type_, right_expression_type)) {
|
||||
error_handling::HandleTypecheckError("Operator right expression has wrong type", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
||||
// TODO: Check, that type is not abstract ??
|
||||
auto maybe_operator_id = namespace_visitor_.FindFunction({}, node->operator_name);
|
||||
|
||||
if (!maybe_operator_id.has_value()) {
|
||||
|
|
@ -479,7 +565,7 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
|||
error_handling::HandleTypecheckError("Operator declaration not found", node->base);
|
||||
}
|
||||
|
||||
if (!operator_info.definition.has_value()) { // TODO: builtin
|
||||
if (!operator_info.definition.has_value()) { // TODO: builtin, etc.
|
||||
error_handling::HandleTypecheckError("Operator definition not found", node->base);
|
||||
}
|
||||
|
||||
|
|
@ -492,10 +578,12 @@ void TypeCheckVisitor::Visit(UnaryOperatorExpression* node) {
|
|||
}
|
||||
|
||||
Visitor::Visit(*operator_info.declaration.value().argument_types[0]);
|
||||
utils::IdType expression_type = current_type_;
|
||||
utils::IdType expression_type = current_type_; // TODO: type in context of deduced types
|
||||
|
||||
Visitor::Visit(node->expression);
|
||||
context_manager_.AddTypeRequirement(current_type_, expression_type); // TODO: ConstructAnyType
|
||||
if (!context_manager_.AddTypeRequirement(current_type_, expression_type)) {
|
||||
error_handling::HandleTypecheckError("Operator expression has wrong type", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
||||
|
|
@ -507,15 +595,17 @@ void TypeCheckVisitor::Visit(ReferenceExpression* node) {
|
|||
|
||||
void TypeCheckVisitor::Visit(AccessExpression* node) {
|
||||
Visitor::Visit(node->id);
|
||||
context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Int), current_type_);
|
||||
// TODO: separate type for counting ?
|
||||
if (!context_manager_.EqualTypes(context_manager_.AddType(info::type::InternalType::Int), current_type_)) {
|
||||
error_handling::HandleTypecheckError("Access index has wrong type (not Int)", node->base);
|
||||
}
|
||||
|
||||
Visitor::Visit(node->name.get());
|
||||
|
||||
std::optional<info::type::ArrayType*> maybe_type_value = context_manager_.GetType<info::type::ArrayType>(current_type_);
|
||||
|
||||
if (!maybe_type_value.has_value()) {
|
||||
error_handling::HandleTypecheckError("Access type mismatch", node->base);
|
||||
error_handling::HandleTypecheckError("Access type is not array", node->base);
|
||||
// TODO: redifinitions for other types and tuples (with const index) ??
|
||||
}
|
||||
|
||||
current_type_ = maybe_type_value.value()->GetElementsType();
|
||||
|
|
@ -526,6 +616,7 @@ void TypeCheckVisitor::Visit(AccessExpression* node) {
|
|||
// TODO
|
||||
// TODO: builtin functions/methods
|
||||
// TODO: alias types, abstract types, etc.
|
||||
// TODO: deduce function parameter types
|
||||
void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
||||
std::optional<utils::IdType> maybe_function_id;
|
||||
std::unordered_map<std::string, utils::IdType> context;
|
||||
|
|
@ -556,8 +647,21 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
"TypeCheckVisitor.FunctionCallExpresssion");
|
||||
}
|
||||
|
||||
|
||||
std::optional<utils::IdType> maybe_const_function_id = maybe_type_info.value().parent_namespace->const_namespaces.at(maybe_type_info->type.type).functions[node->name.name];
|
||||
|
||||
// TODO: better decision ??
|
||||
maybe_function_id = maybe_type_info.value().parent_namespace->variable_namespaces.at(maybe_type_info->type.type).functions[node->name.name];
|
||||
if (/*is var expression*/) {
|
||||
maybe_function_id = maybe_type_info.value().parent_namespace->var_namespaces.at(maybe_type_info->type.type).functions[node->name.name];
|
||||
}
|
||||
|
||||
if (maybe_const_function_id.has_value() && maybe_function_id.has_value()) { // TODO: handle on link_types stage
|
||||
error_handling::HandleTypecheckError("Redefinition of method: const & var", node->base);
|
||||
}
|
||||
|
||||
if (!maybe_function_id.has_value()) {
|
||||
maybe_function_id = maybe_const_function_id;
|
||||
}
|
||||
} else if (std::holds_alternative<std::unique_ptr<TypeExpression>>(node->prefix.value())) {
|
||||
TypeExpression* type_expression = std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get();
|
||||
|
||||
|
|
@ -613,9 +717,11 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
error_handling::HandleTypecheckError("Mismatched argument count in function call expression", node->base);
|
||||
}
|
||||
for (size_t i = 0; i < node->arguments.size(); ++i) {
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
Visitor::Visit(*function_declaration.argument_types[i]);
|
||||
context_manager_.AddTypeRequirement(current_type_, TypeInContext(current_type_, context));
|
||||
utils::IdType argument_type = TypeInContext(current_type_, context);
|
||||
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
context_manager_.AddTypeRequirement(current_type_, argument_type);
|
||||
}
|
||||
|
||||
Visitor::Visit(*function_declaration.argument_types.back()); // add return type to info ??
|
||||
|
|
@ -634,7 +740,7 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
|
|||
info::type::TupleType(std::nullopt, fields, context_manager_.GetTypeManager()));
|
||||
}
|
||||
|
||||
// TODO
|
||||
// ??
|
||||
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||
std::vector<info::type::TupleType> constructors;
|
||||
|
||||
|
|
@ -655,13 +761,9 @@ void TypeCheckVisitor::Visit(ReturnExpression* node) {
|
|||
returned_type_ = current_type_;
|
||||
}
|
||||
|
||||
// TODO
|
||||
void Visitor::Visit(TypeConstructorParameter* node) {} // Handeled in TypeConstructor visit
|
||||
|
||||
// TODO
|
||||
// TODO: get argument types, etc.
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor names, etc.
|
||||
// Visit(node->constructor.get());
|
||||
void TypeCheckVisitor::Visit(TypeConstructor* node) {
|
||||
if (!node->constructor->constructor_id_.has_value()) {
|
||||
error_handling::HandleTypecheckError("Type constructor name not found", node->base);
|
||||
}
|
||||
|
|
@ -689,10 +791,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor
|
|||
|
||||
const info::definition::AnyType& type_info = maybe_type_info.value();
|
||||
|
||||
// TODO: check if exist
|
||||
/*info::definition::AnyType* type_info = &std::get<info::definition::AnyType>(
|
||||
namespace_visitor_.GetGlobalInfo()->GetTypeInfo(context_manager_.GetType<info::type::DefinedType>(type).value()->GetTypeId())->type);*/
|
||||
|
||||
if (constructor_info.constructor_tuple_node.has_value()) {
|
||||
|
||||
TupleType* constructor_fields = constructor_info.constructor_tuple_node.value();
|
||||
|
|
@ -703,7 +801,6 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor
|
|||
|
||||
for (size_t i = 0; i < node->parameters.size(); ++i) {
|
||||
// TODO: remove variable on move
|
||||
// TODO: check that has name <-> has name in constructor <- chck correctness
|
||||
if (node->parameters[i].name.has_value()) {
|
||||
if (!constructor_fields->entities[i].first.has_value()
|
||||
|| constructor_fields->entities[i].first.value().name != node->parameters[i].name.value().name) {
|
||||
|
|
@ -733,8 +830,7 @@ void TypeCheckVisitor::Visit(TypeConstructor* node) { // TODO: find constructor
|
|||
current_type_ = TypeInContext(current_type_, context);
|
||||
}
|
||||
|
||||
// TODO
|
||||
void TypeCheckVisitor::Visit(LambdaFunction* node) {
|
||||
void TypeCheckVisitor::Visit(LambdaFunction* node) { // TODO
|
||||
error_handling::HandleInternalError("Unimplemented (unsolved type deduction problems)",
|
||||
"TypeCheckVisitor.LambdaFunction");
|
||||
}
|
||||
|
|
@ -753,35 +849,32 @@ void TypeCheckVisitor::Visit(ArrayExpression* node) {
|
|||
}
|
||||
}
|
||||
|
||||
if (node->elements.size() == 0) {
|
||||
error_handling::HandleInternalError("Element size is 0", "TypeCheckVisitor.ArrayExpression");
|
||||
}
|
||||
|
||||
current_type_ = context_manager_.AddType(
|
||||
info::type::ArrayType(node->elements.size(), elements_type, context_manager_.GetTypeManager()));
|
||||
}
|
||||
|
||||
// Name
|
||||
|
||||
// -------------------------- TODO --------------------------
|
||||
void TypeCheckVisitor::Visit(NameExpression* node) { // TODO: ?? functions without arguments ??
|
||||
std::vector<std::string> path;
|
||||
std::string type_name;
|
||||
|
||||
path.reserve(node->names.size());
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
std::string current_name = node->names[i].name;
|
||||
if (i + 1 == node->names.size()) {
|
||||
type_name = std::move(current_name);
|
||||
} else {
|
||||
path.push_back(std::move(current_name));
|
||||
}
|
||||
// TODO
|
||||
void TypeCheckVisitor::Visit(NameExpression* node) {
|
||||
// TODO: move, etc.
|
||||
if (node->names.size() == 0) {
|
||||
error_handling::HandleInternalError("Name expression with zero names", "TypeCheckVisitor.NameExpression");
|
||||
}
|
||||
|
||||
// auto name_type = namespace_visitor_.FindType();
|
||||
path.push_back(type_name);
|
||||
auto name_namespace = namespace_visitor_.FindNamespace(path);
|
||||
auto maybe_variable_info = context_manager_.GetVariableInfo(node->names[0].name);
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
// Visitor::Visit(node->expressions[i]);
|
||||
if (!maybe_variable_info.has_value()) {
|
||||
error_handling::HandleTypecheckError("Variable not found", node->names[0].base);
|
||||
}
|
||||
|
||||
// TODO: get variable field
|
||||
|
||||
return ;
|
||||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(TupleName* node) {
|
||||
|
|
@ -864,7 +957,6 @@ void TypeCheckVisitor::Visit(AnnotatedName* node) {
|
|||
void TypeCheckVisitor::Visit(FunctionType* node) {
|
||||
std::vector<utils::IdType> argument_types(node->types.size());
|
||||
|
||||
|
||||
for (auto& argument_type : node->types) {
|
||||
Visitor::Visit(argument_type);
|
||||
argument_types.push_back(current_type_);
|
||||
|
|
@ -913,7 +1005,6 @@ void TypeCheckVisitor::Visit(VariantType* node) {
|
|||
current_type_ = context_manager_.AddType(info::type::VariantType(node->type, constructors));
|
||||
}
|
||||
|
||||
// TODO different for constructors
|
||||
// TODO handle local abstract types, abstract types, aliases, etc.
|
||||
void TypeCheckVisitor::Visit(TypeExpression* node) {
|
||||
std::unordered_map<std::string, utils::IdType> context;
|
||||
|
|
@ -949,8 +1040,7 @@ void TypeCheckVisitor::Visit(ExtendedScopedAnyType* node) {
|
|||
|
||||
// Typeclass
|
||||
|
||||
// TODO
|
||||
void Visitor::Visit(ParametrizedTypeclass* node) {
|
||||
void Visitor::Visit(ParametrizedTypeclass* node) { // TODO ??
|
||||
Visit(&node->typeclass);
|
||||
for (auto& parameter : node->parameters) {
|
||||
Visit(parameter.get());
|
||||
|
|
@ -959,12 +1049,10 @@ void Visitor::Visit(ParametrizedTypeclass* node) {
|
|||
|
||||
// Typeclass & Type -----------------
|
||||
|
||||
void TypeCheckVisitor::Visit(ParametrizedType* node) {} // Used in TypeExpression
|
||||
void TypeCheckVisitor::Visit(ParametrizedType* node) {} // Handled in TypeExpression
|
||||
|
||||
// Identifiers, constants, etc. -----------------
|
||||
|
||||
// TODO don't make dublicates of the same types
|
||||
|
||||
void TypeCheckVisitor::Visit(FloatNumberLiteral* node) {
|
||||
current_type_ = context_manager_.AddType(info::type::InternalType::Float);
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue