#!/usr/bin/env perl use strict; use warnings; use feature 'say'; sub do_calc { my ($op, $acc, @args) = @_; for my $arg (@args) { $acc += $arg if $op eq '+'; $acc -= $arg if $op eq '-'; $acc *= $arg if $op eq '*'; $acc /= $arg if $op eq '/'; } return $acc; } sub calc { my $exp = shift; die 'oops!' unless $exp =~ m/\(([\+-\/\*])([0-9 \.-]+)\)/; return do_calc($1, split ' ', $2); } sub pn { my $exp = shift; my $old = $exp; $exp =~ s/(\([\+-\/\*] [0-9 \.-]+\))/calc($1)/eg; die "oops! i'm stuck" if $exp eq $old; return $exp if $exp =~ m/^[0-9 \.-]+$/; return pn($exp); } say pn($ARGV[0]);