]>
Commit | Line | Data |
---|---|---|
b4c522fa IB |
1 | |
2 | /* Compiler implementation of the D programming language | |
8e788ac6 | 3 | * Copyright (C) 1999-2020 by The D Language Foundation, All Rights Reserved |
b4c522fa IB |
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 | ||
f9ab59ff | 11 | #include "root/dsystem.h" |
b4c522fa | 12 | #include "root/root.h" |
f9ab59ff | 13 | |
b4c522fa IB |
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 | ||
fced594b | 113 | char *id = buf.peekChars(); |
b4c522fa IB |
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 | } |