summaryrefslogtreecommitdiff
path: root/src/parse/ttstream.cpp
blob: 32c9a90ac19546b7dc8e3b62b6f434f24c7ddfef (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
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
/*
 * MRustC - Rust Compiler
 * - By John Hodge (Mutabah/thePowersGang)
 *
 * parse/ttstream.cpp
 * - Token-Tree backed token streams
 */
#include "ttstream.hpp"
#include <common.hpp>

TTStream::TTStream(Span parent, const TokenTree& input_tt):
    m_parent_span( new Span(mv$(parent)) )
{
    DEBUG("input_tt = [" << input_tt << "]");
    m_stack.push_back( ::std::make_pair(0, &input_tt) );
}
TTStream::~TTStream()
{
}
Token TTStream::realGetToken()
{
    while(m_stack.size() > 0)
    {
        // If current index is above TT size, go up
        unsigned int& idx = m_stack.back().first;
        assert( m_stack.back().second );
        const TokenTree& tree = *m_stack.back().second;

        if(idx == 0 && tree.is_token()) {
            idx ++;
            m_hygiene_ptr = &tree.hygiene();
            return tree.tok();
        }

        if(idx < tree.size())
        {
            const TokenTree&    subtree = tree[idx];
            idx ++;
            if( subtree.size() == 0 ) {
                m_hygiene_ptr = &subtree.hygiene();
                return subtree.tok().clone();
            }
            else {
                m_stack.push_back( ::std::make_pair(0, &subtree) );
            }
        }
        else {
            m_stack.pop_back();
        }
    }
    //m_hygiene = nullptr;
    return Token(TOK_EOF);
}
Position TTStream::getPosition() const
{
    // TODO: Position associated with the previous/next token?
    return Position("TTStream", 0,0);
}
Ident::Hygiene TTStream::realGetHygiene() const
{
    // Empty.
    if(!m_hygiene_ptr)
        return Ident::Hygiene();
    return *m_hygiene_ptr;
}


TTStreamO::TTStreamO(Span parent, TokenTree input_tt):
    m_input_tt( mv$(input_tt) ),
    m_parent_span( new Span(mv$(parent)) )
{
    m_stack.push_back( ::std::make_pair(0, nullptr) );
}
TTStreamO::~TTStreamO()
{
}
Token TTStreamO::realGetToken()
{
    while(m_stack.size() > 0)
    {
        // If current index is above TT size, go up
        unsigned int& idx = m_stack.back().first;
        TokenTree& tree = (m_stack.back().second ? *m_stack.back().second : m_input_tt);

        if(idx == 0 && tree.is_token()) {
            idx ++;
            m_last_pos = tree.tok().get_pos();
            m_hygiene_ptr = &tree.hygiene();
            return mv$(tree.tok());
        }

        if(idx < tree.size())
        {
            TokenTree& subtree = tree[idx];
            idx ++;
            if( subtree.size() == 0 ) {
                m_last_pos = subtree.tok().get_pos();
                m_hygiene_ptr = &subtree.hygiene();
                return mv$( subtree.tok() );
            }
            else {
                m_stack.push_back( ::std::make_pair(0, &subtree) );
            }
        }
        else {
            m_stack.pop_back();
        }
    }
    return Token(TOK_EOF);
}
Position TTStreamO::getPosition() const
{
    return m_last_pos;
}
Ident::Hygiene TTStreamO::realGetHygiene() const
{
    // Empty.
    if(!m_hygiene_ptr)
        return Ident::Hygiene();
    return *m_hygiene_ptr;
}