Skip to content
Snippets Groups Projects
Commit 6b2407fc authored by Stéphane Del Pino's avatar Stéphane Del Pino
Browse files

Add vector treatment in functions (arguments and returned types)

parent 37e06434
No related branches found
No related tags found
1 merge request!37Feature/language
#include <ASTNode.hpp>
#include <ASTNodeDataType.hpp> #include <ASTNodeDataType.hpp>
#include <PEGGrammar.hpp>
ASTNodeDataType
getVectorDataType(const ASTNode& type_node)
{
if (not(type_node.is_type<language::vector_type>() and (type_node.children.size() == 2))) {
throw parse_error("unexpected node type", type_node.begin());
}
ASTNode& dimension_node = *type_node.children[1];
if (not dimension_node.is_type<language::integer>()) {
throw parse_error("unexpected non integer constant dimension", dimension_node.begin());
}
const size_t dimension = std::stol(dimension_node.string());
return ASTNodeDataType{ASTNodeDataType::vector_t, dimension};
}
std::string std::string
dataTypeName(const ASTNodeDataType& data_type) dataTypeName(const ASTNodeDataType& data_type)
{ {
......
...@@ -52,6 +52,8 @@ class ASTNodeDataType ...@@ -52,6 +52,8 @@ class ASTNodeDataType
~ASTNodeDataType() = default; ~ASTNodeDataType() = default;
}; };
ASTNodeDataType getVectorDataType(const ASTNode& type_node);
std::string dataTypeName(const ASTNodeDataType& data_type); std::string dataTypeName(const ASTNodeDataType& data_type);
ASTNodeDataType dataTypePromotion(const ASTNodeDataType& data_type_1, const ASTNodeDataType& data_type_2); ASTNodeDataType dataTypePromotion(const ASTNodeDataType& data_type_1, const ASTNodeDataType& data_type_2);
......
...@@ -38,12 +38,7 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo ...@@ -38,12 +38,7 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo
} else if (type_node.is_type<language::R_set>()) { } else if (type_node.is_type<language::R_set>()) {
data_type = ASTNodeDataType::double_t; data_type = ASTNodeDataType::double_t;
} else if (type_node.is_type<language::vector_type>()) { } else if (type_node.is_type<language::vector_type>()) {
ASTNode& dimension_node = *type_node.children[1]; data_type = getVectorDataType(type_node);
if (not dimension_node.is_type<language::integer>()) {
throw parse_error("unexpected non integer constant dimension", dimension_node.begin());
}
const size_t dimension = std::stol(dimension_node.string());
data_type = ASTNodeDataType{ASTNodeDataType::vector_t, dimension};
} else if (type_node.is_type<language::string_type>()) { } else if (type_node.is_type<language::string_type>()) {
data_type = ASTNodeDataType::string_t; data_type = ASTNodeDataType::string_t;
} }
...@@ -98,7 +93,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -98,7 +93,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
} else if (n.is_type<language::integer>()) { } else if (n.is_type<language::integer>()) {
n.m_data_type = ASTNodeDataType::int_t; n.m_data_type = ASTNodeDataType::int_t;
} else if (n.is_type<language::vector_type>()) { } else if (n.is_type<language::vector_type>()) {
n.m_data_type = ASTNodeDataType::vector_t; n.m_data_type = getVectorDataType(n);
} else if (n.is_type<language::literal>()) { } else if (n.is_type<language::literal>()) {
n.m_data_type = ASTNodeDataType::string_t; n.m_data_type = ASTNodeDataType::string_t;
} else if (n.is_type<language::cout_kw>() or n.is_type<language::cerr_kw>() or n.is_type<language::clog_kw>()) { } else if (n.is_type<language::cout_kw>() or n.is_type<language::cerr_kw>() or n.is_type<language::clog_kw>()) {
...@@ -134,7 +129,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -134,7 +129,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
} }
const size_t nb_parameter_domains = const size_t nb_parameter_domains =
(parameters_domain_node.children.size() > 0) ? parameters_domain_node.children.size() : 1; (parameters_domain_node.is_type<language::type_expression>()) ? parameters_domain_node.children.size() : 1;
const size_t nb_parameter_names = const size_t nb_parameter_names =
(parameters_name_node.children.size() > 0) ? parameters_name_node.children.size() : 1; (parameters_name_node.children.size() > 0) ? parameters_name_node.children.size() : 1;
...@@ -159,7 +154,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -159,7 +154,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
} else if (type_node.is_type<language::R_set>()) { } else if (type_node.is_type<language::R_set>()) {
data_type = ASTNodeDataType::double_t; data_type = ASTNodeDataType::double_t;
} else if (type_node.is_type<language::vector_type>()) { } else if (type_node.is_type<language::vector_type>()) {
data_type = ASTNodeDataType::vector_t; data_type = getVectorDataType(type_node);
} else if (type_node.is_type<language::string_type>()) { } else if (type_node.is_type<language::string_type>()) {
data_type = ASTNodeDataType::string_t; data_type = ASTNodeDataType::string_t;
} }
...@@ -180,10 +175,10 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -180,10 +175,10 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
i_symbol->attributes().setDataType(data_type); i_symbol->attributes().setDataType(data_type);
}; };
if (parameters_domain_node.children.size() == 0) { if (nb_parameter_domains == 1) {
simple_type_allocator(parameters_domain_node, parameters_name_node); simple_type_allocator(parameters_domain_node, parameters_name_node);
} else { } else {
for (size_t i = 0; i < parameters_domain_node.children.size(); ++i) { for (size_t i = 0; i < nb_parameter_domains; ++i) {
simple_type_allocator(*parameters_domain_node.children[i], *parameters_name_node.children[i]); simple_type_allocator(*parameters_domain_node.children[i], *parameters_name_node.children[i]);
} }
} }
...@@ -229,7 +224,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -229,7 +224,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
} else if (image_node.is_type<language::R_set>()) { } else if (image_node.is_type<language::R_set>()) {
value_type = ASTNodeDataType::double_t; value_type = ASTNodeDataType::double_t;
} else if (image_node.is_type<language::vector_type>()) { } else if (image_node.is_type<language::vector_type>()) {
value_type = ASTNodeDataType::vector_t; value_type = getVectorDataType(image_node);
} else if (image_node.is_type<language::string_type>()) { } else if (image_node.is_type<language::string_type>()) {
value_type = ASTNodeDataType::string_t; value_type = ASTNodeDataType::string_t;
} }
...@@ -351,7 +346,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -351,7 +346,7 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
Assert(image_domain_node.m_data_type == ASTNodeDataType::typename_t); Assert(image_domain_node.m_data_type == ASTNodeDataType::typename_t);
ASTNodeDataType data_type{ASTNodeDataType::undefined_t}; ASTNodeDataType data_type{ASTNodeDataType::undefined_t};
if (image_domain_node.children.size() > 0) { if (image_domain_node.is_type<language::type_expression>()) {
data_type = image_domain_node.m_data_type; data_type = image_domain_node.m_data_type;
} else { } else {
if (image_domain_node.is_type<language::B_set>()) { if (image_domain_node.is_type<language::B_set>()) {
...@@ -362,6 +357,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -362,6 +357,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
data_type = ASTNodeDataType::unsigned_int_t; data_type = ASTNodeDataType::unsigned_int_t;
} else if (image_domain_node.is_type<language::R_set>()) { } else if (image_domain_node.is_type<language::R_set>()) {
data_type = ASTNodeDataType::double_t; data_type = ASTNodeDataType::double_t;
} else if (image_domain_node.is_type<language::vector_type>()) {
data_type = getVectorDataType(image_domain_node);
} else if (image_domain_node.is_type<language::string_type>()) { } else if (image_domain_node.is_type<language::string_type>()) {
data_type = ASTNodeDataType::string_t; data_type = ASTNodeDataType::string_t;
} }
...@@ -390,7 +387,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -390,7 +387,8 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
throw parse_error(message.str(), n.begin()); throw parse_error(message.str(), n.begin());
} }
} else if (n.is_type<language::B_set>() or n.is_type<language::Z_set>() or n.is_type<language::N_set>() or } else if (n.is_type<language::B_set>() or n.is_type<language::Z_set>() or n.is_type<language::N_set>() or
n.is_type<language::R_set>() or n.is_type<language::string_type>()) { n.is_type<language::R_set>() or n.is_type<language::string_type>() or
n.is_type<language::vector_type>()) {
n.m_data_type = ASTNodeDataType::typename_t; n.m_data_type = ASTNodeDataType::typename_t;
} else if (n.is_type<language::name_list>() or n.is_type<language::function_argument_list>()) { } else if (n.is_type<language::name_list>() or n.is_type<language::function_argument_list>()) {
n.m_data_type = ASTNodeDataType::void_t; n.m_data_type = ASTNodeDataType::void_t;
......
...@@ -39,6 +39,8 @@ ASTNodeDataTypeFlattener::ASTNodeDataTypeFlattener(ASTNode& node, FlattenedDataT ...@@ -39,6 +39,8 @@ ASTNodeDataTypeFlattener::ASTNodeDataTypeFlattener(ASTNode& node, FlattenedDataT
data_type = ASTNodeDataType::unsigned_int_t; data_type = ASTNodeDataType::unsigned_int_t;
} else if (image_sub_domain->is_type<language::R_set>()) { } else if (image_sub_domain->is_type<language::R_set>()) {
data_type = ASTNodeDataType::double_t; data_type = ASTNodeDataType::double_t;
} else if (image_sub_domain->is_type<language::vector_type>()) {
data_type = getVectorDataType(*image_sub_domain);
} else if (image_sub_domain->is_type<language::string_type>()) { } else if (image_sub_domain->is_type<language::string_type>()) {
data_type = ASTNodeDataType::string_t; data_type = ASTNodeDataType::string_t;
} }
......
...@@ -43,6 +43,27 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy ...@@ -43,6 +43,27 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy
} }
}; };
auto get_function_argument_converter_for_vector =
[&](const auto& parameter_v) -> std::unique_ptr<IFunctionArgumentConverter> {
using ParameterT = std::decay_t<decltype(parameter_v)>;
switch (node_sub_data_type.m_data_type) {
case ASTNodeDataType::vector_t: {
if (node_sub_data_type.m_data_type.dimension() == parameter_v.dimension()) {
return std::make_unique<FunctionArgumentConverter<ParameterT, ParameterT>>(parameter_id);
} else {
throw parse_error("invalid argument dimension (expected " + std::to_string(parameter_v.dimension()) +
", provided " + std::to_string(node_sub_data_type.m_data_type.dimension()) + ")",
std::vector{node_sub_data_type.m_parent_node.begin()});
}
}
// LCOV_EXCL_START
default: {
throw parse_error("invalid argument type", std::vector{node_sub_data_type.m_parent_node.begin()});
}
// LCOV_EXCL_STOP
}
};
auto get_function_argument_converter_for_string = [&]() -> std::unique_ptr<IFunctionArgumentConverter> { auto get_function_argument_converter_for_string = [&]() -> std::unique_ptr<IFunctionArgumentConverter> {
switch (node_sub_data_type.m_data_type) { switch (node_sub_data_type.m_data_type) {
case ASTNodeDataType::bool_t: { case ASTNodeDataType::bool_t: {
...@@ -85,6 +106,22 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy ...@@ -85,6 +106,22 @@ ASTNodeFunctionExpressionBuilder::_getArgumentConverter(SymbolType& parameter_sy
case ASTNodeDataType::string_t: { case ASTNodeDataType::string_t: {
return get_function_argument_converter_for_string(); return get_function_argument_converter_for_string();
} }
case ASTNodeDataType::vector_t: {
switch (parameter_symbol.attributes().dataType().dimension()) {
case 1: {
return get_function_argument_converter_for_vector(TinyVector<1>{});
}
case 2: {
return get_function_argument_converter_for_vector(TinyVector<2>{});
}
case 3: {
return get_function_argument_converter_for_vector(TinyVector<3>{});
}
default: {
throw parse_error("unexpected error: invalid parameter dimension", std::vector{m_node.begin()});
}
}
}
// LCOV_EXCL_START // LCOV_EXCL_START
default: { default: {
...@@ -194,6 +231,25 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex ...@@ -194,6 +231,25 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex
} }
}; };
auto get_function_processor_for_expression_vector = [&](const auto& return_v) -> std::unique_ptr<INodeProcessor> {
using ReturnT = std::decay_t<decltype(return_v)>;
switch (expression_value_type) {
case ASTNodeDataType::vector_t: {
if (expression_value_type.dimension() == return_v.dimension()) {
return std::make_unique<FunctionExpressionProcessor<ReturnT, ReturnT>>(function_component_expression);
} else {
throw parse_error("invalid dimension for returned vector", std::vector{function_component_expression.begin()});
}
}
// LCOV_EXCL_START
default: {
throw parse_error("unexpected error: undefined expression value type for function",
std::vector{node.children[1]->begin()});
}
// LCOV_EXCL_STOP
}
};
auto get_function_processor_for_value = [&]() { auto get_function_processor_for_value = [&]() {
switch (return_value_type) { switch (return_value_type) {
case ASTNodeDataType::bool_t: { case ASTNodeDataType::bool_t: {
...@@ -208,6 +264,22 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex ...@@ -208,6 +264,22 @@ ASTNodeFunctionExpressionBuilder::_getFunctionProcessor(const ASTNodeDataType ex
case ASTNodeDataType::double_t: { case ASTNodeDataType::double_t: {
return get_function_processor_for_expression_value(double{}); return get_function_processor_for_expression_value(double{});
} }
case ASTNodeDataType::vector_t: {
switch (return_value_type.dimension()) {
case 1: {
return get_function_processor_for_expression_vector(TinyVector<1>{});
}
case 2: {
return get_function_processor_for_expression_vector(TinyVector<2>{});
}
case 3: {
return get_function_processor_for_expression_vector(TinyVector<3>{});
}
default: {
throw parse_error("unexpected error: invalid dimension in returned type", std::vector{node.begin()});
}
}
}
case ASTNodeDataType::string_t: { case ASTNodeDataType::string_t: {
return get_function_processor_for_expression_value(std::string{}); return get_function_processor_for_expression_value(std::string{});
} }
...@@ -248,6 +320,8 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node ...@@ -248,6 +320,8 @@ ASTNodeFunctionExpressionBuilder::ASTNodeFunctionExpressionBuilder(ASTNode& node
return_value_type = ASTNodeDataType::unsigned_int_t; return_value_type = ASTNodeDataType::unsigned_int_t;
} else if (image_domain_node.is_type<language::R_set>()) { } else if (image_domain_node.is_type<language::R_set>()) {
return_value_type = ASTNodeDataType::double_t; return_value_type = ASTNodeDataType::double_t;
} else if (image_domain_node.is_type<language::vector_type>()) {
return_value_type = getVectorDataType(image_domain_node);
} else if (image_domain_node.is_type<language::string_type>()) { } else if (image_domain_node.is_type<language::string_type>()) {
return_value_type = ASTNodeDataType::string_t; return_value_type = ASTNodeDataType::string_t;
} }
......
...@@ -41,6 +41,16 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( ...@@ -41,6 +41,16 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor(
} }
}; };
auto add_affectation_processor_for_vector_data = [&](const auto& value,
const ASTNodeSubDataType& node_sub_data_type) {
using ValueT = std::decay_t<decltype(value)>;
if (node_sub_data_type.m_data_type.dimension() == value.dimension()) {
list_affectation_processor->template add<ValueT, ValueT>(value_node);
} else {
throw parse_error("invalid dimension", std::vector{node_sub_data_type.m_parent_node.begin()});
}
};
auto add_affectation_processor_for_string_data = [&](const ASTNodeSubDataType& node_sub_data_type) { auto add_affectation_processor_for_string_data = [&](const ASTNodeSubDataType& node_sub_data_type) {
if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) { if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) {
switch (node_sub_data_type.m_data_type) { switch (node_sub_data_type.m_data_type) {
...@@ -98,6 +108,26 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor( ...@@ -98,6 +108,26 @@ ASTNodeListAffectationExpressionBuilder::_buildAffectationProcessor(
add_affectation_processor_for_data(double{}, node_sub_data_type); add_affectation_processor_for_data(double{}, node_sub_data_type);
break; break;
} }
case ASTNodeDataType::vector_t: {
switch (value_type.dimension()) {
case 1: {
add_affectation_processor_for_vector_data(TinyVector<1>{}, node_sub_data_type);
break;
}
case 2: {
add_affectation_processor_for_vector_data(TinyVector<2>{}, node_sub_data_type);
break;
}
case 3: {
add_affectation_processor_for_vector_data(TinyVector<3>{}, node_sub_data_type);
break;
}
default: {
throw parse_error("invalid dimension", std::vector{value_node.begin()});
}
}
break;
}
case ASTNodeDataType::string_t: { case ASTNodeDataType::string_t: {
add_affectation_processor_for_string_data(node_sub_data_type); add_affectation_processor_for_string_data(node_sub_data_type);
break; break;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment