Skip to content
Snippets Groups Projects
Commit 1050b71d authored by Adam Wardynski's avatar Adam Wardynski
Browse files

Base class for iterations, WIP.

parent 3875a586
Branches
No related merge requests found
......@@ -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
......
#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 */
#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
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment