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

Continue introduction of R^d vectors with d in {1,2,3}

These are the so-called `TinyVector` (their size is known at compilation time).

On the way ASTNodeDataType has evolved from an `enum class` to a real `class` to
allow the description of more complex types. In is no more just a flag.

First new data is the dimension of the object.
parent 5c24a67a
No related branches found
No related tags found
1 merge request!37Feature/language
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <node_processor/AffectationProcessor.hpp> #include <node_processor/AffectationProcessor.hpp>
#include <../algebra/TinyVector.hpp>
ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n) ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode& n)
{ {
auto set_affectation_processor = [](ASTNode& n, const auto& operator_v) { auto set_affectation_processor = [](ASTNode& n, const auto& operator_v) {
...@@ -38,6 +40,28 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode ...@@ -38,6 +40,28 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode
} }
}; };
auto set_affectation_processor_for_vector_data = [&](const auto& value, const ASTNodeDataType& data_type) {
using OperatorT = std::decay_t<decltype(operator_v)>;
using ValueT = std::decay_t<decltype(value)>;
if constexpr (std::is_same_v<OperatorT, language::eq_op> or std::is_same_v<OperatorT, language::pluseq_op>) {
switch (data_type) {
case ASTNodeDataType::vector_t: {
n.m_node_processor = std::make_unique<AffectationProcessor<OperatorT, ValueT, ValueT>>(n);
break;
}
// LCOV_EXCL_START
default: {
throw parse_error("unexpected error: undefined operand type for vector affectation",
std::vector{n.children[1]->begin()});
}
// LCOV_EXCL_STOP
}
} else {
throw parse_error("unexpected error: undefined operator type", std::vector{n.children[0]->begin()});
}
};
auto set_affectation_processor_for_string_data = [&](const ASTNodeDataType& data_type) { auto set_affectation_processor_for_string_data = [&](const ASTNodeDataType& data_type) {
using OperatorT = std::decay_t<decltype(operator_v)>; using OperatorT = std::decay_t<decltype(operator_v)>;
...@@ -78,8 +102,6 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode ...@@ -78,8 +102,6 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode
auto set_affectation_processor_for_value = [&](const ASTNodeDataType& value_type) { auto set_affectation_processor_for_value = [&](const ASTNodeDataType& value_type) {
const ASTNodeDataType data_type = n.children[1]->m_data_type; const ASTNodeDataType data_type = n.children[1]->m_data_type;
ASTNodeNaturalConversionChecker{n, data_type, value_type};
switch (value_type) { switch (value_type) {
case ASTNodeDataType::bool_t: { case ASTNodeDataType::bool_t: {
set_affectation_processor_for_data(bool{}, data_type); set_affectation_processor_for_data(bool{}, data_type);
...@@ -97,6 +119,10 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode ...@@ -97,6 +119,10 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode
set_affectation_processor_for_data(double{}, data_type); set_affectation_processor_for_data(double{}, data_type);
break; break;
} }
case ASTNodeDataType::vector_t: {
set_affectation_processor_for_vector_data(TinyVector<3>{}, data_type);
break;
}
case ASTNodeDataType::string_t: { case ASTNodeDataType::string_t: {
set_affectation_processor_for_string_data(data_type); set_affectation_processor_for_string_data(data_type);
break; break;
...@@ -107,6 +133,33 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode ...@@ -107,6 +133,33 @@ ASTNodeAffectationExpressionBuilder::ASTNodeAffectationExpressionBuilder(ASTNode
} }
}; };
if (n.m_data_type == ASTNodeDataType::vector_t) {
// Only real data are considered
const ASTNode& data_node = *n.children[1];
switch (data_node.m_data_type) {
case ASTNodeDataType::list_t: {
if (data_node.children.size() != n.m_data_type.dimension()) {
throw parse_error("incompatible dimensions in affectation", std::vector{n.begin()});
}
for (const auto& child : data_node.children) {
ASTNodeNaturalConversionChecker{n, child->m_data_type, ASTNodeDataType::double_t};
}
break;
}
case ASTNodeDataType::vector_t: {
if (data_node.children.size() != n.m_data_type.dimension()) {
throw parse_error("incompatible dimensions in affectation", std::vector{n.begin()});
}
break;
}
default: {
throw parse_error("invalid operand for affectation", std::vector{n.children[1]->begin()});
}
}
} else {
ASTNodeNaturalConversionChecker{n, n.children[1]->m_data_type, n.m_data_type};
}
set_affectation_processor_for_value(n.m_data_type); set_affectation_processor_for_value(n.m_data_type);
}; };
......
...@@ -38,6 +38,9 @@ dataTypeName(const ASTNodeDataType& data_type) ...@@ -38,6 +38,9 @@ dataTypeName(const ASTNodeDataType& data_type)
case ASTNodeDataType::void_t: case ASTNodeDataType::void_t:
name = "void"; name = "void";
break; break;
case ASTNodeDataType::list_t:
name = "list";
break;
} }
return name; return name;
} }
......
...@@ -6,7 +6,10 @@ ...@@ -6,7 +6,10 @@
class ASTNode; class ASTNode;
enum class ASTNodeDataType : int32_t class ASTNodeDataType
{
public:
enum DataType : int32_t
{ {
undefined_t = -1, undefined_t = -1,
bool_t = 0, bool_t = 0,
...@@ -14,13 +17,41 @@ enum class ASTNodeDataType : int32_t ...@@ -14,13 +17,41 @@ enum class ASTNodeDataType : int32_t
unsigned_int_t = 2, unsigned_int_t = 2,
double_t = 3, double_t = 3,
vector_t = 4, vector_t = 4,
string_t = 5, list_t = 5,
string_t = 6,
typename_t = 10, typename_t = 10,
function_t = 11, function_t = 11,
c_function_t = 12, c_function_t = 12,
void_t = std::numeric_limits<int32_t>::max() void_t = std::numeric_limits<int32_t>::max()
}; };
private:
DataType m_data_type;
size_t m_dimension;
public:
size_t
dimension() const
{
return m_dimension;
}
operator DataType() const
{
return m_data_type;
}
ASTNodeDataType& operator=(const ASTNodeDataType&) = default;
constexpr ASTNodeDataType(DataType data_type) : m_data_type{data_type}, m_dimension{1} {}
ASTNodeDataType(DataType data_type, size_t dimension) : m_data_type{data_type}, m_dimension{dimension} {}
ASTNodeDataType(const ASTNodeDataType&) = default;
~ASTNodeDataType() = default;
};
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,7 +38,12 @@ ASTNodeDataTypeBuilder::_buildDeclarationNodeDataTypes(ASTNode& type_node, ASTNo ...@@ -38,7 +38,12 @@ 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>()) {
data_type = ASTNodeDataType::vector_t; 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());
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;
} }
...@@ -387,9 +392,10 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const ...@@ -387,9 +392,10 @@ ASTNodeDataTypeBuilder::_buildNodeDataTypes(ASTNode& n) const
} 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>()) {
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::expression_list>() or } else if (n.is_type<language::name_list>() or n.is_type<language::function_argument_list>()) {
n.is_type<language::function_argument_list>()) {
n.m_data_type = ASTNodeDataType::void_t; n.m_data_type = ASTNodeDataType::void_t;
} else if (n.is_type<language::expression_list>()) {
n.m_data_type = ASTNodeDataType::list_t;
} }
} }
} }
......
...@@ -5,11 +5,22 @@ ...@@ -5,11 +5,22 @@
#include <variant> #include <variant>
#include <vector> #include <vector>
#include <../algebra/TinyVector.hpp>
#include <PugsAssert.hpp> #include <PugsAssert.hpp>
class AggregateDataVariant; class AggregateDataVariant;
using DataVariant = std::variant<std::monostate, bool, uint64_t, int64_t, double, std::string, AggregateDataVariant>; using DataVariant = std::variant<std::monostate,
bool,
uint64_t,
int64_t,
double,
std::string,
AggregateDataVariant,
TinyVector<1>,
TinyVector<2>,
TinyVector<3>>;
class AggregateDataVariant // LCOV_EXCL_LINE class AggregateDataVariant // LCOV_EXCL_LINE
{ {
...@@ -60,14 +71,16 @@ class AggregateDataVariant // LCOV_EXCL_LINE ...@@ -60,14 +71,16 @@ class AggregateDataVariant // LCOV_EXCL_LINE
} }
PUGS_INLINE PUGS_INLINE
DataVariant& operator[](size_t i) DataVariant&
operator[](size_t i)
{ {
Assert(i < m_data_vector.size()); Assert(i < m_data_vector.size());
return m_data_vector[i]; return m_data_vector[i];
} }
PUGS_INLINE PUGS_INLINE
const DataVariant& operator[](size_t i) const const DataVariant&
operator[](size_t i) const
{ {
Assert(i < m_data_vector.size()); Assert(i < m_data_vector.size());
return m_data_vector[i]; return m_data_vector[i];
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment