blob: 9d1df4dd466a2ec7bc281669816376140e2782ee [file] [log] [blame]
/* Compiler implementation of the D programming language
* Copyright (C) 1999-2019 by The D Language Foundation, 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
* https://github.com/D-Programming-Language/dmd/blob/master/src/identifier.c
*/
#include "root/dsystem.h"
#include "root/root.h"
#include "identifier.h"
#include "mars.h"
#include "id.h"
#include "tokens.h"
#include "utf.h"
Identifier::Identifier(const char *string, size_t length, int value)
{
//printf("Identifier('%s', %d)\n", string, value);
this->string = string;
this->value = value;
this->len = length;
}
Identifier::Identifier(const char *string)
{
//printf("Identifier('%s')\n", string);
this->string = string;
this->value = TOKidentifier;
this->len = strlen(string);
}
Identifier *Identifier::create(const char *string)
{
return new Identifier(string);
}
bool Identifier::equals(RootObject *o)
{
return this == o || strncmp(string,o->toChars(),len+1) == 0;
}
int Identifier::compare(RootObject *o)
{
return strncmp(string, o->toChars(), len + 1);
}
const char *Identifier::toChars()
{
return string;
}
int Identifier::getValue() const
{
return value;
}
const char *Identifier::toHChars2()
{
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;
}
void Identifier::print()
{
fprintf(stderr, "%s",string);
}
int Identifier::dyncast() const
{
return DYNCAST_IDENTIFIER;
}
StringTable Identifier::stringtable;
Identifier *Identifier::generateId(const char *prefix)
{
static size_t i;
return generateId(prefix, ++i);
}
Identifier *Identifier::generateId(const char *prefix, size_t i)
{ OutBuffer buf;
buf.writestring(prefix);
buf.printf("%llu", (ulonglong)i);
char *id = buf.peekString();
return idPool(id);
}
/********************************************
* Create an identifier in the string table.
*/
Identifier *Identifier::idPool(const char *s, size_t len)
{
StringValue *sv = stringtable.update(s, len);
Identifier *id = (Identifier *) sv->ptrvalue;
if (!id)
{
id = new Identifier(sv->toDchars(), len, TOKidentifier);
sv->ptrvalue = (char *)id;
}
return id;
}
Identifier *Identifier::idPool(const char *s, size_t len, int value)
{
StringValue *sv = stringtable.insert(s, len, NULL);
assert(sv);
Identifier *id = new Identifier(sv->toDchars(), len, value);
sv->ptrvalue = (char *)id;
return id;
}
/**********************************
* Determine if string is a valid Identifier.
* Returns:
* 0 invalid
*/
bool Identifier::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_t dc;
const char *q = utf_decodeChar((const utf8_t *)p, len, &idx, &dc);
if (q)
goto Linvalid;
if (!((dc >= 0x80 && isUniAlpha(dc)) || isalnum(dc) || dc == '_'))
goto Linvalid;
}
return true;
Linvalid:
return false;
}
Identifier *Identifier::lookup(const char *s, size_t len)
{
StringValue *sv = stringtable.lookup(s, len);
if (!sv)
return NULL;
return (Identifier *)sv->ptrvalue;
}
void Identifier::initTable()
{
stringtable._init(28000);
}