aboutsummaryrefslogtreecommitdiff
path: root/src/main/java/org/shedlang/compiler/tokeniser/TokenIterator.java
blob: 4d1cd5df5183dac48c63ddd262d2eea635e4a7e5 (plain)
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
package org.shedlang.compiler.tokeniser;

import org.zwobble.sourcetext.SourcePosition;

import java.util.List;

public class TokenIterator<TTokenType> {
    private final InfinitelyPaddedIterator<Token<TTokenType>> tokens;

    public TokenIterator(List<Token<TTokenType>> tokens, Token<TTokenType> end) {
        this.tokens = new InfinitelyPaddedIterator<>(tokens, end);
    }

    public void skip(TTokenType tokenType) {
        nextValue(tokenType);
    }

    public Token<TTokenType> next(TTokenType tokenType) {
        var token = tokens.get();
        if (token.tokenType().equals(tokenType)) {
            tokens.moveNext();
            return token;
        } else {
            throw new UnexpectedTokenException(
                tokenType.toString(),
                token
            );
        }
    }

    public String nextValue(TTokenType tokenType) {
        return this.next(tokenType).value().toString();
    }

    public boolean isNext(TTokenType tokenType) {
        return tokens.get().tokenType().equals(tokenType);
    }

    public boolean isNext(TTokenType tokenType1, TTokenType tokenType2) {
        return tokens.get().tokenType().equals(tokenType1) &&
            tokens.get(1).tokenType().equals(tokenType2);
    }

    public boolean trySkip(TTokenType tokenType) {
        if (isNext(tokenType)) {
            tokens.moveNext();
            return true;
        } else {
            return false;
        }
    }

    public Token<TTokenType> peek() {
        return tokens.get();
    }

    public Token<TTokenType> peek(int offset) {
        return tokens.get(offset);
    }

    public SourcePosition startPosition() {
        return tokens.get().sourceRange().start();
    }

    public SourcePosition endPosition() {
        if (tokens.isAtStart()) {
            return startPosition();
        } else {
            return tokens.get(-1).sourceRange().end();
        }
    }
}