ldc/ddmd/identifier.d
David Nadlinger 9f998a398d Initial merge of upstream v2.071.0-b2
Notably, the glue layer side of the changed multiple interface
inheritance layout (DMD a54e89d) has not been implemented yet.

This corresponds to DMD commit 3f6a763c0589dd03c1c206eafd434b593702564e.
2016-04-03 15:15:14 +01:00

179 lines
4.4 KiB
D

// Compiler implementation of the D programming language
// Copyright (c) 1999-2015 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// Distributed under the Boost Software License, Version 1.0.
// http://www.boost.org/LICENSE_1_0.txt
module ddmd.identifier;
import core.stdc.ctype;
import core.stdc.stdio;
import core.stdc.string;
import ddmd.globals;
import ddmd.id;
import ddmd.root.outbuffer;
import ddmd.root.rootobject;
import ddmd.root.stringtable;
import ddmd.tokens;
import ddmd.utf;
/***********************************************************
*/
extern (C++) final class Identifier : RootObject
{
public:
int value;
const(char)* string;
size_t len;
extern (D) this(const(char)* string, int value)
{
//printf("Identifier('%s', %d)\n", string, value);
this.string = string;
this.value = value;
this.len = strlen(string);
}
static Identifier create(const(char)* string, int value)
{
return new Identifier(string, value);
}
override bool equals(RootObject o) const
{
return this == o || strncmp(string, o.toChars(), len + 1) == 0;
}
override int compare(RootObject o) const
{
return strncmp(string, o.toChars(), len + 1);
}
override void print() const
{
fprintf(stderr, "%s", string);
}
override const(char)* toChars() const
{
return string;
}
const(char)* toHChars2() const
{
const(char)* p = null;
if (this == Id.ctor)
p = "this";
else if (this == Id.dtor)
p = "~this";
else if (this == Id.unitTest)
p = "unittest";
else if (this == Id.dollar)
p = "$";
else if (this == Id.withSym)
p = "with";
else if (this == Id.result)
p = "result";
else if (this == Id.returnLabel)
p = "return";
else
{
p = toChars();
if (*p == '_')
{
if (strncmp(p, "_staticCtor", 11) == 0)
p = "static this";
else if (strncmp(p, "_staticDtor", 11) == 0)
p = "static ~this";
else if (strncmp(p, "__invariant", 11) == 0)
p = "invariant";
}
}
return p;
}
override int dyncast() const
{
return DYNCAST_IDENTIFIER;
}
extern (C++) static __gshared StringTable stringtable;
static Identifier generateId(const(char)* prefix)
{
static __gshared size_t i;
return generateId(prefix, ++i);
}
static Identifier generateId(const(char)* prefix, size_t i)
{
OutBuffer buf;
buf.writestring(prefix);
buf.printf("%llu", cast(ulong)i);
return idPool(buf.peekSlice());
}
/********************************************
* Create an identifier in the string table.
*/
extern (D) static Identifier idPool(const(char)[] s)
{
return idPool(s.ptr, s.length);
}
static Identifier idPool(const(char)* s, size_t len)
{
StringValue* sv = stringtable.update(s, len);
Identifier id = cast(Identifier)sv.ptrvalue;
if (!id)
{
id = new Identifier(sv.toDchars(), TOKidentifier);
sv.ptrvalue = cast(char*)id;
}
return id;
}
/**********************************
* Determine if string is a valid Identifier.
* Returns:
* 0 invalid
*/
final static bool isValidIdentifier(const(char)* p)
{
size_t len;
size_t idx;
if (!p || !*p)
goto Linvalid;
if (*p >= '0' && *p <= '9') // beware of isdigit() on signed chars
goto Linvalid;
len = strlen(p);
idx = 0;
while (p[idx])
{
dchar dc;
const q = utf_decodeChar(p, len, idx, dc);
if (q)
goto Linvalid;
if (!((dc >= 0x80 && isUniAlpha(dc)) || isalnum(dc) || dc == '_'))
goto Linvalid;
}
return true;
Linvalid:
return false;
}
static Identifier lookup(const(char)* s, size_t len)
{
StringValue* sv = stringtable.lookup(s, len);
if (!sv)
return null;
return cast(Identifier)sv.ptrvalue;
}
static void initTable()
{
stringtable._init(28000);
}
}