From 1050b71d0614aa73f575195aafd49f3f1ff12d40 Mon Sep 17 00:00:00 2001 From: Adam Wardynski <award@.(B-4.4.46a)> Date: Fri, 3 Dec 2010 16:41:00 +0100 Subject: [PATCH] Base class for iterations, WIP. --- libwccl/CMakeLists.txt | 1 + libwccl/ops/functions/bool/iteration.cpp | 59 +++++++++++++++++++++ libwccl/ops/functions/bool/iteration.h | 66 ++++++++++++++++++++++++ 3 files changed, 126 insertions(+) create mode 100644 libwccl/ops/functions/bool/iteration.cpp create mode 100644 libwccl/ops/functions/bool/iteration.h diff --git a/libwccl/CMakeLists.txt b/libwccl/CMakeLists.txt index a88b82f..320dbd2 100644 --- a/libwccl/CMakeLists.txt +++ b/libwccl/CMakeLists.txt @@ -28,6 +28,7 @@ endif(WIN32) SET(libwccl_STAT_SRC exception.cpp ops/formatters.cpp + ops/functions/bool/iteration.cpp ops/functions/bool/predicate.cpp ops/functions/bool/predicates/and.cpp ops/functions/bool/predicates/logicalpredicate.cpp diff --git a/libwccl/ops/functions/bool/iteration.cpp b/libwccl/ops/functions/bool/iteration.cpp new file mode 100644 index 0000000..fd9c97c --- /dev/null +++ b/libwccl/ops/functions/bool/iteration.cpp @@ -0,0 +1,59 @@ +#include <libwccl/ops/functions/bool/iteration.h> +#include <libwccl/ops/functions/bool/predicate.h> + + +namespace Wccl { + +#ifndef _MSC_VER +const int Iteration::MatchAll; +#endif + +Iteration::BaseRetValPtr Iteration::apply_internal(const FunExecContext& context) const +{ + const boost::shared_ptr<const Position>& range_begin = range_begin_expr_->apply(context); + const boost::shared_ptr<const Position>& range_end = range_end_expr_->apply(context); + const boost::shared_ptr<Position>& iter_var = context.variables()->get_fast(iter_var_acc_); + + const SentenceContext& sc = context.sentence_context(); + + int abs_begin = sc.get_abs_position(*range_begin); + int abs_end = sc.get_abs_position(*range_end); + + // Proceed only if range positions are not "nowhere". + if (abs_begin != Position::Nowhere && abs_end != Position::Nowhere) { + // Trim range to sentence boundaries + if (abs_begin < 0) { + abs_begin = 0; + } + if (abs_end >= sc.size()) { + abs_end = sc.size() - 1; + } + int range_size = abs_begin - abs_end + 1; + // Proceed only if range isn't empty + if (range_size > 0) { + int n = (match_count_ == MatchAll) ? range_size : match_count_; + // Proceed only if the range actually has enough positions to match + if (n <= range_size) { + if (direction_ == Forward) { + if (iterate(abs_begin, abs_end, 1, *iter_var, context)) { + return Predicate::True(context); + } + } + if (iterate(abs_end, abs_begin, -1, *iter_var, context)) { + return Predicate::True(context); + } + } + } + } + // In case of failure, set iteration variable to Nowhere and return False + iter_var->set_value(Position::Nowhere); + return Predicate::False(context); +} + +bool Iteration::iterate(int start, int stop, int step, Position &p, const FunExecContext &context) const +{ + //TODO: implement + return false; +} + +} /* end ns Wccl */ diff --git a/libwccl/ops/functions/bool/iteration.h b/libwccl/ops/functions/bool/iteration.h new file mode 100644 index 0000000..1b27b9f --- /dev/null +++ b/libwccl/ops/functions/bool/iteration.h @@ -0,0 +1,66 @@ +#ifndef LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H +#define LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H + +#include <libwccl/ops/function.h> +#include <libwccl/values/bool.h> +#include <libwccl/values/position.h> + +namespace Wccl { + +/** + * Abstract base class for a class of operators that iterate over a range. + */ +class Iteration : public Function<Bool> { +public: + typedef boost::shared_ptr<Function<Position> > PosFunctionPtr; + typedef boost::shared_ptr<Function<Bool> > BoolFunctionPtr; + static const int MatchAll = boost::integer_traits<int>::const_min; + typedef enum Direction + { + Forward, + Backward + } Direction; + +protected: + + Iteration( + const PosFunctionPtr& range_begin_expr, + const PosFunctionPtr& range_end_expr, + const VariableAccessor<Position>& iter_var_acc, + const BoolFunctionPtr& condition_expr, + int match_count = MatchAll, + Direction direction = Forward) + : range_begin_expr_(range_begin_expr), + range_end_expr_(range_end_expr), + iter_var_acc_(iter_var_acc), + condition_expr_(condition_expr), + match_count_(match_count), + direction_(direction) + { + BOOST_ASSERT(range_begin_expr_); + BOOST_ASSERT(range_end_expr_); + BOOST_ASSERT(condition_expr_); + BOOST_ASSERT(match_count == MatchAll || match_count > 0); + } + + /** + * Evaluate argument expression and assign the result to underlying variable. + * @returns True. + */ + BaseRetValPtr apply_internal(const FunExecContext& context) const; + + const PosFunctionPtr& range_begin_expr_; + const PosFunctionPtr& range_end_expr_; + const VariableAccessor<Position> iter_var_acc_; + const BoolFunctionPtr& condition_expr_; + const int match_count_; + const Direction direction_; + +private: + bool iterate(int start, int stop, int step, Position& p, const FunExecContext& context) const; +}; + + +} /* end ns Wccl */ + +#endif // LIBWCCL_OPS_FUNCTIONS_BOOL_ITERATION_H -- GitLab