审查视图

vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Calculation/Token/Stack.php 3.2 KB
郭盛 authored
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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
<?php

namespace PhpOffice\PhpSpreadsheet\Calculation\Token;

use PhpOffice\PhpSpreadsheet\Calculation\Calculation;

class Stack
{
    /**
     * The parser stack for formulae.
     *
     * @var mixed[]
     */
    private $stack = [];

    /**
     * Count of entries in the parser stack.
     *
     * @var int
     */
    private $count = 0;

    /**
     * Return the number of entries on the stack.
     *
     * @return int
     */
    public function count()
    {
        return $this->count;
    }

    /**
     * Push a new entry onto the stack.
     *
     * @param mixed $type
     * @param mixed $value
     * @param mixed $reference
     * @param null|string $storeKey will store the result under this alias
     * @param null|string $onlyIf will only run computation if the matching
     *      store key is true
     * @param null|string $onlyIfNot will only run computation if the matching
     *      store key is false
     */
    public function push(
        $type,
        $value,
        $reference = null,
        $storeKey = null,
        $onlyIf = null,
        $onlyIfNot = null
    ) {
        $stackItem = $this->getStackItem($type, $value, $reference, $storeKey, $onlyIf, $onlyIfNot);

        $this->stack[$this->count++] = $stackItem;

        if ($type == 'Function') {
            $localeFunction = Calculation::localeFunc($value);
            if ($localeFunction != $value) {
                $this->stack[($this->count - 1)]['localeValue'] = $localeFunction;
            }
        }
    }

    public function getStackItem(
        $type,
        $value,
        $reference = null,
        $storeKey = null,
        $onlyIf = null,
        $onlyIfNot = null
    ) {
        $stackItem = [
            'type' => $type,
            'value' => $value,
            'reference' => $reference,
        ];

        if (isset($storeKey)) {
            $stackItem['storeKey'] = $storeKey;
        }

        if (isset($onlyIf)) {
            $stackItem['onlyIf'] = $onlyIf;
        }

        if (isset($onlyIfNot)) {
            $stackItem['onlyIfNot'] = $onlyIfNot;
        }

        return $stackItem;
    }

    /**
     * Pop the last entry from the stack.
     *
     * @return mixed
     */
    public function pop()
    {
        if ($this->count > 0) {
            return $this->stack[--$this->count];
        }

        return null;
    }

    /**
     * Return an entry from the stack without removing it.
     *
     * @param int $n number indicating how far back in the stack we want to look
     *
     * @return mixed
     */
    public function last($n = 1)
    {
        if ($this->count - $n < 0) {
            return null;
        }

        return $this->stack[$this->count - $n];
    }

    /**
     * Clear the stack.
     */
    public function clear()
    {
        $this->stack = [];
        $this->count = 0;
    }

    public function __toString()
    {
        $str = 'Stack: ';
        foreach ($this->stack as $index => $item) {
            if ($index > $this->count - 1) {
                break;
            }
            $value = $item['value'] ?? 'no value';
            while (is_array($value)) {
                $value = array_pop($value);
            }
            $str .= $value . ' |> ';
        }

        return $str;
    }
}