Top Up Prev Next Bottom Contents Index Search

16.3 Class SymbolList and Unique Symbol Generation

In order to generate a unique symbol within a scope, a list of symbols should be made for that scope. For example, the CGStar class has two protected members which are SymbolLists, starSymbol and codeblockSymbol.

SymbolList starSymbol; 
SymbolList codeblockSymbol;
Class SymbolList is derived from class BaseSymbolList. Class BaseSymbolList is privately derived from class NamedList. A BaseSymbolList keeps two private members which are used to create a unique name for each symbol in the list: a separator and a counter:

BaseSymbolList(char sep='_', int* count=NULL); 
The first argument of the constructor is used to set the separator, and the second argument is used to set the pointer of the count variable. These two variables can be set independently by invoking the following methods:

void setSeparator(char sep); 
void setCounter(int* count);
When we append or insert a new symbol into the list, we create a unique name for that symbol by appending a separator followed by the counter value to the argument symbol, and then return the unique name:

const char* append(const char* name); 
const char* prepend(const char& name);
const char* get(const char* name=NULL);
This last method returns the unique symbol with the given name. If no name is given, it returns the first symbol in the list.

int remove(const char* name=NULL); 
This method removes the unique symbol with the given name. If no name is given, it removes the first symbol in the list. It returns FALSE if no symbol is removed.

Symbols in the list are deleted in the destructor, and in the following method:

void initialize();

The public method

Stringlist symbol(const char* string) 
makes a unique symbol from the supplied argument by adding the separator and a unique counter value to the argument string.

Class SymbolList is privately derived from class BaseSymbolList with the same constructor and a default destructor. Class SymbolList uncovers only three methods of the base class:

BaseSymbolList::setSeparator; 
BaseSymbolList::setCounter;
BaseSymbolList::initialize;

Class SymbolList adds one additional method:

const char* lookup(const char* name); 
If a unique symbol with the given name exists, this method returns that unique symbol. Otherwise, it creates a unique symbol with that name and puts it into the list.

Recall that the CGStar class has two SymbolLists. The macros $codeblockSymbol, $label, and $starSymbol are resolved by the lookUp method of the codeblockSymbol and starSymbol SymbolLists, based on the scope of the symbol. If the symbol already exists in the SymbolList, it returns that unique symbol. Otherwise, it creates a unique symbol in the scope of interest.

If we want to generate a unique symbol within the file scope, we use a scoped symbol list defined in the target class.

ScopedSymbolList sharedSymbol; 
It is a protected member of the CGTarget class. Class ScopedSymbolList is privately derived from class NamedList to store a list of SymbolLists. It has the same constructor as the base class.

void setSeparator(char set);
void setCounter(int* count);
These methods in class ScopedSymbolList are used to set the separator and the counter pointer of all SymbolLists in the list.

const char* lookup(const char* scope, const char* name); 
In this method, the first argument determines the SymbolList in the list named scope, and the second argument determines the unique symbol within that SymbolList. If no SymbolList is found with the given name, we create a new SymbolList and insert it into the list.

The SymbolLists in the list are deleted in the destructor and in the following method:

void initialize();

Now we can explain how to expand the last macro defined in the CGStar class: $sharedSymbol. The first argument of the macro determines the StringList and the second argument accesses the unique string in that StringList. It is done by calling the following protected method in the CGStar class:

const char* lookupSharedSymbol(const char* scope, const char* name); 
This method calls the corresponding method defined the CGTarget class.

The CGTarget class has another symbol list:

SymbolStack targetNestedSymbol; 
It is a protected member used in generating unique nested symbols. Class SymbolStack is privately derived from class BaseSymbolList. It has the same constructor as the base class and has a default destructor.

For stack operation, class SymbolStack defines the following two methods:

const char* push(const char* tag="L"); 
StringList pop();
These methods push the symbol with given name onto the top of the list and pop the symbol at the top of the list off of the list, respectively.

This class also exposes several methods of the base class:

BaseSymbolList::get;
BaseSymbolList::setSeparator;
BaseSymbolList::setCounter;
BaseSymbolList::initialize;
BaseSymbolList::symbol;

In this section, we have explained various symbol lists. The separator and the counter are usually defined in the CGTarget class:

char separator; 
int counter;
The first is a public member in class CGTarget, and is set in the constructor. The second is a private member in class CGTarget, and is initialized to zero in the constructor. The counter value is accessed through the following public method:

int* symbolCounter();


Top Up Prev Next Bottom Contents Index Search

Copyright © 1990-1997, University of California. All rights reserved.