1"""
2    pygments.lexers.zig
3    ~~~~~~~~~~~~~~~~~~~
4
5    Lexers for Zig.
6
7    :copyright: Copyright 2006-2021 by the Pygments team, see AUTHORS.
8    :license: BSD, see LICENSE for details.
9"""
10
11from pygments.lexer import RegexLexer, words
12from pygments.token import Comment, Operator, Keyword, Name, String, \
13    Number, Punctuation, Whitespace
14
15__all__ = ['ZigLexer']
16
17
18class ZigLexer(RegexLexer):
19    """
20    For `Zig <http://www.ziglang.org>`_ source code.
21
22    grammar: https://ziglang.org/documentation/master/#Grammar
23    """
24    name = 'Zig'
25    aliases = ['zig']
26    filenames = ['*.zig']
27    mimetypes = ['text/zig']
28
29    type_keywords = (
30        words(('bool', 'f16', 'f32', 'f64', 'f128', 'void', 'noreturn', 'type',
31               'anyerror', 'promise', 'i0', 'u0', 'isize',  'usize', 'comptime_int',
32               'comptime_float', 'c_short', 'c_ushort', 'c_int', 'c_uint', 'c_long',
33               'c_ulong', 'c_longlong', 'c_ulonglong', 'c_longdouble', 'c_void'
34               'i8', 'u8', 'i16', 'u16', 'i32', 'u32', 'i64', 'u64', 'i128',
35               'u128'), suffix=r'\b'),
36        Keyword.Type)
37
38    storage_keywords = (
39        words(('const', 'var', 'extern', 'packed', 'export', 'pub', 'noalias',
40               'inline', 'comptime', 'nakedcc', 'stdcallcc', 'volatile', 'allowzero',
41               'align', 'linksection', 'threadlocal'), suffix=r'\b'),
42        Keyword.Reserved)
43
44    structure_keywords = (
45        words(('struct', 'enum', 'union', 'error'), suffix=r'\b'),
46        Keyword)
47
48    statement_keywords = (
49        words(('break', 'return', 'continue', 'asm', 'defer', 'errdefer',
50               'unreachable', 'try', 'catch', 'async', 'await', 'suspend',
51               'resume', 'cancel'), suffix=r'\b'),
52        Keyword)
53
54    conditional_keywords = (
55        words(('if', 'else', 'switch', 'and', 'or', 'orelse'), suffix=r'\b'),
56        Keyword)
57
58    repeat_keywords = (
59        words(('while', 'for'), suffix=r'\b'),
60        Keyword)
61
62    other_keywords = (
63        words(('fn', 'usingnamespace', 'test'), suffix=r'\b'),
64        Keyword)
65
66    constant_keywords = (
67        words(('true', 'false', 'null', 'undefined'), suffix=r'\b'),
68        Keyword.Constant)
69
70    tokens = {
71        'root': [
72            (r'\n', Whitespace),
73            (r'\s+', Whitespace),
74            (r'//.*?\n', Comment.Single),
75
76            # Keywords
77            statement_keywords,
78            storage_keywords,
79            structure_keywords,
80            repeat_keywords,
81            type_keywords,
82            constant_keywords,
83            conditional_keywords,
84            other_keywords,
85
86            # Floats
87            (r'0x[0-9a-fA-F]+\.[0-9a-fA-F]+([pP][\-+]?[0-9a-fA-F]+)?', Number.Float),
88            (r'0x[0-9a-fA-F]+\.?[pP][\-+]?[0-9a-fA-F]+', Number.Float),
89            (r'[0-9]+\.[0-9]+([eE][-+]?[0-9]+)?', Number.Float),
90            (r'[0-9]+\.?[eE][-+]?[0-9]+', Number.Float),
91
92            # Integers
93            (r'0b[01]+', Number.Bin),
94            (r'0o[0-7]+', Number.Oct),
95            (r'0x[0-9a-fA-F]+', Number.Hex),
96            (r'[0-9]+', Number.Integer),
97
98            # Identifier
99            (r'@[a-zA-Z_]\w*', Name.Builtin),
100            (r'[a-zA-Z_]\w*', Name),
101
102            # Characters
103            (r'\'\\\'\'', String.Escape),
104            (r'\'\\(x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{6}|[nr\\t\'"])\'',
105             String.Escape),
106            (r'\'[^\\\']\'', String),
107
108            # Strings
109            (r'\\\\[^\n]*', String.Heredoc),
110            (r'c\\\\[^\n]*', String.Heredoc),
111            (r'c?"', String, 'string'),
112
113            # Operators, Punctuation
114            (r'[+%=><|^!?/\-*&~:]', Operator),
115            (r'[{}()\[\],.;]', Punctuation)
116        ],
117        'string': [
118            (r'\\(x[a-fA-F0-9]{2}|u[a-fA-F0-9]{4}|U[a-fA-F0-9]{6}|[nr\\t\'"])',
119             String.Escape),
120            (r'[^\\"\n]+', String),
121            (r'"', String, '#pop')
122        ]
123    }
124