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

Continue vector component affectation (still buggy)

parent 9b0c7f9d
Branches
Tags
1 merge request!37Feature/language
......@@ -54,7 +54,7 @@ struct AffOp<language::minuseq_op>
struct IAffectationExecutor
{
virtual void affect(DataVariant&& rhs) = 0;
virtual void affect(ExecutionPolicy& exec_policy, DataVariant&& rhs) = 0;
virtual ~IAffectationExecutor() = default;
};
......@@ -85,7 +85,7 @@ class AffectationExecutor final : public IAffectationExecutor
}
PUGS_INLINE void
affect(DataVariant&& rhs)
affect(ExecutionPolicy&, DataVariant&& rhs)
{
if constexpr (_is_defined) {
if constexpr (std::is_same_v<ValueT, std::string>) {
......@@ -118,6 +118,84 @@ class AffectationExecutor final : public IAffectationExecutor
}
};
template <typename OperatorT, typename ArrayT, typename ValueT, typename DataT>
class ComponentAffectationExecutor final : public IAffectationExecutor
{
private:
ArrayT& m_lhs_array;
ASTNode& m_index_expression;
static inline const bool _is_defined{[] {
if constexpr (not std::is_same_v<typename ArrayT::data_type, ValueT>) {
return false;
} else if constexpr (std::is_same_v<std::decay_t<ValueT>, bool>) {
if constexpr (not std::is_same_v<OperatorT, language::eq_op>) {
return false;
}
}
return true;
}()};
public:
ComponentAffectationExecutor(ASTNode& node, ArrayT& lhs_array)
: m_lhs_array{lhs_array}, m_index_expression{*node.children[1]}
{
// LCOV_EXCL_START
if constexpr (not _is_defined) {
throw parse_error("unexpected error: invalid operands to affectation expression", std::vector{node.begin()});
}
// LCOV_EXCL_STOP
}
PUGS_INLINE void
affect(ExecutionPolicy& exec_policy, DataVariant&& rhs)
{
if constexpr (_is_defined) {
const int64_t index_value = [&](DataVariant&& value_variant) -> int64_t {
int64_t index_value = 0;
std::visit(
[&](auto&& value) {
using IndexValueT = std::decay_t<decltype(value)>;
if constexpr (std::is_integral_v<IndexValueT>) {
index_value = value;
} else {
throw parse_error("unexpected error: invalid index type", std::vector{m_index_expression.begin()});
}
},
value_variant);
return index_value;
}(m_index_expression.execute(exec_policy));
if constexpr (std::is_same_v<ValueT, std::string>) {
if constexpr (std::is_same_v<OperatorT, language::eq_op>) {
if constexpr (std::is_same_v<std::string, DataT>) {
m_lhs_array[index_value] = std::get<DataT>(rhs);
} else {
m_lhs_array[index_value] = std::to_string(std::get<DataT>(rhs));
}
} else {
static_assert(std::is_same_v<OperatorT, language::pluseq_op>, "unexpected operator type");
if constexpr (std::is_same_v<std::string, DataT>) {
m_lhs_array[index_value] += std::get<std::string>(rhs);
} else {
m_lhs_array[index_value] += std::to_string(std::get<DataT>(rhs));
}
}
} else {
if constexpr (std::is_same_v<OperatorT, language::eq_op>) {
if constexpr (std::is_same_v<ValueT, DataT>) {
m_lhs_array[index_value] = std::get<DataT>(rhs);
} else {
m_lhs_array[index_value] = static_cast<ValueT>(std::get<DataT>(rhs));
}
} else {
AffOp<OperatorT>().eval(m_lhs_array[index_value], std::get<DataT>(rhs));
}
}
}
}
};
template <typename OperatorT, typename ValueT, typename DataT>
class AffectationProcessor final : public INodeProcessor
{
......@@ -130,7 +208,7 @@ class AffectationProcessor final : public INodeProcessor
DataVariant
execute(ExecutionPolicy& exec_policy)
{
m_affectation_executor->affect(m_node.children[1]->execute(exec_policy));
m_affectation_executor->affect(exec_policy, m_node.children[1]->execute(exec_policy));
return {};
}
......@@ -149,6 +227,55 @@ class AffectationProcessor final : public INodeProcessor
using AffectationExecutorT = AffectationExecutor<OperatorT, ValueT, DataT>;
m_affectation_executor = std::make_unique<AffectationExecutorT>(m_node, std::get<ValueT>(value));
} else if (node.children[0]->is_type<language::subscript_expression>()) {
auto& array_subscript_expression = *node.children[0];
auto& array_expression = *array_subscript_expression.children[0];
Assert(array_expression.is_type<language::name>());
const std::string& symbol = array_expression.string();
auto [i_symbol, found] = m_node.m_symbol_table->find(symbol, m_node.children[0]->begin());
Assert(found);
DataVariant& value = i_symbol->attributes().value();
if (array_expression.m_data_type != ASTNodeDataType::vector_t) {
throw parse_error("unexpected error: invalid lhs (expecting R^d)", std::vector{node.children[0]->begin()});
}
switch (array_expression.m_data_type.dimension()) {
case 1: {
using ArrayTypeT = TinyVector<1>;
if (not std::holds_alternative<ArrayTypeT>(value)) {
value = ArrayTypeT{};
}
using AffectationExecutorT = ComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
m_affectation_executor = std::make_unique<AffectationExecutorT>(m_node, std::get<ArrayTypeT>(value));
break;
}
case 2: {
using ArrayTypeT = TinyVector<2>;
if (not std::holds_alternative<ArrayTypeT>(value)) {
value = ArrayTypeT{};
}
using AffectationExecutorT = ComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
m_affectation_executor = std::make_unique<AffectationExecutorT>(m_node, std::get<ArrayTypeT>(value));
break;
}
case 3: {
using ArrayTypeT = TinyVector<3>;
if (not std::holds_alternative<ArrayTypeT>(value)) {
value = ArrayTypeT{};
}
using AffectationExecutorT = ComponentAffectationExecutor<OperatorT, ArrayTypeT, ValueT, DataT>;
m_affectation_executor = std::make_unique<AffectationExecutorT>(m_node, std::get<ArrayTypeT>(value));
break;
}
default: {
throw parse_error("unexpected error: invalid vector dimension", std::vector{node.children[0]->begin()});
}
}
} else {
throw parse_error("unexpected error: invalid lhs", std::vector{node.children[0]->begin()});
}
......@@ -264,7 +391,7 @@ class ListAffectationProcessor final : public INodeProcessor
Assert(m_affectation_executor_list.size() == children_values.size());
for (size_t i = 0; i < m_affectation_executor_list.size(); ++i) {
m_affectation_executor_list[i]->affect(std::move(children_values[i]));
m_affectation_executor_list[i]->affect(exec_policy, std::move(children_values[i]));
}
return {};
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please to comment