Top Up Prev Next Bottom Contents Index Search

16.2 Class CodeBlock and Macros

Class CodeBlock stores a pointer to text in its constructor.

CodeBlock(const char* text);
It is up to the programmer to make sure that the argument text lives as long as the codeblock is used.

There are four public methods defined to access the text:

void setText(char* line);
const char* getText();
operator const char*();
void printCode();
The first method sets the text pointer in the CodeBlock. The next two methods return the text this CodeBlock points to. The last method prints the code to the standard output.

A star programmer uses the codeblock directive in the preprocessor language file to define a block of text. In a CodeBlock, the programmer uses the following macros in order to refer to the star ports and variables without needing to be concerned about resource management or name conflicts:

Value of a state

Buffer size of a state or a porthole

Reference to a state or a porthole

$ref(name, offset)
Reference with offset

Unique label inside a codeblock

Another name for $label

Unique label inside a star

$sharedSymbol(list, name)
Unique label for set list, name pair

These macros are resolved into code after resources are allocated or unique symbols are generated.

A CodeBlock defined in a CGStar is put into a CodeStream of the target by the following methods of the CGStar class:

int addCode(const char* code, const char* stream=NULL,
const char* name=NULL);
int addProcedure(const char* code, const char* name);
These are protected methods of class CGStar. The first method puts a segment of code, code, at the end of the target's CodeStream with name stream. If the name of the CodeStream is not given, the method uses the myCode stream of the target. The second method uses the procedure CodeStream of the target. The argument name of both methods is optionally used to specify the name of the code. If the code is successfully added, the methods return TRUE, otherwise they return FALSE. Before putting the code at the end of the CodeStream, the code is processed to resolve any macros by the application of the processCode method:

StringList processCode(CodeBlock& cb); 
StringList processCode(const char* code);
These methods are both protected and essentially equivalent since the first method calls the second method. They scan the code, word by word, and copy it into a StringList. If a macro is found, the macro is expanded through a call to expandMacro before being copied to the StringList. Testing can be done to check whether a word is a macro or not by comparing the first character with the result of the following method:

virtual char substChar() const; 
This method is a virtual protected method of class CGStar. It is used to return the special character that marks the beginning of a macro in a code block. In the CGStar class, it returns the dollar sign character, $.

virtual StringList expandMacro(const char* func,
                               const StringList& argList);
This is a virtual protected method of class CGStar. It is used to expand a macro with the given name func. The argument list must be passed by reference so that the StringList will not be consolidated. It is virtual so that derived classes can define more macros. A macro is identified by the following method:

int matchMacro(const char* func, const StringList& argList,
const char* name, int argc);
This protected method of class CGStar returns TRUE if the first argument func matches with the third argument name, and the number of arguments in argList is the same as the count argc.

Based on the particular macro being applied, one of the following protected methods may be used to expand the macro:

virtual StringList expandVal(const char* name); 
StringList expandSize(const char* name);
virtual StringList expandRef(const char* name);
virtual StringList expandRef(const char* name, const char* offset);
The first three methods expand the $val, $size, and $ref macros. The fourth method expands the $ref macro when it has two arguments. These virtual methods should be redefined in derived classes. In particular, the last two methods must be redefined in derived classes because in class CGStar they generate error messages. The other macros deal with unique symbols within the scope of a code block, within a star, and within a set of symbols. More will be said about these in the next subsection .

When an error is encountered while expanding macros or processing code blocks, the following methods should be called to generate an error message:

void macroError(const char* func, const StringList& argList); 
void codeblockError(const char* p1, const char* p2="");
The arguments of the second method provide the text of the error message.

Top Up Prev Next Bottom Contents Index Search

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