mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-06 06:58:46 +00:00
name tree mostly finished
This commit is contained in:
parent
263b58a17c
commit
fc114ff959
14 changed files with 116 additions and 38 deletions
|
|
@ -8,11 +8,11 @@
|
||||||
namespace nodes {
|
namespace nodes {
|
||||||
|
|
||||||
enum class Modifier {
|
enum class Modifier {
|
||||||
OUT, // -> x
|
OUT, // -> x
|
||||||
IN, // <- x
|
IN, // <- x
|
||||||
REF, // <> x
|
REF, // <> x
|
||||||
OR_FALSE, // x?
|
OPTIONAL, // x?
|
||||||
OR_RETURN, // x!
|
RESULT, // x!
|
||||||
NONE,
|
NONE,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -19,6 +19,8 @@ public:
|
||||||
|
|
||||||
bool insert(const std::string &path, nodes::Statement &&statement);
|
bool insert(const std::string &path, nodes::Statement &&statement);
|
||||||
|
|
||||||
|
bool insert(const std::string &path, const nodes::Statement &statement);
|
||||||
|
|
||||||
std::optional<nodes::Statement *> find(const std::string &path);
|
std::optional<nodes::Statement *> find(const std::string &path);
|
||||||
|
|
||||||
std::optional<const nodes::Statement *> find(const std::string &path) const;
|
std::optional<const nodes::Statement *> find(const std::string &path) const;
|
||||||
|
|
@ -48,6 +50,14 @@ private:
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool set_statement(const nodes::Statement &statement) {
|
||||||
|
if (statement_.has_value()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
statement_ = statement;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
std::optional<size_t> find(size_t name_id) const {
|
std::optional<size_t> find(size_t name_id) const {
|
||||||
auto name_iter = children_.find(name_id);
|
auto name_iter = children_.find(name_id);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "name_tree.hpp"
|
||||||
#include "statement_nodes.hpp"
|
#include "statement_nodes.hpp"
|
||||||
#include "tree_sitter_wrapper.hpp"
|
#include "tree_sitter_wrapper.hpp"
|
||||||
|
|
||||||
|
|
@ -7,14 +8,18 @@
|
||||||
|
|
||||||
namespace builders {
|
namespace builders {
|
||||||
|
|
||||||
|
// statements (copies of statements are in name_tree) returned to print /
|
||||||
|
// translate them in required order
|
||||||
std::vector<nodes::Statement>
|
std::vector<nodes::Statement>
|
||||||
build_source_file(parser::ParseTree::Node parser_node,
|
build_source_file(parser::ParseTree::Node parser_node,
|
||||||
nodes::ExpressionStorage &expression_storage,
|
nodes::ExpressionStorage &expression_storage,
|
||||||
nodes::TypeStorage &type_storage);
|
nodes::TypeStorage &type_storage, names::NameTree &name_tree);
|
||||||
|
|
||||||
|
// copy of statement inserted into name_tree
|
||||||
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
||||||
nodes::ExpressionStorage &expression_storage,
|
nodes::ExpressionStorage &expression_storage,
|
||||||
nodes::TypeStorage &type_storage);
|
nodes::TypeStorage &type_storage,
|
||||||
|
names::NameTree &name_tree);
|
||||||
|
|
||||||
nodes::Import build_import(parser::ParseTree::Node parser_node);
|
nodes::Import build_import(parser::ParseTree::Node parser_node);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -464,6 +464,10 @@ private:
|
||||||
|
|
||||||
class Statement {
|
class Statement {
|
||||||
public:
|
public:
|
||||||
|
Statement(const Statement &) = default;
|
||||||
|
Statement(Statement &&) = default;
|
||||||
|
Statement &operator=(const Statement &) = default;
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
Statement(T &&statement) : expression_(std::forward<T>(statement)) {}
|
Statement(T &&statement) : expression_(std::forward<T>(statement)) {}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "basic_printers.hpp"
|
#include "basic_printers.hpp"
|
||||||
|
#include "name_tree.hpp"
|
||||||
#include "statement_nodes.hpp"
|
#include "statement_nodes.hpp"
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,9 @@ nodes::Modifier build_modifier(parser::ParseTree::Node parser_node) {
|
||||||
std::string modifier = parser_node.get_value();
|
std::string modifier = parser_node.get_value();
|
||||||
|
|
||||||
if (modifier == "?") {
|
if (modifier == "?") {
|
||||||
return nodes::Modifier::OR_FALSE;
|
return nodes::Modifier::OPTIONAL;
|
||||||
} else if (modifier == "!") {
|
} else if (modifier == "!") {
|
||||||
return nodes::Modifier::OR_RETURN;
|
return nodes::Modifier::RESULT;
|
||||||
} else if (modifier == "->" || modifier == "out") {
|
} else if (modifier == "->" || modifier == "out") {
|
||||||
return nodes::Modifier::OUT;
|
return nodes::Modifier::OUT;
|
||||||
} else if (modifier == "<-" || modifier == "in") {
|
} else if (modifier == "<-" || modifier == "in") {
|
||||||
|
|
|
||||||
|
|
@ -17,10 +17,10 @@ void print_modifier(const nodes::Modifier &modifier, Printer &printer) {
|
||||||
case nodes::Modifier::REF:
|
case nodes::Modifier::REF:
|
||||||
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
|
printer.print(printer.print_words_instead_of_symbols() ? "ref " : "<> ");
|
||||||
break;
|
break;
|
||||||
case nodes::Modifier::OR_FALSE:
|
case nodes::Modifier::OPTIONAL:
|
||||||
printer.print("?");
|
printer.print("?");
|
||||||
break;
|
break;
|
||||||
case nodes::Modifier::OR_RETURN:
|
case nodes::Modifier::RESULT:
|
||||||
printer.print("!");
|
printer.print("!");
|
||||||
break;
|
break;
|
||||||
case nodes::Modifier::NONE:
|
case nodes::Modifier::NONE:
|
||||||
|
|
|
||||||
|
|
@ -338,8 +338,8 @@ void print_modifier_expression(const nodes::ModifierExpression &expression,
|
||||||
|
|
||||||
print_expression(*expression.get_expression(), printer);
|
print_expression(*expression.get_expression(), printer);
|
||||||
|
|
||||||
if (expression.get_modifier() == nodes::Modifier::OR_FALSE ||
|
if (expression.get_modifier() == nodes::Modifier::OPTIONAL ||
|
||||||
expression.get_modifier() == nodes::Modifier::OR_RETURN) {
|
expression.get_modifier() == nodes::Modifier::RESULT) {
|
||||||
print_modifier(expression.get_modifier(), printer);
|
print_modifier(expression.get_modifier(), printer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
#include "basic_printers.hpp"
|
#include "basic_printers.hpp"
|
||||||
#include "error_handling.hpp"
|
#include "error_handling.hpp"
|
||||||
#include "expression_nodes.hpp"
|
#include "expression_nodes.hpp"
|
||||||
|
#include "name_tree.hpp"
|
||||||
#include "statement_builders.hpp"
|
#include "statement_builders.hpp"
|
||||||
#include "statement_printers.hpp"
|
#include "statement_printers.hpp"
|
||||||
#include "type_nodes.hpp"
|
#include "type_nodes.hpp"
|
||||||
|
|
@ -38,9 +39,10 @@ int main(int argc, char **argv) {
|
||||||
|
|
||||||
nodes::ExpressionStorage expression_storage;
|
nodes::ExpressionStorage expression_storage;
|
||||||
nodes::TypeStorage type_storage;
|
nodes::TypeStorage type_storage;
|
||||||
|
names::NameTree name_tree;
|
||||||
|
|
||||||
auto statements = builders::build_source_file(
|
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::Printer printer(std::cout, 2, 80, false);
|
||||||
printers::print_source_file(statements, printer);
|
printers::print_source_file(statements, printer);
|
||||||
|
|
|
||||||
|
|
@ -17,6 +17,20 @@ bool NameTree::insert(const std::string &path, nodes::Statement &&statement) {
|
||||||
return true;
|
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) {
|
std::optional<nodes::Statement *> NameTree::find(const std::string &path) {
|
||||||
auto name_ids = slice_path_to_existing_name_ids(path);
|
auto name_ids = slice_path_to_existing_name_ids(path);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
#include "tree_sitter_wrapper.hpp"
|
#include "tree_sitter_wrapper.hpp"
|
||||||
#include "type_builders.hpp"
|
#include "type_builders.hpp"
|
||||||
#include "type_nodes.hpp"
|
#include "type_nodes.hpp"
|
||||||
|
#include "utils.hpp"
|
||||||
|
|
||||||
#include <optional>
|
#include <optional>
|
||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
|
|
@ -22,13 +23,14 @@ namespace builders {
|
||||||
std::vector<nodes::Statement>
|
std::vector<nodes::Statement>
|
||||||
build_source_file(parser::ParseTree::Node parser_node,
|
build_source_file(parser::ParseTree::Node parser_node,
|
||||||
nodes::ExpressionStorage &expression_storage,
|
nodes::ExpressionStorage &expression_storage,
|
||||||
nodes::TypeStorage &type_storage) {
|
nodes::TypeStorage &type_storage,
|
||||||
|
names::NameTree &name_tree) {
|
||||||
std::vector<nodes::Statement> statements;
|
std::vector<nodes::Statement> statements;
|
||||||
|
|
||||||
auto current_node = parser_node.nth_named_child(0);
|
auto current_node = parser_node.nth_named_child(0);
|
||||||
while (!current_node.is_null()) {
|
while (!current_node.is_null()) {
|
||||||
statements.push_back(
|
statements.push_back(build_statement(current_node, expression_storage,
|
||||||
build_statement(current_node, expression_storage, type_storage));
|
type_storage, name_tree));
|
||||||
current_node = current_node.next_named_sibling();
|
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
|
// import | type_definition | function_definition | typeclass_definition
|
||||||
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
nodes::Statement build_statement(parser::ParseTree::Node parser_node,
|
||||||
nodes::ExpressionStorage &expression_storage,
|
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());
|
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||||
|
|
||||||
|
std::optional<std::string> statement_name;
|
||||||
|
std::optional<nodes::Statement> statement;
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case tokens::Type::IMPORT:
|
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:
|
case tokens::Type::TYPE_DEFINITION:
|
||||||
return nodes::Statement(
|
statement = nodes::Statement(
|
||||||
build_type_definition(parser_node, expression_storage, type_storage));
|
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:
|
case tokens::Type::FUNCTION_DEFINITION:
|
||||||
return nodes::Statement(build_function_definition(
|
statement = nodes::Statement(build_function_definition(
|
||||||
parser_node, expression_storage, type_storage));
|
parser_node, expression_storage, type_storage));
|
||||||
|
statement_name = *statement.value()
|
||||||
|
.get<nodes::FunctionDefinition>()
|
||||||
|
.value()
|
||||||
|
->get_name()
|
||||||
|
->get();
|
||||||
|
break;
|
||||||
case tokens::Type::TYPECLASS_DEFINITION:
|
case tokens::Type::TYPECLASS_DEFINITION:
|
||||||
return nodes::Statement(build_typeclass_definition(
|
statement = nodes::Statement(build_typeclass_definition(
|
||||||
parser_node, expression_storage, type_storage));
|
parser_node, expression_storage, type_storage));
|
||||||
|
statement_name = *statement.value()
|
||||||
|
.get<nodes::TypeclassDefinition>()
|
||||||
|
.value()
|
||||||
|
->get_name()
|
||||||
|
->get();
|
||||||
|
break;
|
||||||
case tokens::Type::EMPTY_LINES:
|
case tokens::Type::EMPTY_LINES:
|
||||||
return nodes::Statement(build_empty_lines(parser_node));
|
statement = build_empty_lines(parser_node);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
error_handling::handle_parsing_error("Unexprected statement node type",
|
error_handling::handle_parsing_error("Unexprected statement node type",
|
||||||
parser_node);
|
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*)?
|
// ('::' | '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);
|
last_after_modifier = build_modifier(maybe_reference_node);
|
||||||
|
|
||||||
// only optional, result allowed
|
// only optional, result allowed
|
||||||
if (last_after_modifier != nodes::Modifier::OR_FALSE &&
|
if (last_after_modifier != nodes::Modifier::OPTIONAL &&
|
||||||
last_after_modifier != nodes::Modifier::OR_RETURN) {
|
last_after_modifier != nodes::Modifier::RESULT) {
|
||||||
last_after_modifier = nodes::Modifier::NONE;
|
last_after_modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
#include "doc_printers.hpp"
|
#include "doc_printers.hpp"
|
||||||
#include "expression_nodes.hpp"
|
#include "expression_nodes.hpp"
|
||||||
#include "expression_printers.hpp"
|
#include "expression_printers.hpp"
|
||||||
|
#include "statement_nodes.hpp"
|
||||||
#include "type_printers.hpp"
|
#include "type_printers.hpp"
|
||||||
|
|
||||||
namespace printers {
|
namespace printers {
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
||||||
modifier = build_modifier(current_node);
|
modifier = build_modifier(current_node);
|
||||||
|
|
||||||
// only optional, result allowed
|
// only optional, result allowed
|
||||||
if (modifier != nodes::Modifier::OR_FALSE &&
|
if (modifier != nodes::Modifier::OPTIONAL &&
|
||||||
modifier != nodes::Modifier::OR_RETURN) {
|
modifier != nodes::Modifier::RESULT) {
|
||||||
modifier = nodes::Modifier::NONE;
|
modifier = nodes::Modifier::NONE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -2,10 +2,10 @@
|
||||||
|
|
||||||
:: module; // import module to current namespace
|
:: module; // import module to current namespace
|
||||||
|
|
||||||
:: _ = module; // import module to current namespace and use functions inside without namespace
|
:: _ = module_2; // import module to current namespace and use functions inside without namespace
|
||||||
|
|
||||||
:: module : func1 func2 func3;
|
:: module_3 : func1 func2 func3;
|
||||||
:: module_namespace = module;
|
:: module_namespace = module_4;
|
||||||
|
|
||||||
func = {
|
func = {
|
||||||
|
|
||||||
|
|
@ -40,7 +40,7 @@ sum 'a? 'b? =
|
||||||
: example that shows that default annotations are argument names (without ')
|
: example that shows that default annotations are argument names (without ')
|
||||||
@a is integer
|
@a is integer
|
||||||
@b also integer
|
@b also integer
|
||||||
sum 'a 'b = 'a + 'b;
|
sum_2 'a 'b = 'a + 'b;
|
||||||
|
|
||||||
: this function can be used to calculate Fibonacci sequence elements
|
: this function can be used to calculate Fibonacci sequence elements
|
||||||
: it is important is some algorithmic tasks
|
: it is important is some algorithmic tasks
|
||||||
|
|
@ -137,7 +137,7 @@ bubble_sort 'arr : <> Array['A] = {
|
||||||
}
|
}
|
||||||
|
|
||||||
: bubble_sort with names instead of symbols
|
: bubble_sort with names instead of symbols
|
||||||
bubble_sort 'arr : ref Array['A] = {
|
bubble_sort_2 'arr : ref Array['A] = {
|
||||||
var swap_occured := true;
|
var swap_occured := true;
|
||||||
for swap_occured do {
|
for swap_occured do {
|
||||||
swap_occured = false;
|
swap_occured = false;
|
||||||
|
|
@ -151,9 +151,7 @@ bubble_sort 'arr : ref Array['A] = {
|
||||||
& @key Key
|
& @key Key
|
||||||
& @value Value
|
& @value Value
|
||||||
& @left ^TreeNode['Key 'Value]
|
& @left ^TreeNode['Key 'Value]
|
||||||
& @right ^TreeNode['Key 'Value];
|
& @right ^TreeNode['Key 'Value] {
|
||||||
|
|
||||||
TreeNode {
|
|
||||||
new = do_something; // static methods
|
new = do_something; // static methods
|
||||||
|
|
||||||
$insert 'key = do_something; // const methods
|
$insert 'key = do_something; // const methods
|
||||||
|
|
@ -186,7 +184,7 @@ print_two 'a 'b = print 'a, print 'b;
|
||||||
swap 'a 'b : <> 'A <> 'A = %c := <- 'a, 'a := <- 'b, 'b := <- c;
|
swap 'a 'b : <> 'A <> 'A = %c := <- 'a, 'a := <- 'b, 'b := <- c;
|
||||||
|
|
||||||
: previous example with automatic type deduction
|
: previous example with automatic type deduction
|
||||||
swap <> 'a <> 'b = %c := <- 'a, 'a := <- 'b, 'b := <- c;
|
swap_2 <> 'a <> 'b = %c := <- 'a, 'a := <- 'b, 'b := <- c;
|
||||||
|
|
||||||
: several outputs example
|
: several outputs example
|
||||||
scan_three : -> String -> String -> String = scan & scan & scan;
|
scan_three : -> String -> String -> String = scan & scan & scan;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue