diff --git a/src/language/ASTNodeArraySubscriptExpressionBuilder.cpp b/src/language/ASTNodeArraySubscriptExpressionBuilder.cpp new file mode 100644 index 0000000000000000000000000000000000000000..fd214c54de37c58724d57b743357f57a989d3d11 --- /dev/null +++ b/src/language/ASTNodeArraySubscriptExpressionBuilder.cpp @@ -0,0 +1,32 @@ +#include <ASTNodeArraySubscriptExpressionBuilder.hpp> + +#include <../algebra/TinyVector.hpp> + +#include <node_processor/ArraySubscriptProcessor.hpp> + +ASTNodeArraySubscriptExpressionBuilder::ASTNodeArraySubscriptExpressionBuilder(ASTNode& node) +{ + auto& array_expression = *node.children[0]; + + if (array_expression.m_data_type == ASTNodeDataType::vector_t) { + switch (array_expression.m_data_type.dimension()) { + case 1: { + node.m_node_processor = std::make_unique<ArraySubscriptProcessor<TinyVector<1>>>(node); + break; + } + case 2: { + node.m_node_processor = std::make_unique<ArraySubscriptProcessor<TinyVector<2>>>(node); + break; + } + case 3: { + node.m_node_processor = std::make_unique<ArraySubscriptProcessor<TinyVector<3>>>(node); + break; + } + default: { + break; + } + } + } else { + throw parse_error("unexpected error: invalid array type", array_expression.begin()); + } +} diff --git a/src/language/ASTNodeArraySubscriptExpressionBuilder.hpp b/src/language/ASTNodeArraySubscriptExpressionBuilder.hpp new file mode 100644 index 0000000000000000000000000000000000000000..d93ee2461ba5923f8104c2adfd4a32d9bcdffd24 --- /dev/null +++ b/src/language/ASTNodeArraySubscriptExpressionBuilder.hpp @@ -0,0 +1,12 @@ +#ifndef AST_NODE_ARRAY_SUBSCRIPT_EXPRESSION_BUILDER_HPP +#define AST_NODE_ARRAY_SUBSCRIPT_EXPRESSION_BUILDER_HPP + +#include <ASTNode.hpp> + +class ASTNodeArraySubscriptExpressionBuilder +{ + public: + ASTNodeArraySubscriptExpressionBuilder(ASTNode& node); +}; + +#endif // AST_NODE_ARRAY_SUBSCRIPT_EXPRESSION_BUILDER_HPP diff --git a/src/language/ASTNodeExpressionBuilder.cpp b/src/language/ASTNodeExpressionBuilder.cpp index 716926170282f86f985fb3fa1eadabcadcbb097d..cc20137ede9df53d64d484a96fe81377d6f7eb2b 100644 --- a/src/language/ASTNodeExpressionBuilder.cpp +++ b/src/language/ASTNodeExpressionBuilder.cpp @@ -3,6 +3,7 @@ #include <ASTNodeAffectationExpressionBuilder.hpp> #include <ASTNodeListAffectationExpressionBuilder.hpp> +#include <ASTNodeArraySubscriptExpressionBuilder.hpp> #include <ASTNodeBinaryOperatorExpressionBuilder.hpp> #include <ASTNodeFunctionEvaluationExpressionBuilder.hpp> #include <ASTNodeIncDecExpressionBuilder.hpp> @@ -63,6 +64,9 @@ ASTNodeExpressionBuilder::_buildExpression(ASTNode& n) } else if (n.is_type<language::function_evaluation>()) { ASTNodeFunctionEvaluationExpressionBuilder{n}; + } else if (n.is_type<language::subscript_expression>()) { + ASTNodeArraySubscriptExpressionBuilder{n}; + } else if (n.is_type<language::real>()) { n.m_node_processor = std::make_unique<ValueProcessor>(n); } else if (n.is_type<language::integer>()) { diff --git a/src/language/CMakeLists.txt b/src/language/CMakeLists.txt index 368fa5a9f98c7220da7c3441569722a57ead1868..acd8b1e57764fcfc0a194aebc516aeb751c324b2 100644 --- a/src/language/CMakeLists.txt +++ b/src/language/CMakeLists.txt @@ -11,6 +11,7 @@ add_library( ASTDotPrinter.cpp ASTModulesImporter.cpp ASTNodeAffectationExpressionBuilder.cpp + ASTNodeArraySubscriptExpressionBuilder.cpp ASTNodeBinaryOperatorExpressionBuilder.cpp ASTNodeCFunctionExpressionBuilder.cpp ASTNodeDataType.cpp diff --git a/src/language/node_processor/ArraySubscriptProcessor.hpp b/src/language/node_processor/ArraySubscriptProcessor.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c0426e2f030f45956524578e6a48fff29ac23b23 --- /dev/null +++ b/src/language/node_processor/ArraySubscriptProcessor.hpp @@ -0,0 +1,47 @@ +#ifndef ARRAY_SUBSCRIPT_PROCESSOR_HPP +#define ARRAY_SUBSCRIPT_PROCESSOR_HPP + +#include <node_processor/INodeProcessor.hpp> + +template <typename ArrayTypeT> +class ArraySubscriptProcessor : public INodeProcessor +{ + private: + ASTNode& m_array_subscript_expression; + + public: + DataVariant + execute(ExecutionPolicy& exec_policy) + { + auto& index_expression = *m_array_subscript_expression.children[1]; + + const int64_t index_value = [&](DataVariant&& value_variant) -> int64_t { + int64_t index_value = 0; + std::visit( + [&](auto&& value) { + using ValueT = std::decay_t<decltype(value)>; + if constexpr (std::is_integral_v<ValueT>) { + index_value = value; + } else { + throw parse_error("unexpected error: invalid index type", std::vector{index_expression.begin()}); + } + }, + value_variant); + return index_value; + }(index_expression.execute(exec_policy)); + + auto& array_expression = *m_array_subscript_expression.children[0]; + + const ArrayTypeT& array = std::get<ArrayTypeT>(array_expression.execute(exec_policy)); + + return array[index_value]; + } + + ArraySubscriptProcessor(ASTNode& array_subscript_expression) + : m_array_subscript_expression{array_subscript_expression} + {} + + virtual ~ArraySubscriptProcessor() = default; +}; + +#endif // ARRAY_SUBSCRIPT_PROCESSOR_HPP