| //===-- StackerCompiler.h - Interface to the Stacker Compiler ---*- C++ -*-===// |
| // |
| // The LLVM Compiler Infrastructure |
| // |
| // This file was developed by Reid Spencer and donated to the LLVM research |
| // group and is distributed under the University of Illinois Open Source |
| // License. See LICENSE.TXT for details. |
| // |
| //===----------------------------------------------------------------------===// |
| // |
| // This header file defines the various variables that are shared among the |
| // different components of the parser... |
| // |
| //===----------------------------------------------------------------------===// |
| |
| #ifndef LLVM_STACKERCOMPILER_H |
| #define LLVM_STACKERCOMPILER_H |
| |
| #include <llvm/Constants.h> |
| #include <llvm/DerivedTypes.h> |
| #include <llvm/Function.h> |
| #include <llvm/Instruction.h> |
| #include <llvm/Module.h> |
| #include <llvm/Assembly/Parser.h> |
| #include <llvm/ADT/StringExtras.h> |
| |
| using namespace llvm; |
| |
| // Global variables exported from the lexer... |
| extern std::FILE *Stackerin; |
| extern int Stackerlineno; |
| extern char* Stackertext; |
| extern int Stackerleng; |
| |
| /// @brief This class provides the Compiler for the Stacker language. |
| /// |
| /// The main method to call is \c compile. The other methods are |
| /// all internal to the compiler and protected. In general the |
| /// handle_* methods are called by the BISON generated parser |
| /// (see StackerParser.y). The methods returning Instruction* all |
| /// produce some snippet of code to manipulate the stack in some |
| /// way. These functions are just conveniences as they are used |
| /// often by the compiler. |
| class StackerCompiler |
| { |
| /// @name Constructors and Operators |
| /// @{ |
| public: |
| /// Default Constructor |
| StackerCompiler(); |
| |
| /// Destructor |
| ~StackerCompiler(); |
| private: |
| /// Do not copy StackerCompilers |
| StackerCompiler(const StackerCompiler&); |
| |
| /// Do not copy StackerCompilers. |
| StackerCompiler& operator=(const StackerCompiler& ); |
| |
| /// @} |
| /// @name High Level Interface |
| /// @{ |
| public: |
| /// @brief Compile a single file to LLVM bytecode. |
| /// |
| /// To use the StackerCompiler, just create one on |
| /// the stack and call this method. |
| Module* compile( |
| const std::string& filename, ///< File to compile |
| bool echo, ///< Causes compiler to echo output |
| unsigned optLevel, ///< Level of optimization |
| size_t stack_size ); ///< Size of generated stack |
| /// @} |
| /// @name Accessors |
| /// @{ |
| public: |
| /// @brief Returns the name of the file being compiled. |
| std::string& filename() { return CurFilename; } |
| |
| /// @} |
| /// @name Parse Handling Methods |
| /// @{ |
| private: |
| /// Allow only the parser to access these methods. No |
| /// one else should call them. |
| friend int Stackerparse(); |
| |
| /// @brief Handle the start of a module |
| Module* handle_module_start(); |
| |
| /// @brief Handle the end of a module |
| /// @param mod The module we're defining. |
| Module* handle_module_end( Module* mod ); |
| |
| /// @brief Handle the start of a list of definitions |
| Module* handle_definition_list_start( ); |
| |
| /// @brief Handle the end of a list of definitions |
| /// @param mod The module we're constructing |
| /// @param definition A definition (function) to add to the module |
| Module* handle_definition_list_end( Module* mod, Function* definition ); |
| |
| /// @brief Handle creation of the MAIN definition |
| /// @param func The function to be used as the MAIN definition |
| Function* handle_main_definition( Function* func ); |
| |
| /// @brief Handle a forward definition |
| /// @param name The name of the definition being declared |
| Function* handle_forward( char* name ); |
| |
| /// @brief Handle a general definition |
| /// @param name The name of the definition being defined |
| /// @param func The Function definition. |
| Function* handle_definition( char* name, Function* func ); |
| |
| /// @brief Handle the start of a definition's word list |
| Function* handle_word_list_start(); |
| |
| /// @brief Handle the end of a definition's word list |
| /// @param func The function to which the basic block is added |
| /// @param next The block to add to the function |
| Function* handle_word_list_end( Function* func, BasicBlock* next ); |
| |
| /// @brief Handle an if statement, possibly without an else |
| /// @brief ifTrue The block to execute if true |
| /// @brief ifFalse The optional block to execute if false |
| BasicBlock* handle_if( char* ifTrue, char* ifFalse = 0 ); |
| |
| /// @brief Handle a while statement |
| /// @brief todo The block to repeatedly execute |
| BasicBlock* handle_while( char* todo ); |
| |
| /// @brief Handle an identifier to call the identified definition |
| /// @param name The name of the identifier to be called. |
| BasicBlock* handle_identifier( char * name ); |
| |
| /// @brief Handle the push of a string onto the stack |
| /// @param value The string to be pushed. |
| BasicBlock* handle_string( char * value ); |
| |
| /// @brief Handle the push of an integer onto the stack. |
| /// @param value The integer value to be pushed. |
| BasicBlock* handle_integer( const int64_t value ); |
| |
| /// @brief Handle one of the reserved words (given as a token) |
| BasicBlock* handle_word( int tkn ); |
| |
| /// @} |
| /// @name Utility functions |
| /// @{ |
| public: |
| /// @brief Throws an exception to indicate an error |
| /// @param message The message to be output |
| /// @param line Override for the current line no |
| static inline void ThrowException( const std::string &message, |
| int line = -1) |
| { |
| if (line == -1) line = Stackerlineno; |
| // TODO: column number in exception |
| throw ParseException(TheInstance->CurFilename, message, line); |
| } |
| private: |
| /// @brief Generate code to increment the stack index |
| Instruction* incr_stack_index( BasicBlock* bb, Value* ); |
| /// @brief Generate code to decrement the stack index. |
| Instruction* decr_stack_index( BasicBlock* bb, Value* ); |
| /// @brief Generate code to dereference the top of stack. |
| Instruction* get_stack_pointer( BasicBlock* bb, Value* ); |
| /// @brief Generate code to push any value onto the stack. |
| Instruction* push_value( BasicBlock* bb, Value* value ); |
| /// @brief Generate code to push a constant integer onto the stack. |
| Instruction* push_integer( BasicBlock* bb, int64_t value ); |
| /// @brief Generate code to pop an integer off the stack. |
| Instruction* pop_integer( BasicBlock* bb ); |
| /// @brief Generate code to push a string pointer onto the stack. |
| Instruction* push_string( BasicBlock* bb, const char* value ); |
| /// @brief Generate code to pop a string pointer off the stack. |
| Instruction* pop_string( BasicBlock* bb ); |
| /// @brief Generate code to get the top stack element. |
| Instruction* stack_top( BasicBlock* bb, Value* index ); |
| /// @brief Generate code to get the top stack element as a string. |
| Instruction* stack_top_string( BasicBlock* bb, Value* index ); |
| /// @brief Generate code to replace the top element of the stack. |
| Instruction* replace_top( BasicBlock* bb, Value* new_top, Value* index); |
| |
| /// @} |
| /// @name Data Members (used during parsing) |
| /// @{ |
| public: |
| static StackerCompiler* TheInstance; ///< The instance for the parser |
| |
| private: |
| std::string CurFilename; ///< Current file name |
| Module* TheModule; ///< Module instance we'll build |
| Function* TheFunction; ///< Function we're building |
| FunctionType* DefinitionType; ///< FT for Definitions |
| GlobalVariable* TheStack; ///< For referencing _stack_ |
| GlobalVariable* TheIndex; ///< For referencing _index_ |
| Function* TheScanf; ///< External input function |
| Function* ThePrintf; ///< External output function |
| Function* TheExit; ///< External exit function |
| GlobalVariable* StrFormat; ///< Format for strings |
| GlobalVariable* NumFormat; ///< Format for numbers |
| GlobalVariable* ChrFormat; ///< Format for chars |
| GlobalVariable* InStrFormat; ///< Format for input strings |
| GlobalVariable* InNumFormat; ///< Format for input numbers |
| GlobalVariable* InChrFormat; ///< Format for input chars |
| ConstantInt* Zero; ///< long constant 0 |
| ConstantInt* One; ///< long constant 1 |
| ConstantInt* Two; ///< long constant 2 |
| ConstantInt* Three; ///< long constant 3 |
| ConstantInt* Four; ///< long constant 4 |
| ConstantInt* Five; ///< long constant 5 |
| std::vector<Value*> no_arguments; ///< no arguments for Stacker |
| bool echo; ///< Echo flag |
| size_t stack_size; ///< Size of stack to gen. |
| ArrayType* stack_type; ///< The type of the stack |
| /// @} |
| }; |
| |
| #endif |