Initial stacker checkin
[oota-llvm.git] / projects / Stacker / lib / compiler / StackerCompiler.h
1 //===-- StackerCompiler.h - Interface to the Stacker Compiler ---*- C++ -*-===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and donated to the LLVM research 
6 // group and is distributed under the University of Illinois Open Source 
7 // License. See LICENSE.TXT for details.
8 // 
9 //===----------------------------------------------------------------------===//
10 //
11 //  This header file defines the various variables that are shared among the 
12 //  different components of the parser...
13 //
14 //===----------------------------------------------------------------------===//
15
16 #ifndef LLVM_STACKERCOMPILER_H
17 #define LLVM_STACKERCOMPILER_H
18
19 #include <llvm/Constants.h>
20 #include <llvm/DerivedTypes.h>
21 #include <llvm/Function.h>
22 #include <llvm/Instruction.h>
23 #include <llvm/Module.h>
24 #include <llvm/Assembly/Parser.h>
25 #include <Support/StringExtras.h>
26
27 using namespace llvm;
28
29 // Global variables exported from the lexer...
30 extern std::FILE *Stackerin;
31 extern int Stackerlineno;
32 extern char* Stackertext;
33 extern int Stackerleng;
34
35 /// @brief This class provides the Compiler for the Stacker language. 
36 /// 
37 /// The main method to call is \c compile. The other methods are
38 /// all internal to the compiler and protected. In general the 
39 /// handle_* methods are called by the BISON generated parser
40 /// (see StackerParser.y). The methods returning Instruction* all
41 /// produce some snippet of code to manipulate the stack in some
42 /// way. These functions are just conveniences as they are used
43 /// often by the compiler.
44 class StackerCompiler
45 {
46     /// @name Constructors and Operators
47     /// @{
48     public:
49         /// Default Constructor
50         StackerCompiler();
51
52         /// Destructor
53         ~StackerCompiler();
54     private:
55         /// Do not copy StackerCompilers
56         StackerCompiler(const StackerCompiler&);
57
58         /// Do not copy StackerCompilers.
59         StackerCompiler& operator=(const StackerCompiler& );
60
61     /// @}
62     /// @name High Level Interface
63     /// @{
64     public:
65         /// @brief Compile a single file to LLVM bytecode.
66         ///
67         /// To use the StackerCompiler, just create one on
68         /// the stack and call this method.
69         Module* compile( 
70             const std::string& filename, ///< File to compile
71             bool echo, ///< Causes compiler to echo output
72             size_t stack_size ); ///< Size of generated stack
73     /// @}
74     /// @name Accessors
75     /// @{
76     public:
77         /// @brief Returns the name of the file being compiled.
78         std::string& filename() { return CurFilename; }
79
80     /// @}
81     /// @name Parse Handling Methods
82     /// @{
83     private:
84         /// Allow only the parser to access these methods. No
85         /// one else should call them.
86         friend int Stackerparse();
87
88         /// @brief Handle the start of a module
89         Module* handle_module_start();
90
91         /// @brief Handle the end of a module
92         /// @param mod The module we're defining.
93         Module* handle_module_end( Module* mod );
94
95         /// @brief Handle the start of a list of definitions
96         Module* handle_definition_list_start( );
97
98         /// @brief Handle the end of a list of definitions
99         /// @param mod The module we're constructing
100         /// @param definition A definition (function) to add to the module
101         Module* handle_definition_list_end( Module* mod, Function* definition );
102
103         /// @brief Handle creation of the MAIN definition
104         /// @param func The function to be used as the MAIN definition
105         Function* handle_main_definition( Function* func );
106
107         /// @brief Handle a forward definition
108         /// @param name The name of the definition being declared
109         Function* handle_forward( char* name );
110
111         /// @brief Handle a general definition
112         /// @param name The name of the definition being defined
113         /// @param func The Function definition.
114         Function* handle_definition( char* name, Function* func );
115
116         /// @brief Handle the start of a definition's word list
117         Function* handle_word_list_start();
118
119         /// @brief Handle the end of a definition's word list
120         /// @param func The function to which the basic block is added
121         /// @param next The block to add to the function
122         Function* handle_word_list_end( Function* func, BasicBlock* next );
123
124         /// @brief Handle an if statement, possibly without an else
125         /// @brief ifTrue The block to execute if true
126         /// @brief ifFalse The optional block to execute if false
127         BasicBlock* handle_if( char* ifTrue, char* ifFalse = 0 );
128
129         /// @brief Handle a while statement
130         /// @brief todo The block to repeatedly execute
131         BasicBlock* handle_while( char* todo );
132
133         /// @brief Handle an identifier to call the identified definition
134         /// @param name The name of the identifier to be called.
135         BasicBlock* handle_identifier( char * name );
136
137         /// @brief Handle the push of a string onto the stack
138         /// @param value The string to be pushed.
139         BasicBlock* handle_string( char * value );
140
141         /// @brief Handle the push of an integer onto the stack.
142         /// @param value The integer value to be pushed.
143         BasicBlock* handle_integer( const int32_t value );
144
145         /// @brief Handle one of the reserved words (given as a token)
146         BasicBlock* handle_word( int tkn );
147
148     /// @}
149     /// @name Utility functions
150     /// @{
151     public:
152         /// @brief Throws an exception to indicate an error
153         /// @param message The message to be output
154         /// @param line Override for the current line no
155         static inline void ThrowException( const std::string &message, 
156                 int line = -1)      
157         {
158           if (line == -1) line = Stackerlineno;
159           // TODO: column number in exception
160           throw ParseException(TheInstance->CurFilename, message, line);
161         }
162     private:
163         /// @brief Generate code to increment the stack index
164         Instruction* incr_stack_index( BasicBlock* bb, Value* );
165         /// @brief Generate code to decrement the stack index.
166         Instruction* decr_stack_index( BasicBlock* bb, Value* );
167         /// @brief Generate code to dereference the top of stack.
168         Instruction* get_stack_pointer( BasicBlock* bb, Value* );
169         /// @brief Generate code to push any value onto the stack.
170         Instruction* push_value( BasicBlock* bb, Value* value );
171         /// @brief Generate code to push a constant integer onto the stack.
172         Instruction* push_integer( BasicBlock* bb, int32_t value );
173         /// @brief Generate code to pop an integer off the stack.
174         Instruction* pop_integer( BasicBlock* bb );
175         /// @brief Generate code to push a string pointer onto the stack.
176         Instruction* push_string( BasicBlock* bb, const char* value );
177         /// @brief Generate code to pop a string pointer off the stack.
178         Instruction* pop_string( BasicBlock* bb );
179         /// @brief Generate code to get the top stack element.
180         Instruction* stack_top( BasicBlock* bb, Value* index );
181         /// @brief Generate code to get the top stack element as a string.
182         Instruction* stack_top_string( BasicBlock* bb, Value* index );
183         /// @brief Generate code to replace the top element of the stack.
184         Instruction* replace_top( BasicBlock* bb, Value* new_top, Value* index);
185
186     /// @}
187     /// @name Data Members (used during parsing)
188     /// @{
189     public:
190         static StackerCompiler* TheInstance;    ///< The instance for the parser
191
192     private:
193         std::string             CurFilename;    ///< Current file name
194         Module*                 TheModule;      ///< Module instance we'll build
195         Function*               TheFunction;    ///< Function we're building
196         FunctionType*           DefinitionType; ///< FT for Definitions
197         GlobalVariable*         TheStack;       ///< For referencing _stack_
198         GlobalVariable*         TheIndex;       ///< For referencing _index_
199         Function*               TheScanf;       ///< External input function
200         Function*               ThePrintf;      ///< External output function
201         Function*               TheExit;        ///< External exit function
202         GlobalVariable*         StrFormat;      ///< Format for strings
203         GlobalVariable*         NumFormat;      ///< Format for numbers
204         GlobalVariable*         ChrFormat;      ///< Format for chars
205         GlobalVariable*         InStrFormat;    ///< Format for input strings
206         GlobalVariable*         InNumFormat;    ///< Format for input numbers
207         GlobalVariable*         InChrFormat;    ///< Format for input chars
208         ConstantInt*            Zero;           ///< long constant 0
209         ConstantInt*            One;            ///< long constant 1
210         ConstantInt*            Two;            ///< long constant 2
211         ConstantInt*            Three;          ///< long constant 3
212         ConstantInt*            Four;           ///< long constant 4
213         ConstantInt*            Five;           ///< long constant 5
214         ConstantInt*            IZero;          ///< int constant 0
215         ConstantInt*            IOne;           ///< int constant 1
216         ConstantInt*            ITwo;           ///< int constant 2
217         std::vector<Value*>     no_arguments;   ///< no arguments for Stacker
218         bool                    echo;           ///< Echo flag
219         size_t                  stack_size;     ///< Size of stack to gen.
220         ArrayType*              stack_type;     ///< The type of the stack
221     /// @}
222 };
223
224 #endif