name tree mostly finished

This commit is contained in:
ProgramSnail 2023-07-28 19:42:09 +03:00
parent 263b58a17c
commit fc114ff959
14 changed files with 116 additions and 38 deletions

View file

@ -43,9 +43,9 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
std::string modifier = parser_node.get_value();
if (modifier == "?") {
return nodes::Modifier::OR_FALSE;
return nodes::Modifier::OPTIONAL;
} else if (modifier == "!") {
return nodes::Modifier::OR_RETURN;
return nodes::Modifier::RESULT;
} else if (modifier == "->" || modifier == "out") {
return nodes::Modifier::OUT;
} else if (modifier == "<-" || modifier == "in") {

View file

@ -17,10 +17,10 @@ void print_modifier(const nodes::Modifier &modifier, Printer &printer) {
case nodes::Modifier::REF:
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
break;
case nodes::Modifier::OR_FALSE:
case nodes::Modifier::OPTIONAL:
printer.print("?");
break;
case nodes::Modifier::OR_RETURN:
case nodes::Modifier::RESULT:
printer.print("!");
break;
case nodes::Modifier::NONE:

View file

@ -338,8 +338,8 @@ void print_modifier_expression(const nodes::ModifierExpression &expression,
print_expression(*expression.get_expression(), printer);
if (expression.get_modifier() == nodes::Modifier::OR_FALSE ||
expression.get_modifier() == nodes::Modifier::OR_RETURN) {
if (expression.get_modifier() == nodes::Modifier::OPTIONAL ||
expression.get_modifier() == nodes::Modifier::RESULT) {
print_modifier(expression.get_modifier(), printer);
}
}

View file

@ -5,6 +5,7 @@
#include "basic_printers.hpp"
#include "error_handling.hpp"
#include "expression_nodes.hpp"
#include "name_tree.hpp"
#include "statement_builders.hpp"
#include "statement_printers.hpp"
#include "type_nodes.hpp"
@ -38,9 +39,10 @@ int main(int argc, char **argv) {
nodes::ExpressionStorage expression_storage;
nodes::TypeStorage type_storage;
names::NameTree name_tree;
auto statements = builders::build_source_file(
parse_tree.get_root(), expression_storage, type_storage);
parse_tree.get_root(), expression_storage, type_storage, name_tree);
printers::Printer printer(std::cout, 2, 80, false);
printers::print_source_file(statements, printer);

View file

@ -17,6 +17,20 @@ bool NameTree::insert(const std::string &path, nodes::Statement &&statement) {
return true;
}
bool NameTree::insert(const std::string &path,
const nodes::Statement &statement) {
auto name_ids = slice_path_to_name_ids(path);
size_t node_id = add_node(get_root(), name_ids);
if (nodes_[node_id].get_statement().has_value()) {
return false;
}
nodes_[node_id].set_statement(statement);
return true;
}
std::optional<nodes::Statement *> NameTree::find(const std::string &path) {
auto name_ids = slice_path_to_existing_name_ids(path);

View file

@ -11,6 +11,7 @@
#include "tree_sitter_wrapper.hpp"
#include "type_builders.hpp"
#include "type_nodes.hpp"
#include "utils.hpp"
#include <optional>
#include <type_traits>
@ -22,13 +23,14 @@ namespace builders {
std::vector<nodes::Statement>
build_source_file(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
nodes::TypeStorage &type_storage,
names::NameTree &name_tree) {
std::vector<nodes::Statement> statements;
auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
statements.push_back(
build_statement(current_node, expression_storage, type_storage));
statements.push_back(build_statement(current_node, expression_storage,
type_storage, name_tree));
current_node = current_node.next_named_sibling();
}
@ -38,29 +40,70 @@ build_source_file(parser::ParseTree::Node parser_node,
// import | type_definition | function_definition | typeclass_definition
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
nodes::ExpressionStorage &expression_storage,
nodes::TypeStorage &type_storage) {
nodes::TypeStorage &type_storage,
names::NameTree &name_tree) {
tokens::Type type = tokens::string_to_type(parser_node.get_type());
std::optional<std::string> statement_name;
std::optional<nodes::Statement> statement;
switch (type) {
case tokens::Type::IMPORT:
return nodes::Statement(build_import(parser_node));
statement = nodes::Statement(build_import(parser_node));
statement_name = *statement.value()
.get<nodes::Import>()
.value()
->get_module_name()
->get();
break;
case tokens::Type::TYPE_DEFINITION:
return nodes::Statement(
statement = nodes::Statement(
build_type_definition(parser_node, expression_storage, type_storage));
statement_name = *statement.value()
.get<nodes::TypeDefinition>()
.value()
->get_name()
->get();
break;
case tokens::Type::FUNCTION_DEFINITION:
return nodes::Statement(build_function_definition(
statement = nodes::Statement(build_function_definition(
parser_node, expression_storage, type_storage));
statement_name = *statement.value()
.get<nodes::FunctionDefinition>()
.value()
->get_name()
->get();
break;
case tokens::Type::TYPECLASS_DEFINITION:
return nodes::Statement(build_typeclass_definition(
statement = nodes::Statement(build_typeclass_definition(
parser_node, expression_storage, type_storage));
statement_name = *statement.value()
.get<nodes::TypeclassDefinition>()
.value()
->get_name()
->get();
break;
case tokens::Type::EMPTY_LINES:
return nodes::Statement(build_empty_lines(parser_node));
statement = build_empty_lines(parser_node);
break;
default:
error_handling::handle_parsing_error("Unexprected statement node type",
parser_node);
}
error_handling::handle_general_error("Unreachable");
exit(1); // unreachable
if (!statement.has_value()) {
error_handling::handle_general_error("Unreachable");
}
if (statement_name.has_value()) {
// TODO: combine statements with same name
if (!name_tree.insert(statement_name.value(), statement.value())) {
error_handling::handle_parsing_error(
"Two or more statements in file have the same name", parser_node);
}
}
return std::move(statement.value());
}
// ('::' | 'import') simple_name ('=' simple_name)? (':' identifier*)?
@ -272,8 +315,8 @@ build_function_definition(parser::ParseTree::Node parser_node,
last_after_modifier = build_modifier(maybe_reference_node);
// only optional, result allowed
if (last_after_modifier != nodes::Modifier::OR_FALSE &&
last_after_modifier != nodes::Modifier::OR_RETURN) {
if (last_after_modifier != nodes::Modifier::OPTIONAL &&
last_after_modifier != nodes::Modifier::RESULT) {
last_after_modifier = nodes::Modifier::NONE;
}
}

View file

@ -4,6 +4,7 @@
#include "doc_printers.hpp"
#include "expression_nodes.hpp"
#include "expression_printers.hpp"
#include "statement_nodes.hpp"
#include "type_printers.hpp"
namespace printers {

View file

@ -24,8 +24,8 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
modifier = build_modifier(current_node);
// only optional, result allowed
if (modifier != nodes::Modifier::OR_FALSE &&
modifier != nodes::Modifier::OR_RETURN) {
if (modifier != nodes::Modifier::OPTIONAL &&
modifier != nodes::Modifier::RESULT) {
modifier = nodes::Modifier::NONE;
}
}