mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-25 16:28:46 +00:00
type structure change, part done
This commit is contained in:
parent
78c696b99a
commit
522dd16f79
13 changed files with 386 additions and 218 deletions
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue