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