145
|
1
|
|
2 /* Compiler implementation of the D programming language
|
|
3 * Copyright (C) 1999-2019 by The D Language Foundation, All Rights Reserved
|
|
4 * written by Walter Bright
|
|
5 * http://www.digitalmars.com
|
|
6 * Distributed under the Boost Software License, Version 1.0.
|
|
7 * http://www.boost.org/LICENSE_1_0.txt
|
|
8 * https://github.com/D-Programming-Language/dmd/blob/master/src/identifier.c
|
|
9 */
|
|
10
|
|
11 #include "root/dsystem.h"
|
|
12 #include "root/root.h"
|
|
13
|
|
14 #include "identifier.h"
|
|
15 #include "mars.h"
|
|
16 #include "id.h"
|
|
17 #include "tokens.h"
|
|
18 #include "utf.h"
|
|
19
|
|
20 Identifier::Identifier(const char *string, size_t length, int value)
|
|
21 {
|
|
22 //printf("Identifier('%s', %d)\n", string, value);
|
|
23 this->string = string;
|
|
24 this->value = value;
|
|
25 this->len = length;
|
|
26 }
|
|
27
|
|
28 Identifier::Identifier(const char *string)
|
|
29 {
|
|
30 //printf("Identifier('%s')\n", string);
|
|
31 this->string = string;
|
|
32 this->value = TOKidentifier;
|
|
33 this->len = strlen(string);
|
|
34 }
|
|
35
|
|
36 Identifier *Identifier::create(const char *string)
|
|
37 {
|
|
38 return new Identifier(string);
|
|
39 }
|
|
40
|
|
41 bool Identifier::equals(RootObject *o)
|
|
42 {
|
|
43 return this == o || strncmp(string,o->toChars(),len+1) == 0;
|
|
44 }
|
|
45
|
|
46 int Identifier::compare(RootObject *o)
|
|
47 {
|
|
48 return strncmp(string, o->toChars(), len + 1);
|
|
49 }
|
|
50
|
|
51 const char *Identifier::toChars()
|
|
52 {
|
|
53 return string;
|
|
54 }
|
|
55
|
|
56 int Identifier::getValue() const
|
|
57 {
|
|
58 return value;
|
|
59 }
|
|
60
|
|
61 const char *Identifier::toHChars2()
|
|
62 {
|
|
63 const char *p = NULL;
|
|
64
|
|
65 if (this == Id::ctor) p = "this";
|
|
66 else if (this == Id::dtor) p = "~this";
|
|
67 else if (this == Id::unitTest) p = "unittest";
|
|
68 else if (this == Id::dollar) p = "$";
|
|
69 else if (this == Id::withSym) p = "with";
|
|
70 else if (this == Id::result) p = "result";
|
|
71 else if (this == Id::returnLabel) p = "return";
|
|
72 else
|
|
73 { p = toChars();
|
|
74 if (*p == '_')
|
|
75 {
|
|
76 if (strncmp(p, "_staticCtor", 11) == 0)
|
|
77 p = "static this";
|
|
78 else if (strncmp(p, "_staticDtor", 11) == 0)
|
|
79 p = "static ~this";
|
|
80 else if (strncmp(p, "__invariant", 11) == 0)
|
|
81 p = "invariant";
|
|
82 }
|
|
83 }
|
|
84
|
|
85 return p;
|
|
86 }
|
|
87
|
|
88 void Identifier::print()
|
|
89 {
|
|
90 fprintf(stderr, "%s",string);
|
|
91 }
|
|
92
|
|
93 int Identifier::dyncast() const
|
|
94 {
|
|
95 return DYNCAST_IDENTIFIER;
|
|
96 }
|
|
97
|
|
98 StringTable Identifier::stringtable;
|
|
99
|
|
100 Identifier *Identifier::generateId(const char *prefix)
|
|
101 {
|
|
102 static size_t i;
|
|
103
|
|
104 return generateId(prefix, ++i);
|
|
105 }
|
|
106
|
|
107 Identifier *Identifier::generateId(const char *prefix, size_t i)
|
|
108 { OutBuffer buf;
|
|
109
|
|
110 buf.writestring(prefix);
|
|
111 buf.printf("%llu", (ulonglong)i);
|
|
112
|
|
113 char *id = buf.peekString();
|
|
114 return idPool(id);
|
|
115 }
|
|
116
|
|
117 /********************************************
|
|
118 * Create an identifier in the string table.
|
|
119 */
|
|
120
|
|
121 Identifier *Identifier::idPool(const char *s, size_t len)
|
|
122 {
|
|
123 StringValue *sv = stringtable.update(s, len);
|
|
124 Identifier *id = (Identifier *) sv->ptrvalue;
|
|
125 if (!id)
|
|
126 {
|
|
127 id = new Identifier(sv->toDchars(), len, TOKidentifier);
|
|
128 sv->ptrvalue = (char *)id;
|
|
129 }
|
|
130 return id;
|
|
131 }
|
|
132
|
|
133 Identifier *Identifier::idPool(const char *s, size_t len, int value)
|
|
134 {
|
|
135 StringValue *sv = stringtable.insert(s, len, NULL);
|
|
136 assert(sv);
|
|
137 Identifier *id = new Identifier(sv->toDchars(), len, value);
|
|
138 sv->ptrvalue = (char *)id;
|
|
139 return id;
|
|
140 }
|
|
141
|
|
142 /**********************************
|
|
143 * Determine if string is a valid Identifier.
|
|
144 * Returns:
|
|
145 * 0 invalid
|
|
146 */
|
|
147
|
|
148 bool Identifier::isValidIdentifier(const char *p)
|
|
149 {
|
|
150 size_t len;
|
|
151 size_t idx;
|
|
152
|
|
153 if (!p || !*p)
|
|
154 goto Linvalid;
|
|
155
|
|
156 if (*p >= '0' && *p <= '9') // beware of isdigit() on signed chars
|
|
157 goto Linvalid;
|
|
158
|
|
159 len = strlen(p);
|
|
160 idx = 0;
|
|
161 while (p[idx])
|
|
162 {
|
|
163 dchar_t dc;
|
|
164 const char *q = utf_decodeChar((const utf8_t *)p, len, &idx, &dc);
|
|
165 if (q)
|
|
166 goto Linvalid;
|
|
167
|
|
168 if (!((dc >= 0x80 && isUniAlpha(dc)) || isalnum(dc) || dc == '_'))
|
|
169 goto Linvalid;
|
|
170 }
|
|
171 return true;
|
|
172
|
|
173 Linvalid:
|
|
174 return false;
|
|
175 }
|
|
176
|
|
177 Identifier *Identifier::lookup(const char *s, size_t len)
|
|
178 {
|
|
179 StringValue *sv = stringtable.lookup(s, len);
|
|
180 if (!sv)
|
|
181 return NULL;
|
|
182 return (Identifier *)sv->ptrvalue;
|
|
183 }
|
|
184
|
|
185 void Identifier::initTable()
|
|
186 {
|
|
187 stringtable._init(28000);
|
|
188 }
|