changes for new grammar, fixes

This commit is contained in:
ProgramSnail 2023-06-03 19:01:03 +03:00
parent 91f9affadc
commit 3106a64949
35 changed files with 605 additions and 550 deletions

View file

@ -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) {

View file

@ -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;

View file

@ -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;

View file

@ -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);
}

View file

@ -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"});

View file

@ -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_ << ')';

View file

@ -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();
}
}

View file

@ -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_ << ')';

View file

@ -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 += ")";

View file

@ -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;

View file

@ -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());
}
}
}