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

@ -75,11 +75,14 @@
<RegExpr String="\b[0-9]+\b" attribute="Decimal" context="#stay"/> <RegExpr String="\b[0-9]+\b" attribute="Decimal" context="#stay"/>
<RegExpr String="&quot;([^\\&quot;]|(\\.))*&quot;" attribute="String" context="#stay" /> <RegExpr String="&quot;([^\\&quot;]|(\\.))*&quot;" attribute="String" context="#stay" />
<DetectChar char="[" attribute="Symbol" context="#stay"/> <DetectChar char="(" attribute="Symbol" context="#stay" beginRegion="OpenBracket"/>
<DetectChar char="]" attribute="Symbol" context="#stay"/> <DetectChar char=")" attribute="Symbol" context="#stay" endRegion="OpenBracket"/>
<DetectChar char="{" attribute="Symbol" context="#stay" beginRegion="Brace"/> <DetectChar char="[" attribute="Symbol" context="#stay" beginRegion="AngledBracket"/>
<DetectChar char="}" attribute="Symbol" context="#stay" endRegion="Brace"/> <DetectChar char="]" attribute="Symbol" context="#stay" endRegion="AngledBracket"/>
<DetectChar char="{" attribute="Symbol" context="#stay" beginRegion="CurlyBrace"/>
<DetectChar char="}" attribute="Symbol" context="#stay" endRegion="CurlyBrace"/>
<IncludeRules context="FindComments" /> <IncludeRules context="FindComments" />
</context> </context>
@ -130,7 +133,7 @@
<itemData name="Escape" defStyleNum="dsSpecialChar"/> <itemData name="Escape" defStyleNum="dsSpecialChar"/>
<itemData name="Character" defStyleNum="dsChar"/> <itemData name="Character" defStyleNum="dsChar"/>
<itemData name="Operator" defStyleNum="dsOperator"/> <itemData name="Operator" defStyleNum="dsOperator"/>
<itemData name="Symbol" defStyleNum="dsOperator"/> <itemData name="Symbol" defStyleNum="dsNormal"/>
<itemData name="Error" defStyleNum="dsError"/> <itemData name="Error" defStyleNum="dsError"/>
</itemDatas> </itemDatas>
</highlighting> </highlighting>

View file

@ -8,10 +8,22 @@ namespace builders {
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node, nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage); nodes::TypeStorage &type_storage);
nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node, nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage); nodes::TypeStorage &type_storage);
nodes::VariantType build_variant_type(parser::ParseTree::Node parse_node, nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_array_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_reference_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_modified_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage);
nodes::TypeProxy build_simple_type(parser::ParseTree::Node parse_node,
nodes::TypeStorage &type_storage); nodes::TypeStorage &type_storage);
} // namespace builders } // namespace builders

View file

@ -0,0 +1,17 @@
#pragma once
#include <string>
namespace builtin {
const static std::string TUPLE_IDENTIFIER = "Tuple";
const static std::string VARIANT_IDENTIFIER = "Variant";
const static std::string ARRAY_IDENTIFIER = "Array";
const static std::string OPTIONAL_IDENTIFIER = "Optional";
const static std::string RESULT_IDENTIFIER = "Result";
} // namespace builtin

View file

