chengkun
2025-09-12 26c5c0296e7c094f9a7ae4a4bb3c975796992eaf
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
<?php
 
namespace PhpOffice\PhpSpreadsheet\Calculation\Token;
 
use PhpOffice\PhpSpreadsheet\Calculation\Calculation;
use PhpOffice\PhpSpreadsheet\Calculation\Engine\BranchPruner;
 
class Stack
{
    private BranchPruner $branchPruner;
 
    /**
     * The parser stack for formulae.
     *
     * @var mixed[]
     */
    private array $stack = [];
 
    /**
     * Count of entries in the parser stack.
     */
    private int $count = 0;
 
    public function __construct(BranchPruner $branchPruner)
    {
        $this->branchPruner = $branchPruner;
    }
 
    /**
     * Return the number of entries on the stack.
     */
    public function count(): int
    {
        return $this->count;
    }
 
    /**
     * Push a new entry onto the stack.
     */
    public function push(string $type, mixed $value, ?string $reference = null): void
    {
        $stackItem = $this->getStackItem($type, $value, $reference);
        $this->stack[$this->count++] = $stackItem;
 
        if ($type === 'Function') {
            $localeFunction = Calculation::localeFunc($value);
            if ($localeFunction != $value) {
                $this->stack[($this->count - 1)]['localeValue'] = $localeFunction;
            }
        }
    }
 
    public function pushStackItem(array $stackItem): void
    {
        $this->stack[$this->count++] = $stackItem;
    }
 
    public function getStackItem(string $type, mixed $value, ?string $reference = null): array
    {
        $stackItem = [
            'type' => $type,
            'value' => $value,
            'reference' => $reference,
        ];
 
        // will store the result under this alias
        $storeKey = $this->branchPruner->currentCondition();
        if (isset($storeKey) || $reference === 'NULL') {
            $stackItem['storeKey'] = $storeKey;
        }
 
        // will only run computation if the matching store key is true
        $onlyIf = $this->branchPruner->currentOnlyIf();
        if (isset($onlyIf) || $reference === 'NULL') {
            $stackItem['onlyIf'] = $onlyIf;
        }
 
        // will only run computation if the matching store key is false
        $onlyIfNot = $this->branchPruner->currentOnlyIfNot();
        if (isset($onlyIfNot) || $reference === 'NULL') {
            $stackItem['onlyIfNot'] = $onlyIfNot;
        }
 
        return $stackItem;
    }
 
    /**
     * Pop the last entry from the stack.
     */
    public function pop(): ?array
    {
        if ($this->count > 0) {
            return $this->stack[--$this->count];
        }
 
        return null;
    }
 
    /**
     * Return an entry from the stack without removing it.
     */
    public function last(int $n = 1): ?array
    {
        if ($this->count - $n < 0) {
            return null;
        }
 
        return $this->stack[$this->count - $n];
    }
 
    /**
     * Clear the stack.
     */
    public function clear(): void
    {
        $this->stack = [];
        $this->count = 0;
    }
}