1 /** 2 * Defines lexical tokens. 3 * 4 * Specification: $(LINK2 https://dlang.org/spec/lex.html#tokens, Tokens) 5 * 6 * Copyright: Copyright (C) 1999-2020 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 14 module dmd.tokens; 15 16 import core.stdc.ctype; 17 import core.stdc.stdio; 18 import core.stdc..string; 19 import dmd.globals; 20 import dmd.identifier; 21 import dmd.root.ctfloat; 22 import dmd.root.outbuffer; 23 import dmd.root.rmem; 24 import dmd.utf; 25 26 enum TOK : ubyte 27 { 28 reserved, 29 30 // Other 31 leftParentheses, 32 rightParentheses, 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 arrow, 132 comma, 133 question, 134 andAnd, 135 orOr, 136 prePlusPlus, 137 preMinusMinus, 138 139 // Numeric literals 140 int32Literal = 105, 141 uns32Literal, 142 int64Literal, 143 uns64Literal, 144 int128Literal, 145 uns128Literal, 146 float32Literal, 147 float64Literal, 148 float80Literal, 149 imaginary32Literal, 150 imaginary64Literal, 151 imaginary80Literal, 152 153 // Char constants 154 charLiteral = 117, 155 wcharLiteral, 156 dcharLiteral, 157 158 // Leaf operators 159 identifier = 120, 160 string_, 161 hexadecimalString, 162 this_, 163 super_, 164 halt, 165 tuple, 166 error, 167 168 // Basic types 169 void_ = 128, 170 int8, 171 uns8, 172 int16, 173 uns16, 174 int32, 175 uns32, 176 int64, 177 uns64, 178 int128, 179 uns128, 180 float32, 181 float64, 182 float80, 183 imaginary32, 184 imaginary64, 185 imaginary80, 186 complex32, 187 complex64, 188 complex80, 189 char_, 190 wchar_, 191 dchar_, 192 bool_, 193 194 // Aggregates 195 struct_ = 152, 196 class_, 197 interface_, 198 union_, 199 enum_, 200 import_, 201 alias_, 202 override_, 203 delegate_, 204 function_, 205 mixin_, 206 align_, 207 extern_, 208 private_, 209 protected_, 210 public_, 211 export_, 212 static_, 213 final_, 214 const_, 215 abstract_, 216 debug_, 217 deprecated_, 218 in_, 219 out_, 220 inout_, 221 lazy_, 222 auto_, 223 package_, 224 immutable_, 225 226 // Statements 227 if_ = 182, 228 else_, 229 while_, 230 for_, 231 do_, 232 switch_, 233 case_, 234 default_, 235 break_, 236 continue_, 237 with_, 238 synchronized_, 239 return_, 240 goto_, 241 try_, 242 catch_, 243 finally_, 244 asm_, 245 foreach_, 246 foreach_reverse_, 247 scope_, 248 onScopeExit, 249 onScopeFailure, 250 onScopeSuccess, 251 252 // Contracts 253 invariant_ = 206, 254 255 // Testing 256 unittest_, 257 258 // Added after 1.0 259 argumentTypes, 260 ref_, 261 macro_, 262 263 parameters = 211, 264 traits, 265 overloadSet, 266 pure_, 267 nothrow_, 268 gshared, 269 line, 270 file, 271 fileFullPath, 272 moduleString, 273 functionString, 274 prettyFunction, 275 shared_, 276 at, 277 pow, 278 powAssign, 279 goesTo, 280 vector, 281 pound, 282 283 interval = 230, 284 voidExpression, 285 cantExpression, 286 showCtfeContext, 287 288 objcClassReference, 289 vectorArray, 290 291 max_, 292 } 293 294 // Assert that all token enum members have consecutive values and 295 // that none of them overlap 296 static assert(() { 297 foreach (idx, enumName; __traits(allMembers, TOK)) { 298 static if (idx != __traits(getMember, TOK, enumName)) { 299 pragma(msg, "Error: Expected TOK.", enumName, " to be ", idx, " but is ", __traits(getMember, TOK, enumName)); 300 static assert(0); 301 } 302 } 303 return true; 304 }()); 305 306 307 /**************************************** 308 */ 309 310 private immutable TOK[] keywords = 311 [ 312 TOK.this_, 313 TOK.super_, 314 TOK.assert_, 315 TOK.null_, 316 TOK.true_, 317 TOK.false_, 318 TOK.cast_, 319 TOK.new_, 320 TOK.delete_, 321 TOK.throw_, 322 TOK.module_, 323 TOK.pragma_, 324 TOK.typeof_, 325 TOK.typeid_, 326 TOK.template_, 327 TOK.void_, 328 TOK.int8, 329 TOK.uns8, 330 TOK.int16, 331 TOK.uns16, 332 TOK.int32, 333 TOK.uns32, 334 TOK.int64, 335 TOK.uns64, 336 TOK.int128, 337 TOK.uns128, 338 TOK.float32, 339 TOK.float64, 340 TOK.float80, 341 TOK.bool_, 342 TOK.char_, 343 TOK.wchar_, 344 TOK.dchar_, 345 TOK.imaginary32, 346 TOK.imaginary64, 347 TOK.imaginary80, 348 TOK.complex32, 349 TOK.complex64, 350 TOK.complex80, 351 TOK.delegate_, 352 TOK.function_, 353 TOK.is_, 354 TOK.if_, 355 TOK.else_, 356 TOK.while_, 357 TOK.for_, 358 TOK.do_, 359 TOK.switch_, 360 TOK.case_, 361 TOK.default_, 362 TOK.break_, 363 TOK.continue_, 364 TOK.synchronized_, 365 TOK.return_, 366 TOK.goto_, 367 TOK.try_, 368 TOK.catch_, 369 TOK.finally_, 370 TOK.with_, 371 TOK.asm_, 372 TOK.foreach_, 373 TOK.foreach_reverse_, 374 TOK.scope_, 375 TOK.struct_, 376 TOK.class_, 377 TOK.interface_, 378 TOK.union_, 379 TOK.enum_, 380 TOK.import_, 381 TOK.mixin_, 382 TOK.static_, 383 TOK.final_, 384 TOK.const_, 385 TOK.alias_, 386 TOK.override_, 387 TOK.abstract_, 388 TOK.debug_, 389 TOK.deprecated_, 390 TOK.in_, 391 TOK.out_, 392 TOK.inout_, 393 TOK.lazy_, 394 TOK.auto_, 395 TOK.align_, 396 TOK.extern_, 397 TOK.private_, 398 TOK.package_, 399 TOK.protected_, 400 TOK.public_, 401 TOK.export_, 402 TOK.invariant_, 403 TOK.unittest_, 404 TOK.version_, 405 TOK.argumentTypes, 406 TOK.parameters, 407 TOK.ref_, 408 TOK.macro_, 409 TOK.pure_, 410 TOK.nothrow_, 411 TOK.gshared, 412 TOK.traits, 413 TOK.vector, 414 TOK.overloadSet, 415 TOK.file, 416 TOK.fileFullPath, 417 TOK.line, 418 TOK.moduleString, 419 TOK.functionString, 420 TOK.prettyFunction, 421 TOK.shared_, 422 TOK.immutable_, 423 ]; 424 425 // Initialize the identifier pool 426 shared static this() nothrow 427 { 428 Identifier.initTable(); 429 foreach (kw; keywords) 430 { 431 //printf("keyword[%d] = '%s'\n",kw, tochars[kw].ptr); 432 Identifier.idPool(Token.tochars[kw].ptr, Token.tochars[kw].length, cast(uint)kw); 433 } 434 } 435 436 /*********************************************************** 437 */ 438 extern (C++) struct Token 439 { 440 Token* next; 441 Loc loc; 442 const(char)* ptr; // pointer to first character of this token within buffer 443 TOK value; 444 const(char)[] blockComment; // doc comment string prior to this token 445 const(char)[] lineComment; // doc comment for previous token 446 447 union 448 { 449 // Integers 450 sinteger_t intvalue; 451 uinteger_t unsvalue; 452 // Floats 453 real_t floatvalue; 454 455 struct 456 { 457 const(char)* ustring; // UTF8 string 458 uint len; 459 ubyte postfix; // 'c', 'w', 'd' 460 } 461 462 Identifier ident; 463 } 464 465 extern (D) private static immutable string[TOK.max_] tochars = 466 [ 467 // Keywords 468 TOK.this_: "this", 469 TOK.super_: "super", 470 TOK.assert_: "assert", 471 TOK.null_: "null", 472 TOK.true_: "true", 473 TOK.false_: "false", 474 TOK.cast_: "cast", 475 TOK.new_: "new", 476 TOK.delete_: "delete", 477 TOK.throw_: "throw", 478 TOK.module_: "module", 479 TOK.pragma_: "pragma", 480 TOK.typeof_: "typeof", 481 TOK.typeid_: "typeid", 482 TOK.template_: "template", 483 TOK.void_: "void", 484 TOK.int8: "byte", 485 TOK.uns8: "ubyte", 486 TOK.int16: "short", 487 TOK.uns16: "ushort", 488 TOK.int32: "int", 489 TOK.uns32: "uint", 490 TOK.int64: "long", 491 TOK.uns64: "ulong", 492 TOK.int128: "cent", 493 TOK.uns128: "ucent", 494 TOK.float32: "float", 495 TOK.float64: "double", 496 TOK.float80: "real", 497 TOK.bool_: "bool", 498 TOK.char_: "char", 499 TOK.wchar_: "wchar", 500 TOK.dchar_: "dchar", 501 TOK.imaginary32: "ifloat", 502 TOK.imaginary64: "idouble", 503 TOK.imaginary80: "ireal", 504 TOK.complex32: "cfloat", 505 TOK.complex64: "cdouble", 506 TOK.complex80: "creal", 507 TOK.delegate_: "delegate", 508 TOK.function_: "function", 509 TOK.is_: "is", 510 TOK.if_: "if", 511 TOK.else_: "else", 512 TOK.while_: "while", 513 TOK.for_: "for", 514 TOK.do_: "do", 515 TOK.switch_: "switch", 516 TOK.case_: "case", 517 TOK.default_: "default", 518 TOK.break_: "break", 519 TOK.continue_: "continue", 520 TOK.synchronized_: "synchronized", 521 TOK.return_: "return", 522 TOK.goto_: "goto", 523 TOK.try_: "try", 524 TOK.catch_: "catch", 525 TOK.finally_: "finally", 526 TOK.with_: "with", 527 TOK.asm_: "asm", 528 TOK.foreach_: "foreach", 529 TOK.foreach_reverse_: "foreach_reverse", 530 TOK.scope_: "scope", 531 TOK.struct_: "struct", 532 TOK.class_: "class", 533 TOK.interface_: "interface", 534 TOK.union_: "union", 535 TOK.enum_: "enum", 536 TOK.import_: "import", 537 TOK.mixin_: "mixin", 538 TOK.static_: "static", 539 TOK.final_: "final", 540 TOK.const_: "const", 541 TOK.alias_: "alias", 542 TOK.override_: "override", 543 TOK.abstract_: "abstract", 544 TOK.debug_: "debug", 545 TOK.deprecated_: "deprecated", 546 TOK.in_: "in", 547 TOK.out_: "out", 548 TOK.inout_: "inout", 549 TOK.lazy_: "lazy", 550 TOK.auto_: "auto", 551 TOK.align_: "align", 552 TOK.extern_: "extern", 553 TOK.private_: "private", 554 TOK.package_: "package", 555 TOK.protected_: "protected", 556 TOK.public_: "public", 557 TOK.export_: "export", 558 TOK.invariant_: "invariant", 559 TOK.unittest_: "unittest", 560 TOK.version_: "version", 561 TOK.argumentTypes: "__argTypes", 562 TOK.parameters: "__parameters", 563 TOK.ref_: "ref", 564 TOK.macro_: "macro", 565 TOK.pure_: "pure", 566 TOK.nothrow_: "nothrow", 567 TOK.gshared: "__gshared", 568 TOK.traits: "__traits", 569 TOK.vector: "__vector", 570 TOK.overloadSet: "__overloadset", 571 TOK.file: "__FILE__", 572 TOK.fileFullPath: "__FILE_FULL_PATH__", 573 TOK.line: "__LINE__", 574 TOK.moduleString: "__MODULE__", 575 TOK.functionString: "__FUNCTION__", 576 TOK.prettyFunction: "__PRETTY_FUNCTION__", 577 TOK.shared_: "shared", 578 TOK.immutable_: "immutable", 579 580 TOK.endOfFile: "End of File", 581 TOK.leftCurly: "{", 582 TOK.rightCurly: "}", 583 TOK.leftParentheses: "(", 584 TOK.rightParentheses: ")", 585 TOK.leftBracket: "[", 586 TOK.rightBracket: "]", 587 TOK.semicolon: ";", 588 TOK.colon: ":", 589 TOK.comma: ",", 590 TOK.dot: ".", 591 TOK.xor: "^", 592 TOK.xorAssign: "^=", 593 TOK.assign: "=", 594 TOK.construct: "=", 595 TOK.blit: "=", 596 TOK.lessThan: "<", 597 TOK.greaterThan: ">", 598 TOK.lessOrEqual: "<=", 599 TOK.greaterOrEqual: ">=", 600 TOK.equal: "==", 601 TOK.notEqual: "!=", 602 TOK.not: "!", 603 TOK.leftShift: "<<", 604 TOK.rightShift: ">>", 605 TOK.unsignedRightShift: ">>>", 606 TOK.add: "+", 607 TOK.min: "-", 608 TOK.mul: "*", 609 TOK.div: "/", 610 TOK.mod: "%", 611 TOK.slice: "..", 612 TOK.dotDotDot: "...", 613 TOK.and: "&", 614 TOK.andAnd: "&&", 615 TOK.or: "|", 616 TOK.orOr: "||", 617 TOK.array: "[]", 618 TOK.index: "[i]", 619 TOK.address: "&", 620 TOK.star: "*", 621 TOK.tilde: "~", 622 TOK.dollar: "$", 623 TOK.plusPlus: "++", 624 TOK.minusMinus: "--", 625 TOK.prePlusPlus: "++", 626 TOK.preMinusMinus: "--", 627 TOK.type: "type", 628 TOK.question: "?", 629 TOK.negate: "-", 630 TOK.uadd: "+", 631 TOK.variable: "var", 632 TOK.addAssign: "+=", 633 TOK.minAssign: "-=", 634 TOK.mulAssign: "*=", 635 TOK.divAssign: "/=", 636 TOK.modAssign: "%=", 637 TOK.leftShiftAssign: "<<=", 638 TOK.rightShiftAssign: ">>=", 639 TOK.unsignedRightShiftAssign: ">>>=", 640 TOK.andAssign: "&=", 641 TOK.orAssign: "|=", 642 TOK.concatenateAssign: "~=", 643 TOK.concatenateElemAssign: "~=", 644 TOK.concatenateDcharAssign: "~=", 645 TOK.concatenate: "~", 646 TOK.call: "call", 647 TOK.identity: "is", 648 TOK.notIdentity: "!is", 649 TOK.identifier: "identifier", 650 TOK.at: "@", 651 TOK.pow: "^^", 652 TOK.powAssign: "^^=", 653 TOK.goesTo: "=>", 654 TOK.pound: "#", 655 656 // For debugging 657 TOK.error: "error", 658 TOK.dotIdentifier: "dotid", 659 TOK.dotTemplateDeclaration: "dottd", 660 TOK.dotTemplateInstance: "dotti", 661 TOK.dotVariable: "dotvar", 662 TOK.dotType: "dottype", 663 TOK.symbolOffset: "symoff", 664 TOK.arrayLength: "arraylength", 665 TOK.arrayLiteral: "arrayliteral", 666 TOK.assocArrayLiteral: "assocarrayliteral", 667 TOK.structLiteral: "structliteral", 668 TOK.string_: "string", 669 TOK.dSymbol: "symbol", 670 TOK.tuple: "tuple", 671 TOK.declaration: "declaration", 672 TOK.onScopeExit: "scope(exit)", 673 TOK.onScopeSuccess: "scope(success)", 674 TOK.onScopeFailure: "scope(failure)", 675 TOK.delegatePointer: "delegateptr", 676 677 // Finish up 678 TOK.reserved: "reserved", 679 TOK.remove: "remove", 680 TOK.newAnonymousClass: "newanonclass", 681 TOK.comment: "comment", 682 TOK.classReference: "classreference", 683 TOK.thrownException: "thrownexception", 684 TOK.delegateFunctionPointer: "delegatefuncptr", 685 TOK.arrow: "arrow", 686 TOK.int32Literal: "int32v", 687 TOK.uns32Literal: "uns32v", 688 TOK.int64Literal: "int64v", 689 TOK.uns64Literal: "uns64v", 690 TOK.int128Literal: "int128v", 691 TOK.uns128Literal: "uns128v", 692 TOK.float32Literal: "float32v", 693 TOK.float64Literal: "float64v", 694 TOK.float80Literal: "float80v", 695 TOK.imaginary32Literal: "imaginary32v", 696 TOK.imaginary64Literal: "imaginary64v", 697 TOK.imaginary80Literal: "imaginary80v", 698 TOK.charLiteral: "charv", 699 TOK.wcharLiteral: "wcharv", 700 TOK.dcharLiteral: "dcharv", 701 702 TOK.halt: "halt", 703 TOK.hexadecimalString: "xstring", 704 705 TOK.interval: "interval", 706 TOK.voidExpression: "voidexp", 707 TOK.cantExpression: "cantexp", 708 TOK.showCtfeContext : "showCtfeContext", 709 710 TOK.objcClassReference: "class", 711 TOK.vectorArray: "vectorarray", 712 ]; 713 714 static assert(() { 715 foreach (s; tochars) 716 assert(s.length); 717 return true; 718 }()); 719 720 nothrow: 721 722 int isKeyword() const 723 { 724 foreach (kw; keywords) 725 { 726 if (kw == value) 727 return 1; 728 } 729 return 0; 730 } 731 732 /**** 733 * Set to contents of ptr[0..length] 734 * Params: 735 * ptr = pointer to string 736 * length = length of string 737 */ 738 void setString(const(char)* ptr, size_t length) 739 { 740 auto s = cast(char*)mem.xmalloc_noscan(length + 1); 741 memcpy(s, ptr, length); 742 s[length] = 0; 743 ustring = s; 744 len = cast(uint)length; 745 postfix = 0; 746 } 747 748 /**** 749 * Set to contents of buf 750 * Params: 751 * buf = string (not zero terminated) 752 */ 753 void setString(const ref OutBuffer buf) 754 { 755 setString(cast(const(char)*)buf[].ptr, buf.length); 756 } 757 758 /**** 759 * Set to empty string 760 */ 761 void setString() 762 { 763 ustring = ""; 764 len = 0; 765 postfix = 0; 766 } 767 768 extern (C++) const(char)* toChars() const 769 { 770 __gshared char[3 + 3 * floatvalue.sizeof + 1] buffer; 771 const(char)* p = &buffer[0]; 772 switch (value) 773 { 774 case TOK.int32Literal: 775 sprintf(&buffer[0], "%d", cast(d_int32)intvalue); 776 break; 777 case TOK.uns32Literal: 778 case TOK.charLiteral: 779 case TOK.wcharLiteral: 780 case TOK.dcharLiteral: 781 sprintf(&buffer[0], "%uU", cast(d_uns32)unsvalue); 782 break; 783 case TOK.int64Literal: 784 sprintf(&buffer[0], "%lldL", cast(long)intvalue); 785 break; 786 case TOK.uns64Literal: 787 sprintf(&buffer[0], "%lluUL", cast(ulong)unsvalue); 788 break; 789 case TOK.float32Literal: 790 CTFloat.sprint(&buffer[0], 'g', floatvalue); 791 strcat(&buffer[0], "f"); 792 break; 793 case TOK.float64Literal: 794 CTFloat.sprint(&buffer[0], 'g', floatvalue); 795 break; 796 case TOK.float80Literal: 797 CTFloat.sprint(&buffer[0], 'g', floatvalue); 798 strcat(&buffer[0], "L"); 799 break; 800 case TOK.imaginary32Literal: 801 CTFloat.sprint(&buffer[0], 'g', floatvalue); 802 strcat(&buffer[0], "fi"); 803 break; 804 case TOK.imaginary64Literal: 805 CTFloat.sprint(&buffer[0], 'g', floatvalue); 806 strcat(&buffer[0], "i"); 807 break; 808 case TOK.imaginary80Literal: 809 CTFloat.sprint(&buffer[0], 'g', floatvalue); 810 strcat(&buffer[0], "Li"); 811 break; 812 case TOK.string_: 813 { 814 OutBuffer buf; 815 buf.writeByte('"'); 816 for (size_t i = 0; i < len;) 817 { 818 dchar c; 819 utf_decodeChar(ustring[0 .. len], i, c); 820 switch (c) 821 { 822 case 0: 823 break; 824 case '"': 825 case '\\': 826 buf.writeByte('\\'); 827 goto default; 828 default: 829 if (c <= 0x7F) 830 { 831 if (isprint(c)) 832 buf.writeByte(c); 833 else 834 buf.printf("\\x%02x", c); 835 } 836 else if (c <= 0xFFFF) 837 buf.printf("\\u%04x", c); 838 else 839 buf.printf("\\U%08x", c); 840 continue; 841 } 842 break; 843 } 844 buf.writeByte('"'); 845 if (postfix) 846 buf.writeByte(postfix); 847 buf.writeByte(0); 848 p = buf.extractSlice().ptr; 849 } 850 break; 851 case TOK.hexadecimalString: 852 { 853 OutBuffer buf; 854 buf.writeByte('x'); 855 buf.writeByte('"'); 856 foreach (size_t i; 0 .. len) 857 { 858 if (i) 859 buf.writeByte(' '); 860 buf.printf("%02x", ustring[i]); 861 } 862 buf.writeByte('"'); 863 if (postfix) 864 buf.writeByte(postfix); 865 buf.writeByte(0); 866 p = buf.extractSlice().ptr; 867 break; 868 } 869 case TOK.identifier: 870 case TOK.enum_: 871 case TOK.struct_: 872 case TOK.import_: 873 case TOK.wchar_: 874 case TOK.dchar_: 875 case TOK.bool_: 876 case TOK.char_: 877 case TOK.int8: 878 case TOK.uns8: 879 case TOK.int16: 880 case TOK.uns16: 881 case TOK.int32: 882 case TOK.uns32: 883 case TOK.int64: 884 case TOK.uns64: 885 case TOK.int128: 886 case TOK.uns128: 887 case TOK.float32: 888 case TOK.float64: 889 case TOK.float80: 890 case TOK.imaginary32: 891 case TOK.imaginary64: 892 case TOK.imaginary80: 893 case TOK.complex32: 894 case TOK.complex64: 895 case TOK.complex80: 896 case TOK.void_: 897 p = ident.toChars(); 898 break; 899 default: 900 p = toChars(value); 901 break; 902 } 903 return p; 904 } 905 906 static const(char)* toChars(ubyte value) 907 { 908 return toString(value).ptr; 909 } 910 911 extern (D) static string toString(ubyte value) pure nothrow @nogc @safe 912 { 913 return tochars[value]; 914 } 915 }