mirror of
https://codeberg.org/ProgramSnail/lang.git
synced 2025-12-05 22:48:43 +00:00
shorter names
This commit is contained in:
parent
edf7db284c
commit
76bd92e9fb
24 changed files with 505 additions and 568 deletions
|
|
@ -7,7 +7,7 @@
|
|||
namespace builders {
|
||||
|
||||
// using Code = parser::ParseTree;
|
||||
using Exprs = nodes::ExpressionStorage;
|
||||
using Exprs = nodes::ExprStorage;
|
||||
using Types = nodes::TypeStorage;
|
||||
using Names = names::NameTree;
|
||||
|
||||
|
|
|
|||
|
|
@ -24,12 +24,11 @@ namespace builders {
|
|||
// --- flow control
|
||||
|
||||
template <>
|
||||
struct BuilderTask<nodes::ExpressionProxy>
|
||||
: public BuilderTaskBase<nodes::ExpressionProxy> {
|
||||
using BuilderTaskBase<nodes::ExpressionProxy>::BuilderTaskBase;
|
||||
struct BuilderTask<nodes::Expr> : public BuilderTaskBase<nodes::Expr> {
|
||||
using BuilderTaskBase<nodes::Expr>::BuilderTaskBase;
|
||||
|
||||
nodes::ExpressionProxy operator()(const ParserNode &parser_node,
|
||||
const Arguments &args) override;
|
||||
nodes::Expr operator()(const ParserNode &parser_node,
|
||||
const Arguments &args) override;
|
||||
};
|
||||
|
||||
template <>
|
||||
|
|
@ -104,12 +103,12 @@ struct BuilderTask<nodes::Container, T>
|
|||
? nodes::Container::BLOCK
|
||||
: nodes::Container::ARRAY;
|
||||
|
||||
std::vector<nodes::ExpressionProxy> expressions;
|
||||
std::vector<nodes::Expr> expressions;
|
||||
|
||||
auto current_node = parser_node.nth_named_child(0);
|
||||
|
||||
while (!current_node.is_null()) {
|
||||
expressions.push_back(Run<nodes::ExpressionProxy>(current_node));
|
||||
expressions.push_back(Run<nodes::Expr>(current_node));
|
||||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +181,7 @@ struct BuilderTask<nodes::ModifierExpression, T>
|
|||
return nodes::ModifierExpression(
|
||||
build_node(parser_node),
|
||||
build_modifier(parser_node.nth_child(modifier_pos)),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)));
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -5,22 +5,22 @@
|
|||
|
||||
namespace builders {
|
||||
|
||||
nodes::TypeProxy build_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
nodes::Type build_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
nodes::Type build_variant_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
nodes::Type build_tuple_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::Type 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::Type 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::Type build_simple_type(parser::ParseTree::Node parse_node,
|
||||
nodes::TypeStorage &type_storage);
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -10,9 +10,8 @@
|
|||
|
||||
namespace builders {
|
||||
|
||||
nodes::ExpressionProxy
|
||||
BuilderTask<nodes::ExpressionProxy>::operator()(const ParserNode &parser_node,
|
||||
const Arguments &) {
|
||||
nodes::Expr BuilderTask<nodes::Expr>::operator()(const ParserNode &parser_node,
|
||||
const Arguments &) {
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
auto maybe_parenthesis = parser_node.previous_sibling();
|
||||
|
|
@ -20,20 +19,20 @@ BuilderTask<nodes::ExpressionProxy>::operator()(const ParserNode &parser_node,
|
|||
(!maybe_parenthesis.is_null() && !maybe_parenthesis.is_named() &&
|
||||
maybe_parenthesis.get_value() == "(");
|
||||
|
||||
std::optional<nodes::Expression::Type> expr;
|
||||
std::optional<nodes::ExprData::Type> expr;
|
||||
switch (type) {
|
||||
// --- flow control
|
||||
case tokens::Type::MATCH:
|
||||
expr = Run<nodes::Match>(parser_node);
|
||||
break;
|
||||
case tokens::Type::CONDITION:
|
||||
return state<Exprs>().add_expression({build_node(parser_node),
|
||||
Run<nodes::Condition>(parser_node),
|
||||
is_scoped});
|
||||
return state<Exprs>().add_expr({build_node(parser_node),
|
||||
Run<nodes::Condition>(parser_node),
|
||||
is_scoped});
|
||||
expr = Run<nodes::Match>(parser_node);
|
||||
break;
|
||||
case tokens::Type::LOOP:
|
||||
return state<Exprs>().add_expression(
|
||||
return state<Exprs>().add_expr(
|
||||
{build_node(parser_node), Run<nodes::Loop>(parser_node), is_scoped});
|
||||
expr = Run<nodes::Match>(parser_node);
|
||||
break;
|
||||
|
|
@ -141,7 +140,7 @@ BuilderTask<nodes::ExpressionProxy>::operator()(const ParserNode &parser_node,
|
|||
|
||||
utils::Assert(expr.has_value(), "Expression should have value");
|
||||
|
||||
return state<Exprs>().add_expression(
|
||||
return state<Exprs>().add_expr(
|
||||
{build_node(parser_node), expr.value(), is_scoped});
|
||||
}
|
||||
|
||||
|
|
@ -174,13 +173,11 @@ BuilderTask<nodes::Match::Case>::operator()(const ParserNode &parser_node,
|
|||
build_node(parser_node),
|
||||
case_type == ":=" ? nodes::Match::Case::PATTERN_VALUE
|
||||
: nodes::Match::Case::VALUE_PATTERN,
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
condition_node.has_value()
|
||||
? Run<nodes::ExpressionProxy>(condition_node.value())
|
||||
: std::optional<nodes::ExpressionProxy>(),
|
||||
expression_node.has_value()
|
||||
? Run<nodes::ExpressionProxy>(expression_node.value())
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
condition_node.has_value() ? Run<nodes::Expr>(condition_node.value())
|
||||
: std::optional<nodes::Expr>(),
|
||||
expression_node.has_value() ? Run<nodes::Expr>(expression_node.value())
|
||||
: std::optional<nodes::Expr>());
|
||||
}
|
||||
|
||||
// expression case+
|
||||
|
|
@ -195,10 +192,9 @@ BuilderTask<nodes::Match>::operator()(const ParserNode &parser_node,
|
|||
current_node = current_node.next_named_sibling();
|
||||
}
|
||||
|
||||
return nodes::Match(
|
||||
build_node(parser_node),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
std::move(cases));
|
||||
return nodes::Match(build_node(parser_node),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
std::move(cases));
|
||||
}
|
||||
|
||||
// ('??' | 'if') expression _do_ expression (('!!' | 'elif') expression _do_
|
||||
|
|
@ -208,14 +204,14 @@ BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
|
|||
const Arguments &) {
|
||||
size_t named_child_count = parser_node.named_child_count();
|
||||
|
||||
std::vector<std::pair<nodes::ExpressionProxy, nodes::ExpressionProxy>> cases;
|
||||
std::vector<std::pair<nodes::Expr, nodes::Expr>> cases;
|
||||
|
||||
auto current_node = parser_node.nth_named_child(0);
|
||||
auto next_node = current_node.next_named_sibling();
|
||||
|
||||
while (!current_node.is_null() && !next_node.is_null()) {
|
||||
cases.push_back({Run<nodes::ExpressionProxy>(current_node),
|
||||
Run<nodes::ExpressionProxy>(next_node)});
|
||||
cases.push_back(
|
||||
{Run<nodes::Expr>(current_node), Run<nodes::Expr>(next_node)});
|
||||
current_node = next_node.next_named_sibling();
|
||||
if (current_node.is_null()) {
|
||||
break;
|
||||
|
|
@ -226,9 +222,8 @@ BuilderTask<nodes::Condition>::operator()(const ParserNode &parser_node,
|
|||
return nodes::Condition(
|
||||
build_node(parser_node), std::move(cases),
|
||||
named_child_count % 2 == 1
|
||||
? Run<nodes::ExpressionProxy>(
|
||||
parser_node.nth_named_child(named_child_count - 1))
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
? Run<nodes::Expr>(parser_node.nth_named_child(named_child_count - 1))
|
||||
: std::optional<nodes::Expr>());
|
||||
}
|
||||
|
||||
// ('@' | 'for') (expression | expression ':' expression)? _do_ expression
|
||||
|
|
@ -237,23 +232,20 @@ nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
|
|||
size_t named_child_count = parser_node.named_child_count();
|
||||
|
||||
if (named_child_count == 1) { // body
|
||||
return nodes::Loop(
|
||||
build_node(parser_node),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)));
|
||||
} else if (named_child_count == 2) { // condition,
|
||||
// body
|
||||
return nodes::Loop(
|
||||
build_node(parser_node),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)));
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(1)));
|
||||
} else if (named_child_count == 3) { // variable,
|
||||
// interval,
|
||||
// body
|
||||
return nodes::Loop(
|
||||
build_node(parser_node),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(2)));
|
||||
return nodes::Loop(build_node(parser_node),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(1)),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(2)));
|
||||
} else {
|
||||
error_handling::handle_parsing_error("Unex"
|
||||
"prec"
|
||||
|
|
@ -283,14 +275,13 @@ nodes::Loop BuilderTask<nodes::Loop>::operator()(const ParserNode &parser_node,
|
|||
nodes::NameExpression
|
||||
BuilderTask<nodes::NameExpression, utils::CommaTag>::operator()(
|
||||
const ParserNode &parser_node, const Arguments &) {
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> arguments;
|
||||
|
||||
arguments.emplace_back(std::nullopt, Run<nodes::ExpressionProxy>(
|
||||
parser_node.nth_named_child(0)));
|
||||
arguments.emplace_back(std::nullopt,
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)));
|
||||
|
||||
arguments.emplace_back(std::nullopt, Run<nodes::ExpressionProxy>(
|
||||
parser_node.nth_named_child(1)));
|
||||
arguments.emplace_back(std::nullopt,
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(1)));
|
||||
|
||||
return nodes::NameExpression(
|
||||
build_node(parser_node),
|
||||
|
|
@ -308,14 +299,13 @@ BuilderTask<nodes::NameExpression, utils::OperatorTag>::operator()(
|
|||
"m"
|
||||
"e");
|
||||
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::ExpressionProxy>>
|
||||
arguments;
|
||||
std::vector<std::pair<std::optional<std::string>, nodes::Expr>> arguments;
|
||||
|
||||
arguments.emplace_back(std::nullopt, Run<nodes::ExpressionProxy>(
|
||||
name_node.previous_named_sibling()));
|
||||
arguments.emplace_back(std::nullopt,
|
||||
Run<nodes::Expr>(name_node.previous_named_sibling()));
|
||||
|
||||
arguments.emplace_back(std::nullopt, Run<nodes::ExpressionProxy>(
|
||||
name_node.next_named_sibling()));
|
||||
arguments.emplace_back(std::nullopt,
|
||||
Run<nodes::Expr>(name_node.next_named_sibling()));
|
||||
|
||||
return nodes::NameExpression(build_node(parser_node),
|
||||
build_operator(name_node), std::move(arguments),
|
||||
|
|
@ -334,14 +324,13 @@ BuilderTask<nodes::Return>::operator()(const ParserNode &parser_node,
|
|||
const Arguments &) {
|
||||
std::string modifier = parser_node.nth_child(0).get_value();
|
||||
|
||||
return nodes::Return(
|
||||
build_node(parser_node),
|
||||
modifier == "re"
|
||||
"tu"
|
||||
"rn"
|
||||
? nodes::Return::RETURN
|
||||
: nodes::Return::BRING,
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||
return nodes::Return(build_node(parser_node),
|
||||
modifier == "re"
|
||||
"tu"
|
||||
"rn"
|
||||
? nodes::Return::RETURN
|
||||
: nodes::Return::BRING,
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)));
|
||||
}
|
||||
|
||||
// _var_let_ (simple_name_identifier | placeholder)
|
||||
|
|
@ -362,10 +351,9 @@ BuilderTask<nodes::NameDefinition>::operator()(const ParserNode &parser_node,
|
|||
// expression '[' expression ']'
|
||||
nodes::Access BuilderTask<nodes::Access, utils::ArrayAccessTag>::operator()(
|
||||
const ParserNode &parser_node, const Arguments &) {
|
||||
return nodes::Access(
|
||||
build_node(parser_node), nodes::Access::ARRAY,
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(1)));
|
||||
return nodes::Access(build_node(parser_node), nodes::Access::ARRAY,
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(1)));
|
||||
}
|
||||
|
||||
// expression '.' number_literal
|
||||
|
|
@ -373,8 +361,8 @@ nodes::Access BuilderTask<nodes::Access, utils::TupleAccessTag>::operator()(
|
|||
const ParserNode &parser_node, const Arguments &) {
|
||||
return nodes::Access(
|
||||
build_node(parser_node), nodes::Access::TUPLE,
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)),
|
||||
state<Exprs>().add_expression(
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)),
|
||||
state<Exprs>().add_expr(
|
||||
{build_node(parser_node.nth_named_child(1)),
|
||||
build_index_literal(parser_node.nth_named_child(1)), false}));
|
||||
}
|
||||
|
|
@ -408,7 +396,7 @@ void build_arguments_until_end(
|
|||
} else {
|
||||
arguments.emplace_back(
|
||||
std::move(last_annotation),
|
||||
BuilderTask<nodes::ExpressionProxy>{executor}(current_node, {}));
|
||||
BuilderTask<nodes::Expr>{executor}(current_node, {}));
|
||||
last_annotation = std::nullopt;
|
||||
}
|
||||
current_node = current_node.next_named_sibling();
|
||||
|
|
@ -422,7 +410,7 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
|||
const ParserNode &parser_node, const Arguments &) {
|
||||
std::vector<nodes::AnnotatedArgument> arguments;
|
||||
|
||||
std::optional<nodes::Type> prefix;
|
||||
std::optional<nodes::TypeData> prefix;
|
||||
|
||||
bool is_point_call = false;
|
||||
|
||||
|
|
@ -447,8 +435,7 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
|||
prefix_node = current_node;
|
||||
} else {
|
||||
is_point_call = true;
|
||||
arguments.emplace_back(std::nullopt,
|
||||
Run<nodes::ExpressionProxy>(current_node));
|
||||
arguments.emplace_back(std::nullopt, Run<nodes::Expr>(current_node));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -459,7 +446,7 @@ BuilderTask<nodes::NameExpression, utils::FuncCallTag>::operator()(
|
|||
build_node(parser_node), build_identifier(name_node),
|
||||
std::move(arguments),
|
||||
prefix_node.has_value() ? build_type(prefix_node.value(), state<Types>())
|
||||
: nodes::MaybeTypeProxy(),
|
||||
: nodes::MaybeType(),
|
||||
is_point_call, false);
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +487,7 @@ BuilderTask<nodes::Lambda>::operator()(const ParserNode &parser_node,
|
|||
current_node = current_node.next_named_sibling();
|
||||
|
||||
return nodes::Lambda(build_node(parser_node), std::move(arguments),
|
||||
Run<nodes::ExpressionProxy>(current_node));
|
||||
Run<nodes::Expr>(current_node));
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -132,9 +132,8 @@ BuilderTask<nodes::Import>::operator()(const ParserNode &parser_node,
|
|||
nodes::Constraint
|
||||
BuilderTask<nodes::Constraint>::operator()(const ParserNode &parser_node,
|
||||
const Arguments &) {
|
||||
return nodes::Constraint(
|
||||
build_node(parser_node),
|
||||
Run<nodes::ExpressionProxy>(parser_node.nth_named_child(0)));
|
||||
return nodes::Constraint(build_node(parser_node),
|
||||
Run<nodes::Expr>(parser_node.nth_named_child(0)));
|
||||
}
|
||||
|
||||
parser::ParseTree::Node collect_symbol_doc_nodes(
|
||||
|
|
@ -244,9 +243,9 @@ BuilderTask<nodes::TypeDefinition>::operator()(const ParserNode &parser_node,
|
|||
}
|
||||
}
|
||||
|
||||
nodes::MaybeTypeProxy type =
|
||||
type_node.has_value() ? build_type(type_node.value(), state<Types>())
|
||||
: nodes::MaybeTypeProxy();
|
||||
nodes::MaybeType type = type_node.has_value()
|
||||
? build_type(type_node.value(), state<Types>())
|
||||
: nodes::MaybeType();
|
||||
|
||||
std::unordered_set<std::string> annotations;
|
||||
|
||||
|
|
@ -453,9 +452,8 @@ nodes::FunctionDefinition BuilderTask<nodes::FunctionDefinition>::operator()(
|
|||
std::move(constraints), return_modifier, is_method, name_prefix,
|
||||
build_identifier(name_node), std::move(arguments),
|
||||
are_annotations_same_to_names,
|
||||
expression_node.has_value()
|
||||
? Run<nodes::ExpressionProxy>(expression_node.value())
|
||||
: std::optional<nodes::ExpressionProxy>());
|
||||
expression_node.has_value() ? Run<nodes::Expr>(expression_node.value())
|
||||
: std::optional<nodes::Expr>());
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -8,8 +8,8 @@
|
|||
|
||||
namespace builders {
|
||||
|
||||
nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::Type build_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
tokens::Type type = tokens::string_to_type(parser_node.get_type());
|
||||
|
||||
// TODO: for better formatted printing
|
||||
|
|
@ -37,10 +37,9 @@ nodes::TypeProxy build_type(parser::ParseTree::Node parser_node,
|
|||
exit(1); // unreachable
|
||||
}
|
||||
|
||||
std::vector<nodes::TypeProxy>
|
||||
collect_parameters(parser::ParseTree::Node first_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::TypeProxy> parameters;
|
||||
std::vector<nodes::Type> collect_parameters(parser::ParseTree::Node first_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::Type> parameters;
|
||||
|
||||
std::optional<std::string> current_annotation;
|
||||
|
||||
|
|
@ -61,10 +60,10 @@ collect_parameters(parser::ParseTree::Node first_node,
|
|||
return parameters;
|
||||
}
|
||||
|
||||
nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage,
|
||||
builtin::Type container) {
|
||||
std::vector<nodes::TypeProxy> parameters =
|
||||
nodes::Type build_container_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage,
|
||||
builtin::Type container) {
|
||||
std::vector<nodes::Type> parameters =
|
||||
collect_parameters(parser_node.nth_named_child(0), type_storage);
|
||||
|
||||
return type_storage.add_container_of(std::move(parameters), container,
|
||||
|
|
@ -72,31 +71,30 @@ nodes::TypeProxy build_container_type(parser::ParseTree::Node parser_node,
|
|||
}
|
||||
|
||||
// '|'? annotation? type ('|' annotation? type)+
|
||||
nodes::TypeProxy build_variant_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::Type build_variant_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_container_type(parser_node, type_storage,
|
||||
builtin::Type::VARIANT);
|
||||
}
|
||||
|
||||
// '&'? annotation? type ('&' annotation? type)+
|
||||
nodes::TypeProxy build_tuple_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::Type build_tuple_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
return build_container_type(parser_node, type_storage, builtin::Type::TUPLE);
|
||||
}
|
||||
|
||||
// _reference_ 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);
|
||||
nodes::Type build_reference_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::Type type = build_type(parser_node.nth_named_child(0), type_storage);
|
||||
type.get()->set_modifier(build_modifier(parser_node.nth_child(0)));
|
||||
return type;
|
||||
}
|
||||
|
||||
// type ('?' | '!')
|
||||
nodes::TypeProxy build_modified_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::TypeProxy> parameters;
|
||||
nodes::Type build_modified_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
std::vector<nodes::Type> parameters;
|
||||
parameters.push_back(
|
||||
build_type(parser_node.nth_named_child(0), type_storage));
|
||||
|
||||
|
|
@ -118,22 +116,22 @@ nodes::TypeProxy build_modified_type(parser::ParseTree::Node parser_node,
|
|||
break;
|
||||
}
|
||||
|
||||
return type_storage.add_type(
|
||||
nodes::Type(nodes::Identifier(build_node(parser_node),
|
||||
nodes::Identifier::SIMPLE_TYPE, identifier),
|
||||
std::move(parameters)));
|
||||
return type_storage.add_type(nodes::TypeData(
|
||||
nodes::Identifier(build_node(parser_node), nodes::Identifier::SIMPLE_TYPE,
|
||||
identifier),
|
||||
std::move(parameters)));
|
||||
}
|
||||
|
||||
// type_identifier ('[' (annotation? type)+ ']')?
|
||||
nodes::TypeProxy build_simple_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
nodes::Type build_simple_type(parser::ParseTree::Node parser_node,
|
||||
nodes::TypeStorage &type_storage) {
|
||||
auto name_node = parser_node.child_by_field_name("name");
|
||||
|
||||
std::vector<nodes::TypeProxy> parameters =
|
||||
std::vector<nodes::Type> parameters =
|
||||
collect_parameters(name_node.next_named_sibling(), type_storage);
|
||||
|
||||
return type_storage.add_type(
|
||||
nodes::Type(build_identifier(name_node), std::move(parameters)));
|
||||
nodes::TypeData(build_identifier(name_node), std::move(parameters)));
|
||||
}
|
||||
|
||||
} // namespace builders
|
||||
|
|
|
|||
|
|
@ -196,6 +196,10 @@ struct unicode {
|
|||
|
||||
class Literal : public Node {
|
||||
public:
|
||||
using Type =
|
||||
std::variant<float, double, int32_t, int64_t, size_t, std::string,
|
||||
unicode_string, char, unicode, bool, unit, null>;
|
||||
|
||||
template <typename T>
|
||||
Literal(Node node, T &&value) : Node(node), value_(std::forward<T>(value)) {}
|
||||
|
||||
|
|
@ -213,14 +217,12 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto get_any() { return &value_; }
|
||||
Type &get_any() { return value_; }
|
||||
|
||||
auto get_any() const { return &value_; }
|
||||
const Type &get_any() const { return value_; }
|
||||
|
||||
private:
|
||||
std::variant<float, double, int32_t, int64_t, size_t, std::string,
|
||||
unicode_string, char, unicode, bool, unit, null>
|
||||
value_;
|
||||
Type value_;
|
||||
};
|
||||
|
||||
class Identifier : public Node {
|
||||
|
|
|
|||
|
|
@ -13,52 +13,50 @@ class TypedNode : public Node {
|
|||
public:
|
||||
TypedNode(Node node) : Node(node) {}
|
||||
|
||||
void set_expression_type(TypeProxy expression_type) {
|
||||
void set_expression_type(Type expression_type) {
|
||||
expression_type_ = expression_type;
|
||||
}
|
||||
|
||||
std::optional<TypeProxy> get_expression_type() const {
|
||||
return expression_type_;
|
||||
}
|
||||
std::optional<Type> get_expression_type() const { return expression_type_; }
|
||||
|
||||
protected:
|
||||
std::optional<TypeProxy> expression_type_;
|
||||
std::optional<Type> expression_type_;
|
||||
};
|
||||
|
||||
class Expression;
|
||||
class ExpressionStorage;
|
||||
class ExprData;
|
||||
class ExprStorage;
|
||||
|
||||
class ExpressionProxy {
|
||||
friend ExpressionStorage;
|
||||
class Expr {
|
||||
friend ExprStorage;
|
||||
|
||||
public:
|
||||
ExpressionProxy() = delete;
|
||||
Expr() = delete;
|
||||
|
||||
Expression *get();
|
||||
ExprData *get();
|
||||
|
||||
const Expression *get() const;
|
||||
const ExprData *get() const;
|
||||
|
||||
private:
|
||||
ExpressionProxy(ExpressionStorage &expression_storage, size_t id)
|
||||
Expr(ExprStorage &expression_storage, size_t id)
|
||||
: expression_storage_(&expression_storage), id_(id) {}
|
||||
|
||||
private:
|
||||
ExpressionStorage *expression_storage_;
|
||||
ExprStorage *expression_storage_;
|
||||
size_t id_;
|
||||
};
|
||||
|
||||
namespace utils {
|
||||
|
||||
inline std::optional<nodes::Expression *>
|
||||
proxy_to_expr_optional(std::optional<nodes::ExpressionProxy> &proxy) {
|
||||
inline std::optional<nodes::ExprData *>
|
||||
proxy_to_expr_optional(std::optional<nodes::Expr> &proxy) {
|
||||
if (proxy.has_value()) {
|
||||
return proxy.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline std::optional<const nodes::Expression *>
|
||||
proxy_to_expr_optional(const std::optional<nodes::ExpressionProxy> &proxy) {
|
||||
inline std::optional<const nodes::ExprData *>
|
||||
proxy_to_expr_optional(const std::optional<nodes::Expr> &proxy) {
|
||||
if (proxy.has_value()) {
|
||||
return proxy.value().get();
|
||||
}
|
||||
|
|
@ -78,50 +76,50 @@ public:
|
|||
VALUE_PATTERN,
|
||||
};
|
||||
|
||||
Case(Node node, CaseType case_type, ExpressionProxy value,
|
||||
std::optional<ExpressionProxy> condition = std::nullopt,
|
||||
std::optional<ExpressionProxy> expression = std::nullopt)
|
||||
Case(Node node, CaseType case_type, Expr value,
|
||||
std::optional<Expr> condition = std::nullopt,
|
||||
std::optional<Expr> expression = std::nullopt)
|
||||
: TypedNode(node), case_type_(case_type), value_(value),
|
||||
condition_(condition), expression_(expression) {}
|
||||
|
||||
CaseType case_type() const { return case_type_; }
|
||||
|
||||
Expression *get_value() { return value_.get(); }
|
||||
ExprData *get_value() { return value_.get(); }
|
||||
|
||||
const Expression *get_value() const { return value_.get(); }
|
||||
const ExprData *get_value() const { return value_.get(); }
|
||||
|
||||
std::optional<Expression *> get_condition() {
|
||||
std::optional<ExprData *> get_condition() {
|
||||
return utils::proxy_to_expr_optional(condition_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_condition() const {
|
||||
std::optional<const ExprData *> get_condition() const {
|
||||
return utils::proxy_to_expr_optional(condition_);
|
||||
}
|
||||
|
||||
std::optional<Expression *> get_expression() {
|
||||
std::optional<ExprData *> get_expression() {
|
||||
return utils::proxy_to_expr_optional(expression_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_expression() const {
|
||||
std::optional<const ExprData *> get_expression() const {
|
||||
return utils::proxy_to_expr_optional(expression_);
|
||||
}
|
||||
|
||||
private:
|
||||
CaseType case_type_;
|
||||
ExpressionProxy value_;
|
||||
std::optional<ExpressionProxy> condition_;
|
||||
std::optional<ExpressionProxy> expression_;
|
||||
Expr value_;
|
||||
std::optional<Expr> condition_;
|
||||
std::optional<Expr> expression_;
|
||||
};
|
||||
|
||||
Match(Node node, ExpressionProxy value, std::vector<Case> &&cases)
|
||||
Match(Node node, Expr value, std::vector<Case> &&cases)
|
||||
: TypedNode(node), value_(value), cases_(std::move(cases)) {}
|
||||
|
||||
Match(Node node, ExpressionProxy value, const std::vector<Case> &cases)
|
||||
Match(Node node, Expr value, const std::vector<Case> &cases)
|
||||
: TypedNode(node), value_(value), cases_(cases) {}
|
||||
|
||||
Expression *get_value() { return value_.get(); }
|
||||
ExprData *get_value() { return value_.get(); }
|
||||
|
||||
const Expression *get_value() const { return value_.get(); }
|
||||
const ExprData *get_value() const { return value_.get(); }
|
||||
|
||||
size_t cases_size() const { return cases_.size(); }
|
||||
|
||||
|
|
@ -130,44 +128,41 @@ public:
|
|||
const Case *get_case(size_t id) const { return &cases_.at(id); }
|
||||
|
||||
private:
|
||||
ExpressionProxy value_;
|
||||
Expr value_;
|
||||
std::vector<Case> cases_;
|
||||
};
|
||||
|
||||
class Condition : public Node {
|
||||
public:
|
||||
Condition(Node node,
|
||||
std::vector<std::pair<ExpressionProxy, ExpressionProxy>> &&cases,
|
||||
std::optional<ExpressionProxy> else_case = std::nullopt)
|
||||
Condition(Node node, std::vector<std::pair<Expr, Expr>> &&cases,
|
||||
std::optional<Expr> else_case = std::nullopt)
|
||||
: Node(node), cases_(std::move(cases)), else_case_(else_case) {}
|
||||
|
||||
Condition(
|
||||
Node node,
|
||||
const std::vector<std::pair<ExpressionProxy, ExpressionProxy>> &cases,
|
||||
std::optional<ExpressionProxy> else_case = std::nullopt)
|
||||
Condition(Node node, const std::vector<std::pair<Expr, Expr>> &cases,
|
||||
std::optional<Expr> else_case = std::nullopt)
|
||||
: Node(node), cases_(cases), else_case_(else_case) {}
|
||||
|
||||
size_t cases_size() const { return cases_.size(); }
|
||||
|
||||
std::pair<Expression *, Expression *> get_case(size_t id) {
|
||||
std::pair<ExprData *, ExprData *> get_case(size_t id) {
|
||||
return {cases_.at(id).first.get(), cases_[id].second.get()};
|
||||
}
|
||||
|
||||
std::pair<const Expression *, const Expression *> get_case(size_t id) const {
|
||||
std::pair<const ExprData *, const ExprData *> get_case(size_t id) const {
|
||||
return {cases_.at(id).first.get(), cases_[id].second.get()};
|
||||
}
|
||||
|
||||
std::optional<Expression *> get_else_case() {
|
||||
std::optional<ExprData *> get_else_case() {
|
||||
return utils::proxy_to_expr_optional(else_case_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_else_case() const {
|
||||
std::optional<const ExprData *> get_else_case() const {
|
||||
return utils::proxy_to_expr_optional(else_case_);
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<std::pair<ExpressionProxy, ExpressionProxy>> cases_;
|
||||
std::optional<ExpressionProxy> else_case_;
|
||||
std::vector<std::pair<Expr, Expr>> cases_;
|
||||
std::optional<Expr> else_case_;
|
||||
};
|
||||
|
||||
class Loop : public TypedNode {
|
||||
|
|
@ -179,58 +174,57 @@ public:
|
|||
};
|
||||
|
||||
// LOOP
|
||||
Loop(Node node, ExpressionProxy expression)
|
||||
Loop(Node node, Expr expression)
|
||||
: TypedNode(node), loop_type_(LOOP), expression_(expression) {}
|
||||
|
||||
// WHILE
|
||||
Loop(Node node, ExpressionProxy condition, ExpressionProxy expression)
|
||||
Loop(Node node, Expr condition, Expr expression)
|
||||
: TypedNode(node), loop_type_(WHILE), expression_(expression),
|
||||
condition_(condition) {}
|
||||
|
||||
// FOR
|
||||
Loop(Node node, ExpressionProxy variable, ExpressionProxy interval,
|
||||
ExpressionProxy expression)
|
||||
Loop(Node node, Expr variable, Expr interval, Expr expression)
|
||||
: TypedNode(node), loop_type_(FOR), expression_(expression),
|
||||
variable_(variable), interval_(interval) {}
|
||||
|
||||
LoopType get_type() const { return loop_type_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
ExprData *get_expression() { return expression_.get(); }
|
||||
|
||||
const Expression *get_expression() const { return expression_.get(); }
|
||||
const ExprData *get_expression() const { return expression_.get(); }
|
||||
|
||||
std::optional<Expression *> get_condition() {
|
||||
std::optional<ExprData *> get_condition() {
|
||||
return utils::proxy_to_expr_optional(condition_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_condition() const {
|
||||
std::optional<const ExprData *> get_condition() const {
|
||||
return utils::proxy_to_expr_optional(condition_);
|
||||
}
|
||||
|
||||
std::optional<Expression *> get_variable() {
|
||||
std::optional<ExprData *> get_variable() {
|
||||
return utils::proxy_to_expr_optional(variable_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_variable() const {
|
||||
std::optional<const ExprData *> get_variable() const {
|
||||
return utils::proxy_to_expr_optional(variable_);
|
||||
}
|
||||
|
||||
std::optional<Expression *> get_interval() {
|
||||
std::optional<ExprData *> get_interval() {
|
||||
return utils::proxy_to_expr_optional(interval_);
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_interval() const {
|
||||
std::optional<const ExprData *> get_interval() const {
|
||||
return utils::proxy_to_expr_optional(interval_);
|
||||
}
|
||||
|
||||
private:
|
||||
LoopType loop_type_;
|
||||
|
||||
ExpressionProxy expression_;
|
||||
Expr expression_;
|
||||
|
||||
std::optional<ExpressionProxy> condition_;
|
||||
std::optional<ExpressionProxy> variable_;
|
||||
std::optional<ExpressionProxy> interval_;
|
||||
std::optional<Expr> condition_;
|
||||
std::optional<Expr> variable_;
|
||||
std::optional<Expr> interval_;
|
||||
};
|
||||
|
||||
// --- containers
|
||||
|
|
@ -242,29 +236,27 @@ public:
|
|||
ARRAY,
|
||||
};
|
||||
|
||||
Container(Node node, ContainerType type,
|
||||
std::vector<ExpressionProxy> &&expressions)
|
||||
Container(Node node, ContainerType type, std::vector<Expr> &&expressions)
|
||||
: TypedNode(node), container_type_(type),
|
||||
expressions_(std::move(expressions)) {}
|
||||
|
||||
Container(Node node, ContainerType type,
|
||||
const std::vector<ExpressionProxy> &expressions)
|
||||
Container(Node node, ContainerType type, const std::vector<Expr> &expressions)
|
||||
: TypedNode(node), container_type_(type), expressions_(expressions) {}
|
||||
|
||||
ContainerType get_type() const { return container_type_; }
|
||||
|
||||
size_t expressions_size() const { return expressions_.size(); }
|
||||
|
||||
Expression *get_expression(size_t id) { return expressions_.at(id).get(); }
|
||||
ExprData *get_expression(size_t id) { return expressions_.at(id).get(); }
|
||||
|
||||
const Expression *get_expression(size_t id) const {
|
||||
const ExprData *get_expression(size_t id) const {
|
||||
return expressions_.at(id).get();
|
||||
}
|
||||
|
||||
private:
|
||||
ContainerType container_type_;
|
||||
|
||||
std::vector<ExpressionProxy> expressions_;
|
||||
std::vector<Expr> expressions_;
|
||||
};
|
||||
|
||||
// --- modifiers
|
||||
|
|
@ -276,19 +268,19 @@ public:
|
|||
BRING,
|
||||
};
|
||||
|
||||
Return(Node node, ReturnType type, ExpressionProxy expression)
|
||||
Return(Node node, ReturnType type, Expr expression)
|
||||
: Node(node), return_type_(type), expression_(expression) {}
|
||||
|
||||
ReturnType get_type() const { return return_type_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
ExprData *get_expression() { return expression_.get(); }
|
||||
|
||||
const Expression *get_expression() const { return expression_.get(); }
|
||||
const ExprData *get_expression() const { return expression_.get(); }
|
||||
|
||||
private:
|
||||
ReturnType return_type_;
|
||||
|
||||
ExpressionProxy expression_;
|
||||
Expr expression_;
|
||||
};
|
||||
|
||||
class NameDefinition : public TypedNode {
|
||||
|
|
@ -323,25 +315,24 @@ public:
|
|||
TUPLE, // only number literal index allowed
|
||||
};
|
||||
|
||||
Access(Node node, AccessType type, ExpressionProxy value,
|
||||
ExpressionProxy index)
|
||||
Access(Node node, AccessType type, Expr value, Expr index)
|
||||
: TypedNode(node), access_type_(type), value_(value), index_(index) {}
|
||||
|
||||
AccessType get_type() const { return access_type_; }
|
||||
|
||||
Expression *get_value() { return value_.get(); }
|
||||
ExprData *get_value() { return value_.get(); }
|
||||
|
||||
const Expression *get_value() const { return value_.get(); }
|
||||
const ExprData *get_value() const { return value_.get(); }
|
||||
|
||||
Expression *get_index() { return index_.get(); }
|
||||
ExprData *get_index() { return index_.get(); }
|
||||
|
||||
const Expression *get_index() const { return index_.get(); }
|
||||
const ExprData *get_index() const { return index_.get(); }
|
||||
|
||||
private:
|
||||
AccessType access_type_;
|
||||
|
||||
ExpressionProxy value_;
|
||||
ExpressionProxy index_;
|
||||
Expr value_;
|
||||
Expr index_;
|
||||
};
|
||||
|
||||
class LoopControl : public TypedNode {
|
||||
|
|
@ -362,25 +353,24 @@ private:
|
|||
|
||||
class ModifierExpression : public TypedNode {
|
||||
public:
|
||||
ModifierExpression(Node node, Modifier modifier, ExpressionProxy expression)
|
||||
ModifierExpression(Node node, Modifier modifier, Expr expression)
|
||||
: TypedNode(node), modifier_(modifier), expression_(expression) {}
|
||||
|
||||
Modifier get_modifier() const { return modifier_; }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
ExprData *get_expression() { return expression_.get(); }
|
||||
|
||||
const Expression *get_expression() const { return expression_.get(); }
|
||||
const ExprData *get_expression() const { return expression_.get(); }
|
||||
|
||||
private:
|
||||
Modifier modifier_;
|
||||
|
||||
ExpressionProxy expression_;
|
||||
Expr expression_;
|
||||
};
|
||||
|
||||
// --- other
|
||||
|
||||
using AnnotatedArgument =
|
||||
std::pair<std::optional<std::string>, ExpressionProxy>;
|
||||
using AnnotatedArgument = std::pair<std::optional<std::string>, Expr>;
|
||||
|
||||
class NameExpression : public TypedNode {
|
||||
public:
|
||||
|
|
@ -392,7 +382,7 @@ public:
|
|||
|
||||
NameExpression(Node node, Identifier &&name,
|
||||
std::vector<AnnotatedArgument> &&arguments,
|
||||
std::optional<TypeProxy> &&prefix, bool is_point_call = false,
|
||||
std::optional<Type> &&prefix, bool is_point_call = false,
|
||||
bool is_operator_call = false)
|
||||
: TypedNode(node), name_(std::move(name)),
|
||||
arguments_(std::move(arguments)), prefix_(std::move(prefix)),
|
||||
|
|
@ -402,14 +392,14 @@ public:
|
|||
|
||||
const Identifier *get_name() const { return &name_; }
|
||||
|
||||
std::optional<Type *> get_prefix() {
|
||||
std::optional<TypeData *> get_prefix() {
|
||||
if (prefix_.has_value()) {
|
||||
return prefix_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const Type *> get_prefix() const {
|
||||
std::optional<const TypeData *> get_prefix() const {
|
||||
if (prefix_.has_value()) {
|
||||
return prefix_.value().get();
|
||||
}
|
||||
|
|
@ -418,11 +408,11 @@ public:
|
|||
|
||||
size_t arguments_size() const { return arguments_.size(); }
|
||||
|
||||
Expression *get_argument_value(size_t id) {
|
||||
ExprData *get_argument_value(size_t id) {
|
||||
return arguments_.at(id).second.get();
|
||||
}
|
||||
|
||||
const Expression *get_argument_value(size_t id) const {
|
||||
const ExprData *get_argument_value(size_t id) const {
|
||||
return arguments_.at(id).second.get();
|
||||
}
|
||||
|
||||
|
|
@ -448,7 +438,7 @@ private:
|
|||
Identifier name_;
|
||||
// universal function call syntax
|
||||
std::vector<AnnotatedArgument> arguments_;
|
||||
std::optional<TypeProxy> prefix_;
|
||||
std::optional<Type> prefix_;
|
||||
// for static methods
|
||||
bool is_point_call_ = false; // x.f ... or f x ...
|
||||
bool is_operator_call_ = false; // ... operator ...
|
||||
|
|
@ -456,28 +446,27 @@ private:
|
|||
|
||||
class Constructor : public TypedNode {
|
||||
public:
|
||||
Constructor(Node node, TypeProxy type,
|
||||
std::vector<AnnotatedArgument> &&arguments)
|
||||
Constructor(Node node, Type type, std::vector<AnnotatedArgument> &&arguments)
|
||||
: TypedNode(node), constructor_type_(type),
|
||||
arguments_(std::move(arguments)) {}
|
||||
|
||||
Constructor(Node node, TypeProxy type,
|
||||
Constructor(Node node, Type type,
|
||||
const std::vector<AnnotatedArgument> &arguments)
|
||||
: TypedNode(node), constructor_type_(type), arguments_(arguments) {}
|
||||
|
||||
Type *get_type() { return constructor_type_.get(); }
|
||||
TypeData *get_type() { return constructor_type_.get(); }
|
||||
|
||||
const Type *get_type() const { return constructor_type_.get(); }
|
||||
const TypeData *get_type() const { return constructor_type_.get(); }
|
||||
|
||||
TypeProxy get_type_proxy() const { return constructor_type_; }
|
||||
Type get_type_proxy() const { return constructor_type_; }
|
||||
|
||||
size_t arguments_size() const { return arguments_.size(); }
|
||||
|
||||
Expression *get_argument_value(size_t id) {
|
||||
ExprData *get_argument_value(size_t id) {
|
||||
return arguments_.at(id).second.get();
|
||||
}
|
||||
|
||||
const Expression *get_argument_value(size_t id) const {
|
||||
const ExprData *get_argument_value(size_t id) const {
|
||||
return arguments_.at(id).second.get();
|
||||
}
|
||||
|
||||
|
|
@ -496,20 +485,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
TypeProxy constructor_type_;
|
||||
std::vector<std::pair<std::optional<std::string>, ExpressionProxy>>
|
||||
arguments_;
|
||||
Type constructor_type_;
|
||||
std::vector<std::pair<std::optional<std::string>, Expr>> arguments_;
|
||||
};
|
||||
|
||||
class Lambda : public TypedNode {
|
||||
public:
|
||||
Lambda(Node node, std::vector<Identifier> &&arguments,
|
||||
ExpressionProxy expression)
|
||||
Lambda(Node node, std::vector<Identifier> &&arguments, Expr expression)
|
||||
: TypedNode(node), arguments_(std::move(arguments)),
|
||||
expression_(expression) {}
|
||||
|
||||
Lambda(Node node, const std::vector<Identifier> &arguments,
|
||||
ExpressionProxy expression)
|
||||
Lambda(Node node, const std::vector<Identifier> &arguments, Expr expression)
|
||||
: TypedNode(node), arguments_(arguments), expression_(expression) {}
|
||||
|
||||
size_t arguments_size() const { return arguments_.size(); }
|
||||
|
|
@ -518,16 +504,16 @@ public:
|
|||
|
||||
const Identifier *get_argument(size_t id) const { return &arguments_.at(id); }
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
ExprData *get_expression() { return expression_.get(); }
|
||||
|
||||
const Expression *get_expression() const { return expression_.get(); }
|
||||
const ExprData *get_expression() const { return expression_.get(); }
|
||||
|
||||
private:
|
||||
std::vector<Identifier> arguments_;
|
||||
ExpressionProxy expression_;
|
||||
Expr expression_;
|
||||
};
|
||||
|
||||
class Expression : public Node {
|
||||
class ExprData : public Node {
|
||||
public:
|
||||
using Type = std::variant<
|
||||
// --- flow control
|
||||
|
|
@ -563,7 +549,7 @@ public:
|
|||
|
||||
public:
|
||||
template <typename T>
|
||||
Expression(Node node, T &&expression, bool is_scoped)
|
||||
ExprData(Node node, T &&expression, bool is_scoped)
|
||||
: Node(node), expression_(std::forward<T>(expression)),
|
||||
is_scoped_(is_scoped) {}
|
||||
|
||||
|
|
@ -581,9 +567,9 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto get_any() { return &expression_; }
|
||||
Type &get_any() { return expression_; }
|
||||
|
||||
auto get_any() const { return &expression_; }
|
||||
const Type &get_any() const { return expression_; }
|
||||
|
||||
bool is_scoped() const { return is_scoped_; }
|
||||
|
||||
|
|
@ -593,27 +579,22 @@ private:
|
|||
bool is_scoped_ = false;
|
||||
};
|
||||
|
||||
class ExpressionStorage {
|
||||
friend ExpressionProxy;
|
||||
class ExprStorage {
|
||||
friend Expr;
|
||||
|
||||
public:
|
||||
ExpressionProxy add_expression(const Expression &expression) {
|
||||
storage_.push_back(expression);
|
||||
return ExpressionProxy(*this, storage_.size() - 1);
|
||||
}
|
||||
|
||||
ExpressionProxy add_expression(Expression &&expression) {
|
||||
Expr add_expr(ExprData expression) {
|
||||
storage_.push_back(std::move(expression));
|
||||
return ExpressionProxy(*this, storage_.size() - 1);
|
||||
return Expr(*this, storage_.size() - 1);
|
||||
}
|
||||
|
||||
private:
|
||||
Expression *get_expression(size_t id) { return &storage_.at(id); }
|
||||
ExprData *get_expr(size_t id) { return &storage_.at(id); }
|
||||
|
||||
const Expression *get_expression(size_t id) const { return &storage_.at(id); }
|
||||
const ExprData *get_expr(size_t id) const { return &storage_.at(id); }
|
||||
|
||||
private:
|
||||
std::vector<Expression> storage_;
|
||||
std::vector<ExprData> storage_;
|
||||
};
|
||||
|
||||
} // namespace nodes
|
||||
|
|
|
|||
|
|
@ -62,15 +62,15 @@ private:
|
|||
|
||||
class Constraint : public Node {
|
||||
public:
|
||||
Constraint(Node node, ExpressionProxy expression)
|
||||
Constraint(Node node, Expr expression)
|
||||
: Node(node), expression_(expression) {}
|
||||
|
||||
Expression *get_expression() { return expression_.get(); }
|
||||
ExprData *get_expression() { return expression_.get(); }
|
||||
|
||||
const Expression *get_expression() const { return expression_.get(); }
|
||||
const ExprData *get_expression() const { return expression_.get(); }
|
||||
|
||||
private:
|
||||
ExpressionProxy expression_;
|
||||
Expr expression_;
|
||||
};
|
||||
|
||||
class FunctionDefinition : public Node {
|
||||
|
|
@ -89,7 +89,7 @@ public:
|
|||
: annotation_(annotation), name_(name),
|
||||
before_modifier_(before_modifier), after_modifier_(after_modifier) {}
|
||||
|
||||
Argument(const std::optional<std::string> &annotation, TypeProxy type,
|
||||
Argument(const std::optional<std::string> &annotation, Type type,
|
||||
Modifier before_modifier = Modifier::NONE)
|
||||
: annotation_(annotation), type_(type),
|
||||
before_modifier_(before_modifier),
|
||||
|
|
@ -99,36 +99,36 @@ public:
|
|||
//
|
||||
|
||||
// add type with same annotation and same before_modifier
|
||||
bool update_type_from(const Argument &other_argument) {
|
||||
if (type_.has_value() || !other_argument.type_.has_value()) {
|
||||
bool update_type_from(const Argument &other) {
|
||||
if (type_.has_value() || !other.type_.has_value()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (annotation_.has_value() &&
|
||||
(!other_argument.annotation_.has_value() ||
|
||||
annotation_.value() != other_argument.annotation_.value())) {
|
||||
(!other.annotation_.has_value() ||
|
||||
annotation_.value() != other.annotation_.value())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (before_modifier_ != other_argument.before_modifier_) {
|
||||
if (before_modifier_ != other.before_modifier_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (after_modifier_ != other_argument.after_modifier_) {
|
||||
if (after_modifier_ != other.after_modifier_) {
|
||||
return false;
|
||||
}
|
||||
|
||||
annotation_ = other_argument.annotation_;
|
||||
type_ = other_argument.type_;
|
||||
before_modifier_ = other_argument.before_modifier_;
|
||||
after_modifier_ = other_argument.after_modifier_;
|
||||
annotation_ = other.annotation_;
|
||||
type_ = other.type_;
|
||||
before_modifier_ = other.before_modifier_;
|
||||
after_modifier_ = other.after_modifier_;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// check, that argument modifiers are none or same to different from type
|
||||
// modifiers
|
||||
bool add_type(const std::optional<std::string> &annotation, TypeProxy type,
|
||||
bool add_type(const std::optional<std::string> &annotation, Type type,
|
||||
nodes::Modifier before_modifier = Modifier::NONE) {
|
||||
if (type_.has_value()) {
|
||||
return false;
|
||||
|
|
@ -205,21 +205,21 @@ public:
|
|||
|
||||
//
|
||||
|
||||
std::optional<Type *> get_type() {
|
||||
std::optional<TypeData *> get_type() {
|
||||
if (type_.has_value()) {
|
||||
return type_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const Type *> get_type() const {
|
||||
std::optional<const TypeData *> get_type() const {
|
||||
if (type_.has_value()) {
|
||||
return type_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<TypeProxy> get_type_proxy() const {
|
||||
std::optional<Type> get_type_proxy() const {
|
||||
if (type_.has_value()) {
|
||||
return type_.value();
|
||||
}
|
||||
|
|
@ -235,7 +235,7 @@ public:
|
|||
private:
|
||||
std::optional<std::string> annotation_;
|
||||
std::optional<Identifier> name_; // no name for output arguments
|
||||
std::optional<TypeProxy> type_; // no type if it is deduced
|
||||
std::optional<Type> type_; // no type if it is deduced
|
||||
Modifier before_modifier_ =
|
||||
Modifier::NONE; // in, out, ref, none // sync with type
|
||||
Modifier after_modifier_ =
|
||||
|
|
@ -248,7 +248,7 @@ public:
|
|||
const std::optional<Identifier> &name_prefix,
|
||||
const Identifier &name, std::vector<Argument> &&arguments,
|
||||
bool are_annotations_same_to_names,
|
||||
std::optional<ExpressionProxy> expression)
|
||||
std::optional<Expr> expression)
|
||||
: Node(node), docs_(std::move(docs)),
|
||||
constraints_(std::move(constraints)), return_modifier_(return_modifier),
|
||||
is_method_(is_method), name_(name), full_name_(name),
|
||||
|
|
@ -304,14 +304,14 @@ public:
|
|||
|
||||
//
|
||||
|
||||
std::optional<Expression *> get_expression() {
|
||||
std::optional<ExprData *> get_expression() {
|
||||
if (expression_.has_value()) {
|
||||
return expression_.value().get();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const Expression *> get_expression() const {
|
||||
std::optional<const ExprData *> get_expression() const {
|
||||
if (expression_.has_value()) {
|
||||
return expression_.value().get();
|
||||
}
|
||||
|
|
@ -326,9 +326,9 @@ public:
|
|||
|
||||
//
|
||||
|
||||
bool is_same_to(const FunctionDefinition &other_function_definition) const;
|
||||
bool is_same_to(const FunctionDefinition &other) const;
|
||||
|
||||
CombineResult combine(FunctionDefinition &&other_function_definition);
|
||||
CombineResult combine(FunctionDefinition &&other);
|
||||
|
||||
private:
|
||||
SymbolDocs docs_;
|
||||
|
|
@ -339,15 +339,14 @@ private:
|
|||
Identifier full_name_;
|
||||
std::vector<Argument> arguments_;
|
||||
bool are_annotations_same_to_names_; // needed for easier prinitng process
|
||||
std::optional<ExpressionProxy> expression_;
|
||||
std::optional<Expr> expression_;
|
||||
}; // refactor ??
|
||||
|
||||
class TypeDefinition : public Node {
|
||||
public:
|
||||
TypeDefinition(Node node, SymbolDocs &&docs, bool is_on_heap,
|
||||
const Identifier &name, std::vector<Identifier> &&typeclasses,
|
||||
std::vector<Identifier> &&arguments,
|
||||
std::optional<TypeProxy> type)
|
||||
std::vector<Identifier> &&arguments, std::optional<Type> type)
|
||||
: Node(node), docs_(std::move(docs)), is_on_heap_(is_on_heap),
|
||||
name_(name), typeclasses_(typeclasses),
|
||||
arguments_(std::move(arguments)), type_(std::move(type)) {}
|
||||
|
|
@ -378,7 +377,7 @@ public:
|
|||
|
||||
//
|
||||
|
||||
std::optional<TypeProxy> get_type() const {
|
||||
std::optional<Type> get_type() const {
|
||||
if (type_.has_value()) {
|
||||
return type_.value();
|
||||
}
|
||||
|
|
@ -391,9 +390,9 @@ public:
|
|||
|
||||
//
|
||||
|
||||
bool is_same_to(const TypeDefinition &other_type_definition) const;
|
||||
bool is_same_to(const TypeDefinition &other) const;
|
||||
|
||||
CombineResult combine(TypeDefinition &&other_type_definition);
|
||||
CombineResult combine(TypeDefinition &&other);
|
||||
|
||||
private:
|
||||
SymbolDocs docs_;
|
||||
|
|
@ -401,11 +400,14 @@ private:
|
|||
Identifier name_;
|
||||
std::vector<Identifier> typeclasses_;
|
||||
std::vector<Identifier> arguments_;
|
||||
std::optional<TypeProxy> type_;
|
||||
std::optional<Type> type_;
|
||||
};
|
||||
|
||||
class Statement : public Node {
|
||||
public:
|
||||
using Type = std::variant<Import, TypeDefinition, FunctionDefinition, Extra,
|
||||
EmptyLines>;
|
||||
|
||||
// Statement(const Statement &) = default;
|
||||
// Statement(Statement &&) = default;
|
||||
// Statement &operator=(const Statement &) = default;
|
||||
|
|
@ -413,33 +415,32 @@ public:
|
|||
|
||||
template <typename T>
|
||||
Statement(Node node, T &&statement)
|
||||
: Node(node), expression_(std::forward<T>(statement)) {}
|
||||
: Node(node), expr_(std::forward<T>(statement)) {}
|
||||
|
||||
template <typename T> std::optional<T *> get() {
|
||||
if (std::holds_alternative<T>(expression_)) {
|
||||
return &std::get<T>(expression_);
|
||||
if (std::holds_alternative<T>(expr_)) {
|
||||
return &std::get<T>(expr_);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
template <typename T> std::optional<const T *> get() const {
|
||||
if (std::holds_alternative<T>(expression_)) {
|
||||
return &std::get<T>(expression_);
|
||||
if (std::holds_alternative<T>(expr_)) {
|
||||
return &std::get<T>(expr_);
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto get_any() { return &expression_; }
|
||||
Type &get_any() { return expr_; }
|
||||
|
||||
auto get_any() const { return &expression_; }
|
||||
const Type &get_any() const { return expr_; }
|
||||
|
||||
bool is_same_to(const Statement &other_statement) const;
|
||||
bool is_same_to(const Statement &other) const;
|
||||
|
||||
CombineResult combine(Statement &&other_statement);
|
||||
CombineResult combine(Statement &&other);
|
||||
|
||||
private:
|
||||
std::variant<Import, TypeDefinition, FunctionDefinition, Extra, EmptyLines>
|
||||
expression_;
|
||||
Type expr_;
|
||||
};
|
||||
|
||||
} // namespace nodes
|
||||
|
|
|
|||
|
|
@ -16,23 +16,23 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
class Type;
|
||||
class TypeData;
|
||||
class TypeStorage;
|
||||
|
||||
class TypeProxy {
|
||||
class Type {
|
||||
friend TypeStorage;
|
||||
|
||||
public:
|
||||
Type *get();
|
||||
TypeData *get();
|
||||
|
||||
const Type *get() const;
|
||||
const TypeData *get() const;
|
||||
|
||||
bool operator==(const TypeProxy &other) const;
|
||||
bool operator==(const Type &other) const;
|
||||
|
||||
bool operator!=(const TypeProxy &) const = default;
|
||||
bool operator!=(const Type &) const = default;
|
||||
|
||||
private:
|
||||
TypeProxy(TypeStorage &type_storage, size_t id)
|
||||
Type(TypeStorage &type_storage, size_t id)
|
||||
: type_storage_(&type_storage), id_(id) {}
|
||||
|
||||
private:
|
||||
|
|
@ -40,29 +40,30 @@ private:
|
|||
size_t id_;
|
||||
};
|
||||
|
||||
using MaybeTypeProxy = std::optional<TypeProxy>;
|
||||
using TypeProxies = std::vector<TypeProxy>;
|
||||
using MaybeType = std::optional<Type>;
|
||||
using Types = std::vector<Type>;
|
||||
|
||||
class Type {
|
||||
class TypeData {
|
||||
public:
|
||||
Type(Identifier &&identifier, Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
TypeData(Identifier &&identifier, Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
: name_(std::move(identifier)), modifier_(modifier),
|
||||
annotation_(annotation) {}
|
||||
|
||||
Type(const Identifier &identifier, Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
TypeData(const Identifier &identifier,
|
||||
Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
: name_(identifier), modifier_(modifier), annotation_(annotation) {}
|
||||
|
||||
Type(Identifier &&identifier, std::vector<TypeProxy> &¶meters,
|
||||
Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
TypeData(Identifier &&identifier, std::vector<Type> &¶meters,
|
||||
Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
: name_(std::move(identifier)), parameters_(std::move(parameters)),
|
||||
modifier_(modifier), annotation_(annotation) {}
|
||||
|
||||
Type(const Identifier &identifier, std::vector<TypeProxy> &¶meters,
|
||||
Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
TypeData(const Identifier &identifier, std::vector<Type> &¶meters,
|
||||
Modifier modifier = nodes::Modifier::CONST,
|
||||
const std::optional<std::string> &annotation = std::nullopt)
|
||||
: name_(identifier), parameters_(std::move(parameters)),
|
||||
modifier_(modifier), annotation_(annotation) {}
|
||||
|
||||
|
|
@ -76,16 +77,16 @@ public:
|
|||
|
||||
size_t parameters_size() const { return parameters_.size(); }
|
||||
|
||||
TypeProxy get_parameter_proxy(size_t id) const { return parameters_.at(id); }
|
||||
Type get_parameter_proxy(size_t id) const { return parameters_.at(id); }
|
||||
|
||||
Type *get_parameter(size_t id) { return get_parameter_proxy(id).get(); }
|
||||
TypeData *get_parameter(size_t id) { return get_parameter_proxy(id).get(); }
|
||||
|
||||
const Type *get_parameter(size_t id) const {
|
||||
const TypeData *get_parameter(size_t id) const {
|
||||
return get_parameter_proxy(id).get();
|
||||
}
|
||||
|
||||
// TODO: cache with map ??
|
||||
std::optional<TypeProxy>
|
||||
std::optional<Type>
|
||||
get_parameter_proxy_by_name(const std::string &name) const {
|
||||
const auto it = std::find_if(
|
||||
parameters_.begin(), parameters_.end(), [&name](const auto ¶meter) {
|
||||
|
|
@ -99,16 +100,17 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<const Type *>
|
||||
std::optional<const TypeData *>
|
||||
get_parameter_by_name(const std::string &name) const {
|
||||
const auto proxy = get_parameter_proxy_by_name(name);
|
||||
return proxy.has_value() ? proxy.value().get()
|
||||
: std::optional<const Type *>{};
|
||||
: std::optional<const TypeData *>{};
|
||||
}
|
||||
|
||||
std::optional<Type *> get_parameter_by_name(const std::string &name) {
|
||||
std::optional<TypeData *> get_parameter_by_name(const std::string &name) {
|
||||
auto proxy = get_parameter_proxy_by_name(name);
|
||||
return proxy.has_value() ? proxy.value().get() : std::optional<Type *>{};
|
||||
return proxy.has_value() ? proxy.value().get()
|
||||
: std::optional<TypeData *>{};
|
||||
}
|
||||
|
||||
//
|
||||
|
|
@ -169,7 +171,7 @@ public:
|
|||
|
||||
//
|
||||
|
||||
bool operator==(const Type &other) const {
|
||||
bool operator==(const TypeData &other) const {
|
||||
if (name_ != other.name_ || modifier_ != other.modifier_ ||
|
||||
parameters_.size() != other.parameters_.size()) {
|
||||
return false;
|
||||
|
|
@ -184,11 +186,11 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool operator!=(const Type &other) const { return !(*this == other); }
|
||||
bool operator!=(const TypeData &other) const { return !(*this == other); }
|
||||
|
||||
//
|
||||
|
||||
bool operator<(const Type &other) const {
|
||||
bool operator<(const TypeData &other) const {
|
||||
if (name_ != other.name_) {
|
||||
return *name_.get() < *other.name_.get();
|
||||
}
|
||||
|
|
@ -210,11 +212,11 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool operator>(const Type &other) const { return other < *this; }
|
||||
bool operator>(const TypeData &other) const { return other < *this; }
|
||||
|
||||
bool operator<=(const Type &other) const { return !operator>(other); }
|
||||
bool operator<=(const TypeData &other) const { return !operator>(other); }
|
||||
|
||||
bool operator>=(const Type &other) const { return !operator<(other); }
|
||||
bool operator>=(const TypeData &other) const { return !operator<(other); }
|
||||
|
||||
// is parameters count check necessary ??
|
||||
builtin::Type to_builtin() const {
|
||||
|
|
@ -236,47 +238,45 @@ public:
|
|||
|
||||
private:
|
||||
Identifier name_;
|
||||
std::vector<TypeProxy> parameters_;
|
||||
std::vector<Type> parameters_;
|
||||
Modifier modifier_ = Modifier::NONE;
|
||||
std::optional<std::string> annotation_;
|
||||
};
|
||||
|
||||
class TypeStorage {
|
||||
friend TypeProxy;
|
||||
friend Type;
|
||||
|
||||
public:
|
||||
TypeProxy primitive(builtin::Type type);
|
||||
Type primitive(builtin::Type type);
|
||||
|
||||
TypeProxy add_array_of(TypeProxy type, Node node = Node());
|
||||
Type add_array_of(Type type, Node node = Node());
|
||||
|
||||
TypeProxy add_error_of(TypeProxy type, Node node = Node());
|
||||
Type add_error_of(Type type, Node node = Node());
|
||||
|
||||
nodes::TypeProxy add_container_of(std::vector<TypeProxy> &¶meters,
|
||||
builtin::Type container,
|
||||
Node node = Node());
|
||||
nodes::Type add_container_of(std::vector<Type> &¶meters,
|
||||
builtin::Type container, Node node = Node());
|
||||
|
||||
nodes::TypeProxy add_modification_of(TypeProxy type, Modifier modifier);
|
||||
nodes::Type add_modification_of(Type type, Modifier modifier);
|
||||
|
||||
TypeProxy add_type(const Type &type) {
|
||||
Type add_type(const TypeData &type) {
|
||||
storage_.push_back(type);
|
||||
return TypeProxy(*this, storage_.size() - 1);
|
||||
return Type(*this, storage_.size() - 1);
|
||||
}
|
||||
|
||||
TypeProxy add_type(Type &&type) {
|
||||
Type add_type(TypeData &&type) {
|
||||
storage_.push_back(std::move(type));
|
||||
return TypeProxy(*this, storage_.size() - 1);
|
||||
return Type(*this, storage_.size() - 1);
|
||||
}
|
||||
|
||||
// -- deal with generic types (variable types in this case)
|
||||
|
||||
bool resolve_all_generic_types();
|
||||
|
||||
TypeProxy add_generic_type() {
|
||||
return add_type(Type(generate_generic_type_identifier()));
|
||||
Type add_generic_type() {
|
||||
return add_type(TypeData(generate_generic_type_identifier()));
|
||||
}
|
||||
|
||||
bool resolve_generic_name(const std::string &name,
|
||||
const TypeProxy &actulal_type);
|
||||
bool resolve_generic_name(const std::string &name, const Type &actulal_type);
|
||||
|
||||
void clear_resolved_generic_names() { resolved_generic_names_.clear(); }
|
||||
|
||||
|
|
@ -310,16 +310,15 @@ public:
|
|||
};
|
||||
|
||||
// TODO: next iteration of type check
|
||||
bool unify(TypeProxy left_proxy, TypeProxy right_proxy,
|
||||
UnifyModePolicy policy);
|
||||
bool unify(Type left_proxy, Type right_proxy, UnifyModePolicy policy);
|
||||
|
||||
bool resolve(TypeProxy generic,
|
||||
const Type &replacement /* TODO , Mode mode = {}*/);
|
||||
bool resolve(Type generic,
|
||||
const TypeData &replacement /* TODO , Mode mode = {}*/);
|
||||
|
||||
private:
|
||||
Type *get_type(size_t id) { return &storage_.at(id); }
|
||||
TypeData *get_type(size_t id) { return &storage_.at(id); }
|
||||
|
||||
const Type *get_type(size_t id) const { return &storage_.at(id); }
|
||||
const TypeData *get_type(size_t id) const { return &storage_.at(id); }
|
||||
|
||||
Identifier generate_generic_type_identifier();
|
||||
|
||||
|
|
@ -336,7 +335,7 @@ private:
|
|||
std::vector<std::set<Identifier>> local_name_typeclasses_;
|
||||
|
||||
// storage for all types
|
||||
std::vector<Type> storage_;
|
||||
std::vector<TypeData> storage_;
|
||||
};
|
||||
|
||||
} // namespace nodes
|
||||
|
|
|
|||
|
|
@ -2,12 +2,8 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
Expression *ExpressionProxy::get() {
|
||||
return expression_storage_->get_expression(id_);
|
||||
}
|
||||
ExprData *Expr::get() { return expression_storage_->get_expr(id_); }
|
||||
|
||||
const Expression *ExpressionProxy::get() const {
|
||||
return expression_storage_->get_expression(id_);
|
||||
}
|
||||
const ExprData *Expr::get() const { return expression_storage_->get_expr(id_); }
|
||||
|
||||
}; // namespace nodes
|
||||
|
|
|
|||
|
|
@ -6,9 +6,8 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
bool FunctionDefinition::is_same_to(
|
||||
const FunctionDefinition &other_function_definition) const {
|
||||
if (name_ != other_function_definition.name_) {
|
||||
bool FunctionDefinition::is_same_to(const FunctionDefinition &other) const {
|
||||
if (name_ != other.name_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -20,93 +19,81 @@ bool FunctionDefinition::is_same_to(
|
|||
// name 'arg1 'arg2 'arg3 : Type1 Type2 Type3 -> Type4 = ... // function
|
||||
// definition (with types)
|
||||
// name 'arg1 'arg2 -> 'arg3 = ... // function definition (without types)
|
||||
CombineResult
|
||||
FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
||||
CombineResult FunctionDefinition::combine(FunctionDefinition &&other) {
|
||||
// names should be the same
|
||||
if (name_ != other_function_definition.name_) {
|
||||
if (name_ != other.name_) {
|
||||
return CombineResult::DIFFERENT_NAME_ERROR;
|
||||
}
|
||||
|
||||
// modifiers should be the same
|
||||
if (return_modifier_ != other_function_definition.return_modifier_) {
|
||||
if (return_modifier_ != other.return_modifier_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||
}
|
||||
if (is_method_ != other_function_definition.is_method_) {
|
||||
if (is_method_ != other.is_method_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR; // other error type ??
|
||||
}
|
||||
if (are_annotations_same_to_names_ !=
|
||||
other_function_definition.are_annotations_same_to_names_) {
|
||||
if (are_annotations_same_to_names_ != other.are_annotations_same_to_names_) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should have constraints
|
||||
if (!constraints_.empty() &&
|
||||
!other_function_definition.constraints_.empty()) {
|
||||
if (!constraints_.empty() && !other.constraints_.empty()) {
|
||||
return CombineResult::MORE_THEN_ONE_CONSTRAINTS_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should have expression (body)
|
||||
if (expression_.has_value() &&
|
||||
other_function_definition.expression_.has_value()) {
|
||||
if (expression_.has_value() && other.expression_.has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
|
||||
}
|
||||
|
||||
// only one definition should have documentation
|
||||
if (docs_.get_description().has_value() &&
|
||||
other_function_definition.docs_.get_description().has_value()) {
|
||||
other.docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
if (docs_.annotations_info_size() > 0 &&
|
||||
other_function_definition.docs_.annotations_info_size() > 0) {
|
||||
other.docs_.annotations_info_size() > 0) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
// check, that function definitions have same named arguments
|
||||
for (size_t i = 0; i < std::max(arguments_.size(),
|
||||
other_function_definition.arguments_.size());
|
||||
for (size_t i = 0; i < std::max(arguments_.size(), other.arguments_.size());
|
||||
++i) {
|
||||
if (i < arguments_.size() &&
|
||||
i < other_function_definition.arguments_.size()) {
|
||||
if (i < arguments_.size() && i < other.arguments_.size()) {
|
||||
|
||||
// annotations should be the same
|
||||
if ((!arguments_[i].get_annotation().has_value() &&
|
||||
!other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
.has_value()) ||
|
||||
!other.arguments_[i].get_annotation().has_value()) ||
|
||||
(arguments_[i].get_annotation().has_value() &&
|
||||
other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
.has_value() &&
|
||||
other.arguments_[i].get_annotation().has_value() &&
|
||||
*arguments_[i].get_annotation().value() !=
|
||||
*other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
.value())) {
|
||||
*other.arguments_[i].get_annotation().value())) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// argument names should be the same
|
||||
if ((!arguments_[i].get_name().has_value() &&
|
||||
!other_function_definition.arguments_[i].get_name().has_value()) ||
|
||||
!other.arguments_[i].get_name().has_value()) ||
|
||||
(arguments_[i].get_name().has_value() &&
|
||||
other_function_definition.arguments_[i].get_name().has_value() &&
|
||||
other.arguments_[i].get_name().has_value() &&
|
||||
arguments_[i].get_name().value() !=
|
||||
other_function_definition.arguments_[i].get_name().value())) {
|
||||
other.arguments_[i].get_name().value())) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// types should be the same (if present in both definitions)
|
||||
if (arguments_[i].get_type().has_value() &&
|
||||
other_function_definition.arguments_[i].get_type().has_value() &&
|
||||
other.arguments_[i].get_type().has_value() &&
|
||||
*arguments_[i].get_type().value() !=
|
||||
*other_function_definition.arguments_[i].get_type().value()) {
|
||||
*other.arguments_[i].get_type().value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// argument modifiers should be the same
|
||||
if (arguments_[i].get_before_modifier() !=
|
||||
other_function_definition.arguments_[i].get_before_modifier() ||
|
||||
other.arguments_[i].get_before_modifier() ||
|
||||
arguments_[i].get_after_modifier() !=
|
||||
other_function_definition.arguments_[i].get_after_modifier()) {
|
||||
other.arguments_[i].get_after_modifier()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
} else if (i < arguments_.size()) {
|
||||
|
|
@ -121,14 +108,12 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
}
|
||||
} else { // i < other_function_definition.size()
|
||||
// annotations should be the same
|
||||
if (other_function_definition.arguments_[i]
|
||||
.get_annotation()
|
||||
.has_value()) {
|
||||
if (other.arguments_[i].get_annotation().has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
|
||||
// names should be the same
|
||||
if (other_function_definition.arguments_[i].get_name().has_value()) {
|
||||
if (other.arguments_[i].get_name().has_value()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
@ -136,29 +121,28 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
|
||||
// combine docs
|
||||
// all docs should be in one definition
|
||||
if (other_function_definition.docs_.get_description().has_value() ||
|
||||
other_function_definition.docs_.annotations_info_size() > 0) {
|
||||
if (other.docs_.get_description().has_value() ||
|
||||
other.docs_.annotations_info_size() > 0) {
|
||||
if (docs_.annotations_info_size() > 0 ||
|
||||
docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
docs_ = std::move(other_function_definition.docs_);
|
||||
docs_ = std::move(other.docs_);
|
||||
}
|
||||
|
||||
if (!other_function_definition.constraints_.empty()) {
|
||||
constraints_ = std::move(other_function_definition.constraints_);
|
||||
if (!other.constraints_.empty()) {
|
||||
constraints_ = std::move(other.constraints_);
|
||||
}
|
||||
|
||||
if (other_function_definition.expression_.has_value()) {
|
||||
expression_ = other_function_definition.expression_;
|
||||
if (other.expression_.has_value()) {
|
||||
expression_ = other.expression_;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < other_function_definition.arguments_.size(); ++i) {
|
||||
for (size_t i = 0; i < other.arguments_.size(); ++i) {
|
||||
if (i < arguments_.size()) {
|
||||
if (other_function_definition.arguments_[i].get_type().has_value()) {
|
||||
if (arguments_[i].update_type_from(
|
||||
other_function_definition.arguments_[i])) {
|
||||
if (other.arguments_[i].get_type().has_value()) {
|
||||
if (arguments_[i].update_type_from(other.arguments_[i])) {
|
||||
error_handling::handle_internal_error(
|
||||
"Function arguments are not properly checked before merging "
|
||||
"during combination",
|
||||
|
|
@ -166,16 +150,15 @@ FunctionDefinition::combine(FunctionDefinition &&other_function_definition) {
|
|||
}
|
||||
}
|
||||
} else {
|
||||
arguments_.push_back(std::move(other_function_definition.arguments_[i]));
|
||||
arguments_.push_back(std::move(other.arguments_[i]));
|
||||
}
|
||||
}
|
||||
|
||||
return CombineResult::OK;
|
||||
}
|
||||
|
||||
bool TypeDefinition::is_same_to(
|
||||
const TypeDefinition &other_type_definition) const {
|
||||
if (name_ != other_type_definition.name_) {
|
||||
bool TypeDefinition::is_same_to(const TypeDefinition &other) const {
|
||||
if (name_ != other.name_) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
|
|
@ -185,87 +168,85 @@ bool TypeDefinition::is_same_to(
|
|||
// Type[...] 'A 'B 'C; // declare type / define typeclass (statement without
|
||||
// args in this case)
|
||||
// Type[...] 'A 'B 'C = ... // define type
|
||||
CombineResult TypeDefinition::combine(TypeDefinition &&other_type_definition) {
|
||||
CombineResult TypeDefinition::combine(TypeDefinition &&other) {
|
||||
// name should be same
|
||||
if (name_ != other_type_definition.name_) {
|
||||
if (name_ != other.name_) {
|
||||
return CombineResult::DIFFERENT_NAME_ERROR;
|
||||
}
|
||||
|
||||
// modifier should be the same
|
||||
if (is_on_heap_ != other_type_definition.is_on_heap_) {
|
||||
if (is_on_heap_ != other.is_on_heap_) {
|
||||
return CombineResult::DIFFERNENT_MODIFIER_ERROR;
|
||||
}
|
||||
|
||||
// typeclasses should be the same
|
||||
if (typeclasses_.size() != other_type_definition.typeclasses_.size()) {
|
||||
if (typeclasses_.size() != other.typeclasses_.size()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
for (size_t i = 0; i < typeclasses_.size(); ++i) {
|
||||
if (typeclasses_[i] != other_type_definition.typeclasses_[i]) {
|
||||
if (typeclasses_[i] != other.typeclasses_[i]) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// arguments should be the same
|
||||
if (arguments_.size() != other_type_definition.arguments_.size()) {
|
||||
if (arguments_.size() != other.arguments_.size()) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
for (size_t i = 0; i < arguments_.size(); ++i) {
|
||||
if (arguments_[i] != other_type_definition.arguments_[i]) {
|
||||
if (arguments_[i] != other.arguments_[i]) {
|
||||
return CombineResult::ARGUMENTS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// only one definition should have documentation
|
||||
if (docs_.get_description().has_value() &&
|
||||
other_type_definition.docs_.get_description().has_value()) {
|
||||
other.docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
if (docs_.annotations_info_size() > 0 &&
|
||||
other_type_definition.docs_.annotations_info_size() > 0) {
|
||||
other.docs_.annotations_info_size() > 0) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
// only one type should define type / body
|
||||
if (type_.has_value() && other_type_definition.type_.has_value()) {
|
||||
if (type_.has_value() && other.type_.has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DEFINITION_BODY_ERROR;
|
||||
}
|
||||
|
||||
// combine docs
|
||||
// all docs should be in one definition
|
||||
if (other_type_definition.docs_.get_description().has_value() ||
|
||||
other_type_definition.docs_.annotations_info_size() > 0) {
|
||||
if (other.docs_.get_description().has_value() ||
|
||||
other.docs_.annotations_info_size() > 0) {
|
||||
if (docs_.annotations_info_size() > 0 ||
|
||||
docs_.get_description().has_value()) {
|
||||
return CombineResult::MORE_THEN_ONE_DOCS_ERROR;
|
||||
}
|
||||
|
||||
docs_ = std::move(other_type_definition.docs_);
|
||||
docs_ = std::move(other.docs_);
|
||||
}
|
||||
|
||||
if (other_type_definition.type_.has_value()) {
|
||||
type_ = std::move(other_type_definition.type_);
|
||||
if (other.type_.has_value()) {
|
||||
type_ = std::move(other.type_);
|
||||
}
|
||||
|
||||
return CombineResult::OK;
|
||||
}
|
||||
|
||||
bool Statement::is_same_to(const Statement &other_statement) const {
|
||||
if (expression_.index() != other_statement.expression_.index()) {
|
||||
bool Statement::is_same_to(const Statement &other) const {
|
||||
if (expr_.index() != other.expr_.index()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
switch (expression_.index()) {
|
||||
switch (expr_.index()) {
|
||||
case 0: // Import
|
||||
return false;
|
||||
case 1: // TypeDefinition
|
||||
return std::get<TypeDefinition>(expression_)
|
||||
.is_same_to(
|
||||
std::move(std::get<TypeDefinition>(other_statement.expression_)));
|
||||
return std::get<TypeDefinition>(expr_).is_same_to(
|
||||
std::move(std::get<TypeDefinition>(other.expr_)));
|
||||
case 2: // FunctionDefinition
|
||||
return std::get<FunctionDefinition>(expression_)
|
||||
.is_same_to(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
return std::get<FunctionDefinition>(expr_).is_same_to(
|
||||
std::move(std::get<FunctionDefinition>(other.expr_)));
|
||||
case 3: // Extra
|
||||
return false;
|
||||
case 4: // EmptyLines
|
||||
|
|
@ -280,22 +261,20 @@ bool Statement::is_same_to(const Statement &other_statement) const {
|
|||
exit(1);
|
||||
}
|
||||
|
||||
CombineResult Statement::combine(Statement &&other_statement) {
|
||||
if (expression_.index() != other_statement.expression_.index()) {
|
||||
CombineResult Statement::combine(Statement &&other) {
|
||||
if (expr_.index() != other.expr_.index()) {
|
||||
return CombineResult::DIFFERENT_STATEMENT_TYPES;
|
||||
}
|
||||
|
||||
switch (expression_.index()) {
|
||||
switch (expr_.index()) {
|
||||
case 0: // Import
|
||||
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
|
||||
case 1: // TypeDefinition
|
||||
return std::get<TypeDefinition>(expression_)
|
||||
.combine(
|
||||
std::move(std::get<TypeDefinition>(other_statement.expression_)));
|
||||
return std::get<TypeDefinition>(expr_).combine(
|
||||
std::move(std::get<TypeDefinition>(other.expr_)));
|
||||
case 2: // FunctionDefinition
|
||||
return std::get<FunctionDefinition>(expression_)
|
||||
.combine(std::move(
|
||||
std::get<FunctionDefinition>(other_statement.expression_)));
|
||||
return std::get<FunctionDefinition>(expr_).combine(
|
||||
std::move(std::get<FunctionDefinition>(other.expr_)));
|
||||
case 3: // Extra
|
||||
return CombineResult::STATEMENTS_CANT_BE_COMBINED_ERROR;
|
||||
case 4: // EmptyLines
|
||||
|
|
|
|||
|
|
@ -2,60 +2,59 @@
|
|||
|
||||
namespace nodes {
|
||||
|
||||
Type *TypeProxy::get() { return type_storage_->get_type(id_); }
|
||||
TypeData *Type::get() { return type_storage_->get_type(id_); }
|
||||
|
||||
const Type *TypeProxy::get() const { return type_storage_->get_type(id_); }
|
||||
const TypeData *Type::get() const { return type_storage_->get_type(id_); }
|
||||
|
||||
bool TypeProxy::operator==(const TypeProxy &other) const {
|
||||
bool Type::operator==(const Type &other) const {
|
||||
return *get() == *other.get();
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
TypeProxy TypeStorage::primitive(builtin::Type type) {
|
||||
Type TypeStorage::primitive(builtin::Type type) {
|
||||
auto iter = primitive_type_ids_.find(type);
|
||||
if (iter != primitive_type_ids_.end()) {
|
||||
return TypeProxy(*this, iter->second);
|
||||
return Type(*this, iter->second);
|
||||
} else {
|
||||
primitive_type_ids_[type] = storage_.size();
|
||||
return add_type(Type(Identifier(Node(), Identifier::SIMPLE_TYPE,
|
||||
builtin::types::to_string(type))));
|
||||
return add_type(TypeData(Identifier(Node(), Identifier::SIMPLE_TYPE,
|
||||
builtin::types::to_string(type))));
|
||||
}
|
||||
}
|
||||
|
||||
TypeProxy TypeStorage::add_array_of(TypeProxy type, Node node) {
|
||||
Type TypeStorage::add_array_of(Type type, Node node) {
|
||||
if (type.type_storage_ != this) {
|
||||
error_handling::handle_general_error(
|
||||
"TypeStorage: Can't add array of type from another type "
|
||||
"storage");
|
||||
}
|
||||
|
||||
std::vector<nodes::TypeProxy> parameters;
|
||||
std::vector<nodes::Type> parameters;
|
||||
parameters.push_back(type);
|
||||
|
||||
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||
builtin::types::ARRAY_IDENTIFIER),
|
||||
std::move(parameters)));
|
||||
return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||
builtin::types::ARRAY_IDENTIFIER),
|
||||
std::move(parameters)));
|
||||
}
|
||||
|
||||
TypeProxy TypeStorage::add_error_of(TypeProxy type, Node node) {
|
||||
Type TypeStorage::add_error_of(Type type, Node node) {
|
||||
if (type.type_storage_ != this) {
|
||||
error_handling::handle_general_error(
|
||||
"TypeStorage: Can't add error of type from another type "
|
||||
"storage");
|
||||
}
|
||||
|
||||
std::vector<nodes::TypeProxy> parameters;
|
||||
std::vector<nodes::Type> parameters;
|
||||
parameters.push_back(type);
|
||||
|
||||
return add_type(Type(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||
builtin::types::ERROR_IDENTIFIER),
|
||||
std::move(parameters)));
|
||||
return add_type(TypeData(Identifier(node, Identifier::SIMPLE_TYPE,
|
||||
builtin::types::ERROR_IDENTIFIER),
|
||||
std::move(parameters)));
|
||||
}
|
||||
|
||||
nodes::TypeProxy
|
||||
TypeStorage::add_container_of(std::vector<TypeProxy> &¶meters,
|
||||
builtin::Type container, Node node) {
|
||||
nodes::Type TypeStorage::add_container_of(std::vector<Type> &¶meters,
|
||||
builtin::Type container, Node node) {
|
||||
for (auto ¶meter : parameters) {
|
||||
if (parameter.type_storage_ != this) {
|
||||
error_handling::handle_general_error(
|
||||
|
|
@ -66,20 +65,19 @@ TypeStorage::add_container_of(std::vector<TypeProxy> &¶meters,
|
|||
}
|
||||
|
||||
return add_type(
|
||||
nodes::Type(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
||||
builtin::types::to_string(container)),
|
||||
std::move(parameters)));
|
||||
nodes::TypeData(nodes::Identifier(node, nodes::Identifier::SIMPLE_TYPE,
|
||||
builtin::types::to_string(container)),
|
||||
std::move(parameters)));
|
||||
}
|
||||
|
||||
nodes::TypeProxy TypeStorage::add_modification_of(TypeProxy type,
|
||||
Modifier modifier) {
|
||||
nodes::Type TypeStorage::add_modification_of(Type type, Modifier modifier) {
|
||||
if (type.type_storage_ != this) {
|
||||
error_handling::handle_general_error(
|
||||
"TypeStorage: Can't add modification of type from another type "
|
||||
"storage");
|
||||
}
|
||||
|
||||
Type type_copy = *type.get();
|
||||
TypeData type_copy = *type.get();
|
||||
type_copy.set_modifier(modifier);
|
||||
|
||||
return add_type(std::move(type_copy));
|
||||
|
|
@ -124,7 +122,7 @@ bool TypeStorage::resolve_all_generic_types() {
|
|||
}
|
||||
|
||||
bool TypeStorage::resolve_generic_name(const std::string &name,
|
||||
const TypeProxy &actulal_type) {
|
||||
const Type &actulal_type) {
|
||||
if (actulal_type.type_storage_ != this) {
|
||||
error_handling::handle_general_error(
|
||||
"TypeStorage: Can't resolve generic type to type from another type "
|
||||
|
|
@ -203,7 +201,7 @@ TypeStorage::get_local_type_requirements(const std::string &name) const {
|
|||
|
||||
// TODO
|
||||
|
||||
bool TypeStorage::unify(TypeProxy /*left_proxy*/, TypeProxy /*right_proxy*/,
|
||||
bool TypeStorage::unify(Type /*left_proxy*/, Type /*right_proxy*/,
|
||||
UnifyModePolicy /*policy*/) {
|
||||
// Type &left = left_id.get();
|
||||
// Type &right = right_id.get();
|
||||
|
|
@ -265,13 +263,12 @@ bool TypeStorage::unify(TypeProxy /*left_proxy*/, TypeProxy /*right_proxy*/,
|
|||
throw std::exception();
|
||||
}
|
||||
|
||||
bool TypeStorage::resolve(TypeProxy generic,
|
||||
const Type &replacement /* TODO , Mode mode = {}*/) {
|
||||
bool TypeStorage::resolve(
|
||||
Type generic, const TypeData &replacement /* TODO , Mode mode = {}*/) {
|
||||
error_handling::ensure(generic.get()->is_generic(), "Type should be generic");
|
||||
error_handling::ensure(generic.get()->is_generic(), "Type should be generic");
|
||||
for (auto &type : storage_) {
|
||||
if (type.is_generic() &&
|
||||
type.get_name() == generic.get()->get_name()) {
|
||||
if (type.is_generic() && type.get_name() == generic.get()->get_name()) {
|
||||
type = replacement;
|
||||
// type.mode = mode;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@
|
|||
#include "expression_nodes.hpp"
|
||||
namespace printers {
|
||||
|
||||
void print(const nodes::Expression &expression, printers::Printer &printer);
|
||||
void print(const nodes::ExprData &expression, printers::Printer &printer);
|
||||
|
||||
// --- flow control
|
||||
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
namespace printers {
|
||||
|
||||
void print(const nodes::Type &type, printers::Printer &printer);
|
||||
void print(const nodes::TypeData &type, printers::Printer &printer);
|
||||
|
||||
// void print_tuple_type(const nodes::TupleType &type, printers::Printer
|
||||
// &printer);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ void print(const nodes::Modifier &modifier, Printer &printer,
|
|||
}
|
||||
|
||||
void print(const nodes::Literal &literal, Printer &printer) {
|
||||
switch (literal.get_any()->index()) {
|
||||
switch (literal.get_any().index()) {
|
||||
case 0: // float
|
||||
printer.print(std::to_string(*literal.get<float>().value()));
|
||||
return;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
namespace printers {
|
||||
namespace utils {
|
||||
|
||||
bool is_block_expression(const nodes::Expression &expression) {
|
||||
bool is_block_expression(const nodes::ExprData &expression) {
|
||||
return expression.get<nodes::Container>().has_value() &&
|
||||
expression.get<nodes::Container>().value()->get_type() ==
|
||||
nodes::Container::BLOCK;
|
||||
|
|
@ -16,13 +16,13 @@ bool is_block_expression(const nodes::Expression &expression) {
|
|||
|
||||
} // namespace utils
|
||||
|
||||
void print(const nodes::Expression &expression, printers::Printer &printer) {
|
||||
void print(const nodes::ExprData &expression, printers::Printer &printer) {
|
||||
if (expression.is_scoped()) {
|
||||
printer.print("(");
|
||||
}
|
||||
|
||||
std::visit([&printer](const auto &arg) -> void { print(arg, printer); },
|
||||
*expression.get_any());
|
||||
expression.get_any());
|
||||
|
||||
if (expression.is_scoped()) {
|
||||
printer.print(")");
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ namespace printers {
|
|||
|
||||
void print(const nodes::Statement &statement, Printer &printer) {
|
||||
std::visit([&printer](const auto &arg) -> void { print(arg, printer); },
|
||||
*statement.get_any());
|
||||
statement.get_any());
|
||||
|
||||
if (not statement.get<nodes::EmptyLines>().has_value()) {
|
||||
printer.new_indent_line();
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@
|
|||
namespace printers {
|
||||
|
||||
// TODO: better printing format for builtin types
|
||||
void print(const nodes::Type &type, printers::Printer &printer) {
|
||||
void print(const nodes::TypeData &type, printers::Printer &printer) {
|
||||
if (type.has_annotation()) {
|
||||
print_annotation(*type.get_annotation().value(), printer);
|
||||
printer.space();
|
||||
|
|
|
|||
|
|
@ -8,10 +8,10 @@
|
|||
namespace type_check {
|
||||
|
||||
template <>
|
||||
struct CheckTask<nodes::Expression> : public CheckTaskBase<nodes::Expression> {
|
||||
using CheckTaskBase<nodes::Expression>::CheckTaskBase;
|
||||
struct CheckTask<nodes::ExprData> : public CheckTaskBase<nodes::ExprData> {
|
||||
using CheckTaskBase<nodes::ExprData>::CheckTaskBase;
|
||||
|
||||
Result operator()(const nodes::Expression &expr,
|
||||
Result operator()(const nodes::ExprData &expr,
|
||||
const Arguments &args) override;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -17,14 +17,14 @@ class State {
|
|||
|
||||
public:
|
||||
struct VariableInfo {
|
||||
nodes::TypeProxy type;
|
||||
nodes::Type type;
|
||||
nodes::NameDefinition::Modifier modifier;
|
||||
};
|
||||
|
||||
public:
|
||||
State(Log &log) : log_(log) {}
|
||||
|
||||
bool insert_variable(const std::string &name, nodes::TypeProxy type,
|
||||
bool insert_variable(const std::string &name, nodes::Type type,
|
||||
nodes::NameDefinition::Modifier modifier) {
|
||||
Log::Context logc(log_, utils::Log::Area::kTypeCheck);
|
||||
|
||||
|
|
@ -49,7 +49,7 @@ public:
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
bool bring_type(nodes::TypeProxy type) {
|
||||
bool bring_type(nodes::Type type) {
|
||||
Log::Context logc(log_, utils::Log::Area::kTypeCheck);
|
||||
|
||||
if (contexts_.empty()) {
|
||||
|
|
@ -65,7 +65,7 @@ public:
|
|||
return true;
|
||||
}
|
||||
|
||||
bool return_type(nodes::TypeProxy type) {
|
||||
bool return_type(nodes::Type type) {
|
||||
Log::Context logc(log_, utils::Log::Area::kTypeCheck);
|
||||
|
||||
if (contexts_.empty()) {
|
||||
|
|
@ -91,7 +91,7 @@ private:
|
|||
// TODO: argument for property is returned type should be merged
|
||||
// returns brought type, return type is merged with next context or with
|
||||
// brought type in last context
|
||||
nodes::MaybeTypeProxy exit_context() {
|
||||
nodes::MaybeType exit_context() {
|
||||
Log::Context logc(log_, utils::Log::Area::kTypeCheck);
|
||||
|
||||
if (contexts_.empty()) {
|
||||
|
|
@ -143,8 +143,8 @@ public:
|
|||
// }
|
||||
|
||||
public:
|
||||
nodes::MaybeTypeProxy brought_type;
|
||||
nodes::MaybeTypeProxy returned_type;
|
||||
nodes::MaybeType brought_type;
|
||||
nodes::MaybeType returned_type;
|
||||
std::unordered_map<std::string, VariableInfo> variables;
|
||||
|
||||
private:
|
||||
|
|
@ -159,7 +159,7 @@ private:
|
|||
|
||||
//
|
||||
|
||||
using Exprs = nodes::ExpressionStorage;
|
||||
using Exprs = nodes::ExprStorage;
|
||||
using Types = nodes::TypeStorage;
|
||||
using Names = names::NameTree;
|
||||
|
||||
|
|
@ -183,20 +183,20 @@ public:
|
|||
return copy;
|
||||
}
|
||||
|
||||
Arguments expect(nodes::TypeProxies types) const {
|
||||
Arguments expect(nodes::Types types) const {
|
||||
Arguments copy(*this);
|
||||
copy.expected_types_ = types;
|
||||
return copy;
|
||||
}
|
||||
|
||||
Arguments expect(nodes::MaybeTypeProxy type) const {
|
||||
Arguments expect(nodes::MaybeType type) const {
|
||||
Arguments copy(*this);
|
||||
copy.expected_types_ = (type.has_value() ? nodes::TypeProxies{type.value()}
|
||||
: nodes::TypeProxies{});
|
||||
copy.expected_types_ =
|
||||
(type.has_value() ? nodes::Types{type.value()} : nodes::Types{});
|
||||
return copy;
|
||||
}
|
||||
|
||||
Arguments pass(nodes::MaybeTypeProxy type) const {
|
||||
Arguments pass(nodes::MaybeType type) const {
|
||||
Arguments copy(*this);
|
||||
copy.passed_type_ = type;
|
||||
return copy;
|
||||
|
|
@ -214,16 +214,16 @@ public:
|
|||
return copy;
|
||||
}
|
||||
|
||||
nodes::TypeProxies get_expected() const { return expected_types_; };
|
||||
nodes::Types get_expected() const { return expected_types_; };
|
||||
|
||||
nodes::MaybeTypeProxy get_passed() const { return passed_type_; };
|
||||
nodes::MaybeType get_passed() const { return passed_type_; };
|
||||
|
||||
// TODO: add check, that there is no passed type for some nodes ??
|
||||
// TODO: arguments builder ??
|
||||
|
||||
private:
|
||||
nodes::TypeProxies expected_types_;
|
||||
nodes::MaybeTypeProxy passed_type_;
|
||||
nodes::Types expected_types_;
|
||||
nodes::MaybeType passed_type_;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -231,7 +231,7 @@ private:
|
|||
class ContextHolder {
|
||||
public:
|
||||
ContextHolder(State &state, const nodes::Node &node,
|
||||
nodes::MaybeTypeProxy *context_exit_type)
|
||||
nodes::MaybeType *context_exit_type)
|
||||
: state_(state), context_exit_type_(context_exit_type) {
|
||||
state.enter_context(node);
|
||||
}
|
||||
|
|
@ -252,7 +252,7 @@ public:
|
|||
|
||||
private:
|
||||
State &state_;
|
||||
nodes::MaybeTypeProxy *context_exit_type_;
|
||||
nodes::MaybeType *context_exit_type_;
|
||||
};
|
||||
|
||||
//
|
||||
|
|
@ -262,18 +262,18 @@ public:
|
|||
// for invalid type
|
||||
static Result invalid() { return Result(); }
|
||||
|
||||
explicit Result(nodes::TypeProxy type) : type_(type) {}
|
||||
explicit Result(nodes::Type type) : type_(type) {}
|
||||
|
||||
//
|
||||
|
||||
nodes::TypeProxy &get() {
|
||||
nodes::Type &get() {
|
||||
utils::Assert(type_.has_value(),
|
||||
"Access to invalid type in TypeCheckResult");
|
||||
|
||||
return type_.value();
|
||||
}
|
||||
|
||||
const nodes::TypeProxy &get() const {
|
||||
const nodes::Type &get() const {
|
||||
|
||||
utils::Assert(type_.has_value(),
|
||||
"Access to invalid type in TypeCheckResult");
|
||||
|
|
@ -281,7 +281,7 @@ public:
|
|||
return type_.value();
|
||||
}
|
||||
|
||||
void set(nodes::TypeProxy type) { type_ = type; }
|
||||
void set(nodes::Type type) { type_ = type; }
|
||||
|
||||
//
|
||||
|
||||
|
|
@ -291,15 +291,15 @@ private:
|
|||
Result() = default;
|
||||
|
||||
private:
|
||||
nodes::MaybeTypeProxy type_ = {};
|
||||
nodes::MaybeType type_ = {};
|
||||
};
|
||||
|
||||
using MaybeResult = std::optional<Result>;
|
||||
|
||||
//
|
||||
|
||||
nodes::TypeProxy check_same_to_pass_type_in_arguments(
|
||||
nodes::TypeProxy type, const Arguments &arguments, const nodes::Node &node,
|
||||
nodes::Type check_same_to_pass_type_in_arguments(
|
||||
nodes::Type type, const Arguments &arguments, const nodes::Node &node,
|
||||
Executor &executor,
|
||||
const std::string &message = "Different type with passed one",
|
||||
bool handle_errors = true);
|
||||
|
|
@ -310,13 +310,12 @@ nodes::TypeProxy check_same_to_pass_type_in_arguments(
|
|||
// const std::string &message = "Type can't be passed to this node");
|
||||
|
||||
Result type_same_to_expected(
|
||||
nodes::TypeProxy type, const Arguments &argumensr, const nodes::Node &node,
|
||||
nodes::Type type, const Arguments &argumensr, const nodes::Node &node,
|
||||
Executor &executor,
|
||||
const std::string &message = "Different type with expected one",
|
||||
bool handle_errors = true);
|
||||
|
||||
Result type_check_from_arguments(nodes::TypeProxy type,
|
||||
const Arguments &arguments,
|
||||
Result type_check_from_arguments(nodes::Type type, const Arguments &arguments,
|
||||
const nodes::Node &node, Executor &executor,
|
||||
bool handle_errors = true);
|
||||
|
||||
|
|
@ -328,16 +327,16 @@ std::optional<const nodes::FunctionDefinition *>
|
|||
find_name_definition(const std::string &name, const nodes::Node &node,
|
||||
Executor &executor, bool handle_errors = true);
|
||||
|
||||
nodes::MaybeTypeProxy unfold_user_defined_type(nodes::TypeProxy type,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors = true);
|
||||
nodes::MaybeType unfold_user_defined_type(nodes::Type type,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors = true);
|
||||
|
||||
nodes::MaybeTypeProxy get_field_type_by_name(nodes::TypeProxy type,
|
||||
const std::string &field,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors = true);
|
||||
nodes::MaybeType get_field_type_by_name(nodes::Type type,
|
||||
const std::string &field,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors = true);
|
||||
|
||||
void type_check_error(const std::string &message, const nodes::Node &node,
|
||||
Executor &executor, bool handle_error = true);
|
||||
|
|
@ -353,7 +352,8 @@ template <typename N> struct CheckTask {
|
|||
template <typename N> struct CheckTaskBase : public Task<N> {
|
||||
using Task<N>::Task;
|
||||
|
||||
template <typename OtherN> Result Run(const OtherN &node, const Arguments &args) {
|
||||
template <typename OtherN>
|
||||
Result Run(const OtherN &node, const Arguments &args) {
|
||||
CheckTask<OtherN> task(this->executor);
|
||||
return task(node, args);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,9 +2,9 @@
|
|||
|
||||
namespace type_check {
|
||||
|
||||
nodes::TypeProxy get_literal_type(const nodes::Literal &literal,
|
||||
Executor &executor) {
|
||||
switch (literal.get_any()->index()) {
|
||||
nodes::Type get_literal_type(const nodes::Literal &literal,
|
||||
Executor &executor) {
|
||||
switch (literal.get_any().index()) {
|
||||
case 0: // float
|
||||
return executor.state<Types>().primitive(builtin::Type::FLOAT);
|
||||
case 1: // double
|
||||
|
|
|
|||
|
|
@ -11,13 +11,13 @@
|
|||
|
||||
namespace type_check {
|
||||
|
||||
Result CheckTask<nodes::Expression>::operator()(const nodes::Expression &expr,
|
||||
const Arguments &arguments) {
|
||||
Result CheckTask<nodes::ExprData>::operator()(const nodes::ExprData &expr,
|
||||
const Arguments &arguments) {
|
||||
return std::visit(
|
||||
[this, &arguments](const auto &node) -> Result {
|
||||
return Run(node, arguments);
|
||||
},
|
||||
*expr.get_any());
|
||||
expr.get_any());
|
||||
}
|
||||
|
||||
// --- flow control
|
||||
|
|
@ -43,7 +43,7 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
|
|||
Run(*current_case->get_value(),
|
||||
Arguments{}
|
||||
.expect_builtin(builtin::Type::BOOL, executor)
|
||||
.pass(value_result.is_invalid() ? nodes::MaybeTypeProxy{}
|
||||
.pass(value_result.is_invalid() ? nodes::MaybeType{}
|
||||
: expression_result.value().get()));
|
||||
// TODO: use type modifiers ??
|
||||
|
||||
|
|
@ -60,7 +60,7 @@ Result CheckTask<nodes::Match>::operator()(const nodes::Match &expr,
|
|||
Run(*current_case->get_condition().value(),
|
||||
Arguments{}.expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
: nodes::MaybeType{}));
|
||||
|
||||
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
||||
expression_result = std::move(case_result);
|
||||
|
|
@ -99,7 +99,7 @@ Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
|
|||
Run(*expr.get_case(i).first,
|
||||
Arguments{}.expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
: nodes::MaybeType{}));
|
||||
|
||||
if (!expression_result.has_value() && !case_result.is_invalid()) {
|
||||
expression_result = std::move(case_result);
|
||||
|
|
@ -110,7 +110,7 @@ Result CheckTask<nodes::Condition>::operator()(const nodes::Condition &expr,
|
|||
Run(*expr.get_else_case().value(),
|
||||
Arguments{}.expect(expression_result.has_value()
|
||||
? expression_result.value().get()
|
||||
: nodes::MaybeTypeProxy{}));
|
||||
: nodes::MaybeType{}));
|
||||
}
|
||||
|
||||
if (!expression_result.has_value()) {
|
||||
|
|
@ -216,7 +216,7 @@ Result CheckTask<nodes::Container>::CheckArray(const nodes::Container &expr,
|
|||
|
||||
Result CheckTask<nodes::Container>::CheckBlock(const nodes::Container &expr,
|
||||
const Arguments &args) {
|
||||
nodes::MaybeTypeProxy context_exit_type;
|
||||
nodes::MaybeType context_exit_type;
|
||||
|
||||
{
|
||||
ContextHolder context_holder(
|
||||
|
|
@ -601,7 +601,7 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
|
|||
|
||||
// TODO: check that is not typeclass ??
|
||||
|
||||
nodes::TypeProxy type = type_definition->get_type().value();
|
||||
nodes::Type type = type_definition->get_type().value();
|
||||
|
||||
// TODO: work with different parametric types: tuple, variant, ...
|
||||
|
||||
|
|
@ -770,7 +770,7 @@ Result CheckTask<nodes::Constructor>::operator()(const nodes::Constructor &expr,
|
|||
chosen_variant_option.value())));
|
||||
} else { // TODO: error, if there is more then one possible variant in
|
||||
// answer
|
||||
nodes::TypeProxies possible_options;
|
||||
nodes::Types possible_options;
|
||||
for (size_t i = 0; i < type.get()->parameters_size(); ++i) {
|
||||
possible_options.push_back(type.get()->get_parameter_proxy(i));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,10 +6,9 @@ namespace type_check {
|
|||
|
||||
// pass type -> compare types, return bool
|
||||
// no pass type -> return type
|
||||
nodes::TypeProxy check_same_to_pass_type_in_arguments(
|
||||
nodes::TypeProxy type, const Arguments &arguments,
|
||||
const nodes::Node & /*node*/, Executor &executor,
|
||||
const std::string &message, bool handle_errors) {
|
||||
nodes::Type check_same_to_pass_type_in_arguments(
|
||||
nodes::Type type, const Arguments &arguments, const nodes::Node & /*node*/,
|
||||
Executor &executor, const std::string &message, bool handle_errors) {
|
||||
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
|
||||
|
||||
if (not arguments.get_passed().has_value()) {
|
||||
|
|
@ -38,7 +37,7 @@ bool check_no_pass_type_in_arguments(const Arguments &arguments,
|
|||
return true;
|
||||
}
|
||||
|
||||
Result type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments,
|
||||
Result type_same_to_expected(nodes::Type type, const Arguments &arguments,
|
||||
const nodes::Node & /*node*/, Executor &executor,
|
||||
const std::string &message, bool handle_errors) {
|
||||
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
|
||||
|
|
@ -52,7 +51,7 @@ Result type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments,
|
|||
// TODO: use 'can cast to' (for modifiers), instead '=='
|
||||
bool all_not_expected = std::all_of(
|
||||
expected.begin(), expected.end(),
|
||||
[type](nodes::TypeProxy expected_type) { return type != expected_type; });
|
||||
[type](nodes::Type expected_type) { return type != expected_type; });
|
||||
|
||||
if (all_not_expected and handle_errors) {
|
||||
logc.Error<Log::kProc>({{message}} /* TODO: node */);
|
||||
|
|
@ -61,7 +60,7 @@ Result type_same_to_expected(nodes::TypeProxy type, const Arguments &arguments,
|
|||
return Result{expected.front()}; // any can be choosen
|
||||
}
|
||||
|
||||
Result type_check_from_arguments(nodes::TypeProxy /*type*/,
|
||||
Result type_check_from_arguments(nodes::Type /*type*/,
|
||||
const Arguments & /*arguments*/,
|
||||
const nodes::Node & /*node*/,
|
||||
Executor &executor, bool /*handle_errors*/) {
|
||||
|
|
@ -119,9 +118,10 @@ find_name_definition(const std::string &name, const nodes::Node &node,
|
|||
"Node in name tree is not name definition", handle_errors);
|
||||
}
|
||||
|
||||
std::optional<nodes::TypeProxy>
|
||||
unfold_user_defined_type(nodes::TypeProxy type, const nodes::Node &node,
|
||||
Executor &executor, bool handle_errors) {
|
||||
std::optional<nodes::Type> unfold_user_defined_type(nodes::Type type,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors) {
|
||||
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
|
||||
|
||||
const auto maybe_type_definition = find_type_definition(
|
||||
|
|
@ -147,11 +147,11 @@ unfold_user_defined_type(nodes::TypeProxy type, const nodes::Node &node,
|
|||
return maybe_type_definition.value()->get_type().value();
|
||||
}
|
||||
|
||||
std::optional<nodes::TypeProxy> get_field_type_by_name(nodes::TypeProxy type,
|
||||
const std::string &field,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors) {
|
||||
std::optional<nodes::Type> get_field_type_by_name(nodes::Type type,
|
||||
const std::string &field,
|
||||
const nodes::Node &node,
|
||||
Executor &executor,
|
||||
bool handle_errors) {
|
||||
Log::Context logc(executor.log(), utils::Log::Area::kTypeCheck);
|
||||
|
||||
switch (type.get()->to_builtin()) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue