xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/d/dmd/identifier.c (revision 627f7eb200a4419d89b531d55fccd2ee3ffdcde0)
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 
Identifier(const char * string,size_t length,int value)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 
Identifier(const char * string)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 
create(const char * string)36 Identifier *Identifier::create(const char *string)
37 {
38     return new Identifier(string);
39 }
40 
equals(RootObject * o)41 bool Identifier::equals(RootObject *o)
42 {
43     return this == o || strncmp(string,o->toChars(),len+1) == 0;
44 }
45 
compare(RootObject * o)46 int Identifier::compare(RootObject *o)
47 {
48     return strncmp(string, o->toChars(), len + 1);
49 }
50 
toChars()51 const char *Identifier::toChars()
52 {
53     return string;
54 }
55 
getValue()56 int Identifier::getValue() const
57 {
58     return value;
59 }
60 
toHChars2()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 
print()88 void Identifier::print()
89 {
90     fprintf(stderr, "%s",string);
91 }
92 
dyncast()93 int Identifier::dyncast() const
94 {
95     return DYNCAST_IDENTIFIER;
96 }
97 
98 StringTable Identifier::stringtable;
99 
generateId(const char * prefix)100 Identifier *Identifier::generateId(const char *prefix)
101 {
102     static size_t i;
103 
104     return generateId(prefix, ++i);
105 }
106 
generateId(const char * prefix,size_t i)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 
idPool(const char * s,size_t len)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 
idPool(const char * s,size_t len,int value)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 
isValidIdentifier(const char * p)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 
lookup(const char * s,size_t len)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 
initTable()185 void Identifier::initTable()
186 {
187     stringtable._init(28000);
188 }
189