Operator::getOperator()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
/**
4
 * Platine Expression
5
 *
6
 * Platine Expression is an expression parser, evaluator with support of custom
7
 * operators and functions
8
 *
9
 * This content is released under the MIT License (MIT)
10
 *
11
 * Copyright (c) 2020 Platine Expression
12
 * Copyright (c) Alexander Kiryukhin
13
 *
14
 * Permission is hereby granted, free of charge, to any person obtaining a copy
15
 * of this software and associated documentation files (the "Software"), to deal
16
 * in the Software without restriction, including without limitation the rights
17
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
18
 * copies of the Software, and to permit persons to whom the Software is
19
 * furnished to do so, subject to the following conditions:
20
 *
21
 * The above copyright notice and this permission notice shall be included in all
22
 * copies or substantial portions of the Software.
23
 *
24
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
25
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
26
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
27
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
28
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
29
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30
 * SOFTWARE.
31
 */
32
33
/**
34
 * @file Operator.php
35
 *
36
 * The Operator class
37
 *
38
 *  @package    Platine\Expression
39
 *  @author Platine Developers Team
40
 *  @copyright  Copyright (c) 2020
41
 *  @license    http://opensource.org/licenses/MIT  MIT License
42
 *  @link   https://www.platine-php.com
43
 *  @version 1.0.0
44
 *  @filesource
45
 */
46
declare(strict_types=1);
47
48
namespace Platine\Expression;
49
50
use Closure;
51
use Platine\Expression\Exception\IncorrectExpressionException;
52
use ReflectionFunction;
53
54
/**
55
 * @class Operator
56
 * @package Platine\Expression
57
 */
58
class Operator
59
{
60
    /**
61
     * Number of function argument
62
     * @var int
63
     */
64
    protected int $places = 0;
65
66
    /**
67
     * Create new instance
68
     * @param string $operator The operator like =, >=, ..
69
     * @param bool $isRightAssociative Whether the operator is or right associativity
70
     * @param int $priority The priority of the operator
71
     * @param callable $function The function to be called
72
     */
73
    public function __construct(
74
        protected string $operator,
75
        protected bool $isRightAssociative,
76
        protected int $priority,
77
        protected $function
78
    ) {
79
        $this->operator = $operator;
80
        $this->isRightAssociative = $isRightAssociative;
81
        $this->priority = $priority;
82
        $this->function = $function;
83
84
        $reflection = new ReflectionFunction(Closure::fromCallable($function));
85
        $this->places = $reflection->getNumberOfParameters();
86
    }
87
88
    /**
89
     * Execute the expression for this operator
90
     * @param Token[] $stack
91
     * @return Token
92
     */
93
    public function execute(array &$stack): Token
94
    {
95
        if (count($stack) < $this->places) {
96
            throw new IncorrectExpressionException(sprintf(
97
                'Incorrect number of function parameters, [%d] needed',
98
                $this->places
99
            ));
100
        }
101
102
        $args = [];
103
        for ($i = 0; $i < $this->places; $i++) {
104
            $token = array_pop($stack);
105
            if ($token !== null) {
106
                array_unshift($args, $token->getValue());
107
            }
108
        }
109
110
        $result = call_user_func_array($this->function, $args);
111
112
        return new Token(Token::LITERAL, $result);
113
    }
114
115
    /**
116
     * Return the operator
117
     * @return string
118
     */
119
    public function getOperator(): string
120
    {
121
        return $this->operator;
122
    }
123
124
    /**
125
     * Whether is right associative
126
     * @return bool
127
     */
128
    public function isRightAssociative(): bool
129
    {
130
        return $this->isRightAssociative;
131
    }
132
133
    /**
134
     * Return the priority
135
     * @return int
136
     */
137
    public function getPriority(): int
138
    {
139
        return $this->priority;
140
    }
141
142
    /**
143
     * Return the function
144
     * @return callable
145
     */
146
    public function getFunction(): callable
147
    {
148
        return $this->function;
149
    }
150
151
    /**
152
     * Return the number of parameters
153
     * @return int
154
     */
155
    public function getPlaces(): int
156
    {
157
        return $this->places;
158
    }
159
}
160