Rudiments
Public Member Functions | List of all members
compiler Class Reference

Public Member Functions

 compiler ()
 
virtual ~compiler ()
 
void appendModulePath (const char *path)
 
void clearModulePaths ()
 
linkedlist< char * > * getModulePaths ()
 
void appendPreProcessor (compilerpreprocessor *module)
 
bool appendPreProcessor (const char *filename, const char *classname, const char *id, domnode *parameters)
 
bool appendPreProcessor (const char *filename, const char *classname, const char *id, const char *parameters)
 
void clearPreProcessors ()
 
linkedlist< compilermodule * > * getPreProcessors ()
 
void appendProcessor (compilerprocessor *module)
 
bool appendProcessor (const char *filename, const char *classname, const char *id, domnode *parameters)
 
bool appendProcessor (const char *filename, const char *classname, const char *id, const char *parameters)
 
void clearProcessors ()
 
linkedlist< compilermodule * > * getProcessors ()
 
void appendPostProcessor (compilerpostprocessor *module)
 
bool appendPostProcessor (const char *filename, const char *classname, const char *id, domnode *parameters)
 
bool appendPostProcessor (const char *filename, const char *classname, const char *id, const char *parameters)
 
void clearPostProcessors ()
 
linkedlist< compilermodule * > * getPostProcessors ()
 
bool setInputGrammar (const char *grammar, const char *startsymbol)
 
bool setOutputGrammar (const char *grammar)
 
void setMetaData (domnode *metadata)
 
bool compile (const char *input, stringbuffer *output)
 
bool process (domnode *root)
 
const char * getError ()
 
void setDebugLevel (uint8_t debuglevel)
 

Detailed Description

The compiler class provides a generic compiler framework.

Though targeted at code-to-code translation (transcompiling), it could be used as the basis for any type of translation or compilation system.

Translation/compilation is achieved in three steps:

In the pre-processing step, a unit of code and optional metadata is passed through a chain of pre-processing modules. The output of each module is fed to the next as input.

In the processing step, the output of the final preprocessing module is parsed by an instance of the codetree class, using the provided input grammar, producing an dom tree which represents the code. The tree and optional metadata is then passed through a chain of processing modules which convert the tree from representing one type of code to a tree representing another type of code. The output of the final processing module is converted back to code, using the provided output grammar.

In the post-processing step, the output of the processing step is passed through a chain of post-processing modules. The output of each module is fed to the next as input. Ultimately a unit of compiled code is produced.

Pre-processing modules should inherit from the compilerpreprocessor class. Processing modules should inherit from the compilerprocessor class. Post-processing modules should inherit from the compilerpostprocessor class. All modules must implement the process() method.

The pre and post-processing modules directly manipulate code and might make heavy use of the file, charstring/bytestring and stringbuffer/bytebuffer classes. The processing modules manipulate an dom tree representing code and would likely make heavy use of the domnode class.

The input and output code may be text or binary. The framework is geared toward text processing, but could be used to process binary data as well.

See the codetree class for information on the grammars used to define the input and output formats.

Constructor & Destructor Documentation

◆ compiler()

compiler::compiler ( )

Creates a new instance of the compiler class.

◆ ~compiler()

virtual compiler::~compiler ( )
virtual

Deletes this instance of the compiler class.

Member Function Documentation

◆ appendModulePath()

void compiler::appendModulePath ( const char *  path)

Appends "path" to the list of paths that will be searched for pre-processor, processor and post-processor modules.

◆ appendPostProcessor() [1/3]

void compiler::appendPostProcessor ( compilerpostprocessor module)

Appends postprocessor "module" to the list of postprocessors.

◆ appendPostProcessor() [2/3]

bool compiler::appendPostProcessor ( const char *  filename,
const char *  classname,
const char *  id,
const char *  parameters 
)

Dynamically loads postprocessor module "filename". Calls function new_"classname" to create an instance of the postprocessor class. Sets its "id" and "parameters". Appends the instance to the list of postprocessors. Returns true on success and false on failure.

◆ appendPostProcessor() [3/3]

bool compiler::appendPostProcessor ( const char *  filename,
const char *  classname,
const char *  id,
domnode parameters 
)

Dynamically loads postprocessor module "filename". Calls function new_"classname" to create an instance of the postprocessor class. Sets its "id" and "parameters". Appends the instance to the list of postprocessors. Returns true on success and false on failure.

◆ appendPreProcessor() [1/3]

void compiler::appendPreProcessor ( compilerpreprocessor module)

