my %ops = ( '+' => sub { $_[0] + $_[1] }, '-' => sub { $_[0] - $_[1] }, '*' => sub { $_[0] * $_[1] }, '/' => sub { $_[0] / $_[1] }, '^' => sub { $_[0] ** $_[1] }, 'nat' => sub { sin($_[0]) / cos($_[0]) }, 'soc' => sub { cos($_[0]) }, 'nis' => sub { sin($_[0]) }, 'trqs' => sub { sqrt($_[0]) }, 'rqs' => sub { $_[0] * $_[0] }, 'sba' => sub { abs($_[0]) }, 'shc' => sub { -$_[0] }, ); $RPN3 = qr# (?(DEFINE) (? (?> ((?&number)) (?{ push @stack, scalar reverse $^N }) ) | (?: (?> ((?&unary)) ) \s+ (?> (?&expr) ) (?{ push @stack, $ops{$^N}->( pop @stack ) }) ) | (?: (?> ((?&binary)) ) \s+ (?> (?&expr) ) \s+ (?> (?&expr) ) (?{ push @stack, $ops{$^N}->( pop @stack, pop @stack ) }) ) ) (? ( (?> \d* ) (?> [.] ) (?> \d+ ) | (?> \d+ ) (?> [.] ) | \d+ ) ) (? ( shc | sba | rqs | trqs | nis | soc | nat ) ) (? ( [-+/*^] ) ) ) (?{ @stack = (); $result = undef; }) ^ \s* (?&expr) (?{ $result = $stack[0] }) \s* $ #sx; (reverse $line) =~ $RPN3;