@ -335,7 +335,7 @@ public:
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap, TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
const Identifier &name, std::vector<Identifier> &&typeclasses, const Identifier &name, std::vector<Identifier> &&typeclasses,
std::vector<Identifier> &&arguments, std::vector<Identifier> &&arguments,
std::optional<VariantType> &&type) std::optional<TypeProxy> &type)
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap), : Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
name_(name), typeclasses_(typeclasses), name_(name), typeclasses_(typeclasses),
arguments_(std::move(arguments)), type_(std::move(type)) {} arguments_(std::move(arguments)), type_(std::move(type)) {}
@ -366,16 +366,9 @@ public:
// //
std::optional<VariantType *> get_type() { std::optional<TypeProxy> get_type() const {
if (type_.has_value()) { if (type_.has_value()) {
return &type_.value(); return type_.value();
}
return std::nullopt;
}
std::optional<const VariantType *> get_type() const {
if (type_.has_value()) {
return &type_.value();
} }
return std::nullopt; return std::nullopt;
} }
@ -396,7 +389,7 @@ private:
Identifier name_; Identifier name_;
std::vector<Identifier> typeclasses_; std::vector<Identifier> typeclasses_;
std::vector<Identifier> arguments_; std::vector<Identifier> arguments_;
std::optional<VariantType> type_; // TupleType is VariantType with one variant std::optional<TypeProxy> type_;
}; };
class Statement { class Statement {

View file

@ -34,27 +34,21 @@ private:
// can't have both optional and result modifiers ?? // can't have both optional and result modifiers ??
class Type : public Node { class Type : public Node {
public: public:
Type(Node node, Identifier &&identifier, bool is_on_heap = false, Type(Node node, Identifier &&identifier, bool is_on_heap = false)
Modifier modifier = Modifier::NONE) : Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap) {}
: Node(node), name_(std::move(identifier)), is_on_heap_(is_on_heap),
modifier_(modifier) {}
Type(Node node, const Identifier &identifier, bool is_on_heap = false, Type(Node node, const Identifier &identifier, bool is_on_heap = false)
Modifier modifier = Modifier::NONE) : Node(node), name_(identifier), is_on_heap_(is_on_heap) {}
: Node(node), name_(identifier), is_on_heap_(is_on_heap),
modifier_(modifier) {}
Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &&parameters, Type(Node node, Identifier &&identifier, std::vector<TypeProxy> &&parameters,
bool is_on_heap = false, Modifier modifier = Modifier::NONE) bool is_on_heap = false)
: Node(node), name_(std::move(identifier)), : Node(node), name_(std::move(identifier)),
parameters_(std::move(parameters)), is_on_heap_(is_on_heap), parameters_(std::move(parameters)), is_on_heap_(is_on_heap) {}
modifier_(modifier) {}
Type(Node node, const Identifier &identifier, Type(Node node, const Identifier &identifier,
std::vector<TypeProxy> &&parameters, bool is_on_heap = false, std::vector<TypeProxy> &&parameters, bool is_on_heap = false)
Modifier modifier = Modifier::NONE)
: Node(node), name_(identifier), parameters_(std::move(parameters)), : Node(node), name_(identifier), parameters_(std::move(parameters)),
is_on_heap_(is_on_heap), modifier_(modifier) {} is_on_heap_(is_on_heap) {}
// //
@ -76,13 +70,12 @@ public:
bool is_on_heap() const { return is_on_heap_; } bool is_on_heap() const { return is_on_heap_; }
Modifier get_modifier() const { return modifier_; } void set_is_on_heap(bool is_on_heap) { is_on_heap_ = is_on_heap; }
// //
bool operator==(const Type &other_type) const { bool operator==(const Type &other_type) const {
if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ || if (name_ != other_type.name_ || is_on_heap_ != other_type.is_on_heap_ ||
modifier_ != other_type.modifier_ ||
parameters_.size() != other_type.parameters_.size()) { parameters_.size() != other_type.parameters_.size()) {
return false; return false;
} }
@ -105,7 +98,6 @@ private:
std::vector<TypeProxy> parameters_; std::vector<TypeProxy> parameters_;
// or use allocator ?? // or use allocator ??
bool is_on_heap_ = false; bool is_on_heap_ = false;
Modifier modifier_ = Modifier::NONE; // optional, result or none
}; };
class TypeStorage { class TypeStorage {
@ -131,85 +123,86 @@ private:
std::vector<Type> storage_; std::vector<Type> storage_;
}; };
class TupleType : public Node { // class TupleType : public Node {
public: // public:
TupleType(Node node, // TupleType(Node node,
const std::vector<std::pair<std::optional<std::string>, TypeProxy>> // const std::vector<std::pair<std::optional<std::string>,
&fields) // TypeProxy>>
: Node(node) { // &fields)
annotations_.reserve(fields.size()); // : Node(node) {
fields_.reserve(fields.size()); // annotations_.reserve(fields.size());
for (auto &field : fields) { // fields_.reserve(fields.size());
if (field.first.has_value()) { // for (auto &field : fields) {
annotation_fields_[field.first.value()] = fields_.size(); // if (field.first.has_value()) {
} // annotation_fields_[field.first.value()] = fields_.size();
annotations_.push_back(field.first); // }
fields_.push_back(field.second); // annotations_.push_back(field.first);
} // fields_.push_back(field.second);
} // }
// }
size_t size() const { return fields_.size(); } //
// size_t size() const { return fields_.size(); }
std::optional<std::string *> get_annotation(size_t id) { //
if (annotations_.at(id).has_value()) { // std::optional<std::string *> get_annotation(size_t id) {
return &annotations_[id].value(); // if (annotations_.at(id).has_value()) {
} // return &annotations_[id].value();
return std::nullopt; // }
} // return std::nullopt;
// }
std::optional<const std::string *> get_annotation(size_t id) const { //
if (annotations_.at(id).has_value()) { // std::optional<const std::string *> get_annotation(size_t id) const {
return &annotations_[id].value(); // if (annotations_.at(id).has_value()) {
} // return &annotations_[id].value();
return std::nullopt; // }
} // return std::nullopt;
// }
Type *get(size_t id) { return fields_.at(id).get(); } //
// Type *get(size_t id) { return fields_.at(id).get(); }
const Type *get(size_t id) const { return fields_.at(id).get(); } //
// const Type *get(size_t id) const { return fields_.at(id).get(); }
Type *get(const std::string &annotation) { //
return fields_.at(annotation_fields_.at(annotation)).get(); // Type *get(const std::string &annotation) {
} // return fields_.at(annotation_fields_.at(annotation)).get();
// }
const Type *get(const std::string &annotation) const { //
return fields_.at(annotation_fields_.at(annotation)).get(); // const Type *get(const std::string &annotation) const {
} // return fields_.at(annotation_fields_.at(annotation)).get();
// }
std::vector<std::string> get_all_annotations() { //
std::vector<std::string> annotations; // std::vector<std::string> get_all_annotations() {
// std::vector<std::string> annotations;
annotations.reserve(annotation_fields_.size()); //
for (auto &annotation_with_field : annotation_fields_) { // annotations.reserve(annotation_fields_.size());
annotations.push_back(annotation_with_field.first); // for (auto &annotation_with_field : annotation_fields_) {
} // annotations.push_back(annotation_with_field.first);
// }
return annotations; //
} // return annotations;
// }
private: //
std::unordered_map<std::string, size_t> annotation_fields_; // private:
std::vector<TypeProxy> fields_; // std::unordered_map<std::string, size_t> annotation_fields_;
std::vector<std::optional<std::string>> annotations_; // std::vector<TypeProxy> fields_;
}; // std::vector<std::optional<std::string>> annotations_;
// };
class VariantType : public Node { //
public: // class VariantType : public Node {
VariantType(Node node, std::vector<TupleType> &&constructors_) // public:
: Node(node), constructors_(std::move(constructors_)) {} // VariantType(Node node, std::vector<TupleType> &&constructors_)
// : Node(node), constructors_(std::move(constructors_)) {}
VariantType(Node node, const std::vector<TupleType> &constructors_) //
: Node(node), constructors_(constructors_) {} // VariantType(Node node, const std::vector<TupleType> &constructors_)
// : Node(node), constructors_(constructors_) {}
size_t size() const { return constructors_.size(); } //
// size_t size() const { return constructors_.size(); }
TupleType *get(size_t id) { return &constructors_.at(id); } //
// TupleType *get(size_t id) { return &constructors_.at(id); }
const TupleType *get(size_t id) const { return &constructors_.at(id); } //
// const TupleType *get(size_t id) const { return &constructors_.at(id); }
private: //
// named constructors ?? // private:
std::vector<TupleType> constructors_; // // named constructors ??
}; // std::vector<TupleType> constructors_;
// };
} // namespace nodes } // namespace nodes

