/* 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); }