Example #1
0
 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_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;
     }
 }
Example #2
0
 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;
     }
 }