1""" 
    2    pygments.lexers.nimrod 
    3    ~~~~~~~~~~~~~~~~~~~~~~ 
    4 
    5    Lexer for the Nim language (formerly known as Nimrod). 
    6 
    7    :copyright: Copyright 2006-2025 by the Pygments team, see AUTHORS. 
    8    :license: BSD, see LICENSE for details. 
    9""" 
    10 
    11import re 
    12 
    13from pygments.lexer import RegexLexer, include, default, bygroups 
    14from pygments.token import Text, Comment, Operator, Keyword, Name, String, \ 
    15    Number, Punctuation, Error 
    16 
    17__all__ = ['NimrodLexer'] 
    18 
    19 
    20class NimrodLexer(RegexLexer): 
    21    """ 
    22    For Nim source code. 
    23    """ 
    24 
    25    name = 'Nimrod' 
    26    url = 'http://nim-lang.org/' 
    27    aliases = ['nimrod', 'nim'] 
    28    filenames = ['*.nim', '*.nimrod'] 
    29    mimetypes = ['text/x-nim'] 
    30    version_added = '1.5' 
    31 
    32    flags = re.MULTILINE | re.IGNORECASE 
    33 
    34    def underscorize(words): 
    35        newWords = [] 
    36        new = [] 
    37        for word in words: 
    38            for ch in word: 
    39                new.append(ch) 
    40                new.append("_?") 
    41            newWords.append(''.join(new)) 
    42            new = [] 
    43        return "|".join(newWords) 
    44 
    45    keywords = [ 
    46        'addr', 'and', 'as', 'asm', 'bind', 'block', 'break', 'case', 
    47        'cast', 'concept', 'const', 'continue', 'converter', 'defer', 'discard', 
    48        'distinct', 'div', 'do', 'elif', 'else', 'end', 'enum', 'except', 
    49        'export', 'finally', 'for', 'if', 'in', 'yield', 'interface', 
    50        'is', 'isnot', 'iterator', 'let', 'mixin', 'mod', 
    51        'not', 'notin', 'object', 'of', 'or', 'out', 'ptr', 'raise', 
    52        'ref', 'return', 'shl', 'shr', 'static', 'try', 
    53        'tuple', 'type', 'using', 'when', 'while', 'xor' 
    54    ] 
    55 
    56    keywordsPseudo = [ 
    57        'nil', 'true', 'false' 
    58    ] 
    59 
    60    opWords = [ 
    61        'and', 'or', 'not', 'xor', 'shl', 'shr', 'div', 'mod', 'in', 
    62        'notin', 'is', 'isnot' 
    63    ] 
    64 
    65    types = [ 
    66        'int', 'int8', 'int16', 'int32', 'int64', 'float', 'float32', 'float64', 
    67        'bool', 'char', 'range', 'array', 'seq', 'set', 'string' 
    68    ] 
    69 
    70    tokens = { 
    71        'root': [ 
    72            # Comments 
    73            (r'##\[', String.Doc, 'doccomment'), 
    74            (r'##.*$', String.Doc), 
    75            (r'#\[', Comment.Multiline, 'comment'), 
    76            (r'#.*$', Comment), 
    77 
    78            # Pragmas 
    79            (r'\{\.', String.Other, 'pragma'), 
    80 
    81            # Operators 
    82            (r'[*=><+\-/@$~&%!?|\\\[\]]', Operator), 
    83            (r'\.\.|\.|,|\[\.|\.\]|\{\.|\.\}|\(\.|\.\)|\{|\}|\(|\)|:|\^|`|;', 
    84             Punctuation), 
    85 
    86            # Case statement branch 
    87            (r'(\n\s*)(of)(\s)', bygroups(Text.Whitespace, Keyword, 
    88                                          Text.Whitespace), 'casebranch'), 
    89 
    90            # Strings 
    91            (r'(?:[\w]+)"', String, 'rdqs'), 
    92            (r'"""', String.Double, 'tdqs'), 
    93            ('"', String, 'dqs'), 
    94 
    95            # Char 
    96            ("'", String.Char, 'chars'), 
    97 
    98            # Keywords 
    99            (rf'({underscorize(opWords)})\b', Operator.Word), 
    100            (r'(proc|func|method|macro|template)(\s)(?![(\[\]])', 
    101             bygroups(Keyword, Text.Whitespace), 'funcname'), 
    102            (rf'({underscorize(keywords)})\b', Keyword), 
    103            (r'({})\b'.format(underscorize(['from', 'import', 'include', 'export'])), 
    104             Keyword.Namespace), 
    105            (r'(v_?a_?r)\b', Keyword.Declaration), 
    106            (rf'({underscorize(types)})\b', Name.Builtin), 
    107            (rf'({underscorize(keywordsPseudo)})\b', Keyword.Pseudo), 
    108 
    109            # Identifiers 
    110            (r'\b((?![_\d])\w)(((?!_)\w)|(_(?!_)\w))*', Name), 
    111 
    112            # Numbers 
    113            (r'[0-9][0-9_]*(?=([e.]|\'f(32|64)))', 
    114             Number.Float, ('float-suffix', 'float-number')), 
    115            (r'0x[a-f0-9][a-f0-9_]*', Number.Hex, 'int-suffix'), 
    116            (r'0b[01][01_]*', Number.Bin, 'int-suffix'), 
    117            (r'0o[0-7][0-7_]*', Number.Oct, 'int-suffix'), 
    118            (r'[0-9][0-9_]*', Number.Integer, 'int-suffix'), 
    119 
    120            # Whitespace 
    121            (r'\s+', Text.Whitespace), 
    122            (r'.+$', Error), 
    123        ], 
    124        'chars': [ 
    125            (r'\\([\\abcefnrtvl"\']|x[a-f0-9]{2}|[0-9]{1,3})', String.Escape), 
    126            (r"'", String.Char, '#pop'), 
    127            (r".", String.Char) 
    128        ], 
    129        'strings': [ 
    130            (r'(?<!\$)\$(\d+|#|\w+)+', String.Interpol), 
    131            (r'[^\\\'"$\n]+', String), 
    132            # quotes, dollars and backslashes must be parsed one at a time 
    133            (r'[\'"\\]', String), 
    134            # unhandled string formatting sign 
    135            (r'\$', String) 
    136            # newlines are an error (use "nl" state) 
    137        ], 
    138        'doccomment': [ 
    139            (r'[^\]#]+', String.Doc), 
    140            (r'##\[', String.Doc, '#push'), 
    141            (r'\]##', String.Doc, '#pop'), 
    142            (r'[\]#]', String.Doc), 
    143        ], 
    144        'comment': [ 
    145            (r'[^\]#]+', Comment.Multiline), 
    146            (r'#\[', Comment.Multiline, '#push'), 
    147            (r'\]#', Comment.Multiline, '#pop'), 
    148            (r'[\]#]', Comment.Multiline), 
    149        ], 
    150        'dqs': [ 
    151            (r'\\([\\abcefnrtvl"\']|\n|x[a-f0-9]{2}|[0-9]{1,3})', 
    152             String.Escape), 
    153            (r'"', String, '#pop'), 
    154            include('strings') 
    155        ], 
    156        'rdqs': [ 
    157            (r'"(?!")', String, '#pop'), 
    158            (r'""', String.Escape), 
    159            include('strings') 
    160        ], 
    161        'tdqs': [ 
    162            (r'"""', String.Double, '#pop'), 
    163            include('strings'), 
    164            (r'\n', String.Double) 
    165        ], 
    166        'funcname': [ 
    167            (r'((?![\d_])\w)(((?!_)\w)|(_(?!_)\w))*', Name.Function, '#pop'), 
    168            (r'`.+`', Name.Function, '#pop') 
    169        ], 
    170        'nl': [ 
    171            (r'\n', String) 
    172        ], 
    173        'float-number': [ 
    174            (r'\.(?!\.)[0-9_]*[f]*', Number.Float), 
    175            (r'e[+-]?[0-9][0-9_]*', Number.Float), 
    176            default('#pop') 
    177        ], 
    178        'float-suffix': [ 
    179            (r'\'f(32|64)', Number.Float), 
    180            default('#pop') 
    181        ], 
    182        'int-suffix': [ 
    183            (r'\'i(32|64)', Number.Integer.Long), 
    184            (r'\'i(8|16)', Number.Integer), 
    185            default('#pop') 
    186        ], 
    187        'casebranch': [ 
    188            (r',', Punctuation), 
    189            (r'[\n ]+', Text.Whitespace), 
    190            (r':', Operator, '#pop'), 
    191            (r'\w+|[^:]', Name.Label), 
    192        ], 
    193        'pragma': [ 
    194            (r'[:,]', Text), 
    195            (r'[\n ]+', Text.Whitespace), 
    196            (r'\.\}', String.Other, '#pop'), 
    197            (r'\w+|\W+|[^.}]', String.Other), 
    198        ], 
    199    }