NAME

   Math::Calc::Parser - Parse and evaluate mathematical expressions

SYNOPSIS

     use Math::Calc::Parser 'calc';
     use utf8; # for π in source code

     my $result = calc '2 + 2'; # 4
     my $result = calc 'int rand 5'; # Random integer between 0 and 4
     my $result = calc 'sqrt -1'; # i
     my $result = calc '0xff << 2'; # 1020
     my $result = calc '1/0'; # Division by 0 exception

     # Class methods
     my $result = Math::Calc::Parser->evaluate('2 + 2'); # 4
     my $result = Math::Calc::Parser->evaluate('3π^2'); # 29.608813203268
     my $result = Math::Calc::Parser->evaluate('0.7(ln 4)'); # 0.970406052783923

     # With more advanced error handling
     my $result = Math::Calc::Parser->try_evaluate('rand(abs'); # undef (Mismatched parentheses)
     if (defined $result) {
       print "Result: $result\n";
     } else {
       print "Error: ".Math::Calc::Parser->error."\n";
     }

     # Or as an object for more control
     my $parser = Math::Calc::Parser->new;
     $parser->add_functions(triple => { args => 1, code => sub { $_[0]*3 } });
     $parser->add_functions(pow => { args => 2, code => sub { $_[0] ** $_[1] });
     $parser->add_functions(one => sub { 1 }, two => sub { 2 }, three => sub { 3 });

     my $result = $parser->evaluate('2(triple one)'); # 2*(1*3) = 6
     my $result = $parser->evaluate('pow(triple two, three)'); # (2*3)^3 = 216
     my $result = $parser->try_evaluate('triple triple'); # undef (Malformed expression)
     die $parser->error unless defined $result;

     $parser->remove_functions('π', 'e');
     $parser->evaluate('3π'); # Invalid function exception

DESCRIPTION

   Math::Calc::Parser is a simplified mathematical expression evaluator
   with support for complex and trigonometric operations, implicit
   multiplication, and perlish "parentheses optional" functions, while
   being safe for arbitrary user input. It parses input strings into a
   structure based on Reverse Polish notation
   <http://en.wikipedia.org/wiki/Reverse_Polish_notation> (RPN), and then
   evaluates the result. The list of recognized functions may be
   customized using "add_functions" and "remove_functions".

FUNCTIONS

calc

     use Math::Calc::Parser 'calc';
     my $result = calc '2+2';

     $ perl -MMath::Calc::Parser=calc -E 'say calc "2+2"'
     $ perl -Math -e '2+2'

   Compact exportable function wrapping "evaluate" for string expressions.
   Throws an exception on error. See ath for easy compact one-liners.

METHODS

   Aside from add_functions and remove_functions, all methods can be
   called as class methods, and will act on a singleton object with the
   default functions available.

new

     my $parser = Math::Calc::Parser->new;

   Creates a new Math::Calc::Parser object.

parse

     my $parsed = Math::Calc::Parser->parse('5 / e^(i*pi)');
     my $parsed = $parser->parse('3pi');

   Parses a mathematical expression. On success, returns an array
   reference representation of the expression in RPN notation which can be
   passed to "evaluate". Throws an exception on failure.

evaluate

     my $result = Math::Calc::Parser->evaluate($parsed);
     my $result = Math::Calc::Parser->evaluate('log rand 7');
     my $result = $parser->evaluate('round 13/3');

   Evaluates a mathematical expression. The argument can be either an
   arrayref from "parse" or a string expression which will be passed to
   "parse". Returns the result of the expression on success or throws an
   exception on failure.

try_evaluate

     if (defined (my $result = Math::Calc::Parser->try_evaluate('floor 2.5'))) {
       print "Result: $result\n";
     } else {
       print "Error: ".Math::Calc::Parser->error."\n";
     }

     if (defined (my $result = $parser->try_evaluate('log(5'))) {
           print "Result: $result\n";
     } else {
           print "Error: ".$parser->error."\n";
     }

   Same as "evaluate" but instead of throwing an exception on failure,
   returns undef. The "error" method can then be used to retrieve the
   error message. The error message for the most recent "try_evaluate"
   call can also be retrieved from the package variable
   $Math::Calc::Parser::ERROR.

error

     my $result = Math::Calc::Parser->try_evaluate('(i');
     die Math::Calc::Parser->error unless defined $result;
     my $result = $parser->try_evaluate('2//');
     die $parser->error unless defined $result;

   Returns the error message after a failed "try_evaluate".

add_functions

     $parser->add_functions(
       my_function => { args => 5, code => sub { return grep { $_ > 0 } @_; } },
       other_function => sub { 20 }
     );

   Adds functions to be recognized by the parser object. Keys are function
   names which must start with an alphabetic character and consist only of
   word characters
   <http://perldoc.perl.org/perlrecharclass.html#Word-characters>. Values
   are either a hashref containing args and code keys, or a coderef that
   is assumed to be a 0-argument function. args must be an integer greater
   than or equal to 0. code or the passed coderef will be called with the
   numeric operands passed as parameters, and must either return a numeric
   result or throw an exception. Non-numeric results will be cast to
   numbers in the usual perl fashion, and undefined results will throw an
   evaluation error.

remove_functions

     $parser->remove_functions('rand','nonexistent');

   Removes functions from the parser object if they exist. Can be used to
   remove default functions as well as functions previously added with
   "add_functions".

OPERATORS

   Math::Calc::Parser recognizes the following operators with their usual
   mathematical definitions.

     +, -, *, /, %, ^, !, <<, >>

   Note: + and - can represent both binary addition/subtraction and unary
   negation.

DEFAULT FUNCTIONS

   Math::Calc::Parser parses several functions by default, which can be
   customized using "add_functions" or "remove_functions" on an object
   instance.

   abs

     Absolute value.

   acos

   asin

   atan

     Inverse sine, cosine, and tangent.

   ceil

     Round up to nearest integer.

   cos

     Cosine.

   e

     Euler's number.

   floor

     Round down to nearest integer.

   i

     Imaginary unit.

   int

     Cast (truncate) to integer.

   ln

     Natural log.

   log

     Log base 10.

   logn

     Log with arbitrary base given as second argument.

   pi

     π

   π

     π (this must be the decoded Unicode character)

   rand

     Random value between 0 and 1 (exclusive of 1).

   round

     Round to nearest integer, with halfway cases rounded away from zero.

   sin

     Sine.

   sqrt

     Square root.

   tan

     Tangent.

CAVEATS

   While parentheses are optional for functions with 0 or 1 argument, they
   are required when a comma is used to separate multiple arguments.

   Due to the nature of handling complex numbers, the evaluated result may
   be a Math::Complex object. These objects can be directly printed or
   used in numeric operations but may be more difficult to use in
   comparisons.

   Operators that are not defined to operate on complex numbers will
   return the result of the operation on the real components of their
   operands. This includes the operators <<, >>, %, and !.

BUGS

   Report any issues on the public bugtracker.

AUTHOR

   Dan Book, [email protected]

COPYRIGHT AND LICENSE

   Copyright 2015, Dan Book.

   This library is free software; you may redistribute it and/or modify it
   under the terms of the Artistic License version 2.0.

SEE ALSO

   Math::Complex