コード例 #1
0
 public function testParserWithStringConstants()
 {
     $context = new Context();
     $const = 'string constant';
     $context->def('const', $const, 'string');
     $actual = Parser::parse('const', $context);
     $this->assertEquals($const, $actual);
 }
コード例 #2
0
 public function testFunctionDefinitionWithOptionalParams()
 {
     $context = new Context();
     $context->defFunction('func', function ($param1, $param2 = 100) {
         return $param1 + $param2;
     });
     $actual = $context->fn('func', array(3));
     $this->assertEquals(103.0, $actual);
     $actual = $context->fn('func', array(3, 200));
     $this->assertEquals(203.0, $actual);
 }
コード例 #3
0
ファイル: Parser.php プロジェクト: 3nr1c/php-shunting-yard
 /**
  * @param $op
  * @param $lhs
  * @param $rhs
  * @param Context $ctx
  * @return float|int|null
  * @throws RuntimeError
  */
 protected function op($op, $lhs, $rhs, Context $ctx)
 {
     // If there is a custom operator handler function defined in the context, call it instead
     if ($ctx->hasCustomOperatorHandler($op)) {
         $lhsValue = is_object($lhs) ? $lhs->value : null;
         $rhsValue = is_object($rhs) ? $rhs->value : null;
         return $ctx->execCustomOperatorHandler($op, $lhsValue, $rhsValue);
     }
     if ($lhs !== null) {
         $lhs = $lhs->value;
         $rhs = $rhs->value;
         switch ($op) {
             case Token::T_GREATER_EQUAL:
             case Token::T_LESS_EQUAL:
             case Token::T_GREATER:
             case Token::T_LESS:
             case Token::T_PLUS:
             case Token::T_MINUS:
             case Token::T_TIMES:
             case Token::T_DIV:
             case Token::T_MOD:
             case Token::T_POW:
                 if (is_bool($lhs) && is_bool($rhs)) {
                     throw new RuntimeError('run-time error: trying to do a number only operation over two booleans');
                 } else {
                     if (is_bool($lhs) || is_bool($rhs)) {
                         throw new RuntimeError('run-time error: trying to calculate a value out of a decimal and a boolean');
                     }
                 }
                 break;
             case Token::T_EQUAL:
             case Token::T_NOT_EQUAL:
                 if (is_bool($lhs) ^ is_bool($rhs)) {
                     throw new RuntimeError('run-time error: trying to calculate a value out of a decimal and a boolean');
                 }
                 break;
             case Token::T_AND:
             case Token::T_OR:
             case Token::T_XOR:
                 if (!is_bool($lhs) || !is_bool($rhs)) {
                     throw new RuntimeError('run-time error: trying to do a boolean only operation over two numbers');
                 }
                 break;
         }
         switch ($op) {
             case Token::T_AND:
                 return $lhs && $rhs;
             case Token::T_OR:
                 return $lhs || $rhs;
             case Token::T_XOR:
                 return $lhs ^ $rhs;
             case Token::T_GREATER_EQUAL:
                 return $lhs >= $rhs;
             case Token::T_LESS_EQUAL:
                 return $lhs <= $rhs;
             case Token::T_GREATER:
                 return $lhs > $rhs;
             case Token::T_LESS:
                 return $lhs < $rhs;
             case Token::T_EQUAL:
                 return $lhs == $rhs;
             case Token::T_NOT_EQUAL:
                 return $lhs != $rhs;
             case Token::T_PLUS:
                 return $lhs + $rhs;
             case Token::T_MINUS:
                 return $lhs - $rhs;
             case Token::T_TIMES:
                 return $lhs * $rhs;
             case Token::T_DIV:
                 if ($rhs === 0.0) {
                     throw new RuntimeError('run-time error: division by zero');
                 }
                 return $lhs / $rhs;
             case Token::T_MOD:
                 if ($rhs === 0.0) {
                     throw new RuntimeError('run-time error: rest-division by zero');
                 }
                 return (double) $lhs % $rhs;
             case Token::T_POW:
                 return (double) pow($lhs, $rhs);
         }
         // throw?
         return 0;
     }
     switch ($op) {
         case Token::T_NOT:
             return is_null($rhs->value) ? null : (double) (!$rhs->value);
         case Token::T_UNARY_MINUS:
             return is_null($rhs->value) ? null : -$rhs->value;
         case Token::T_UNARY_PLUS:
             return is_null($rhs->value) ? null : +$rhs->value;
     }
 }
コード例 #4
0
 /**
  * @expectedException \Shunt\Exception\ParseError
  */
 public function testParserExceptionSurplusClosingBracket()
 {
     $context = new Context();
     $context->defFunction('pi');
     $equation = 'pi())';
     $actual = Parser::parse($equation, $context);
 }
コード例 #5
0
 /**
  * @expectedException \Shunt\Exception\RuntimeError
  */
 public function testCallNotSetConstantCausesException()
 {
     $context = new Context();
     $context->cs('notdefinedfunction');
 }