Search code examples
phpmathrpn

Error RPN in PHP


I'm trying to use RPN in order to do a simple calculator in PHP. I tried to follow the wiki description and several tutorial in order to do it but i'm currently meeting a an issue with the first Operand. I can't assign it with the end().

My issue come from the line $nb1 = end($stack);

<?php

function add($stack, $nb1, $nb2)
{
    array_push($stack, $nb1 + $nb2);
    $result = $nb1 + $nb2;
    echo $nb1 . ' + ' . $nb2 . ' = ' . $result . "\n";
}

function sub($stack, $nb1, $nb2)
{
    array_push($stack, $nb1 - $nb2);
    $result = $nb1 - $nb2;
    echo $nb1 . ' - ' . $nb2 . ' = ' . $result . "\n";
}

function div($stack, $nb1, $nb2)
{
    array_push($stack, $nb1 / $nb2);
    $result = $nb1 / $nb2;
    echo $nb1 . ' / ' . $nb2 . ' = ' . $result . "\n";
}

function mul($stack, $nb1, $nb2)
{
    array_push($stack, $nb1 * $nb2);
    $result = $nb1 * $nb2;
    echo $nb1 . ' * ' . $nb2 . ' = ' . $result . "\n";
}

function calc($input)
{
$stack = array();
$token = explode(" ", trim($input));
$count = count($token);
// echo $count . "\n";
// print_r($token);

for ($i = 0; $i < $count; $i++) {
    $tokenNUm = "";

    if (is_numeric($token[$i])) {
        array_push($stack, $token[$i]);
        print_r($token);
    } else {
        $nb2 = end($stack);
        array_pop($stack);
        $nb1 = end($stack);
        array_pop($stack);
        echo "nb1 : ". $nb1 . "\n";
        echo "nb2 : ". $nb2 . "\n";

        switch($token[$i]) {
        case '+':
            add($stack, $nb1, $nb2);
        case '-':
            sub($stack, $nb1, $nb2);
        case '/':
            div($stack, $nb1, $nb2);
        case '*':
            mul($stack, $nb1, $nb2);
        default:
            die('Error');
        }
    }
    return end($stack);
    }
}

echo "Final result = " . calc($argv[1]) . "\n";

Solution

  • Not diving too deep into the logic I can point out on couple mistakes you made:

    1. Your return end($stack); is inside the for loop. Basically, your loop will only run the first iteration and then exits the function.
    2. You have to put break; in every case block, otherwise it will execute every single function in the switch block and die with error:

      switch($token[$i]) {
          case '+':
              add($stack, $nb1, $nb2);
              break;
          case '-':
              sub($stack, $nb1, $nb2);
              break;
          case '/':
              div($stack, $nb1, $nb2);
              break;
          case '*':
              mul($stack, $nb1, $nb2);
              break;
          default:
              die('Error');
      }
      

    Hope these would help.

    Update:

    Forgot to mention that you have to run you script like that php rpn.php "1 + 2" because you are using $argv[1]. Assuming rpn.php is the name of your file. Here is the DEMO. Try running it with and without my suggestions, you will see the difference. It doesn't fix your algorithm but it fixes the error you were talking about.