Javenue logo

Javenue

Программирование на Java

Информационные технологии

Программа-калькулятор на Perl

"Сколько ты знаешь языков, столько раз ты человек" - подумал я и решил посмотреть на какой-нибудь скриптовый язык.

Выбор довольно большой, но из наиболее нашумевших языков, а именно Python, Ruby, Perl, я решил попробовать последний. Даже не знаю, чем был обоснован мой выбор.

Вашему вниманию предлагается простая программка - "калькулятор" на Perl.

Не судите строго, это все таки первое, что я написал используя Perl. Итак, исходник программки.

$args_len = scalar(@ARGV);
die "1 argument needed" unless $args_len == 1;

($expression) = @ARGV;

unless ($expression =~ /^\d[\+|\-|\*|\/|\d]+\d$/) {
  die "invalid expression (invalid symbols)";
}

if ($expression =~ /[\+\-\*\/]{2,}/) {
  die "invalid expression (duplicate operations)";
}

@numbers = split /(?:[\+|\-|\*|\/])/, $expression;

@signs = split /(?:\d+)/, $expression;
unless (@signs[0]) {
  @signs = @signs[1..$#signs];
}

$changed = 1;
while ($changed) {
  $changed = 0;
  for ($i = 0; $i < = $#signs; $i++) {
    if (@signs[$i] eq "*" || @signs[$i] eq "/") {
      my $first = @numbers[$i];
      my $second = @numbers[$i + 1];
      my $result = &calcula ($first, $second, @signs[$i]);

      print ($first . @signs[$i] . $second . "=" . $result . "\n");
      
      if ($i == 0) {
        if ($i == $#signs) {
          @signs = (); 
        } else {
          @signs = (@signs[$i+1..$#signs]);
        }
      } else {
        if ($i == $#signs) {
          @signs = (@signs[0..$i-1]);
        } else {
          @signs = (@signs[0..$i-1], @signs[$i+1..$#signs]);
        }
      }

      if ($i == 0) {
        if ($i == $#numbers - 1) {
          @numbers = ($result); 
        } else {
          @numbers = ($result, @numbers[$i+2..$#numbers]);
        }
      } else {
        if ($i == $#numbers - 1) {
          @numbers = (@numbers[0..$i-1], $result);
        } else {
          @numbers = (@numbers[0..$i-1], $result, @numbers[$i+2..$#numbers]);
        }
      }

      $changed = 1;
      last;
    }
  }
}

$changed = 1;
while ($changed) {
  $changed = 0;
  for ($i = 0; $i <= $#signs; $i++) {
    if (@signs[$i] eq "+" || @signs[$i] eq "-") {
      my $first = @numbers[$i];
      my $second = @numbers[$i + 1];
      my $result = &calcula ($first, $second, @signs[$i]);

      print ($first . @signs[$i] . $second . "=" . $result . "\n");
      
      if ($i == 0) {
        if ($i == $#signs) {
          @signs = (); 
        } else {
          @signs = (@signs[$i+1..$#signs]);
        }
      } else {
        if ($i == $#signs) {
          @signs = (@signs[0..$i-1]);
        } else {
          @signs = (@signs[0..$i-1], @signs[$i+1..$#signs]);
        }
      }

      if ($i == 0) {
        if ($i == $#numbers - 1) {
          @numbers = ($result); 
        } else {
          @numbers = ($result, @numbers[$i+2..$#numbers]);
        }
      } else {
        if ($i == $#numbers - 1) {
          @numbers = (@numbers[0..$i-1], $result);
        } else {
          @numbers = (@numbers[0..$i-1], $result, @numbers[$i+2..$#numbers]);
        }
      }

      $changed = 1;
      last;
    }
  }
}

print ($expression . "=" . @numbers[0]);

sub calcula {
  my $res;
  my ($lex1, $lex2, $sign) = @_;

  if ($sign eq "+") {
    $res = $lex1 + $lex2;
  } elsif ($sign eq "-") {
    $res = $lex1 - $lex2;
  } elsif ($sign eq "*") {
    $res = $lex1 * $lex2;
  } elsif ($sign eq "/") {
    $res = $lex1 / $lex2;
  } else {
    die "unknown operation";
  }

  return $res;
}

Входящий параметр должен быть один и представлять собой строку из чисел и знаков сложения, вычитания, умножения и деления без пробелов. Например, 2+3*4-8/2+1.

Приоритет операций учитывается.

Код, как вы заметите, очень похож по форматированию на Java код :). Так что буду благодарен за любые советы, особенно идеалогические.


Комментариев: 0

  Выйти

  * для публикации комментариев нужно