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