View file

@ -7,9 +7,10 @@ namespace printers {
void print_type(const nodes::Type &type, printers::Printer &printer); void print_type(const nodes::Type &type, printers::Printer &printer);
void print_tuple_type(const nodes::TupleType &type, printers::Printer &printer); // void print_tuple_type(const nodes::TupleType &type, printers::Printer
// &printer);
void print_variant_type(const nodes::VariantType &type, //
printers::Printer &printer); // void print_variant_type(const nodes::VariantType &type,
// printers::Printer &printer);
} // namespace printers } // namespace printers

View file

@ -54,7 +54,10 @@ enum class Type {
VARIANT_TYPE, VARIANT_TYPE,
TUPLE_TYPE, TUPLE_TYPE,
TYPE, ARRAY_TYPE,
REFERENCE_TYPE,
MODIFIED_TYPE,
SIMPLE_TYPE,
// --- comments // --- comments
@ -141,7 +144,10 @@ const static std::string LAMBDA = "lambda";
const static std::string VARIANT_TYPE = "variant_type"; const static std::string VARIANT_TYPE = "variant_type";
const static std::string TUPLE_TYPE = "tuple_type"; const static std::string TUPLE_TYPE = "tuple_type";
const static std::string TYPE = "type"; const static std::string ARRAY_TYPE = "array_type";
const static std::string REFERENCE_TYPE = "reference_type";
const static std::string MODIFIED_TYPE = "modified_type";
const static std::string SIMPLE_TYPE = "simple_type";
// --- comments // --- comments
@ -226,8 +232,14 @@ inline Type string_to_type(const std::string &str) {
return Type::VARIANT_TYPE; return Type::VARIANT_TYPE;
} else if (str == TUPLE_TYPE) { } else if (str == TUPLE_TYPE) {
return Type::TUPLE_TYPE; return Type::TUPLE_TYPE;
} else if (str == TYPE) { } else if (str == ARRAY_TYPE) {
return Type::TYPE; return Type::ARRAY_TYPE;
} else if (str == REFERENCE_TYPE) {
return Type::REFERENCE_TYPE;
} else if (str == MODIFIED_TYPE) {
return Type::MODIFIED_TYPE;
} else if (str == SIMPLE_TYPE) {
return Type::SIMPLE_TYPE;
} else if (str == DEFINITION_INFO) { } else if (str == DEFINITION_INFO) {
return Type::DEFINITION_INFO; return Type::DEFINITION_INFO;
} else if (str == ANNOTATION_INFO) { } else if (str == ANNOTATION_INFO) {

View file

@ -4,6 +4,7 @@
#include "name_tree.hpp" #include "name_tree.hpp"
#include "statement_nodes.hpp" #include "statement_nodes.hpp"
#include <optional>
#include <vector> #include <vector>
namespace types { namespace types {
@ -30,11 +31,8 @@ private:
class Defined { class Defined {
public: public:
Defined(nodes::Modifier modifier, Defined(names::StatementProxy<nodes::TypeDefinition> definition)
names::StatementProxy<nodes::TypeDefinition> definition) : definition_(definition) {}
: modifier_(modifier), definition_(definition) {}
nodes::Modifier get_modifier() const { return modifier_; }
nodes::TypeDefinition *get_definition() { return definition_.get(); } nodes::TypeDefinition *get_definition() { return definition_.get(); }
@ -43,10 +41,64 @@ public:
} }
private: private:
nodes::Modifier modifier_;
names::StatementProxy<nodes::TypeDefinition> definition_; names::StatementProxy<nodes::TypeDefinition> definition_;
}; };
class Abstract {
public:
Abstract(std::optional<std::string> name,
std::vector<std::string> typeclasses)
: name_(name), typeclasses_(typeclasses) {}
//
std::optional<std::string *> get_name() {
if (name_.has_value()) {
return &name_.value();
}
return std::nullopt;
}
std::optional<const std::string *> get_name() const {
if (name_.has_value()) {
return &name_.value();
}
return std::nullopt;
}
//
size_t typeclasses_size() const { return typeclasses_.size(); }
std::string *get_typeclass(size_t id) { return &typeclasses_.at(id); }
const std::string *get_typeclass(size_t id) const {
return &typeclasses_.at(id);
}
private:
std::optional<std::string> name_;
std::vector<std::string> typeclasses_;
};
class Modified {
public:
Modified(nodes::Modifier modifier, TypeProxy type)
: modifier_(modifier), type_(type) {}
nodes::Modifier get_modifier() const { return modifier_; }
Type *get_type() { return type_.get(); }
const Type *get_type() const { return type_.get(); }
const TypeProxy &get_type_proxy() const { return type_; }
private:
nodes::Modifier modifier_;
TypeProxy type_;
};
class Container { class Container {
public: public:
enum ContainerType { enum ContainerType {
@ -72,6 +124,8 @@ public:
const Type *get_field(size_t id) const { return fields_.at(id).get(); } const Type *get_field(size_t id) const { return fields_.at(id).get(); }
const TypeProxy &get_field_proxy(size_t id) const { return fields_.at(id); }
private: private:
ContainerType type_; ContainerType type_;
std::vector<TypeProxy> fields_; // or constructors std::vector<TypeProxy> fields_; // or constructors
@ -105,7 +159,7 @@ public:
auto get_any() const { return &type_; } auto get_any() const { return &type_; }
private: private:
std::variant<Defined, Container> type_; std::variant<Defined, Abstract, Modified, Container> type_;
}; };
class TypeStorage { class TypeStorage {

View file

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

View file

@ -1,80 +1,152 @@
#include "type_builders.hpp" #include "type_builders.hpp"
#include "basic_builders.hpp" #include "basic_builders.hpp"
#include "basic_nodes.hpp" #include "basic_nodes.hpp"
#include "builtin_identifiers.hpp"
#include "error_handling.hpp"
#include "tokens.hpp" #include "tokens.hpp"
#include "type_nodes.hpp"
namespace builders { namespace builders {
// '^'? type_identifer '?'? ('[' type+ ']')? nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
nodes::TypeProxy build_type(parser::ParseTree::Node parse_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) { nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters; std::vector<nodes::TypeProxy> parameters;
auto name_node = parse_node.child_by_field_name("name"); auto current_node = parser_node.nth_named_child(0);
;
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();
while (!current_node.is_null()) { while (!current_node.is_null()) {
parameters.push_back(build_type(current_node, type_storage)); parameters.push_back(build_type(current_node, type_storage));
current_node = current_node.next_named_sibling(); current_node = current_node.next_named_sibling();
} }
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::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) {
std::vector<nodes::TypeProxy> parameters;
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(parser_node),
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
builtin::TUPLE_IDENTIFIER),
std::move(parameters), false));
}
// '[[' 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));
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( return type_storage.add_type(
nodes::Type(build_node(parse_node), build_identifier(name_node), nodes::Type(build_node(parser_node),
std::move(parameters), is_on_heap, modifier)); nodes::Identifier(build_node(parser_node),
nodes::Identifier::SIMPLE_TYPE, identifier),
std::move(parameters), false));
} }
// '&'? annotation? type ('&' annotation? type)* // type_identifier ('[' type+ ']')?
nodes::TupleType build_tuple_type(parser::ParseTree::Node parse_node, nodes::TypeProxy build_simple_type(parser::ParseTree::Node parser_node,
nodes::TypeStorage &type_storage) { 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); auto name_node = parser_node.child_by_field_name("name");
std::optional<std::string> last_annotation; auto current_node = name_node.next_named_sibling();
while (!current_node.is_null()) { while (!current_node.is_null()) {
if (tokens::string_to_type(current_node.get_type()) == parameters.push_back(build_type(current_node, type_storage));
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;
}
current_node = current_node.next_named_sibling(); 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),
} build_identifier(name_node),
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;
auto current_node = parse_node.nth_named_child(0);
while (!current_node.is_null()) {
constructors.push_back(build_tuple_type(current_node, type_storage));
current_node = current_node.next_named_sibling();
}
return nodes::VariantType(build_node(parse_node), std::move(constructors));
} }
} // namespace builders } // namespace builders

View file

@ -104,7 +104,7 @@ void print_type_definition(const nodes::TypeDefinition &statement,
printer.set_indentation_level(printer.get_current_position() - 2); printer.set_indentation_level(printer.get_current_position() - 2);
print_variant_type(*statement.get_type().value(), printer); print_type(*statement.get_type().value().get(), printer);
printer.set_indentation_level(previous_indentation_level); printer.set_indentation_level(previous_indentation_level);
} }