Appends preprocessor "module" to the list of preprocessors.

◆ appendPreProcessor() [2/3]

bool compiler::appendPreProcessor ( const char *  filename,
const char *  classname,
const char *  id,
const char *  parameters 
)

Dynamically loads preprocessor module "filename". Calls function new_"classname" to create an instance of the preprocessor class. Sets its "id" and "parameters". Appends the instance to the list of preprocessors. Returns true on success and false on failure.

◆ appendPreProcessor() [3/3]

bool compiler::appendPreProcessor ( const char *  filename,
const char *  classname,
const char *  id,
domnode parameters 
)

Dynamically loads preprocessor module "filename". Calls function new_"classname" to create an instance of the preprocessor class. Sets its "id" and "parameters". Appends the instance to the list of preprocessors. Returns true on success and false on failure.

◆ appendProcessor() [1/3]

void compiler::appendProcessor ( compilerprocessor module)

Appends processor "module" to the list of processors.

◆ appendProcessor() [2/3]

bool compiler::appendProcessor ( const char *  filename,
const char *  classname,
const char *  id,
const char *  parameters 
)

Dynamically loads processor module "filename". Calls function new_"classname" to create an instance of the processor class. Sets its "id" and "parameters". Appends the instance to the list of processors. Returns true on success and false on failure.

◆ appendProcessor() [3/3]

bool compiler::appendProcessor ( const char *  filename,
const char *  classname,
const char *  id,
domnode parameters 
)

Dynamically loads processor module "filename". Calls function new_"classname" to create an instance of the processor class. Sets its "id" and "parameters". Appends the instance to the list of processors. Returns true on success and false on failure.

◆ clearModulePaths()

void compiler::clearModulePaths ( )

Removes all currently loaded module paths.

◆ clearPostProcessors()

void compiler::clearPostProcessors ( )

Removes all currently loaded postprocessor modules.

◆ clearPreProcessors()

void compiler::clearPreProcessors ( )

Removes all currently loaded preprocessor modules.

◆ clearProcessors()

void compiler::clearProcessors ( )

Removes all currently loaded processor modules.

◆ compile()

bool compiler::compile ( const char *  input,
stringbuffer output 
)

Passes "input" through the preprocessors, input grammar, processors, output grammar, and postprocessors.

If "output" is specified then the output is written to that buffer.

Neither "input" nor "output" need necessarily be supplied.

Alternatively, preprocessing modules could load a file or files, the locations of which are known or supplied in the metadata, and the postprocessing modules could write output to a file or files, the locations of which may be known by the calling process or returned in the metadata.

Returns true on success and false on failure.

◆ getError()

const char* compiler::getError ( )

Returns the error that occurred if compile() fails.

◆ getModulePaths()

linkedlist< char * >* compiler::getModulePaths ( )

Returns the list of loaded module paths.

◆ getPostProcessors()

linkedlist< compilermodule * >* compiler::getPostProcessors ( )

Returns the list of loaded postprocessor modules.

◆ getPreProcessors()

linkedlist< compilermodule * >* compiler::getPreProcessors ( )

Returns the list of loaded preprocessor modules.

◆ getProcessors()

linkedlist< compilermodule * >* compiler::getProcessors ( )

Returns the list of loaded processor modules.

◆ process()

bool compiler::process ( domnode root)

Passes already-parsed tree "root" through the set of loaded processor modules.

No pre-processing, parsing, post-processing, or writing back out is done.

This is useful for nesting sub-compilers inside of processor modules but could be used for other purposes as well.

Returns true on success and false on failure.

◆ setDebugLevel()

void compiler::setDebugLevel ( uint8_t  debuglevel)

Sets the debug level. Debug is written to standard out.

◆ setInputGrammar()

bool compiler::setInputGrammar ( const char *  grammar,
const char *  startsymbol 
)

Sets the input grammar and start symbol. Returns true on success and false if "grammar" is not a valid grammar.

◆ setMetaData()

void compiler::setMetaData ( domnode metadata)

Sets the compilation metadata.

The compilation metadata will be passed into every module and may be examined and/or altered by any of them.

The metadata may contain any information the user wishes to provide to or collect from the modules.

For example, during input, it may contain the names and locations of source code files, headers or other support files, search paths, database access information, etc.

When the compilation is complete, it may contain the locations of files that were created by the process.

◆ setOutputGrammar()

bool compiler::setOutputGrammar ( const char *  grammar)

Sets the output grammar. Returns true on success and false if "grammar" is not a valid grammar.