summaryrefslogtreecommitdiff
path: root/tools/standalone_miri/lex.hpp
blob: 1d1b5c2a9ab08521e422ae20ebcf2d9032dbbd8b (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
/*
 * mrustc Standalone MIRI
 * - by John Hodge (Mutabah)
 *
 * lex.hpp
 * - Simple lexer for MIR files (HEADER)
 */
#pragma once
#include <string>
#include <fstream>

enum class TokenClass
{
    Eof,
    Symbol,
    Ident,
    Integer,
    Real,
    String,
    ByteString,
    Lifetime,
};

struct Token
{
    TokenClass  type;
    ::std::string   strval;
    union {
        double  real_val;
        uint64_t    int_val;
    } numbers;

    bool operator==(TokenClass tc) const;
    bool operator!=(TokenClass tc) const { return !(*this == tc); }
    bool operator==(char c) const;
    bool operator!=(char c) const { return !(*this == c); }
    bool operator==(const char* s) const;
    bool operator!=(const char* s) const { return !(*this == s); }

    uint64_t integer() const;
    double real() const;

    friend ::std::ostream& operator<<(::std::ostream& os, const Token& x);
};

class Lexer
{
    ::std::string   m_filename;
    unsigned m_cur_line;
    ::std::ifstream m_if;
    Token   m_cur;
    bool    m_next_valid = false;
    Token   m_next;
public:
    Lexer(const ::std::string& path);


    const Token& next() const;
    const Token& lookahead();
    Token consume();
    void check(TokenClass tc);
    void check(char ch);
    void check(const char* s);
    Token check_consume(TokenClass tc) { check(tc); return consume(); }
    Token check_consume(char ch) { check(ch); return consume(); }
    Token check_consume(const char* s) { check(s); return consume(); }
    bool consume_if(char ch) { if(next() == ch) { consume(); return true; } return false; }
    bool consume_if(const char* s) { if(next() == s) { consume(); return true; } return false; }

    friend ::std::ostream& operator<<(::std::ostream& os, const Lexer& x);

private:
    void advance();

    ::std::string parse_string();
};