Data-Formula

 view release on metacpan or  search on metacpan

lib/Data/Formula.pm  view on Meta::CPAN

package Data::Formula;

use warnings;
use strict;
use utf8;
use 5.010;

use List::MoreUtils qw(any);
use Moose;
use MooseX::StrictConstructor;
use Carp qw(croak);

our $VERSION = '0.02';
our @CARP_NOT;

my %operators = (
    '+' => {
        method => 'plus',
        calc   => 'plus',
        prio   => 10,
    },
    '-' => {
        method => 'minus',
        calc   => 'minus',
        prio   => 10,
    },
    '*' => {
        method => 'multiply',
        calc   => 'multiply',
        prio   => 50,
    },
    '/' => {
        method => 'divide',
        calc   => 'divide',
        prio   => 50,
    },
    '(' => {method => 'bracket_left',},
    ')' => {method => 'bracket_right',},
);

has 'variables'      => (is => 'rw', isa => 'ArrayRef', default    => sub {[]});
has 'formula'        => (is => 'ro', isa => 'Str',      default    => sub {[]});
has '_tokens'        => (is => 'ro', isa => 'ArrayRef', lazy_build => 1,);
has '_rpn'           => (is => 'ro', isa => 'ArrayRef', lazy_build => 1,);
has '_op_indent'     => (is => 'rw', isa => 'Int',      default    => 0,);
has 'used_variables' => (is => 'ro', isa => 'ArrayRef', lazy_build => 1,);

has 'on_error' => (
    is        => 'rw',
    predicate => 'has_on_error',
    clearer   => 'clear_on_error',
);
has 'on_missing_token' => (
    is        => 'rw',
    predicate => 'has_on_missing_token',
    clearer   => 'clear_on_missing_token',
);

sub _indented_operator {
    my ($self, $op) = @_;
    return {
        name => $op,
        %{$operators{$op}},
        prio => ($operators{$op}->{prio} + ($self->_op_indent * 100)),
    };
}

sub _build__rpn {
    my ($self) = @_;

    my $rpn = [];
    my $ops = [];
    foreach my $token (@{$self->_tokens}) {
        if ($operators{$token}) {
            my $rpn_method = '_rpn_method_' . $operators{$token}->{method};
            ($rpn, $ops) = $self->$rpn_method($rpn, $ops);
        }
        else {
            push(@$rpn, $token);
        }
    }

    return [@$rpn, reverse(@$ops)];
}

sub _rpn_method_plus {
    my ($self, $rpn, $ops) = @_;
    return $self->rpn_standard_operator('+', $rpn, $ops);
}

sub _rpn_method_minus {
    my ($self, $rpn, $ops) = @_;
    return $self->rpn_standard_operator('-', $rpn, $ops);
}

sub _rpn_method_multiply {
    my ($self, $rpn, $ops) = @_;
    return $self->rpn_standard_operator('*', $rpn, $ops);
}

sub _rpn_method_divide {
    my ($self, $rpn, $ops) = @_;
    return $self->rpn_standard_operator('/', $rpn, $ops);
}

sub rpn_standard_operator {



( run in 1.461 second using v1.01-cache-2.11-cpan-39bf76dae61 )