View file

@ -5,6 +5,7 @@
namespace printers { namespace printers {
// TODO: better printing format for builtin types
void print_type(const nodes::Type &type, printers::Printer &printer) { void print_type(const nodes::Type &type, printers::Printer &printer) {
if (type.is_on_heap()) { if (type.is_on_heap()) {
printer.print("^"); printer.print("^");
@ -12,8 +13,6 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
print_identifier(*type.get_name(), printer); print_identifier(*type.get_name(), printer);
print_modifier(type.get_modifier(), printer);
if (type.get_parametrs_size() > 0) { if (type.get_parametrs_size() > 0) {
printer.print("["); printer.print("[");
for (size_t i = 0; i < type.get_parametrs_size(); ++i) { for (size_t i = 0; i < type.get_parametrs_size(); ++i) {
@ -26,36 +25,36 @@ void print_type(const nodes::Type &type, printers::Printer &printer) {
} }
} }
void print_tuple_type(const nodes::TupleType &type, // void print_tuple_type(const nodes::TupleType &type,
printers::Printer &printer) { // printers::Printer &printer) {
for (size_t i = 0; i < type.size(); ++i) { // for (size_t i = 0; i < type.size(); ++i) {
if (i > 0) { // if (i > 0) {
printer.print(" & "); // printer.print(" & ");
} // }
auto annotation = type.get_annotation(i); // auto annotation = type.get_annotation(i);
//
if (annotation.has_value()) { // if (annotation.has_value()) {
print_annotation(*annotation.value(), printer); // print_annotation(*annotation.value(), printer);
printer.space(); // printer.space();
} // }
//
print_type(*type.get(i), printer); // print_type(*type.get(i), printer);
} // }
} // }
//
void print_variant_type(const nodes::VariantType &type, // void print_variant_type(const nodes::VariantType &type,
printers::Printer &printer) { // printers::Printer &printer) {
for (size_t i = 0; i < type.size(); ++i) { // for (size_t i = 0; i < type.size(); ++i) {
if (i > 0) { // if (i > 0) {
printer.print("| "); // printer.print("| ");
} // }
//
print_tuple_type(*type.get(i), printer); // print_tuple_type(*type.get(i), printer);
//
if (i + 1 < type.size()) { // if (i + 1 < type.size()) {
printer.new_indent_line(); // printer.new_indent_line();
} // }
} // }
} // IN PROGRESS // } // IN PROGRESS
} // namespace printers } // namespace printers

View file

@ -1,3 +1,4 @@
#!/usr/bin/env lang #!/usr/bin/env lang
:: module; // import module to current namespace :: module; // import module to current namespace
@ -221,3 +222,9 @@ parse_number : Unit! = {
: function, that return result ('!' not used on calls) : function, that return result ('!' not used on calls)
: useful when tuples returned : useful when tuples returned
result_func! 'a 'b -> 'c -> 'd = ?? 'a == 0 => error "some error" !!=> ('c := 'a, 'd := 'b, ()); result_func! 'a 'b -> 'c -> 'd = ?? 'a == 0 => error "some error" !!=> ('c := 'a, 'd := 'b, ());
// (A & B & C) same to Tuple[A B C]
tuple_argument_test 'x : (A & B & C) = do_something;
// ((A1 & A2) | B | C) same to Variant[Tuple[A1 A2] B C]
variant_argument_test 'x : ((A1 & A2) | B | C) = do_something;