mirror of
https://codeberg.org/ProgramSnail/lang_2023.git
synced 2025-12-26 00:38:43 +00:00
changes for new grammar, fixes
This commit is contained in:
parent
91f9affadc
commit
3106a64949
35 changed files with 605 additions and 550 deletions
|
|
@ -62,7 +62,9 @@ void BuildVisitor::Visit(Namespace* node) {
|
|||
node->modifier = utils::ClassInternalsModifier::Static;
|
||||
}
|
||||
|
||||
node->type = parse_node.ChildByFieldName("type").GetValue();
|
||||
current_node_ = parse_node.ChildByFieldName("type");
|
||||
node->type = current_node_.GetValue();
|
||||
node->is_type_namespace = (current_node_.PreviousSibling().GetValue() == "\\");
|
||||
|
||||
current_node_ = parse_node.ChildByFieldName("scope");
|
||||
Visit(&node->scope);
|
||||
|
|
@ -130,7 +132,7 @@ void BuildVisitor::Visit(AliasDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
current_node_ = parse_node.ChildByFieldName("value");
|
||||
node->value = std::make_unique<TypeExpression>();
|
||||
node->value = std::make_unique<WrappedTypeExpression>();
|
||||
Visit(node->value.get());
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
@ -961,9 +963,9 @@ void BuildVisitor::Visit(FunctionCallExpression* node) {
|
|||
node->prefix = std::make_unique<SubExpressionToken>();
|
||||
Visit(*std::get<std::unique_ptr<SubExpressionToken>>(node->prefix.value()));
|
||||
++excluded_child_count;
|
||||
} else if (current_node_type == parser::tokens::TypeExpression) {
|
||||
node->prefix = std::make_unique<TypeExpression>();
|
||||
Visit(std::get<std::unique_ptr<TypeExpression>>(node->prefix.value()).get());
|
||||
} else if (current_node_type == parser::tokens::WrappedTypeExpression) {
|
||||
node->prefix = std::make_unique<WrappedTypeExpression>();
|
||||
Visit(std::get<std::unique_ptr<WrappedTypeExpression>>(node->prefix.value()).get());
|
||||
++excluded_child_count;
|
||||
} else {
|
||||
// no prefix
|
||||
|
|
@ -1282,7 +1284,8 @@ void BuildVisitor::Visit(FunctionType* node) {
|
|||
|
||||
for (size_t i = 0; i < types_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i);
|
||||
Visit(node->types[i]);
|
||||
node->types[i] = std::make_unique<ExtendedScopedAnyType>();
|
||||
Visit(node->types[i].get());
|
||||
}
|
||||
|
||||
current_node_ = parse_node;
|
||||
|
|
@ -1340,19 +1343,28 @@ void BuildVisitor::Visit(VariantType* node) {
|
|||
}
|
||||
|
||||
|
||||
node->constructors.resize(child_count - excluded_child_count);
|
||||
for (size_t i = 0; i < node->constructors.size(); ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
||||
if (child_count > excluded_child_count) {
|
||||
node->constructors.reserve(child_count - excluded_child_count);
|
||||
for (size_t i = 0; i < child_count - excluded_child_count; ++i) {
|
||||
current_node_ = parse_node.NthNamedChild(i + excluded_child_count);
|
||||
|
||||
std::string current_node_type = current_node_.GetType();
|
||||
std::string current_node_type = current_node_.GetType();
|
||||
|
||||
if (current_node_type == parser::tokens::Constructor) {
|
||||
node->constructors[i] = current_node_.GetValue();
|
||||
} else if (current_node_type == parser::tokens::TupleType) {
|
||||
node->constructors[i] = std::make_unique<TupleType>();
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(node->constructors[i]).get());
|
||||
} else {
|
||||
// error
|
||||
if (current_node_type == parser::tokens::Constructor) {
|
||||
std::string constructor_name = current_node_.GetValue();
|
||||
constructor_name = constructor_name.substr(1, constructor_name.size() - 1);
|
||||
node->constructors.push_back({constructor_name, std::nullopt});
|
||||
} else if (current_node_type == parser::tokens::TupleType) {
|
||||
if (!node->constructors.empty() && !node->constructors.back().second.has_value()) {
|
||||
node->constructors.back().second = std::make_unique<TupleType>();
|
||||
Visit(node->constructors.back().second.value().get());
|
||||
} else {
|
||||
node->constructors.push_back({std::nullopt, std::make_unique<TupleType>()});
|
||||
Visit(node->constructors.back().second.value().get());
|
||||
}
|
||||
} else {
|
||||
// error
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1389,11 +1401,11 @@ void BuildVisitor::Visit(TypeExpression* node) {
|
|||
|
||||
node->is_optional = true;
|
||||
} else {
|
||||
if (suffix_node1.GetValue() == "_" && suffix_node2.GetValue() == "!") {
|
||||
if (suffix_node1.GetValue() == "`" && suffix_node2.GetValue() == "?") {
|
||||
node->array_size = 0;
|
||||
|
||||
node->is_optional = true;
|
||||
} else if (suffix_node1.GetValue() == "_") {
|
||||
} else if (suffix_node1.GetValue() == "`") {
|
||||
current_node_ = suffix_node2;
|
||||
|
||||
NumberLiteral literal;
|
||||
|
|
@ -1407,9 +1419,9 @@ void BuildVisitor::Visit(TypeExpression* node) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
if (suffix_node1.GetValue() == "_") {
|
||||
if (suffix_node1.GetValue() == "`") {
|
||||
node->array_size = 0;
|
||||
} else if (suffix_node1.GetValue() == "!") {
|
||||
} else if (suffix_node1.GetValue() == "?") {
|
||||
node->is_optional = true;
|
||||
} else {
|
||||
error_handling::HandleInternalError("Undefined suffix (1 element)",
|
||||
|
|
@ -1438,9 +1450,9 @@ void BuildVisitor::Visit(AnyType& node) {
|
|||
|
||||
std::string current_node_type = current_node_.GetType();
|
||||
|
||||
if (current_node_type == parser::tokens::TypeExpression) {
|
||||
node = std::make_unique<TypeExpression>();
|
||||
Visit(std::get<std::unique_ptr<TypeExpression>>(node).get());
|
||||
if (current_node_type == parser::tokens::WrappedTypeExpression) {
|
||||
node = std::make_unique<WrappedTypeExpression>();
|
||||
Visit(std::get<std::unique_ptr<WrappedTypeExpression>>(node).get());
|
||||
} else if (current_node_type == parser::tokens::TupleType) {
|
||||
node = std::make_unique<TupleType>();
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(node).get());
|
||||
|
|
@ -1550,18 +1562,47 @@ void BuildVisitor::Visit(NumberLiteral* node) {
|
|||
node->value = std::stoll(current_node_.GetValue());
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(StringLiteral* node) { // TODO: special symbols, etc.
|
||||
void BuildVisitor::Visit(StringLiteral* node) { // TODO: other special symbols, etc.
|
||||
SetPosition(node->base, current_node_);
|
||||
|
||||
std::string literal = current_node_.GetValue();
|
||||
node->value = literal.substr(1, literal.size() - 2);
|
||||
literal = literal.substr(1, literal.size() - 2);
|
||||
node->value.reserve(literal.size());
|
||||
|
||||
bool is_escape_symbol = false;
|
||||
for (size_t i = 0; i < literal.size(); ++i) {
|
||||
if (literal[i] == '\\' && !is_escape_symbol) {
|
||||
is_escape_symbol = true;
|
||||
} else {
|
||||
if (is_escape_symbol) {
|
||||
auto maybe_escape_symbol = utils::ToEscapeSymbol(literal[i]);
|
||||
if (maybe_escape_symbol.has_value()) {
|
||||
node->value += maybe_escape_symbol.value();
|
||||
} else {
|
||||
node->value += literal[i];
|
||||
}
|
||||
} else {
|
||||
node->value += literal[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(CharLiteral* node) {
|
||||
SetPosition(node->base, current_node_);
|
||||
|
||||
std::string literal = current_node_.GetValue();
|
||||
node->value = literal.substr(1, literal.size() - 2).back(); // TODO: special symbols, etc.
|
||||
literal = literal.substr(2, literal.size() - 2); // TODO: other special symbols, etc.
|
||||
if (literal[0] == '\\') {
|
||||
auto maybe_escape_symbol = utils::ToEscapeSymbol(literal.back());
|
||||
if (maybe_escape_symbol.has_value()) {
|
||||
node->value = maybe_escape_symbol.value();
|
||||
} else {
|
||||
node->value = literal.back();
|
||||
}
|
||||
} else {
|
||||
node->value = literal.back();
|
||||
}
|
||||
}
|
||||
|
||||
void BuildVisitor::Visit(UnitLiteral* node) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ void FindSymbolsVisitor::Visit(FunctionDeclaration* node) {
|
|||
|
||||
info.argument_types.resize(node->type->types.size());
|
||||
for (size_t i = 0; i < node->type->types.size(); ++i) {
|
||||
info.argument_types[i] = &node->type->types[i];
|
||||
info.argument_types[i] = node->type->types[i].get();
|
||||
}
|
||||
|
||||
info.node = node;
|
||||
|
|
|
|||
|
|
@ -179,35 +179,18 @@ utils::IdType GlobalInfo::NamespaceVisitor::AddType(const std::string& type,
|
|||
if (std::holds_alternative<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value)) {
|
||||
interpreter::tokens::VariantType& variant_type_info = *std::get<std::unique_ptr<interpreter::tokens::VariantType>>(any_type_info.node->value);
|
||||
for (size_t i = 0; i < variant_type_info.constructors.size(); ++i) {
|
||||
std::string constructor_name;
|
||||
definition::Constructor constructor_info;
|
||||
|
||||
constructor_info.type_id = id;
|
||||
constructor_info.order = i;
|
||||
|
||||
if (std::holds_alternative<interpreter::tokens::Constructor>(variant_type_info.constructors[i])) {
|
||||
constructor_name = std::get<interpreter::tokens::Constructor>(variant_type_info.constructors[i]);
|
||||
} else if (std::holds_alternative<
|
||||
std::unique_ptr<interpreter::tokens::TupleType>>(variant_type_info.constructors[i])) {
|
||||
constructor_info.constructor_tuple_node =
|
||||
std::get<std::unique_ptr<interpreter::tokens::TupleType>>(variant_type_info.constructors[i]).get();
|
||||
|
||||
auto maybe_constructor_name = constructor_info.constructor_tuple_node.value()->type;
|
||||
|
||||
if (maybe_constructor_name.has_value()) {
|
||||
constructor_name = maybe_constructor_name.value();
|
||||
} else {
|
||||
constructor_name = type;
|
||||
}
|
||||
if (variant_type_info.constructors[i].first.has_value()) {
|
||||
constructor_info.name = variant_type_info.constructors[i].first.value();
|
||||
} else {
|
||||
error_handling::HandleInternalError("Unexprected VariantType constructor node type",
|
||||
"GlobalInfo.NamespaceVisitor.AddType",
|
||||
&base_node);
|
||||
constructor_info.name = any_type_info.type.type;
|
||||
}
|
||||
|
||||
constructor_info.name = constructor_name;
|
||||
|
||||
AddConstructor(constructor_name, std::move(constructor_info), base_node);
|
||||
AddConstructor(constructor_info.name, std::move(constructor_info), base_node);
|
||||
}
|
||||
} else if (std::holds_alternative<std::unique_ptr<interpreter::tokens::TupleType>>(any_type_info.node->value)) {
|
||||
definition::Constructor constructor_info;
|
||||
|
|
|
|||
|
|
@ -20,6 +20,14 @@ void LinkSymbolsVisitor::Visit(Namespace* node) {
|
|||
maybe_typeclass = namespace_visitor_.FindTypeclassId(node->type);
|
||||
}
|
||||
|
||||
if (!node->is_type_namespace && (maybe_type.has_value() || maybe_typeclass.has_value())) {
|
||||
error_handling::HandleNamesError("Not type / typeclass namespace has associated type / typeclass", node->base);
|
||||
}
|
||||
|
||||
if (node->is_type_namespace && !maybe_type.has_value() && !maybe_typeclass.has_value()) {
|
||||
error_handling::HandleNamesError("Type / typeclass namespace has no associated type / typeclass", node->base);
|
||||
}
|
||||
|
||||
if (maybe_type.has_value() && maybe_typeclass.has_value()) {
|
||||
error_handling::HandleNamesError("Ambigious namespace name (typeclass or type)", node->base);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -48,7 +48,7 @@ int main(int argc, char** argv) { // TODO, only test version
|
|||
info::ContextManager<info::value::Value, info::value::ValueManager> context_manager;
|
||||
|
||||
interpreter::BuildVisitor build_visitor(parse_tree);
|
||||
// interpreter::PrintVisitor print_visitor(std::cout);
|
||||
interpreter::PrintVisitor print_visitor(std::cout);
|
||||
interpreter::FindSymbolsVisitor find_symbols_visitor(global_info);
|
||||
interpreter::LinkSymbolsVisitor link_symbols_visitor(global_info);
|
||||
interpreter::TypeCheckVisitor type_check_visitor(global_info, type_context_manager);
|
||||
|
|
@ -56,8 +56,8 @@ int main(int argc, char** argv) { // TODO, only test version
|
|||
|
||||
build_visitor.VisitSourceFile(source_file.get());
|
||||
|
||||
// std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n";
|
||||
// print_visitor.VisitSourceFile(source_file.get());
|
||||
std::cout << "\n---------------------------------- Untyped -------------------------------------\n\n";
|
||||
print_visitor.VisitSourceFile(source_file.get());
|
||||
|
||||
try {
|
||||
find_symbols_visitor.VisitSourceFile(source_file.get());
|
||||
|
|
@ -69,7 +69,7 @@ int main(int argc, char** argv) { // TODO, only test version
|
|||
|
||||
try {
|
||||
type_check_visitor.VisitSourceFile(source_file.get());
|
||||
} catch (bool) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
|
||||
} catch (...) { error_handling::HandleInternalError("type_check_visitor exception", "main", std::nullopt); }
|
||||
|
||||
std::optional<utils::IdType> maybe_main_partition_id = global_info.FindPartition({"main"});
|
||||
|
||||
|
|
|
|||
|
|
@ -271,7 +271,7 @@ void PrintVisitor::Visit(MatchCase* node) {
|
|||
out_ << "[MatchCase | ";
|
||||
Visitor::Visit(node->value);
|
||||
if (node->condition.has_value()) {
|
||||
out_ << " ? ";
|
||||
out_ << " ?? ";
|
||||
Visitor::Visit(node->condition.value());
|
||||
}
|
||||
if (node->statement.has_value()) {
|
||||
|
|
@ -428,7 +428,7 @@ void PrintVisitor::Visit(FunctionCallExpression* node) {
|
|||
} else {
|
||||
// error
|
||||
}
|
||||
out_ << ").";
|
||||
out_ << ")..";
|
||||
}
|
||||
|
||||
Visit(&node->name);
|
||||
|
|
@ -554,7 +554,7 @@ void PrintVisitor::Visit(PartitionName* node) {
|
|||
for (size_t i = 0; i < node->path.size(); ++i) {
|
||||
Visit(&node->path[i]);
|
||||
if (i + 1 < node->path.size()) {
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -565,7 +565,7 @@ void PrintVisitor::Visit(NameExpression* node) {
|
|||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
Visit(&node->names[i]);
|
||||
if (i + 1 < node->names.size()) {
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -612,7 +612,7 @@ void PrintVisitor::Visit(FunctionType* node) {
|
|||
out_ << " -> ";
|
||||
}
|
||||
is_first = false;
|
||||
Visitor::Visit(type);
|
||||
Visit(type.get());
|
||||
}
|
||||
out_ << ')';
|
||||
}
|
||||
|
|
@ -641,13 +641,14 @@ void PrintVisitor::Visit(VariantType* node) {
|
|||
}
|
||||
out_ << "] (";
|
||||
for (auto& constructor : node->constructors) {
|
||||
out_ << "| ";
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
Visit(&std::get<Constructor>(constructor));
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
} else {
|
||||
// error
|
||||
out_ << "|";
|
||||
if (constructor.first.has_value()) {
|
||||
out_ << " ";
|
||||
Visit(&constructor.first.value());
|
||||
}
|
||||
if (constructor.second.has_value()) {
|
||||
out_ << " ";
|
||||
Visit(constructor.second.value().get());
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -667,7 +668,7 @@ void PrintVisitor::Visit(TypeExpression* node) {
|
|||
out_ << "] (";
|
||||
for (auto& type : node->path) {
|
||||
Visit(&type);
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
Visit(&node->type);
|
||||
out_ << ')';
|
||||
|
|
|
|||
|
|
@ -224,14 +224,14 @@ void TypeCheckVisitor::Visit(FunctionDefinitionStatement* node) {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < node->definition->arguments.size(); ++i) {
|
||||
Visitor::Visit(declaration->type->types[i]);
|
||||
Visit(declaration->type->types[i].get());
|
||||
current_type_ = context_manager_.ToModifiedValue(current_type_, utils::ValueType::Const);
|
||||
if (!context_manager_.DefineVariable(node->definition->arguments[i], current_type_)) {
|
||||
error_handling::HandleTypecheckError("Can't define function argument variable: name redefinition", node->base);
|
||||
}
|
||||
}
|
||||
|
||||
Visitor::Visit(declaration->type->types.back());
|
||||
Visit(declaration->type->types.back().get());
|
||||
utils::IdType returned_type = current_type_;
|
||||
|
||||
returned_type_ = std::nullopt;
|
||||
|
|
@ -812,7 +812,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
|
||||
for (size_t i = index_shift; i < node->arguments.size(); ++i) {
|
||||
Visitor::Visit(function_declaration->type->types[i - index_shift]);
|
||||
Visit(function_declaration->type->types[i - index_shift].get());
|
||||
utils::IdType argument_type = TypeInContext(current_type_, context);
|
||||
|
||||
Visitor::Visit(node->arguments[i]);
|
||||
|
|
@ -847,7 +847,7 @@ void TypeCheckVisitor::Visit(FunctionCallExpression* node) {
|
|||
}
|
||||
}
|
||||
|
||||
Visitor::Visit(function_declaration->type->types.back());
|
||||
Visit(function_declaration->type->types.back().get());
|
||||
current_type_ = TypeInContext(current_type_, context);
|
||||
|
||||
context_manager_.ExitContext();
|
||||
|
|
@ -871,14 +871,14 @@ void TypeCheckVisitor::Visit(TupleExpression* node) {
|
|||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(VariantExpression* node) {
|
||||
std::vector<info::type::TupleType> constructors;
|
||||
std::vector<std::pair<std::string, std::optional<info::type::TupleType>>> constructors;
|
||||
|
||||
for (auto& expression : node->expressions) {
|
||||
Visitor::Visit(expression);
|
||||
|
||||
// TODO: deal with expression tuple types, etc, ??
|
||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> constructor_fields {{std::nullopt, current_type_}};
|
||||
constructors.push_back(info::type::TupleType(std::nullopt, constructor_fields, context_manager_.GetValueManager()));
|
||||
constructors.push_back({"", info::type::TupleType(std::nullopt, constructor_fields, context_manager_.GetValueManager())});
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1170,14 +1170,14 @@ void TypeCheckVisitor::Visit(VariantName* node) {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
if (type_value->GetConstructors()[i].GetFields().empty()) {
|
||||
if (!type_value->GetConstructors()[i].second.has_value()) {
|
||||
current_type_ = context_manager_.AddValue(
|
||||
info::type::OptionalType(
|
||||
internal_to_abstract_type_.at(info::type::InternalType::Unit),
|
||||
context_manager_.GetValueManager()),
|
||||
utils::IsConstModifierToValueType(is_const_definition_.value())); // TODO ??
|
||||
} else {
|
||||
info::type::TupleType constructor_type_value = type_value->GetConstructors()[i];
|
||||
info::type::TupleType constructor_type_value = type_value->GetConstructors()[i].second.value();
|
||||
|
||||
utils::IdType constructor_type =
|
||||
context_manager_.AddValue(std::move(constructor_type_value),
|
||||
|
|
@ -1227,7 +1227,7 @@ void TypeCheckVisitor::Visit(FunctionType* node) {
|
|||
std::vector<utils::IdType> argument_types(node->types.size());
|
||||
|
||||
for (auto& argument_type : node->types) {
|
||||
Visitor::Visit(argument_type);
|
||||
Visit(argument_type.get());
|
||||
argument_types.push_back(current_type_);
|
||||
}
|
||||
|
||||
|
|
@ -1262,24 +1262,25 @@ void TypeCheckVisitor::Visit(TupleType* node) {
|
|||
}
|
||||
|
||||
void TypeCheckVisitor::Visit(VariantType* node) {
|
||||
std::vector<info::type::TupleType> constructors;
|
||||
std::vector<std::pair<std::string, std::optional<info::type::TupleType>>> constructors;
|
||||
|
||||
constructors.reserve(node->constructors.size());
|
||||
for (auto& constructor : node->constructors) {
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
std::vector<std::pair<std::optional<std::string>, utils::IdType>> constructor_fields;
|
||||
constructors.push_back(info::type::TupleType(std::get<Constructor>(constructor), constructor_fields, context_manager_.GetValueManager()));
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
if (!constructor.first.has_value() && !node->type.has_value()) {
|
||||
error_handling::HandleTypecheckError("Constructor type not recognized", node->base);
|
||||
} // TODO: decide
|
||||
|
||||
constructors.push_back({constructor.first.has_value() ? constructor.first.value() : node->type.value(), std::nullopt}); // TODO: real constructor name, instead of variant name (names in namespaces, etc)
|
||||
|
||||
if (constructor.second.has_value()) {
|
||||
Visit(constructor.second.value().get());
|
||||
std::optional<info::type::TupleType*> maybe_constructor = context_manager_.GetValue<info::type::TupleType>(current_type_);
|
||||
if (!maybe_constructor.has_value()) {
|
||||
error_handling::HandleInternalError("Entity of VariantType is not TupleType",
|
||||
"TypeCheckVisitor.VariantType",
|
||||
&node->base);
|
||||
}
|
||||
constructors.push_back(*maybe_constructor.value());
|
||||
} else {
|
||||
// error
|
||||
constructors.back().second = *maybe_constructor.value();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -599,7 +599,7 @@ void TypedPrintVisitor::Visit(FunctionCallExpression* node) {
|
|||
} else {
|
||||
// error
|
||||
}
|
||||
out_ << ").";
|
||||
out_ << ")..";
|
||||
}
|
||||
|
||||
Visit(&node->name);
|
||||
|
|
@ -772,7 +772,7 @@ void TypedPrintVisitor::Visit(PartitionName* node) {
|
|||
for (size_t i = 0; i < node->path.size(); ++i) {
|
||||
Visit(&node->path[i]);
|
||||
if (i + 1 < node->path.size()) {
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -789,7 +789,7 @@ void TypedPrintVisitor::Visit(NameExpression* node) {
|
|||
for (size_t i = 0; i < node->names.size(); ++i) {
|
||||
Visit(&node->names[i]);
|
||||
if (i + 1 < node->names.size()) {
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -860,7 +860,7 @@ void TypedPrintVisitor::Visit(FunctionType* node) {
|
|||
out_ << " -> ";
|
||||
}
|
||||
is_first = false;
|
||||
Visitor::Visit(type);
|
||||
Visit(type.get());
|
||||
}
|
||||
out_ << ')';
|
||||
}
|
||||
|
|
@ -902,12 +902,13 @@ void TypedPrintVisitor::Visit(VariantType* node) {
|
|||
out_ << "] (";
|
||||
for (auto& constructor : node->constructors) {
|
||||
out_ << "| ";
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
Visit(&std::get<Constructor>(constructor));
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
} else {
|
||||
// error
|
||||
if (constructor.first.has_value()) {
|
||||
out_ << " ";
|
||||
Visit(&constructor.first.value());
|
||||
}
|
||||
if (constructor.second.has_value()) {
|
||||
out_ << " ";
|
||||
Visit(constructor.second.value().get());
|
||||
}
|
||||
}
|
||||
out_ << ')';
|
||||
|
|
@ -932,7 +933,7 @@ void TypedPrintVisitor::Visit(TypeExpression* node) {
|
|||
out_ << "] (";
|
||||
for (auto& type : node->path) {
|
||||
Visit(&type);
|
||||
out_ << "::";
|
||||
out_ << '.';
|
||||
}
|
||||
Visit(&node->type);
|
||||
out_ << ')';
|
||||
|
|
|
|||
|
|
@ -144,7 +144,9 @@ std::string TupleType::ToString() const {
|
|||
|
||||
std::optional<utils::IdType> VariantType::InContext(const std::unordered_map<std::string, utils::IdType>& context) {
|
||||
for (size_t i = 0; i < constructors_.size(); ++i) {
|
||||
constructors_[i].InContext(context);
|
||||
if (constructors_[i].second.has_value()) {
|
||||
constructors_[i].second.value().InContext(context);
|
||||
}
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
|
|
@ -156,9 +158,20 @@ bool VariantType::Same(const VariantType& type) const {
|
|||
}
|
||||
|
||||
for (size_t i = 0; i < constructors_.size(); ++i) {
|
||||
if (!constructors_[i].Same(constructors_[i])) {
|
||||
|
||||
if (constructors_[i].first != type.constructors_[i].first) { // TODO: decide
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constructors_[i].second.has_value() != type.constructors_[i].second.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (constructors_[i].second.has_value()) {
|
||||
if (!constructors_[i].second.value().Same(type.constructors_[i].second.value())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
|
|
@ -184,8 +197,8 @@ bool VariantType::operator>(const VariantType& type) const {
|
|||
|
||||
std::optional<utils::IdType> VariantType::GetFieldType(const std::string& name,
|
||||
const std::unordered_set<utils::IdType>& type_namespaces) const {
|
||||
if (current_constructor_.has_value()) {
|
||||
return constructors_.at(current_constructor_.value()).GetFieldType(name, type_namespaces);
|
||||
if (current_constructor_.has_value() && constructors_.at(current_constructor_.value()).second.has_value()) {
|
||||
return constructors_[current_constructor_.value()].second.value().GetFieldType(name, type_namespaces);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
|
@ -197,7 +210,10 @@ std::string VariantType::ToString() const {
|
|||
|
||||
for (auto& constructor : constructors_) {
|
||||
result += "& ";
|
||||
result += constructor.ToString();
|
||||
result += constructor.first;
|
||||
if (constructor.second.has_value()) {
|
||||
result += " " + constructor.second.value().ToString();
|
||||
}
|
||||
}
|
||||
|
||||
result += ")";
|
||||
|
|
|
|||
|
|
@ -38,6 +38,29 @@ ValueType ClassInternalsModifierToValueType(ClassInternalsModifier modifier) {
|
|||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
std::optional<char> ToEscapeSymbol(char symbol) {
|
||||
switch (symbol) {
|
||||
case 'a':
|
||||
return '\a';
|
||||
case 'b':
|
||||
return '\b';
|
||||
case 'e':
|
||||
return '\e';
|
||||
case 'f':
|
||||
return '\f';
|
||||
case 'n':
|
||||
return '\n';
|
||||
case 'r':
|
||||
return '\r';
|
||||
case 't':
|
||||
return '\t';
|
||||
case 'v':
|
||||
return '\v';
|
||||
default:
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
bool IsBuiltinFunction(const std::string& name) { // optimize ??
|
||||
std::unordered_set<std::string> builtin_functions;
|
||||
|
||||
|
|
|
|||
|
|
@ -583,7 +583,7 @@ void Visitor::Visit(AnnotatedName* node) {
|
|||
|
||||
void Visitor::Visit(FunctionType* node) {
|
||||
for (auto& type : node->types) {
|
||||
Visit(type);
|
||||
Visit(type.get());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -604,12 +604,11 @@ void Visitor::Visit(VariantType* node) {
|
|||
Visit(&node->type.value());
|
||||
}
|
||||
for (auto& constructor : node->constructors) {
|
||||
if (std::holds_alternative<Constructor>(constructor)) {
|
||||
Visit(&std::get<Constructor>(constructor));
|
||||
} else if (std::holds_alternative<std::unique_ptr<TupleType>>(constructor)) {
|
||||
Visit(std::get<std::unique_ptr<TupleType>>(constructor).get());
|
||||
} else {
|
||||
// error
|
||||
if (constructor.first.has_value()) {
|
||||
Visit(&constructor.first.value());
|
||||
}
|
||||
if (constructor.second.has_value()) {
|
||||
Visit(constructor.second.value().get());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue