type structure change, part done

This commit is contained in:
ProgramSnail 2023-08-08 10:30:16 +03:00
parent 78c696b99a
commit 522dd16f79
13 changed files with 386 additions and 218 deletions

View file

@ -168,8 +168,8 @@ parser::ParseTree::Node collect_symbol_doc_nodes(
return current_node;
}
// definition_info? annotation_info* '^'? (simple_type | typeclass)
// (argument_type* '=' variant_type)? ';'
// definition_info? annotation_info* '^'? (simple_type_identifier | typeclass)
// (argument_type* '=' type)? ';'
nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
bool is_on_heap = parser_node.nth_child(0).get_value() == "^";
@ -240,16 +240,16 @@ nodes::TypeDefinition build_type_definition(parser::ParseTree::Node parser_node,
}
}
std::optional<nodes::VariantType> type =
type_node.has_value()
? build_variant_type(type_node.value(), type_storage)
: std::optional<nodes::VariantType>();
std::optional<nodes::TypeProxy> type =
type_node.has_value() ? build_type(type_node.value(), type_storage)
: std::optional<nodes::TypeProxy>();
std::unordered_set<std::string> annotations;
// collect annotations from type
if (type.has_value()) {
for (size_t i = 0; i < type.value().size(); ++i) {
// TODO: deal with annotations
auto constructor_annotations = type.value().get(i)->get_all_annotations();
for (auto &annotation : constructor_annotations) {
annotations.insert(annotation);
@ -373,7 +373,12 @@ nodes::FunctionDefinition build_function_definition(
last_annotation = std::nullopt;
break;
case tokens::Type::TYPE:
case tokens::Type::VARIANT_TYPE:
case tokens::Type::TUPLE_TYPE:
case tokens::Type::ARRAY_TYPE:
case tokens::Type::REFERENCE_TYPE:
case tokens::Type::MODIFIED_TYPE:
case tokens::Type::SIMPLE_TYPE:
if (current_type_id >= arguments.size()) {
arguments.push_back(nodes::FunctionDefinition::Argument(
last_annotation, build_type(current_node, type_storage),

View file

@ -1,80 +1,152 @@
#include "type_builders.hpp"
#include "basic_builders.hpp"
#include "basic_nodes.hpp"
#include "builtin_identifiers.hpp"
#include "error_handling.hpp"
#include "tokens.hpp"
#include "type_nodes.hpp"
namespace builders {
// '^'? type_identifer '?'? ('[' type+ ']')?
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
tokens::Type type = tokens::string_to_type(parser_node.get_type());
// TODO
// auto maybe_parenthesis = parser_node.previous_sibling();
// bool is_scoped =
// (!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() &&
// maybe_parenthesis.get_value() == "(");
switch (type) {
case tokens::Type::VARIANT_TYPE:
return build_variant_type(parser_node, type_storage);
case tokens::Type::TUPLE_TYPE:
return build_tuple_type(parser_node, type_storage);
case tokens::Type::ARRAY_TYPE:
return build_array_type(parser_node, type_storage);
case tokens::Type::REFERENCE_TYPE:
return build_reference_type(parser_node, type_storage);
case tokens::Type::MODIFIED_TYPE:
return build_modified_type(parser_node, type_storage);
case tokens::Type::SIMPLE_TYPE:
return build_simple_type(parser_node, type_storage);
default:
error_handling::handle_parsing_error("Unexprected type node type",
parser_node);
}
error_handling::handle_general_error("Unreachable");
exit(1); // unreachable
}
// '|'? annotation? type ('|' annotation? type)+
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
auto name_node = parse_node.child_by_field_name("name");
auto current_node = parse_node.nth_child(0);
bool is_on_heap = (!current_node.is_null() && !current_node.is_named() &&
current_node.get_value() == "^");
nodes::Modifier modifier = nodes::Modifier::NONE;
current_node = name_node.next_sibling();
// update last after modifier
if (!current_node.is_null() && !current_node.is_named()) {
modifier = build_modifier(current_node);
// only optional, result allowed
if (!utils::is_suffix_modifier(modifier)) {
modifier = nodes::Modifier::NONE;
}
}
current_node = name_node.next_named_sibling();
auto current_node = parser_node.nth_named_child(0);
;
while (!current_node.is_null()) {
parameters.push_back(build_type(current_node, type_storage));
current_node = current_node.next_named_sibling();
}
return type_storage.add_type(
nodes::Type(build_node(parse_node), build_identifier(name_node),
std::move(parameters), is_on_heap, modifier));
return type_storage.add_type(nodes::Type(
build_node(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::VARIANT_IDENTIFIER),
std::move(parameters), false));
}
// '&'? annotation? type ('&' annotation? type)*
nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node,
// '&'? annotation? type ('&' annotation? type)+
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<std::pair<std::optional<std::string>, nodes::TypeProxy>> fields;
std::vector<nodes::TypeProxy> parameters;
auto current_node = parse_node.nth_named_child(0);
std::optional<std::string> last_annotation;
auto current_node = parser_node.nth_named_child(0);
while (!current_node.is_null()) {
if (tokens::string_to_type(current_node.get_type()) ==
tokens::Type::ANNOTATION_IDENTIFIER) {
last_annotation = build_annotation(current_node);
} else {
fields.emplace_back(std::move(last_annotation),
build_type(current_node, type_storage));
last_annotation = std::nullopt;
}
parameters.push_back(build_type(current_node, type_storage));
current_node = current_node.next_named_sibling();
}
return nodes::TupleType(build_node(parse_node), std::move(fields));
return type_storage.add_type(nodes::Type(
build_node(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::TUPLE_IDENTIFIER),
std::move(parameters), false));
}
// '|'? tuple_type ('|' tuple_type)*
nodes::VariantType build_variant_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TupleType> constructors;
// '[[' type ']]'
nodes::TypeProxy build_array_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
parameters.push_back(
build_type(parser_node.nth_named_child(0), type_storage));
auto current_node = parse_node.nth_named_child(0);
return type_storage.add_type(nodes::Type(
build_node(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::ARRAY_IDENTIFIER),
std::move(parameters), false));
}
// '^' type
nodes::TypeProxy build_reference_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
nodes::TypeProxy type =
build_type(parser_node.nth_named_child(0), type_storage);
type.get()->set_is_on_heap(true);
return type;
}
// type ('?' | '!')
nodes::TypeProxy build_modified_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
parameters.push_back(
build_type(parser_node.nth_named_child(0), type_storage));
nodes::Modifier modifier =
build_modifier(parser_node.nth_child(parser_node.child_count() - 1));
std::string identifier;
switch (modifier) {
case nodes::Modifier::OPTIONAL:
identifier = builtin::OPTIONAL_IDENTIFIER;
break;
case nodes::Modifier::RESULT:
identifier = builtin::RESULT_IDENTIFIER;
break;
default:
error_handling::handle_parsing_error(
"Unexpected modifier type in modified type", parser_node);
break;
}
return type_storage.add_type(
nodes::Type(build_node(parser_node),
nodes::Identifier(build_node(parser_node),
nodes::Identifier::SIMPLE_TYPE, identifier),
std::move(parameters), false));
}
// type_identifier ('[' type+ ']')?
nodes::TypeProxy build_simple_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
auto name_node = parser_node.child_by_field_name("name");
auto current_node = name_node.next_named_sibling();
while (!current_node.is_null()) {
constructors.push_back(build_tuple_type(current_node, type_storage));
parameters.push_back(build_type(current_node, type_storage));
current_node = current_node.next_named_sibling();
}
return nodes::VariantType(build_node(parse_node), std::move(constructors));
return type_storage.add_type(nodes::Type(build_node(parser_node),
build_identifier(name_node),
std::move(parameters), false));
}
} // namespace builders