PreviewBuffer::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 5
ccs 4
cts 4
cp 1
rs 10
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Remorhaz\Lexer\Runtime\IO;
6
7
use function array_slice;
8
9
final class PreviewBuffer implements PreviewBufferInterface
10
{
11
12
    /**
13
     * @var SymbolReaderInterface
14
     */
15
    private $input;
16
17
    /**
18
     * @var SymbolInterface[]
19
     * @psalm-var array<int,SymbolInterface>
20
     */
21
    private $buffer = [];
22
23
    /**
24
     * @var int
25
     */
26
    private $previewOffset;
27
28
    /**
29
     * @var int
30
     */
31
    private $tokenOffset;
32
33 29
    public function __construct(SymbolReaderInterface $input)
34
    {
35 29
        $this->input = $input;
36 29
        $this->tokenOffset = $input->getOffset();
37 29
        $this->previewOffset = $this->tokenOffset;
38 29
    }
39
40 10
    public function getPreviewSymbol(): SymbolInterface
41
    {
42 10
        if (!isset($this->buffer[$this->previewOffset])) {
43 5
            $this->buffer[$this->previewOffset] = $this->input->read();
44
        }
45
46 10
        return $this->buffer[$this->previewOffset];
47
    }
48
49 5
    public function resetPreview(): void
50
    {
51 5
        $this->previewOffset = $this->tokenOffset;
52 5
    }
53
54 18
    public function previewNext(): void
55
    {
56 18
        if (!isset($this->buffer[$this->previewOffset])) {
57 18
            $this->buffer[$this->previewOffset] = $this->input->read();
58
        }
59 18
        $this->previewOffset++;
60 18
    }
61
62 8
    public function previewPrevious(): void
63
    {
64 8
        if ($this->previewOffset == $this->tokenOffset) {
65 2
            throw new Exception\InvalidPreviewOffsetException($this->tokenOffset);
66
        }
67 6
        $this->previewOffset--;
68 6
    }
69
70
    /**
71
     * @return bool
72
     * @psalm-pure
73
     */
74 4
    public function isFinished(): bool
75
    {
76 4
        return !isset($this->buffer[$this->previewOffset]) && $this->input->isFinished();
77
    }
78
79 8
    public function acceptLexeme(): LexemeInterface
80
    {
81 8
        $length = $this->previewOffset - $this->tokenOffset;
82 8
        $lexeme = new Lexeme(...array_slice($this->buffer, $this->tokenOffset, $length));
83 7
        $this->tokenOffset = $this->previewOffset;
84
85 7
        return $lexeme;
86
    }
87
88
    /**
89
     * @return LexemeInterface
90
     * @psalm-pure
91
     */
92 8
    public function getEmptyLexeme(): LexemeInterface
93
    {
94 8
        if (isset($this->buffer[$this->previewOffset])) {
95 2
            $symbol = $this->buffer[$this->previewOffset];
96
97 2
            return EmptyLexeme::fromOffsets(...$symbol->getLexeme()->getStartOffsets());
98
        }
99
100 6
        return $this->input->getEmptyLexeme();
101
    }
102
}
103