optional variable deffinition added, annotations removed

This commit is contained in:
ProgramSnail 2023-06-08 19:22:56 +03:00
parent 7ce8513ad0
commit de7c1e062f
20 changed files with 178 additions and 57 deletions

View file

@ -1202,6 +1202,17 @@ void BuildVisitor::Visit(NameExpression* node) {
current_node_ = parse_node;
}
void BuildVisitor::Visit(OptionalName* node) {
SetPosition(node->base, current_node_);
auto parse_node = current_node_;
current_node_ = parse_node.ChildByFieldName("name");
Visit(node->name);
current_node_ = parse_node;
}
void BuildVisitor::Visit(TupleName* node) {
SetPosition(node->base, current_node_);
@ -1213,7 +1224,7 @@ void BuildVisitor::Visit(TupleName* node) {
for (size_t i = 0; i < names_count; ++i) {
current_node_ = parse_node.NthNamedChild(i);
node->names[i] = std::make_unique<AnnotatedName>();
node->names[i] = std::make_unique<Name>();
Visit(node->names[i]);
}
@ -1231,27 +1242,21 @@ void BuildVisitor::Visit(VariantName* node) {
for (size_t i = 0; i < names_count; ++i) {
current_node_ = parse_node.NthNamedChild(i);
node->names[i] =std::make_unique<AnnotatedName>();
node->names[i] =std::make_unique<Name>();
Visit(node->names[i]);
}
current_node_ = parse_node;
}
void BuildVisitor::Visit(AnnotatedName* node) {
void BuildVisitor::Visit(Name* node) {
SetPosition(node->base, current_node_);
auto parse_node = current_node_;
node->name = parse_node.ChildByFieldName("name").GetValue();
if (parse_node.NamedChildCount() > 1) {
current_node_ = parse_node.ChildByFieldName("type");
node->type.emplace();
Visit(node->type.value());
current_node_ = parse_node;
}
current_node_ = parse_node;
}
void BuildVisitor::Visit(AnyName& node) {
@ -1261,9 +1266,12 @@ void BuildVisitor::Visit(AnyName& node) {
std::string current_node_type = current_node_.GetType();
if (current_node_type == parser::tokens::AnnotatedName) {
node = std::make_unique<AnnotatedName>();
Visit(std::get<std::unique_ptr<AnnotatedName>>(node).get());
if (current_node_type == parser::tokens::Name) {
node = std::make_unique<Name>();
Visit(std::get<std::unique_ptr<Name>>(node).get());
} else if (current_node_type == parser::tokens::OptionalName) {
node = std::make_unique<OptionalName>();
Visit(std::get<std::unique_ptr<OptionalName>>(node).get());
} else if (current_node_type == parser::tokens::TupleName) {
node = std::make_unique<TupleName>();
Visit(std::get<std::unique_ptr<TupleName>>(node).get());

View file

@ -55,14 +55,19 @@ void ExecuteVisitor::Visit(VariableDefinitionStatement* node) {
Visitor::Visit(node->value);
is_definition_failed_ = false;
is_const_definition_ = node->modifier;
Visitor::Visit(node->name); // current_type_ passed from value
is_const_definition_ = std::nullopt;
if (node->in_expression.has_value()) {
Visitor::Visit(node->in_expression.value());
if (!is_definition_failed_) {
Visitor::Visit(node->in_expression.value());
}
context_manager_.ExitContext();
}
is_definition_failed_ = false;
}
void ExecuteVisitor::Visit(FunctionDeclaration* node) {
@ -754,6 +759,25 @@ void ExecuteVisitor::Visit(NameExpression* node) { // TODO: check
}
}
void ExecuteVisitor::Visit(OptionalName* node) {
utils::IdType value = current_value_;
std::optional<info::value::OptionalValue*> maybe_optional_value = context_manager_.GetValue<info::value::OptionalValue>(value);
if (!maybe_optional_value.has_value()) {
error_handling::HandleRuntimeError("Mismatched value types in optional variable definition", node->base);
}
if (maybe_optional_value.value()->value.has_value()) {
current_value_ = maybe_optional_value.value()->value.value();
Visitor::Visit(node->name);
} else {
is_definition_failed_ = true;
}
current_value_ = value;
}
void ExecuteVisitor::Visit(TupleName* node) {
utils::IdType value = current_value_;
@ -817,7 +841,7 @@ void ExecuteVisitor::Visit(VariantName* node) {
}
// TODO: move, etc.
void ExecuteVisitor::Visit(AnnotatedName* node) {
void ExecuteVisitor::Visit(Name* node) {
if (!is_const_definition_.has_value()) {
error_handling::HandleInternalError("No value in is_const_definition_",
"TypeCheckVisitor.AnnotatedName",

View file

@ -577,6 +577,12 @@ void PrintVisitor::Visit(NameExpression* node) {
out_ << ')';
}
void PrintVisitor::Visit(OptionalName* node) {
out_ << "[OptionalName] (";
Visitor::Visit(node->name);
out_ << ')';
}
void PrintVisitor::Visit(TupleName* node) {
out_ << "[TupleName] (";
for (auto& name : node->names) {
@ -595,15 +601,10 @@ void PrintVisitor::Visit(VariantName* node) {
out_ << ')';
}
void PrintVisitor::Visit(AnnotatedName* node) {
out_ << "[AnnotatedName ";
void PrintVisitor::Visit(Name* node) {
out_ << "[Name ";
Visit(&node->name);
out_ << ']';
if (node->type.has_value()) {
out_ << " : (";
Visitor::Visit(node->type.value());
out_ << ')';
}
}
// Type, typeclass, etc. -----------------

View file

@ -110,6 +110,7 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
Visitor::Visit(node->value);
// current_type from value automatically passed to name definitions
definition_can_fail_ = false;
is_const_definition_ = node->modifier;
Visitor::Visit(node->name);
is_const_definition_ = std::nullopt;
@ -117,10 +118,16 @@ void TypeCheckVisitor::Visit(VariableDefinitionStatement* node) {
if (node->in_expression.has_value()) {
Visitor::Visit(node->in_expression.value());
context_manager_.ExitContext();
} else {
if (definition_can_fail_) {
error_handling::HandleTypecheckError("Can't make definition that can fail (use \'in\' for associated block)", node->base);
}
}
current_type_ = internal_to_abstract_type_.at(info::type::InternalType::Unit);
definition_can_fail_ = false;
node->base.type_ = current_type_;
}
@ -1110,6 +1117,43 @@ void TypeCheckVisitor::Visit(NameExpression* node) {
node->base.type_ = current_type_;
}
void TypeCheckVisitor::Visit(OptionalName* node) {
utils::IdType type = current_type_;
std::optional<info::type::DefinedType*> maybe_defined_type_value = context_manager_.GetValue<info::type::DefinedType>(type);
if (maybe_defined_type_value.has_value()) {
type = maybe_defined_type_value.value()->GetType();
}
auto maybe_type_value = context_manager_.GetValue<info::type::OptionalType>(type);
if (!maybe_type_value.has_value()) {
error_handling::HandleTypecheckError("Mismatched types in optional variable definition", node->base);
}
info::type::OptionalType* type_value = maybe_type_value.value();
if (!is_const_definition_.has_value()) {
error_handling::HandleInternalError("No value in is_const_definition_",
"TypeCheckVisitor.OptionalName",
&node->base);
}
utils::ValueType value_type = context_manager_.GetValueType(type);
current_type_ = type_value->GetType();
if (value_type == utils::ValueType::Tmp) { // TODO: instead of recusive modification ??
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Tmp);
}
Visitor::Visit(node->name);
current_type_ = type;
definition_can_fail_ = true;
node->base.type_ = current_type_;
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(TupleName* node) {
utils::IdType type = current_type_;
@ -1204,7 +1248,7 @@ void TypeCheckVisitor::Visit(VariantName* node) {
}
// TODO: move, etc.
void TypeCheckVisitor::Visit(AnnotatedName* node) {
void TypeCheckVisitor::Visit(Name* node) {
utils::IdType type = current_type_;
if (!is_const_definition_.has_value()) {
@ -1217,12 +1261,14 @@ 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()) { // TODO: check
Visitor::Visit(node->type.value());
if (!context_manager_.EqualValues(type, current_type_)) {
error_handling::HandleTypecheckError("Wrong type annotation in annotated name", node->base);
}
}
// --------- FOR ANNOTATIONS ---------
// if (node->type.has_value()) {
// Visitor::Visit(node->type.value());
// if (!context_manager_.EqualValues(type, current_type_)) {
// error_handling::HandleTypecheckError("Wrong type annotation in annotated name", node->base);
// }
// }
node->base.type_ = current_type_;
}

View file

@ -801,6 +801,18 @@ void TypedPrintVisitor::Visit(NameExpression* node) {
out_ << ')';
}
void TypedPrintVisitor::Visit(OptionalName* node) {
out_ << "[OptionalName : ";
if (node->base.type_.has_value()) {
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
}
out_ << "] (";
Visitor::Visit(node->name);
out_ << ')';
}
void TypedPrintVisitor::Visit(TupleName* node) {
out_ << "[TupleName : ";
@ -831,8 +843,8 @@ void TypedPrintVisitor::Visit(VariantName* node) {
out_ << ')';
}
void TypedPrintVisitor::Visit(AnnotatedName* node) {
out_ << "[AnnotatedName : (";
void TypedPrintVisitor::Visit(Name* node) {
out_ << "[Name : (";
if (node->base.type_.has_value()) {
out_ << context_manager_.GetAnyValue(node->base.type_.value())->GetTypeName();
@ -841,11 +853,6 @@ void TypedPrintVisitor::Visit(AnnotatedName* node) {
out_ << ") ";
Visit(&node->name);
out_ << ']';
if (node->type.has_value()) {
out_ << " : (";
Visitor::Visit(node->type.value());
out_ << ')';
}
}
// Type, typeclass, etc. -----------------

View file

@ -222,12 +222,15 @@ void Visitor::Visit(SuperExpression& node) {
void Visitor::Visit(AnyName& node) {
switch (node.index()) {
case 0:
Visit(std::get<std::unique_ptr<AnnotatedName>>(node).get());
Visit(std::get<std::unique_ptr<Name>>(node).get());
break;
case 1:
Visit(std::get<std::unique_ptr<TupleName>>(node).get());
Visit(std::get<std::unique_ptr<OptionalName>>(node).get());
break;
case 2:
Visit(std::get<std::unique_ptr<TupleName>>(node).get());
break;
case 3:
Visit(std::get<std::unique_ptr<VariantName>>(node).get());
break;
default:
@ -561,6 +564,10 @@ void Visitor::Visit(NameExpression* node) {
}
}
void Visitor::Visit(OptionalName* node) {
Visit(node->name);
}
void Visitor::Visit(TupleName* node) {
for (auto& name : node->names) {
Visit(name);
@ -573,11 +580,8 @@ void Visitor::Visit(VariantName* node) {
}
}
void Visitor::Visit(AnnotatedName* node) {
void Visitor::Visit(Name* node) {
Visit(&node->name);
if (node->type.has_value()) {
Visit(node->type.value());
}
}
// Type, typeclass, etc. -----------------