2 * Defines lexical tokens.
4 * Specification: $(LINK2 https://dlang.org/spec/lex.html#tokens, Tokens)
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
16 import core
.stdc
.ctype
;
17 import core
.stdc
.stdio
;
18 import core
.stdc
.string
;
20 import dmd
.identifier
;
21 import dmd
.root
.ctfloat
;
22 import dmd
.common
.outbuffer
;
67 dotTemplateDeclaration
,
83 delegateFunctionPointer
,
102 unsignedRightShiftAssign
,
104 concatenateAssign
, // ~=
105 concatenateElemAssign
,
106 concatenateDcharAssign
,
271 moduleString
, // __MODULE__
272 functionString
, // __FUNCTION__
273 prettyFunction
, // __PRETTY_FUNCTION__
293 compoundLiteral
, // ( type-name ) { initializer-list }
315 // C only extended keywords
321 enum FirstCKeyword
= TOK
.inline
;
323 // Assert that all token enum members have consecutive values and
324 // that none of them overlap
326 foreach (idx
, enumName
; __traits(allMembers
, TOK
)) {
327 static if (idx
!= __traits(getMember
, TOK
, enumName
)) {
328 pragma(msg
, "Error: Expected TOK.", enumName
, " to be ", idx
, " but is ", __traits(getMember
, TOK
, enumName
));
335 /****************************************
338 private immutable TOK
[] keywords
=
401 TOK
.foreach_reverse_
,
472 // C only extended keywords
478 // Initialize the identifier pool
479 shared static this() nothrow
481 Identifier
.initTable();
482 foreach (kw
; keywords
)
484 //printf("keyword[%d] = '%s'\n",kw, tochars[kw].ptr);
485 Identifier
.idPool(Token
.tochars
[kw
].ptr
, Token
.tochars
[kw
].length
, cast(uint)kw
);
489 /************************************
490 * This is used to pick the C keywords out of the tokens.
491 * If it's not a C keyword, then it's an identifier.
493 static immutable TOK
[TOK
.max
+ 1] Ckeywords
=
497 TOK
[TOK
.max
+ 1] tab
= identifier
; // default to identifier
498 enum Ckwds
= [ auto_
, break_
, case_
, char_
, const_
, continue_
, default_
, do_
, float64
, else_
,
499 enum_
, extern_
, float32
, for_
, goto_
, if_
, inline
, int32
, int64
, register
,
500 restrict
, return_
, int16
, signed
, sizeof_
, static_
, struct_
, switch_
, typedef_
,
501 union_
, unsigned
, void_
, volatile, while_
, asm_
,
502 _Alignas
, _Alignof
, _Atomic
, _Bool
, _Complex
, _Generic
, _Imaginary
, _Noreturn
,
503 _Static_assert
, _Thread_local
, __cdecl
, __declspec
, __attribute__
];
506 tab
[kw
] = cast(TOK
) kw
;
513 /***********************************************************
515 extern (C
++) struct Token
519 const(char)* ptr
; // pointer to first character of this token within buffer
521 const(char)[] blockComment
; // doc comment string prior to this token
522 const(char)[] lineComment
; // doc comment for previous token
534 const(char)* ustring
; // UTF8 string
536 ubyte postfix
; // 'c', 'w', 'd'
542 extern (D
) private static immutable string
[TOK
.max
+ 1] tochars
=
547 TOK
.assert_
: "assert",
553 TOK
.delete_
: "delete",
555 TOK
.module_
: "module",
556 TOK
.pragma_
: "pragma",
557 TOK
.typeof_
: "typeof",
558 TOK
.typeid_
: "typeid",
559 TOK
.template_
: "template",
571 TOK
.float32
: "float",
572 TOK
.float64
: "double",
578 TOK
.imaginary32
: "ifloat",
579 TOK
.imaginary64
: "idouble",
580 TOK
.imaginary80
: "ireal",
581 TOK
.complex32
: "cfloat",
582 TOK
.complex64
: "cdouble",
583 TOK
.complex80
: "creal",
584 TOK
.delegate_
: "delegate",
585 TOK
.function_
: "function",
592 TOK
.switch_
: "switch",
594 TOK
.default_
: "default",
596 TOK
.continue_
: "continue",
597 TOK
.synchronized_
: "synchronized",
598 TOK
.return_
: "return",
602 TOK
.finally_
: "finally",
605 TOK
.foreach_
: "foreach",
606 TOK
.foreach_reverse_
: "foreach_reverse",
608 TOK
.struct_
: "struct",
610 TOK
.interface_
: "interface",
613 TOK
.import_
: "import",
615 TOK
.static_
: "static",
619 TOK
.override_
: "override",
620 TOK
.abstract_
: "abstract",
622 TOK
.deprecated_
: "deprecated",
629 TOK
.extern_
: "extern",
630 TOK
.private_
: "private",
631 TOK
.package_
: "package",
632 TOK
.protected_
: "protected",
633 TOK
.public_
: "public",
634 TOK
.export_
: "export",
635 TOK
.invariant_
: "invariant",
636 TOK
.unittest_
: "unittest",
637 TOK
.version_
: "version",
638 TOK
.argumentTypes
: "__argTypes",
639 TOK
.parameters
: "__parameters",
643 TOK
.nothrow_
: "nothrow",
644 TOK
.gshared
: "__gshared",
645 TOK
.traits
: "__traits",
646 TOK
.vector
: "__vector",
647 TOK
.overloadSet
: "__overloadset",
648 TOK
.file
: "__FILE__",
649 TOK
.fileFullPath
: "__FILE_FULL_PATH__",
650 TOK
.line
: "__LINE__",
651 TOK
.moduleString
: "__MODULE__",
652 TOK
.functionString
: "__FUNCTION__",
653 TOK
.prettyFunction
: "__PRETTY_FUNCTION__",
654 TOK
.shared_
: "shared",
655 TOK
.immutable_
: "immutable",
657 TOK
.endOfFile
: "End of File",
660 TOK
.leftParenthesis
: "(",
661 TOK
.rightParenthesis
: ")",
662 TOK
.leftBracket
: "[",
663 TOK
.rightBracket
: "]",
674 TOK
.greaterThan
: ">",
675 TOK
.lessOrEqual
: "<=",
676 TOK
.greaterOrEqual
: ">=",
681 TOK
.rightShift
: ">>",
682 TOK
.unsignedRightShift
: ">>>",
689 TOK
.dotDotDot
: "...",
701 TOK
.minusMinus
: "--",
702 TOK
.prePlusPlus
: "++",
703 TOK
.preMinusMinus
: "--",
714 TOK
.leftShiftAssign
: "<<=",
715 TOK
.rightShiftAssign
: ">>=",
716 TOK
.unsignedRightShiftAssign
: ">>>=",
719 TOK
.concatenateAssign
: "~=",
720 TOK
.concatenateElemAssign
: "~=",
721 TOK
.concatenateDcharAssign
: "~=",
722 TOK
.concatenate
: "~",
725 TOK
.notIdentity
: "!is",
726 TOK
.identifier
: "identifier",
729 TOK
.powAssign
: "^^=",
733 TOK
.colonColon
: "::",
737 TOK
.dotIdentifier
: "dotid",
738 TOK
.dotTemplateDeclaration
: "dottd",
739 TOK
.dotTemplateInstance
: "dotti",
740 TOK
.dotVariable
: "dotvar",
741 TOK
.dotType
: "dottype",
742 TOK
.symbolOffset
: "symoff",
743 TOK
.arrayLength
: "arraylength",
744 TOK
.arrayLiteral
: "arrayliteral",
745 TOK
.assocArrayLiteral
: "assocarrayliteral",
746 TOK
.structLiteral
: "structliteral",
747 TOK
.string_
: "string",
748 TOK
.dSymbol
: "symbol",
750 TOK
.declaration
: "declaration",
751 TOK
.onScopeExit
: "scope(exit)",
752 TOK
.onScopeSuccess
: "scope(success)",
753 TOK
.onScopeFailure
: "scope(failure)",
754 TOK
.delegatePointer
: "delegateptr",
757 TOK
.reserved
: "reserved",
758 TOK
.remove
: "remove",
759 TOK
.newAnonymousClass
: "newanonclass",
760 TOK
.comment
: "comment",
761 TOK
.classReference
: "classreference",
762 TOK
.thrownException
: "thrownexception",
763 TOK
.delegateFunctionPointer
: "delegatefuncptr",
764 TOK
.int32Literal
: "int32v",
765 TOK
.uns32Literal
: "uns32v",
766 TOK
.int64Literal
: "int64v",
767 TOK
.uns64Literal
: "uns64v",
768 TOK
.int128Literal
: "int128v",
769 TOK
.uns128Literal
: "uns128v",
770 TOK
.float32Literal
: "float32v",
771 TOK
.float64Literal
: "float64v",
772 TOK
.float80Literal
: "float80v",
773 TOK
.imaginary32Literal
: "imaginary32v",
774 TOK
.imaginary64Literal
: "imaginary64v",
775 TOK
.imaginary80Literal
: "imaginary80v",
776 TOK
.charLiteral
: "charv",
777 TOK
.wcharLiteral
: "wcharv",
778 TOK
.dcharLiteral
: "dcharv",
779 TOK
.wchar_tLiteral
: "wchar_tv",
780 TOK
.compoundLiteral
: "compoundliteral",
783 TOK
.hexadecimalString
: "xstring",
785 TOK
.interval
: "interval",
786 TOK
.voidExpression
: "voidexp",
787 TOK
.cantExpression
: "cantexp",
788 TOK
.showCtfeContext
: "showCtfeContext",
790 TOK
.objcClassReference
: "class",
791 TOK
.vectorArray
: "vectorarray",
794 TOK
.inline
: "inline",
795 TOK
.register
: "register",
796 TOK
.restrict
: "restrict",
797 TOK
.signed
: "signed",
798 TOK
.sizeof_
: "sizeof",
799 TOK
.typedef_
: "typedef",
800 TOK
.unsigned
: "unsigned",
801 TOK
.volatile : "volatile",
802 TOK
._Alignas
: "_Alignas",
803 TOK
._Alignof
: "_Alignof",
804 TOK
._Atomic
: "_Atomic",
806 TOK
._Complex
: "_Complex",
807 TOK
._Generic
: "_Generic",
808 TOK
._Imaginary
: "_Imaginary",
809 TOK
._Noreturn
: "_Noreturn",
810 TOK
._Static_assert
: "_Static_assert",
811 TOK
._Thread_local
: "_Thread_local",
813 // C only extended keywords
814 TOK
.__cdecl
: "__cdecl",
815 TOK
.__declspec
: "__declspec",
816 TOK
.__attribute__
: "__attribute__",
827 int isKeyword() const
829 foreach (kw
; keywords
)
838 * Set to contents of ptr[0..length]
840 * ptr = pointer to string
841 * length = length of string
843 void setString(const(char)* ptr
, size_t length
)
845 auto s
= cast(char*)mem
.xmalloc_noscan(length
+ 1);
846 memcpy(s
, ptr
, length
);
849 len
= cast(uint)length
;
854 * Set to contents of buf
856 * buf = string (not zero terminated)
858 void setString(const ref OutBuffer buf
)
860 setString(cast(const(char)*)buf
[].ptr
, buf
.length
);
864 * Set to empty string
873 extern (C
++) const(char)* toChars() const
875 __gshared
char[3 + 3 * floatvalue
.sizeof
+ 1] buffer
;
876 const(char)* p
= &buffer
[0];
879 case TOK
.int32Literal
:
880 sprintf(&buffer
[0], "%d", cast(d_int32
)intvalue
);
882 case TOK
.uns32Literal
:
883 case TOK
.charLiteral
:
884 case TOK
.wcharLiteral
:
885 case TOK
.dcharLiteral
:
886 case TOK
.wchar_tLiteral
:
887 sprintf(&buffer
[0], "%uU", cast(d_uns32
)unsvalue
);
889 case TOK
.int64Literal
:
890 sprintf(&buffer
[0], "%lldL", cast(long)intvalue
);
892 case TOK
.uns64Literal
:
893 sprintf(&buffer
[0], "%lluUL", cast(ulong)unsvalue
);
895 case TOK
.float32Literal
:
896 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
897 strcat(&buffer
[0], "f");
899 case TOK
.float64Literal
:
900 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
902 case TOK
.float80Literal
:
903 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
904 strcat(&buffer
[0], "L");
906 case TOK
.imaginary32Literal
:
907 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
908 strcat(&buffer
[0], "fi");
910 case TOK
.imaginary64Literal
:
911 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
912 strcat(&buffer
[0], "i");
914 case TOK
.imaginary80Literal
:
915 CTFloat
.sprint(&buffer
[0], 'g', floatvalue
);
916 strcat(&buffer
[0], "Li");
922 for (size_t i
= 0; i
< len
;)
925 utf_decodeChar(ustring
[0 .. len
], i
, c
);
940 buf
.printf("\\x%02x", c
);
942 else if (c
<= 0xFFFF)
943 buf
.printf("\\u%04x", c
);
945 buf
.printf("\\U%08x", c
);
952 buf
.writeByte(postfix
);
954 p
= buf
.extractSlice().ptr
;
957 case TOK
.hexadecimalString
:
962 foreach (size_t i
; 0 .. len
)
966 buf
.printf("%02x", ustring
[i
]);
970 buf
.writeByte(postfix
);
972 p
= buf
.extractSlice().ptr
;
996 case TOK
.imaginary32
:
997 case TOK
.imaginary64
:
998 case TOK
.imaginary80
:
1003 p
= ident
.toChars();
1012 static const(char)* toChars(uint value
)
1014 return toString(value
).ptr
;
1017 extern (D
) static string
toString(uint value
) pure nothrow @nogc @safe
1019 return tochars
[value
];