Home | History | Annotate | Line # | Download | only in dmd
      1  1.1  mrg /**
      2  1.1  mrg  * Defines lexical tokens.
      3  1.1  mrg  *
      4  1.1  mrg  * Specification: $(LINK2 https://dlang.org/spec/lex.html#tokens, Tokens)
      5  1.1  mrg  *
      6  1.1  mrg  * Copyright:   Copyright (C) 1999-2022 by The D Language Foundation, All Rights Reserved
      7  1.1  mrg  * Authors:     $(LINK2 https://www.digitalmars.com, Walter Bright)
      8  1.1  mrg  * License:     $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
      9  1.1  mrg  * Source:      $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/tokens.d, _tokens.d)
     10  1.1  mrg  * Documentation:  https://dlang.org/phobos/dmd_tokens.html
     11  1.1  mrg  * Coverage:    https://codecov.io/gh/dlang/dmd/src/master/src/dmd/tokens.d
     12  1.1  mrg  */
     13  1.1  mrg 
     14  1.1  mrg module dmd.tokens;
     15  1.1  mrg 
     16  1.1  mrg import core.stdc.ctype;
     17  1.1  mrg import core.stdc.stdio;
     18  1.1  mrg import core.stdc.string;
     19  1.1  mrg import dmd.globals;
     20  1.1  mrg import dmd.identifier;
     21  1.1  mrg import dmd.root.ctfloat;
     22  1.1  mrg import dmd.common.outbuffer;
     23  1.1  mrg import dmd.root.rmem;
     24  1.1  mrg import dmd.root.utf;
     25  1.1  mrg 
     26  1.1  mrg enum TOK : ubyte
     27  1.1  mrg {
     28  1.1  mrg     reserved,
     29  1.1  mrg 
     30  1.1  mrg     // Other
     31  1.1  mrg     leftParenthesis,
     32  1.1  mrg     rightParenthesis,
     33  1.1  mrg     leftBracket,
     34  1.1  mrg     rightBracket,
     35  1.1  mrg     leftCurly,
     36  1.1  mrg     rightCurly,
     37  1.1  mrg     colon,
     38  1.1  mrg     semicolon,
     39  1.1  mrg     dotDotDot,
     40  1.1  mrg     endOfFile,
     41  1.1  mrg     cast_,
     42  1.1  mrg     null_,
     43  1.1  mrg     assert_,
     44  1.1  mrg     true_,
     45  1.1  mrg     false_,
     46  1.1  mrg     throw_,
     47  1.1  mrg     new_,
     48  1.1  mrg     delete_,
     49  1.1  mrg     variable,
     50  1.1  mrg     slice,
     51  1.1  mrg     version_,
     52  1.1  mrg     module_,
     53  1.1  mrg     dollar,
     54  1.1  mrg     template_,
     55  1.1  mrg     typeof_,
     56  1.1  mrg     pragma_,
     57  1.1  mrg     typeid_,
     58  1.1  mrg     comment,
     59  1.1  mrg 
     60  1.1  mrg     // Operators
     61  1.1  mrg     lessThan,
     62  1.1  mrg     greaterThan,
     63  1.1  mrg     lessOrEqual,
     64  1.1  mrg     greaterOrEqual,
     65  1.1  mrg     equal,
     66  1.1  mrg     notEqual,
     67  1.1  mrg     identity,
     68  1.1  mrg     notIdentity,
     69  1.1  mrg     is_,
     70  1.1  mrg 
     71  1.1  mrg     leftShift,
     72  1.1  mrg     rightShift,
     73  1.1  mrg     leftShiftAssign,
     74  1.1  mrg     rightShiftAssign,
     75  1.1  mrg     unsignedRightShift,
     76  1.1  mrg     unsignedRightShiftAssign,
     77  1.1  mrg     concatenateAssign, // ~=
     78  1.1  mrg     add,
     79  1.1  mrg     min,
     80  1.1  mrg     addAssign,
     81  1.1  mrg     minAssign,
     82  1.1  mrg     mul,
     83  1.1  mrg     div,
     84  1.1  mrg     mod,
     85  1.1  mrg     mulAssign,
     86  1.1  mrg     divAssign,
     87  1.1  mrg     modAssign,
     88  1.1  mrg     and,
     89  1.1  mrg     or,
     90  1.1  mrg     xor,
     91  1.1  mrg     andAssign,
     92  1.1  mrg     orAssign,
     93  1.1  mrg     xorAssign,
     94  1.1  mrg     assign,
     95  1.1  mrg     not,
     96  1.1  mrg     tilde,
     97  1.1  mrg     plusPlus,
     98  1.1  mrg     minusMinus,
     99  1.1  mrg     dot,
    100  1.1  mrg     comma,
    101  1.1  mrg     question,
    102  1.1  mrg     andAnd,
    103  1.1  mrg     orOr,
    104  1.1  mrg 
    105  1.1  mrg     // Numeric literals
    106  1.1  mrg     int32Literal,
    107  1.1  mrg     uns32Literal,
    108  1.1  mrg     int64Literal,
    109  1.1  mrg     uns64Literal,
    110  1.1  mrg     int128Literal,
    111  1.1  mrg     uns128Literal,
    112  1.1  mrg     float32Literal,
    113  1.1  mrg     float64Literal,
    114  1.1  mrg     float80Literal,
    115  1.1  mrg     imaginary32Literal,
    116  1.1  mrg     imaginary64Literal,
    117  1.1  mrg     imaginary80Literal,
    118  1.1  mrg 
    119  1.1  mrg     // Char constants
    120  1.1  mrg     charLiteral,
    121  1.1  mrg     wcharLiteral,
    122  1.1  mrg     dcharLiteral,
    123  1.1  mrg 
    124  1.1  mrg     // Leaf operators
    125  1.1  mrg     identifier,
    126  1.1  mrg     string_,
    127  1.1  mrg     this_,
    128  1.1  mrg     super_,
    129  1.1  mrg     error,
    130  1.1  mrg 
    131  1.1  mrg     // Basic types
    132  1.1  mrg     void_,
    133  1.1  mrg     int8,
    134  1.1  mrg     uns8,
    135  1.1  mrg     int16,
    136  1.1  mrg     uns16,
    137  1.1  mrg     int32,
    138  1.1  mrg     uns32,
    139  1.1  mrg     int64,
    140  1.1  mrg     uns64,
    141  1.1  mrg     int128,
    142  1.1  mrg     uns128,
    143  1.1  mrg     float32,
    144  1.1  mrg     float64,
    145  1.1  mrg     float80,
    146  1.1  mrg     imaginary32,
    147  1.1  mrg     imaginary64,
    148  1.1  mrg     imaginary80,
    149  1.1  mrg     complex32,
    150  1.1  mrg     complex64,
    151  1.1  mrg     complex80,
    152  1.1  mrg     char_,
    153  1.1  mrg     wchar_,
    154  1.1  mrg     dchar_,
    155  1.1  mrg     bool_,
    156  1.1  mrg 
    157  1.1  mrg     // Aggregates
    158  1.1  mrg     struct_,
    159  1.1  mrg     class_,
    160  1.1  mrg     interface_,
    161  1.1  mrg     union_,
    162  1.1  mrg     enum_,
    163  1.1  mrg     import_,
    164  1.1  mrg     alias_,
    165  1.1  mrg     override_,
    166  1.1  mrg     delegate_,
    167  1.1  mrg     function_,
    168  1.1  mrg     mixin_,
    169  1.1  mrg     align_,
    170  1.1  mrg     extern_,
    171  1.1  mrg     private_,
    172  1.1  mrg     protected_,
    173  1.1  mrg     public_,
    174  1.1  mrg     export_,
    175  1.1  mrg     static_,
    176  1.1  mrg     final_,
    177  1.1  mrg     const_,
    178  1.1  mrg     abstract_,
    179  1.1  mrg     debug_,
    180  1.1  mrg     deprecated_,
    181  1.1  mrg     in_,
    182  1.1  mrg     out_,
    183  1.1  mrg     inout_,
    184  1.1  mrg     lazy_,
    185  1.1  mrg     auto_,
    186  1.1  mrg     package_,
    187  1.1  mrg     immutable_,
    188  1.1  mrg 
    189  1.1  mrg     // Statements
    190  1.1  mrg     if_,
    191  1.1  mrg     else_,
    192  1.1  mrg     while_,
    193  1.1  mrg     for_,
    194  1.1  mrg     do_,
    195  1.1  mrg     switch_,
    196  1.1  mrg     case_,
    197  1.1  mrg     default_,
    198  1.1  mrg     break_,
    199  1.1  mrg     continue_,
    200  1.1  mrg     with_,
    201  1.1  mrg     synchronized_,
    202  1.1  mrg     return_,
    203  1.1  mrg     goto_,
    204  1.1  mrg     try_,
    205  1.1  mrg     catch_,
    206  1.1  mrg     finally_,
    207  1.1  mrg     asm_,
    208  1.1  mrg     foreach_,
    209  1.1  mrg     foreach_reverse_,
    210  1.1  mrg     scope_,
    211  1.1  mrg     onScopeExit,
    212  1.1  mrg     onScopeFailure,
    213  1.1  mrg     onScopeSuccess,
    214  1.1  mrg 
    215  1.1  mrg     // Contracts
    216  1.1  mrg     invariant_,
    217  1.1  mrg 
    218  1.1  mrg     // Testing
    219  1.1  mrg     unittest_,
    220  1.1  mrg 
    221  1.1  mrg     // Added after 1.0
    222  1.1  mrg     argumentTypes,
    223  1.1  mrg     ref_,
    224  1.1  mrg     macro_,
    225  1.1  mrg 
    226  1.1  mrg     parameters,
    227  1.1  mrg     traits,
    228  1.1  mrg     pure_,
    229  1.1  mrg     nothrow_,
    230  1.1  mrg     gshared,
    231  1.1  mrg     line,
    232  1.1  mrg     file,
    233  1.1  mrg     fileFullPath,
    234  1.1  mrg     moduleString,   // __MODULE__
    235  1.1  mrg     functionString, // __FUNCTION__
    236  1.1  mrg     prettyFunction, // __PRETTY_FUNCTION__
    237  1.1  mrg     shared_,
    238  1.1  mrg     at,
    239  1.1  mrg     pow,
    240  1.1  mrg     powAssign,
    241  1.1  mrg     goesTo,
    242  1.1  mrg     vector,
    243  1.1  mrg     pound,
    244  1.1  mrg 
    245  1.1  mrg     arrow,      // ->
    246  1.1  mrg     colonColon, // ::
    247  1.1  mrg     wchar_tLiteral,
    248  1.1  mrg     endOfLine,  // \n, \r, \u2028, \u2029
    249  1.1  mrg     whitespace,
    250  1.1  mrg 
    251  1.1  mrg     // C only keywords
    252  1.1  mrg     inline,
    253  1.1  mrg     register,
    254  1.1  mrg     restrict,
    255  1.1  mrg     signed,
    256  1.1  mrg     sizeof_,
    257  1.1  mrg     typedef_,
    258  1.1  mrg     unsigned,
    259  1.1  mrg     volatile,
    260  1.1  mrg     _Alignas,
    261  1.1  mrg     _Alignof,
    262  1.1  mrg     _Atomic,
    263  1.1  mrg     _Bool,
    264  1.1  mrg     _Complex,
    265  1.1  mrg     _Generic,
    266  1.1  mrg     _Imaginary,
    267  1.1  mrg     _Noreturn,
    268  1.1  mrg     _Static_assert,
    269  1.1  mrg     _Thread_local,
    270  1.1  mrg 
    271  1.1  mrg     // C only extended keywords
    272  1.1  mrg     _import,
    273  1.1  mrg     __cdecl,
    274  1.1  mrg     __declspec,
    275  1.1  mrg     __stdcall,
    276  1.1  mrg     __attribute__,
    277  1.1  mrg }
    278  1.1  mrg 
    279  1.1  mrg /// Expression nodes
    280  1.1  mrg enum EXP : ubyte
    281  1.1  mrg {
    282  1.1  mrg     reserved,
    283  1.1  mrg 
    284  1.1  mrg     // Other
    285  1.1  mrg     negate,
    286  1.1  mrg     cast_,
    287  1.1  mrg     null_,
    288  1.1  mrg     assert_,
    289  1.1  mrg     true_,
    290  1.1  mrg     false_,
    291  1.1  mrg     array,
    292  1.1  mrg     call,
    293  1.1  mrg     address,
    294  1.1  mrg     type,
    295  1.1  mrg     throw_,
    296  1.1  mrg     new_,
    297  1.1  mrg     delete_,
    298  1.1  mrg     star,
    299  1.1  mrg     symbolOffset,
    300  1.1  mrg     variable,
    301  1.1  mrg     dotVariable,
    302  1.1  mrg     dotIdentifier,
    303  1.1  mrg     dotTemplateInstance,
    304  1.1  mrg     dotType,
    305  1.1  mrg     slice,
    306  1.1  mrg     arrayLength,
    307  1.1  mrg     version_,
    308  1.1  mrg     dollar,
    309  1.1  mrg     template_,
    310  1.1  mrg     dotTemplateDeclaration,
    311  1.1  mrg     declaration,
    312  1.1  mrg     typeof_,
    313  1.1  mrg     pragma_,
    314  1.1  mrg     dSymbol,
    315  1.1  mrg     typeid_,
    316  1.1  mrg     uadd,
    317  1.1  mrg     remove,
    318  1.1  mrg     newAnonymousClass,
    319  1.1  mrg     arrayLiteral,
    320  1.1  mrg     assocArrayLiteral,
    321  1.1  mrg     structLiteral,
    322  1.1  mrg     classReference,
    323  1.1  mrg     thrownException,
    324  1.1  mrg     delegatePointer,
    325  1.1  mrg     delegateFunctionPointer,
    326  1.1  mrg 
    327  1.1  mrg     // Operators
    328  1.1  mrg     lessThan,
    329  1.1  mrg     greaterThan,
    330  1.1  mrg     lessOrEqual,
    331  1.1  mrg     greaterOrEqual,
    332  1.1  mrg     equal,
    333  1.1  mrg     notEqual,
    334  1.1  mrg     identity,
    335  1.1  mrg     notIdentity,
    336  1.1  mrg     index,
    337  1.1  mrg     is_,
    338  1.1  mrg 
    339  1.1  mrg     leftShift,
    340  1.1  mrg     rightShift,
    341  1.1  mrg     leftShiftAssign,
    342  1.1  mrg     rightShiftAssign,
    343  1.1  mrg     unsignedRightShift,
    344  1.1  mrg     unsignedRightShiftAssign,
    345  1.1  mrg     concatenate,
    346  1.1  mrg     concatenateAssign, // ~=
    347  1.1  mrg     concatenateElemAssign,
    348  1.1  mrg     concatenateDcharAssign,
    349  1.1  mrg     add,
    350  1.1  mrg     min,
    351  1.1  mrg     addAssign,
    352  1.1  mrg     minAssign,
    353  1.1  mrg     mul,
    354  1.1  mrg     div,
    355  1.1  mrg     mod,
    356  1.1  mrg     mulAssign,
    357  1.1  mrg     divAssign,
    358  1.1  mrg     modAssign,
    359  1.1  mrg     and,
    360  1.1  mrg     or,
    361  1.1  mrg     xor,
    362  1.1  mrg     andAssign,
    363  1.1  mrg     orAssign,
    364  1.1  mrg     xorAssign,
    365  1.1  mrg     assign,
    366  1.1  mrg     not,
    367  1.1  mrg     tilde,
    368  1.1  mrg     plusPlus,
    369  1.1  mrg     minusMinus,
    370  1.1  mrg     construct,
    371  1.1  mrg     blit,
    372  1.1  mrg     dot,
    373  1.1  mrg     comma,
    374  1.1  mrg     question,
    375  1.1  mrg     andAnd,
    376  1.1  mrg     orOr,
    377  1.1  mrg     prePlusPlus,
    378  1.1  mrg     preMinusMinus,
    379  1.1  mrg 
    380  1.1  mrg     // Leaf operators
    381  1.1  mrg     identifier,
    382  1.1  mrg     string_,
    383  1.1  mrg     this_,
    384  1.1  mrg     super_,
    385  1.1  mrg     halt,
    386  1.1  mrg     tuple,
    387  1.1  mrg     error,
    388  1.1  mrg 
    389  1.1  mrg     // Basic types
    390  1.1  mrg     void_,
    391  1.1  mrg     int64,
    392  1.1  mrg     float64,
    393  1.1  mrg     complex80,
    394  1.1  mrg     char_,
    395  1.1  mrg     import_,
    396  1.1  mrg     delegate_,
    397  1.1  mrg     function_,
    398  1.1  mrg     mixin_,
    399  1.1  mrg     in_,
    400  1.1  mrg     default_,
    401  1.1  mrg     break_,
    402  1.1  mrg     continue_,
    403  1.1  mrg     goto_,
    404  1.1  mrg     scope_,
    405  1.1  mrg 
    406  1.1  mrg     traits,
    407  1.1  mrg     overloadSet,
    408  1.1  mrg     line,
    409  1.1  mrg     file,
    410  1.1  mrg     fileFullPath,
    411  1.1  mrg     moduleString,   // __MODULE__
    412  1.1  mrg     functionString, // __FUNCTION__
    413  1.1  mrg     prettyFunction, // __PRETTY_FUNCTION__
    414  1.1  mrg     shared_,
    415  1.1  mrg     pow,
    416  1.1  mrg     powAssign,
    417  1.1  mrg     vector,
    418  1.1  mrg 
    419  1.1  mrg     voidExpression,
    420  1.1  mrg     cantExpression,
    421  1.1  mrg     showCtfeContext,
    422  1.1  mrg     objcClassReference,
    423  1.1  mrg     vectorArray,
    424  1.1  mrg     arrow,      // ->
    425  1.1  mrg     compoundLiteral, // ( type-name ) { initializer-list }
    426  1.1  mrg     _Generic,
    427  1.1  mrg     interval,
    428  1.1  mrg }
    429  1.1  mrg 
    430  1.1  mrg enum FirstCKeyword = TOK.inline;
    431  1.1  mrg 
    432  1.1  mrg // Assert that all token enum members have consecutive values and
    433  1.1  mrg // that none of them overlap
    434  1.1  mrg static assert(() {
    435  1.1  mrg     foreach (idx, enumName; __traits(allMembers, TOK)) {
    436  1.1  mrg        static if (idx != __traits(getMember, TOK, enumName)) {
    437  1.1  mrg            pragma(msg, "Error: Expected TOK.", enumName, " to be ", idx, " but is ", __traits(getMember, TOK, enumName));
    438  1.1  mrg            static assert(0);
    439  1.1  mrg        }
    440  1.1  mrg     }
    441  1.1  mrg     return true;
    442  1.1  mrg }());
    443  1.1  mrg 
    444  1.1  mrg /****************************************
    445  1.1  mrg  */
    446  1.1  mrg 
    447  1.1  mrg private immutable TOK[] keywords =
    448  1.1  mrg [
    449  1.1  mrg     TOK.this_,
    450  1.1  mrg     TOK.super_,
    451  1.1  mrg     TOK.assert_,
    452  1.1  mrg     TOK.null_,
    453  1.1  mrg     TOK.true_,
    454  1.1  mrg     TOK.false_,
    455  1.1  mrg     TOK.cast_,
    456  1.1  mrg     TOK.new_,
    457  1.1  mrg     TOK.delete_,
    458  1.1  mrg     TOK.throw_,
    459  1.1  mrg     TOK.module_,
    460  1.1  mrg     TOK.pragma_,
    461  1.1  mrg     TOK.typeof_,
    462  1.1  mrg     TOK.typeid_,
    463  1.1  mrg     TOK.template_,
    464  1.1  mrg     TOK.void_,
    465  1.1  mrg     TOK.int8,
    466  1.1  mrg     TOK.uns8,
    467  1.1  mrg     TOK.int16,
    468  1.1  mrg     TOK.uns16,
    469  1.1  mrg     TOK.int32,
    470  1.1  mrg     TOK.uns32,
    471  1.1  mrg     TOK.int64,
    472  1.1  mrg     TOK.uns64,
    473  1.1  mrg     TOK.int128,
    474  1.1  mrg     TOK.uns128,
    475  1.1  mrg     TOK.float32,
    476  1.1  mrg     TOK.float64,
    477  1.1  mrg     TOK.float80,
    478  1.1  mrg     TOK.bool_,
    479  1.1  mrg     TOK.char_,
    480  1.1  mrg     TOK.wchar_,
    481  1.1  mrg     TOK.dchar_,
    482  1.1  mrg     TOK.imaginary32,
    483  1.1  mrg     TOK.imaginary64,
    484  1.1  mrg     TOK.imaginary80,
    485  1.1  mrg     TOK.complex32,
    486  1.1  mrg     TOK.complex64,
    487  1.1  mrg     TOK.complex80,
    488  1.1  mrg     TOK.delegate_,
    489  1.1  mrg     TOK.function_,
    490  1.1  mrg     TOK.is_,
    491  1.1  mrg     TOK.if_,
    492  1.1  mrg     TOK.else_,
    493  1.1  mrg     TOK.while_,
    494  1.1  mrg     TOK.for_,
    495  1.1  mrg     TOK.do_,
    496  1.1  mrg     TOK.switch_,
    497  1.1  mrg     TOK.case_,
    498  1.1  mrg     TOK.default_,
    499  1.1  mrg     TOK.break_,
    500  1.1  mrg     TOK.continue_,
    501  1.1  mrg     TOK.synchronized_,
    502  1.1  mrg     TOK.return_,
    503  1.1  mrg     TOK.goto_,
    504  1.1  mrg     TOK.try_,
    505  1.1  mrg     TOK.catch_,
    506  1.1  mrg     TOK.finally_,
    507  1.1  mrg     TOK.with_,
    508  1.1  mrg     TOK.asm_,
    509  1.1  mrg     TOK.foreach_,
    510  1.1  mrg     TOK.foreach_reverse_,
    511  1.1  mrg     TOK.scope_,
    512  1.1  mrg     TOK.struct_,
    513  1.1  mrg     TOK.class_,
    514  1.1  mrg     TOK.interface_,
    515  1.1  mrg     TOK.union_,
    516  1.1  mrg     TOK.enum_,
    517  1.1  mrg     TOK.import_,
    518  1.1  mrg     TOK.mixin_,
    519  1.1  mrg     TOK.static_,
    520  1.1  mrg     TOK.final_,
    521  1.1  mrg     TOK.const_,
    522  1.1  mrg     TOK.alias_,
    523  1.1  mrg     TOK.override_,
    524  1.1  mrg     TOK.abstract_,
    525  1.1  mrg     TOK.debug_,
    526  1.1  mrg     TOK.deprecated_,
    527  1.1  mrg     TOK.in_,
    528  1.1  mrg     TOK.out_,
    529  1.1  mrg     TOK.inout_,
    530  1.1  mrg     TOK.lazy_,
    531  1.1  mrg     TOK.auto_,
    532  1.1  mrg     TOK.align_,
    533  1.1  mrg     TOK.extern_,
    534  1.1  mrg     TOK.private_,
    535  1.1  mrg     TOK.package_,
    536  1.1  mrg     TOK.protected_,
    537  1.1  mrg     TOK.public_,
    538  1.1  mrg     TOK.export_,
    539  1.1  mrg     TOK.invariant_,
    540  1.1  mrg     TOK.unittest_,
    541  1.1  mrg     TOK.version_,
    542  1.1  mrg     TOK.argumentTypes,
    543  1.1  mrg     TOK.parameters,
    544  1.1  mrg     TOK.ref_,
    545  1.1  mrg     TOK.macro_,
    546  1.1  mrg     TOK.pure_,
    547  1.1  mrg     TOK.nothrow_,
    548  1.1  mrg     TOK.gshared,
    549  1.1  mrg     TOK.traits,
    550  1.1  mrg     TOK.vector,
    551  1.1  mrg     TOK.file,
    552  1.1  mrg     TOK.fileFullPath,
    553  1.1  mrg     TOK.line,
    554  1.1  mrg     TOK.moduleString,
    555  1.1  mrg     TOK.functionString,
    556  1.1  mrg     TOK.prettyFunction,
    557  1.1  mrg     TOK.shared_,
    558  1.1  mrg     TOK.immutable_,
    559  1.1  mrg 
    560  1.1  mrg     // C only keywords
    561  1.1  mrg     TOK.inline,
    562  1.1  mrg     TOK.register,
    563  1.1  mrg     TOK.restrict,
    564  1.1  mrg     TOK.signed,
    565  1.1  mrg     TOK.sizeof_,
    566  1.1  mrg     TOK.typedef_,
    567  1.1  mrg     TOK.unsigned,
    568  1.1  mrg     TOK.volatile,
    569  1.1  mrg     TOK._Alignas,
    570  1.1  mrg     TOK._Alignof,
    571  1.1  mrg     TOK._Atomic,
    572  1.1  mrg     TOK._Bool,
    573  1.1  mrg     TOK._Complex,
    574  1.1  mrg     TOK._Generic,
    575  1.1  mrg     TOK._Imaginary,
    576  1.1  mrg     TOK._Noreturn,
    577  1.1  mrg     TOK._Static_assert,
    578  1.1  mrg     TOK._Thread_local,
    579  1.1  mrg 
    580  1.1  mrg     // C only extended keywords
    581  1.1  mrg     TOK._import,
    582  1.1  mrg     TOK.__cdecl,
    583  1.1  mrg     TOK.__declspec,
    584  1.1  mrg     TOK.__stdcall,
    585  1.1  mrg     TOK.__attribute__,
    586  1.1  mrg ];
    587  1.1  mrg 
    588  1.1  mrg // Initialize the identifier pool
    589  1.1  mrg shared static this() nothrow
    590  1.1  mrg {
    591  1.1  mrg     Identifier.initTable();
    592  1.1  mrg     foreach (kw; keywords)
    593  1.1  mrg     {
    594  1.1  mrg         //printf("keyword[%d] = '%s'\n",kw, Token.tochars[kw].ptr);
    595  1.1  mrg         Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw);
    596  1.1  mrg     }
    597  1.1  mrg }
    598  1.1  mrg 
    599  1.1  mrg /************************************
    600  1.1  mrg  * This is used to pick the C keywords out of the tokens.
    601  1.1  mrg  * If it's not a C keyword, then it's an identifier.
    602  1.1  mrg  */
    603  1.1  mrg static immutable TOK[TOK.max + 1] Ckeywords =
    604  1.1  mrg () {
    605  1.1  mrg     with (TOK)
    606  1.1  mrg     {
    607  1.1  mrg         TOK[TOK.max + 1] tab = identifier;  // default to identifier
    608  1.1  mrg         enum Ckwds = [ auto_, break_, case_, char_, const_, continue_, default_, do_, float64, else_,
    609  1.1  mrg                        enum_, extern_, float32, for_, goto_, if_, inline, int32, int64, register,
    610  1.1  mrg                        restrict, return_, int16, signed, sizeof_, static_, struct_, switch_, typedef_,
    611  1.1  mrg                        union_, unsigned, void_, volatile, while_, asm_,
    612  1.1  mrg                        _Alignas, _Alignof, _Atomic, _Bool, _Complex, _Generic, _Imaginary, _Noreturn,
    613  1.1  mrg                        _Static_assert, _Thread_local, _import, __cdecl, __declspec, __stdcall, __attribute__ ];
    614  1.1  mrg 
    615  1.1  mrg         foreach (kw; Ckwds)
    616  1.1  mrg             tab[kw] = cast(TOK) kw;
    617  1.1  mrg 
    618  1.1  mrg         return tab;
    619  1.1  mrg     }
    620  1.1  mrg } ();
    621  1.1  mrg 
    622  1.1  mrg 
    623  1.1  mrg /***********************************************************
    624  1.1  mrg  */
    625  1.1  mrg extern (C++) struct Token
    626  1.1  mrg {
    627  1.1  mrg     Token* next;
    628  1.1  mrg     Loc loc;
    629  1.1  mrg     const(char)* ptr; // pointer to first character of this token within buffer
    630  1.1  mrg     TOK value;
    631  1.1  mrg     const(char)[] blockComment; // doc comment string prior to this token
    632  1.1  mrg     const(char)[] lineComment; // doc comment for previous token
    633  1.1  mrg 
    634  1.1  mrg     union
    635  1.1  mrg     {
    636  1.1  mrg         // Integers
    637  1.1  mrg         sinteger_t intvalue;
    638  1.1  mrg         uinteger_t unsvalue;
    639  1.1  mrg         // Floats
    640  1.1  mrg         real_t floatvalue;
    641  1.1  mrg 
    642  1.1  mrg         struct
    643  1.1  mrg         {
    644  1.1  mrg             const(char)* ustring; // UTF8 string
    645  1.1  mrg             uint len;
    646  1.1  mrg             ubyte postfix; // 'c', 'w', 'd'
    647  1.1  mrg         }
    648  1.1  mrg 
    649  1.1  mrg         Identifier ident;
    650  1.1  mrg     }
    651  1.1  mrg 
    652  1.1  mrg     extern (D) private static immutable string[TOK.max + 1] tochars =
    653  1.1  mrg     [
    654  1.1  mrg         // Keywords
    655  1.1  mrg         TOK.this_: "this",
    656  1.1  mrg         TOK.super_: "super",
    657  1.1  mrg         TOK.assert_: "assert",
    658  1.1  mrg         TOK.null_: "null",
    659  1.1  mrg         TOK.true_: "true",
    660  1.1  mrg         TOK.false_: "false",
    661  1.1  mrg         TOK.cast_: "cast",
    662  1.1  mrg         TOK.new_: "new",
    663  1.1  mrg         TOK.delete_: "delete",
    664  1.1  mrg         TOK.throw_: "throw",
    665  1.1  mrg         TOK.module_: "module",
    666  1.1  mrg         TOK.pragma_: "pragma",
    667  1.1  mrg         TOK.typeof_: "typeof",
    668  1.1  mrg         TOK.typeid_: "typeid",
    669  1.1  mrg         TOK.template_: "template",
    670  1.1  mrg         TOK.void_: "void",
    671  1.1  mrg         TOK.int8: "byte",
    672  1.1  mrg         TOK.uns8: "ubyte",
    673  1.1  mrg         TOK.int16: "short",
    674  1.1  mrg         TOK.uns16: "ushort",
    675  1.1  mrg         TOK.int32: "int",
    676  1.1  mrg         TOK.uns32: "uint",
    677  1.1  mrg         TOK.int64: "long",
    678  1.1  mrg         TOK.uns64: "ulong",
    679  1.1  mrg         TOK.int128: "cent",
    680  1.1  mrg         TOK.uns128: "ucent",
    681  1.1  mrg         TOK.float32: "float",
    682  1.1  mrg         TOK.float64: "double",
    683  1.1  mrg         TOK.float80: "real",
    684  1.1  mrg         TOK.bool_: "bool",
    685  1.1  mrg         TOK.char_: "char",
    686  1.1  mrg         TOK.wchar_: "wchar",
    687  1.1  mrg         TOK.dchar_: "dchar",
    688  1.1  mrg         TOK.imaginary32: "ifloat",
    689  1.1  mrg         TOK.imaginary64: "idouble",
    690  1.1  mrg         TOK.imaginary80: "ireal",
    691  1.1  mrg         TOK.complex32: "cfloat",
    692  1.1  mrg         TOK.complex64: "cdouble",
    693  1.1  mrg         TOK.complex80: "creal",
    694  1.1  mrg         TOK.delegate_: "delegate",
    695  1.1  mrg         TOK.function_: "function",
    696  1.1  mrg         TOK.is_: "is",
    697  1.1  mrg         TOK.if_: "if",
    698  1.1  mrg         TOK.else_: "else",
    699  1.1  mrg         TOK.while_: "while",
    700  1.1  mrg         TOK.for_: "for",
    701  1.1  mrg         TOK.do_: "do",
    702  1.1  mrg         TOK.switch_: "switch",
    703  1.1  mrg         TOK.case_: "case",
    704  1.1  mrg         TOK.default_: "default",
    705  1.1  mrg         TOK.break_: "break",
    706  1.1  mrg         TOK.continue_: "continue",
    707  1.1  mrg         TOK.synchronized_: "synchronized",
    708  1.1  mrg         TOK.return_: "return",
    709  1.1  mrg         TOK.goto_: "goto",
    710  1.1  mrg         TOK.try_: "try",
    711  1.1  mrg         TOK.catch_: "catch",
    712  1.1  mrg         TOK.finally_: "finally",
    713  1.1  mrg         TOK.with_: "with",
    714  1.1  mrg         TOK.asm_: "asm",
    715  1.1  mrg         TOK.foreach_: "foreach",
    716  1.1  mrg         TOK.foreach_reverse_: "foreach_reverse",
    717  1.1  mrg         TOK.scope_: "scope",
    718  1.1  mrg         TOK.struct_: "struct",
    719  1.1  mrg         TOK.class_: "class",
    720  1.1  mrg         TOK.interface_: "interface",
    721  1.1  mrg         TOK.union_: "union",
    722  1.1  mrg         TOK.enum_: "enum",
    723  1.1  mrg         TOK.import_: "import",
    724  1.1  mrg         TOK.mixin_: "mixin",
    725  1.1  mrg         TOK.static_: "static",
    726  1.1  mrg         TOK.final_: "final",
    727  1.1  mrg         TOK.const_: "const",
    728  1.1  mrg         TOK.alias_: "alias",
    729  1.1  mrg         TOK.override_: "override",
    730  1.1  mrg         TOK.abstract_: "abstract",
    731  1.1  mrg         TOK.debug_: "debug",
    732  1.1  mrg         TOK.deprecated_: "deprecated",
    733  1.1  mrg         TOK.in_: "in",
    734  1.1  mrg         TOK.out_: "out",
    735  1.1  mrg         TOK.inout_: "inout",
    736  1.1  mrg         TOK.lazy_: "lazy",
    737  1.1  mrg         TOK.auto_: "auto",
    738  1.1  mrg         TOK.align_: "align",
    739  1.1  mrg         TOK.extern_: "extern",
    740  1.1  mrg         TOK.private_: "private",
    741  1.1  mrg         TOK.package_: "package",
    742  1.1  mrg         TOK.protected_: "protected",
    743  1.1  mrg         TOK.public_: "public",
    744  1.1  mrg         TOK.export_: "export",
    745  1.1  mrg         TOK.invariant_: "invariant",
    746  1.1  mrg         TOK.unittest_: "unittest",
    747  1.1  mrg         TOK.version_: "version",
    748  1.1  mrg         TOK.argumentTypes: "__argTypes",
    749  1.1  mrg         TOK.parameters: "__parameters",
    750  1.1  mrg         TOK.ref_: "ref",
    751  1.1  mrg         TOK.macro_: "macro",
    752  1.1  mrg         TOK.pure_: "pure",
    753  1.1  mrg         TOK.nothrow_: "nothrow",
    754  1.1  mrg         TOK.gshared: "__gshared",
    755  1.1  mrg         TOK.traits: "__traits",
    756  1.1  mrg         TOK.vector: "__vector",
    757  1.1  mrg         TOK.file: "__FILE__",
    758  1.1  mrg         TOK.fileFullPath: "__FILE_FULL_PATH__",
    759  1.1  mrg         TOK.line: "__LINE__",
    760  1.1  mrg         TOK.moduleString: "__MODULE__",
    761  1.1  mrg         TOK.functionString: "__FUNCTION__",
    762  1.1  mrg         TOK.prettyFunction: "__PRETTY_FUNCTION__",
    763  1.1  mrg         TOK.shared_: "shared",
    764  1.1  mrg         TOK.immutable_: "immutable",
    765  1.1  mrg 
    766  1.1  mrg         TOK.endOfFile: "End of File",
    767  1.1  mrg         TOK.leftCurly: "{",
    768  1.1  mrg         TOK.rightCurly: "}",
    769  1.1  mrg         TOK.leftParenthesis: "(",
    770  1.1  mrg         TOK.rightParenthesis: ")",
    771  1.1  mrg         TOK.leftBracket: "[",
    772  1.1  mrg         TOK.rightBracket: "]",
    773  1.1  mrg         TOK.semicolon: ";",
    774  1.1  mrg         TOK.colon: ":",
    775  1.1  mrg         TOK.comma: ",",
    776  1.1  mrg         TOK.dot: ".",
    777  1.1  mrg         TOK.xor: "^",
    778  1.1  mrg         TOK.xorAssign: "^=",
    779  1.1  mrg         TOK.assign: "=",
    780  1.1  mrg         TOK.lessThan: "<",
    781  1.1  mrg         TOK.greaterThan: ">",
    782  1.1  mrg         TOK.lessOrEqual: "<=",
    783  1.1  mrg         TOK.greaterOrEqual: ">=",
    784  1.1  mrg         TOK.equal: "==",
    785  1.1  mrg         TOK.notEqual: "!=",
    786  1.1  mrg         TOK.not: "!",
    787  1.1  mrg         TOK.leftShift: "<<",
    788  1.1  mrg         TOK.rightShift: ">>",
    789  1.1  mrg         TOK.unsignedRightShift: ">>>",
    790  1.1  mrg         TOK.add: "+",
    791  1.1  mrg         TOK.min: "-",
    792  1.1  mrg         TOK.mul: "*",
    793  1.1  mrg         TOK.div: "/",
    794  1.1  mrg         TOK.mod: "%",
    795  1.1  mrg         TOK.slice: "..",
    796  1.1  mrg         TOK.dotDotDot: "...",
    797  1.1  mrg         TOK.and: "&",
    798  1.1  mrg         TOK.andAnd: "&&",
    799  1.1  mrg         TOK.or: "|",
    800  1.1  mrg         TOK.orOr: "||",
    801  1.1  mrg         TOK.tilde: "~",
    802  1.1  mrg         TOK.dollar: "$",
    803  1.1  mrg         TOK.plusPlus: "++",
    804  1.1  mrg         TOK.minusMinus: "--",
    805  1.1  mrg         TOK.question: "?",
    806  1.1  mrg         TOK.variable: "var",
    807  1.1  mrg         TOK.addAssign: "+=",
    808  1.1  mrg         TOK.minAssign: "-=",
    809  1.1  mrg         TOK.mulAssign: "*=",
    810  1.1  mrg         TOK.divAssign: "/=",
    811  1.1  mrg         TOK.modAssign: "%=",
    812  1.1  mrg         TOK.leftShiftAssign: "<<=",
    813  1.1  mrg         TOK.rightShiftAssign: ">>=",
    814  1.1  mrg         TOK.unsignedRightShiftAssign: ">>>=",
    815  1.1  mrg         TOK.andAssign: "&=",
    816  1.1  mrg         TOK.orAssign: "|=",
    817  1.1  mrg         TOK.concatenateAssign: "~=",
    818  1.1  mrg         TOK.identity: "is",
    819  1.1  mrg         TOK.notIdentity: "!is",
    820  1.1  mrg         TOK.identifier: "identifier",
    821  1.1  mrg         TOK.at: "@",
    822  1.1  mrg         TOK.pow: "^^",
    823  1.1  mrg         TOK.powAssign: "^^=",
    824  1.1  mrg         TOK.goesTo: "=>",
    825  1.1  mrg         TOK.pound: "#",
    826  1.1  mrg         TOK.arrow: "->",
    827  1.1  mrg         TOK.colonColon: "::",
    828  1.1  mrg 
    829  1.1  mrg         // For debugging
    830  1.1  mrg         TOK.error: "error",
    831  1.1  mrg         TOK.string_: "string",
    832  1.1  mrg         TOK.onScopeExit: "scope(exit)",
    833  1.1  mrg         TOK.onScopeSuccess: "scope(success)",
    834  1.1  mrg         TOK.onScopeFailure: "scope(failure)",
    835  1.1  mrg 
    836  1.1  mrg         // Finish up
    837  1.1  mrg         TOK.reserved: "reserved",
    838  1.1  mrg         TOK.comment: "comment",
    839  1.1  mrg         TOK.int32Literal: "int32v",
    840  1.1  mrg         TOK.uns32Literal: "uns32v",
    841  1.1  mrg         TOK.int64Literal: "int64v",
    842  1.1  mrg         TOK.uns64Literal: "uns64v",
    843  1.1  mrg         TOK.int128Literal: "int128v",
    844  1.1  mrg         TOK.uns128Literal: "uns128v",
    845  1.1  mrg         TOK.float32Literal: "float32v",
    846  1.1  mrg         TOK.float64Literal: "float64v",
    847  1.1  mrg         TOK.float80Literal: "float80v",
    848  1.1  mrg         TOK.imaginary32Literal: "imaginary32v",
    849  1.1  mrg         TOK.imaginary64Literal: "imaginary64v",
    850  1.1  mrg         TOK.imaginary80Literal: "imaginary80v",
    851  1.1  mrg         TOK.charLiteral: "charv",
    852  1.1  mrg         TOK.wcharLiteral: "wcharv",
    853  1.1  mrg         TOK.dcharLiteral: "dcharv",
    854  1.1  mrg         TOK.wchar_tLiteral: "wchar_tv",
    855  1.1  mrg         TOK.endOfLine: "\\n",
    856  1.1  mrg         TOK.whitespace: "whitespace",
    857  1.1  mrg 
    858  1.1  mrg         // C only keywords
    859  1.1  mrg         TOK.inline    : "inline",
    860  1.1  mrg         TOK.register  : "register",
    861  1.1  mrg         TOK.restrict  : "restrict",
    862  1.1  mrg         TOK.signed    : "signed",
    863  1.1  mrg         TOK.sizeof_   : "sizeof",
    864  1.1  mrg         TOK.typedef_  : "typedef",
    865  1.1  mrg         TOK.unsigned  : "unsigned",
    866  1.1  mrg         TOK.volatile  : "volatile",
    867  1.1  mrg         TOK._Alignas  : "_Alignas",
    868  1.1  mrg         TOK._Alignof  : "_Alignof",
    869  1.1  mrg         TOK._Atomic   : "_Atomic",
    870  1.1  mrg         TOK._Bool     : "_Bool",
    871  1.1  mrg         TOK._Complex  : "_Complex",
    872  1.1  mrg         TOK._Generic  : "_Generic",
    873  1.1  mrg         TOK._Imaginary: "_Imaginary",
    874  1.1  mrg         TOK._Noreturn : "_Noreturn",
    875  1.1  mrg         TOK._Static_assert : "_Static_assert",
    876  1.1  mrg         TOK._Thread_local  : "_Thread_local",
    877  1.1  mrg 
    878  1.1  mrg         // C only extended keywords
    879  1.1  mrg         TOK._import       : "__import",
    880  1.1  mrg         TOK.__cdecl        : "__cdecl",
    881  1.1  mrg         TOK.__declspec     : "__declspec",
    882  1.1  mrg         TOK.__stdcall      : "__stdcall",
    883  1.1  mrg         TOK.__attribute__  : "__attribute__",
    884  1.1  mrg     ];
    885  1.1  mrg 
    886  1.1  mrg     static assert(() {
    887  1.1  mrg         foreach (s; tochars)
    888  1.1  mrg             assert(s.length);
    889  1.1  mrg         return true;
    890  1.1  mrg     }());
    891  1.1  mrg 
    892  1.1  mrg nothrow:
    893  1.1  mrg 
    894  1.1  mrg     int isKeyword() const
    895  1.1  mrg     {
    896  1.1  mrg         foreach (kw; keywords)
    897  1.1  mrg         {
    898  1.1  mrg             if (kw == value)
    899  1.1  mrg                 return 1;
    900  1.1  mrg         }
    901  1.1  mrg         return 0;
    902  1.1  mrg     }
    903  1.1  mrg 
    904  1.1  mrg     /****
    905  1.1  mrg      * Set to contents of ptr[0..length]
    906  1.1  mrg      * Params:
    907  1.1  mrg      *  ptr = pointer to string
    908  1.1  mrg      *  length = length of string
    909  1.1  mrg      */
    910  1.1  mrg     void setString(const(char)* ptr, size_t length)
    911  1.1  mrg     {
    912  1.1  mrg         auto s = cast(char*)mem.xmalloc_noscan(length + 1);
    913  1.1  mrg         memcpy(s, ptr, length);
    914  1.1  mrg         s[length] = 0;
    915  1.1  mrg         ustring = s;
    916  1.1  mrg         len = cast(uint)length;
    917  1.1  mrg         postfix = 0;
    918  1.1  mrg     }
    919  1.1  mrg 
    920  1.1  mrg     /****
    921  1.1  mrg      * Set to contents of buf
    922  1.1  mrg      * Params:
    923  1.1  mrg      *  buf = string (not zero terminated)
    924  1.1  mrg      */
    925  1.1  mrg     void setString(const ref OutBuffer buf)
    926  1.1  mrg     {
    927  1.1  mrg         setString(cast(const(char)*)buf[].ptr, buf.length);
    928  1.1  mrg     }
    929  1.1  mrg 
    930  1.1  mrg     /****
    931  1.1  mrg      * Set to empty string
    932  1.1  mrg      */
    933  1.1  mrg     void setString()
    934  1.1  mrg     {
    935  1.1  mrg         ustring = "";
    936  1.1  mrg         len = 0;
    937  1.1  mrg         postfix = 0;
    938  1.1  mrg     }
    939  1.1  mrg 
    940  1.1  mrg     extern (C++) const(char)* toChars() const
    941  1.1  mrg     {
    942  1.1  mrg         __gshared char[3 + 3 * floatvalue.sizeof + 1] buffer;
    943  1.1  mrg         const(char)* p = &buffer[0];
    944  1.1  mrg         switch (value)
    945  1.1  mrg         {
    946  1.1  mrg         case TOK.int32Literal:
    947  1.1  mrg             sprintf(&buffer[0], "%d", cast(int)intvalue);
    948  1.1  mrg             break;
    949  1.1  mrg         case TOK.uns32Literal:
    950  1.1  mrg         case TOK.wchar_tLiteral:
    951  1.1  mrg             sprintf(&buffer[0], "%uU", cast(uint)unsvalue);
    952  1.1  mrg             break;
    953  1.1  mrg         case TOK.wcharLiteral:
    954  1.1  mrg         case TOK.dcharLiteral:
    955  1.1  mrg         case TOK.charLiteral:
    956  1.1  mrg             {
    957  1.1  mrg                 OutBuffer buf;
    958  1.1  mrg                 buf.writeSingleCharLiteral(cast(dchar) intvalue);
    959  1.1  mrg                 buf.writeByte('\0');
    960  1.1  mrg                 p = buf.extractSlice().ptr;
    961  1.1  mrg             }
    962  1.1  mrg             break;
    963  1.1  mrg         case TOK.int64Literal:
    964  1.1  mrg             sprintf(&buffer[0], "%lldL", cast(long)intvalue);
    965  1.1  mrg             break;
    966  1.1  mrg         case TOK.uns64Literal:
    967  1.1  mrg             sprintf(&buffer[0], "%lluUL", cast(ulong)unsvalue);
    968  1.1  mrg             break;
    969  1.1  mrg         case TOK.float32Literal:
    970  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    971  1.1  mrg             strcat(&buffer[0], "f");
    972  1.1  mrg             break;
    973  1.1  mrg         case TOK.float64Literal:
    974  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    975  1.1  mrg             break;
    976  1.1  mrg         case TOK.float80Literal:
    977  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    978  1.1  mrg             strcat(&buffer[0], "L");
    979  1.1  mrg             break;
    980  1.1  mrg         case TOK.imaginary32Literal:
    981  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    982  1.1  mrg             strcat(&buffer[0], "fi");
    983  1.1  mrg             break;
    984  1.1  mrg         case TOK.imaginary64Literal:
    985  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    986  1.1  mrg             strcat(&buffer[0], "i");
    987  1.1  mrg             break;
    988  1.1  mrg         case TOK.imaginary80Literal:
    989  1.1  mrg             CTFloat.sprint(&buffer[0], 'g', floatvalue);
    990  1.1  mrg             strcat(&buffer[0], "Li");
    991  1.1  mrg             break;
    992  1.1  mrg         case TOK.string_:
    993  1.1  mrg             {
    994  1.1  mrg                 OutBuffer buf;
    995  1.1  mrg                 buf.writeByte('"');
    996  1.1  mrg                 for (size_t i = 0; i < len;)
    997  1.1  mrg                 {
    998  1.1  mrg                     dchar c;
    999  1.1  mrg                     utf_decodeChar(ustring[0 .. len], i, c);
   1000  1.1  mrg                     writeCharLiteral(buf, c);
   1001  1.1  mrg                 }
   1002  1.1  mrg                 buf.writeByte('"');
   1003  1.1  mrg                 if (postfix)
   1004  1.1  mrg                     buf.writeByte(postfix);
   1005  1.1  mrg                 buf.writeByte(0);
   1006  1.1  mrg                 p = buf.extractSlice().ptr;
   1007  1.1  mrg             }
   1008  1.1  mrg             break;
   1009  1.1  mrg         case TOK.identifier:
   1010  1.1  mrg         case TOK.enum_:
   1011  1.1  mrg         case TOK.struct_:
   1012  1.1  mrg         case TOK.import_:
   1013  1.1  mrg         case TOK.wchar_:
   1014  1.1  mrg         case TOK.dchar_:
   1015  1.1  mrg         case TOK.bool_:
   1016  1.1  mrg         case TOK.char_:
   1017  1.1  mrg         case TOK.int8:
   1018  1.1  mrg         case TOK.uns8:
   1019  1.1  mrg         case TOK.int16:
   1020  1.1  mrg         case TOK.uns16:
   1021  1.1  mrg         case TOK.int32:
   1022  1.1  mrg         case TOK.uns32:
   1023  1.1  mrg         case TOK.int64:
   1024  1.1  mrg         case TOK.uns64:
   1025  1.1  mrg         case TOK.int128:
   1026  1.1  mrg         case TOK.uns128:
   1027  1.1  mrg         case TOK.float32:
   1028  1.1  mrg         case TOK.float64:
   1029  1.1  mrg         case TOK.float80:
   1030  1.1  mrg         case TOK.imaginary32:
   1031  1.1  mrg         case TOK.imaginary64:
   1032  1.1  mrg         case TOK.imaginary80:
   1033  1.1  mrg         case TOK.complex32:
   1034  1.1  mrg         case TOK.complex64:
   1035  1.1  mrg         case TOK.complex80:
   1036  1.1  mrg         case TOK.void_:
   1037  1.1  mrg             p = ident.toChars();
   1038  1.1  mrg             break;
   1039  1.1  mrg         default:
   1040  1.1  mrg             p = toChars(value);
   1041  1.1  mrg             break;
   1042  1.1  mrg         }
   1043  1.1  mrg         return p;
   1044  1.1  mrg     }
   1045  1.1  mrg 
   1046  1.1  mrg     static const(char)* toChars(TOK value)
   1047  1.1  mrg     {
   1048  1.1  mrg         return toString(value).ptr;
   1049  1.1  mrg     }
   1050  1.1  mrg 
   1051  1.1  mrg     extern (D) static string toString(TOK value) pure nothrow @nogc @safe
   1052  1.1  mrg     {
   1053  1.1  mrg         return tochars[value];
   1054  1.1  mrg     }
   1055  1.1  mrg }
   1056  1.1  mrg 
   1057  1.1  mrg /**
   1058  1.1  mrg  * Write a character, using a readable escape sequence if needed
   1059  1.1  mrg  *
   1060  1.1  mrg  * Useful for printing "" string literals in e.g. error messages, ddoc, or the `.stringof` property
   1061  1.1  mrg  *
   1062  1.1  mrg  * Params:
   1063  1.1  mrg  *   buf = buffer to append character in
   1064  1.1  mrg  *   c = code point to write
   1065  1.1  mrg  */
   1066  1.1  mrg nothrow
   1067  1.1  mrg void writeCharLiteral(ref OutBuffer buf, dchar c)
   1068  1.1  mrg {
   1069  1.1  mrg     switch (c)
   1070  1.1  mrg     {
   1071  1.1  mrg         case '\0':
   1072  1.1  mrg             buf.writestring("\\0");
   1073  1.1  mrg             break;
   1074  1.1  mrg         case '\n':
   1075  1.1  mrg             buf.writestring("\\n");
   1076  1.1  mrg             break;
   1077  1.1  mrg         case '\r':
   1078  1.1  mrg             buf.writestring("\\r");
   1079  1.1  mrg             break;
   1080  1.1  mrg         case '\t':
   1081  1.1  mrg             buf.writestring("\\t");
   1082  1.1  mrg             break;
   1083  1.1  mrg         case '\b':
   1084  1.1  mrg             buf.writestring("\\b");
   1085  1.1  mrg             break;
   1086  1.1  mrg         case '\f':
   1087  1.1  mrg             buf.writestring("\\f");
   1088  1.1  mrg             break;
   1089  1.1  mrg         case '"':
   1090  1.1  mrg         case '\\':
   1091  1.1  mrg             buf.writeByte('\\');
   1092  1.1  mrg             goto default;
   1093  1.1  mrg         default:
   1094  1.1  mrg             if (c <= 0xFF)
   1095  1.1  mrg             {
   1096  1.1  mrg                 if (isprint(c))
   1097  1.1  mrg                     buf.writeByte(c);
   1098  1.1  mrg                 else
   1099  1.1  mrg                     buf.printf("\\x%02x", c);
   1100  1.1  mrg             }
   1101  1.1  mrg             else if (c <= 0xFFFF)
   1102  1.1  mrg                 buf.printf("\\u%04x", c);
   1103  1.1  mrg             else
   1104  1.1  mrg                 buf.printf("\\U%08x", c);
   1105  1.1  mrg             break;
   1106  1.1  mrg     }
   1107  1.1  mrg }
   1108  1.1  mrg 
   1109  1.1  mrg unittest
   1110  1.1  mrg {
   1111  1.1  mrg     OutBuffer buf;
   1112  1.1  mrg     foreach(dchar d; "a\n\r\t\b\f\0\x11\u7233\U00017233"d)
   1113  1.1  mrg     {
   1114  1.1  mrg         writeCharLiteral(buf, d);
   1115  1.1  mrg     }
   1116  1.1  mrg     assert(buf.extractSlice() == `a\n\r\t\b\f\0\x11\u7233\U00017233`);
   1117  1.1  mrg }
   1118  1.1  mrg 
   1119  1.1  mrg /**
   1120  1.1  mrg  * Write a single-quoted character literal
   1121  1.1  mrg  *
   1122  1.1  mrg  * Useful for printing '' char literals in e.g. error messages, ddoc, or the `.stringof` property
   1123  1.1  mrg  *
   1124  1.1  mrg  * Params:
   1125  1.1  mrg  *   buf = buffer to append character in
   1126  1.1  mrg  *   c = code point to write
   1127  1.1  mrg  */
   1128  1.1  mrg nothrow
   1129  1.1  mrg void writeSingleCharLiteral(ref OutBuffer buf, dchar c)
   1130  1.1  mrg {
   1131  1.1  mrg     buf.writeByte('\'');
   1132  1.1  mrg     if (c == '\'')
   1133  1.1  mrg         buf.writeByte('\\');
   1134  1.1  mrg 
   1135  1.1  mrg     if (c == '"')
   1136  1.1  mrg         buf.writeByte('"');
   1137  1.1  mrg     else
   1138  1.1  mrg         writeCharLiteral(buf, c);
   1139  1.1  mrg 
   1140  1.1  mrg     buf.writeByte('\'');
   1141  1.1  mrg }
   1142  1.1  mrg 
   1143  1.1  mrg unittest
   1144  1.1  mrg {
   1145  1.1  mrg     OutBuffer buf;
   1146  1.1  mrg     writeSingleCharLiteral(buf, '\'');
   1147  1.1  mrg     assert(buf.extractSlice() == `'\''`);
   1148  1.1  mrg     buf.reset();
   1149  1.1  mrg     writeSingleCharLiteral(buf, '"');
   1150  1.1  mrg     assert(buf.extractSlice() == `'"'`);
   1151  1.1  mrg     buf.reset();
   1152  1.1  mrg     writeSingleCharLiteral(buf, '\n');
   1153  1.1  mrg     assert(buf.extractSlice() == `'\n'`);
   1154  1.1  mrg }
   1155