00001 /*---------------------------------------------------------------------\ 00002 | | 00003 | __ __ ____ _____ ____ | 00004 | \ \ / /_ _/ ___|_ _|___ \ | 00005 | \ V / _` \___ \ | | __) | | 00006 | | | (_| |___) || | / __/ | 00007 | |_|\__,_|____/ |_| |_____| | 00008 | | 00009 | core system | 00010 | (C) SuSE GmbH | 00011 \----------------------------------------------------------------------/ 00012 00013 File: YBlock.h 00014 00015 Author: Klaus Kaempf <kkaempf@suse.de> 00016 Stanislav Visnovsky <visnov@suse.cz> 00017 Maintainer: Stanislav Visnovsky <visnov@suse.cz> 00018 00019 /-*/ 00020 // -*- c++ -*- 00021 00022 #ifndef YBlock_h 00023 #define YBlock_h 00024 00025 #include <string> 00026 #include <list> 00027 using std::string; 00028 #include <y2util/Ustring.h> 00029 00030 #include <y2/Y2Namespace.h> 00031 #include "ycp/YStatement.h" 00032 00033 //------------------------------------------------------------------- 00034 00043 class YSImport; 00044 00049 class YBlock : public YCode, public Y2Namespace 00050 { 00051 REP_BODY (YBlock); 00052 00053 public: 00054 // block kinds 00055 typedef enum { 00056 b_unknown = 0, // 0: unspecified 00057 b_module, // 1: toplevel module (-> m_table != 0) 00058 b_file, // 2: toplevel file block 00059 b_statement, // 3: used as statement (local block which might contain return) 00060 b_definition, // 4: used as function definition 00061 b_value, // 5: used as value (intermediate block) 00062 b_namespace, // 6: block defines a namespace 00063 b_using // 7: block is evaluated in different namespace 00064 } blockkind_t; 00065 00066 private: 00067 // -------------------------------- 00068 // general block data 00069 00070 // Block kind 00071 // b_statement == implict return YCPNull() (block is statement, default) 00072 // else YCPVoid () (treat block as expression) 00073 blockkind_t m_kind; 00074 00075 // Pointer to name of block. 00076 // normaly empty, non-empty for b_module and b_namespace 00077 string m_name; 00078 00079 // -------------------------------- 00080 // Environment 00081 // keep track of symbols entered into SymbolTable (declared 00082 // in this block), we must remove then at finishBlock() 00083 // so they go out of scope 00084 00085 struct yTElist { 00086 struct yTElist *next; 00087 TableEntry *tentry; 00088 unsigned int position; 00089 }; 00090 typedef struct yTElist yTElist_t; 00091 00092 // block environment (linked list of local declarations) 00093 // as TableEntry used during parse time 00094 yTElist_t *m_tenvironment; 00095 00096 // pointer to last declaration for easier append 00097 // points to 0 after detachEnvironment() 00098 yTElist_t *m_last_tparm; 00099 00100 // -------------------------------- 00101 // source file, needs environment 00102 00103 // Point (Filename) of source file (global SymbolEntry:c_filename) 00104 // always points to the current file. During include, it points to 00105 // a chain <include file> -> <toplevel file>. See Point.h 00106 const Point *m_point; 00107 00108 // -------------------------------- 00109 // Block content 00110 00111 struct stmtlist { 00112 YStatementPtr stmt; 00113 struct stmtlist *next; 00114 }; 00115 typedef struct stmtlist stmtlist_t; 00116 00117 // linked list of statements 00118 stmtlist_t *m_statements; 00119 00120 // pointer to last statement for easier append 00121 stmtlist_t *m_last_statement; 00122 00126 typedef std::list<std::string> stringlist_t; 00127 stringlist_t* m_includes; 00128 00129 constTypePtr m_type; 00130 00131 bool m_running; 00132 00133 public: 00134 //--------------------------------------------------------------- 00135 // Constructor / Destructor 00136 00137 // toplevel block 00138 YBlock (const std::string & filename, blockkind_t kind = b_unknown); 00139 // midlevel block 00140 YBlock (const Point *point); 00141 YBlock (bytecodeistream & str); 00142 ~YBlock (); 00143 00144 //--------------------------------------------------------------- 00145 // YCode 00146 00147 // warning: it is return type in fact! 00148 constTypePtr type () const { return m_type; } 00149 00150 // set the return type of this block 00151 void setType (constTypePtr type); 00152 00153 // the whole block is parsed, do final changes 00154 void finishBlock (); 00155 00156 // evaluate the complete block 00157 virtual YCPValue evaluate (bool cse = false); 00158 00159 // evaluate the block from the given statement (switch) 00160 YCPValue evaluateFrom (int statement_index); 00161 00162 // evaluate a single statement 00163 // this is a special purpose interface for macro player 00164 // does not handle break, return 00165 // and also skips initial 'import' statements (e.g. autogenerated 00166 // import "UI") by default 00167 YCPValue evaluate (int statement_index, bool skip_initial_imports = true); 00168 00169 //--------------------------------------------------------------- 00170 // member access 00171 00172 // return name of source file 00173 virtual const std::string filename () const; 00174 00175 // SymbolTable for global module environment (m_kind == b_module) 00176 // non-const return since we must be able to find() which tracks references 00177 virtual SymbolTable *table () const; 00178 00179 virtual Y2Function* createFunctionCall (const string name, constFunctionTypePtr type); 00180 00181 // returns the current parse file as Point 00182 const Point *point () const; 00183 00184 // returns the name of the block 00185 const string name () const; 00186 void setName (const string & name); 00187 00188 const Y2Namespace *nameSpace () const { return (const Y2Namespace *)this; } 00189 Y2Namespace *nameSpace () { return (Y2Namespace *)this; } 00190 00191 //--------------------------------------------------------------- 00192 // block kind 00193 00194 // set block kind 00195 void setKind (blockkind_t kind); 00196 00197 // get block kind 00198 blockkind_t kind () const; 00199 00200 // block is toplevel block of a module 00201 bool isModule () const { return (m_kind == b_module); } // toplevel module block 00202 bool isFile () const { return (m_kind == b_file); } // toplevel file block 00203 bool isStatement () const { return (m_kind == b_statement); } // used as statement (local block) 00204 bool isDefinition () const { return (m_kind == b_definition); } // used as function definition 00205 bool isValue () const { return (m_kind == b_value); } // used as value (intermediate block) 00206 bool isNamespace () const { return (m_kind == b_namespace); } // block defines a namespace 00207 00208 //--------------------------------------------------------------- 00209 // Value / Entry 00210 00211 // add new value code to this block 00212 // (used for functions which accept either symbolic variables or values, e.g. foreach()) 00213 // returns position 00214 unsigned int newValue (constTypePtr type, YCodePtr code); 00215 00216 // add a new table entry to this block 00217 // and attach it to m_tenvironment 00218 // return NULL if symbol of same name already declared in this block 00219 TableEntry *newEntry (const char *name, SymbolEntry::category_t cat, constTypePtr type, unsigned int line); 00220 00221 //--------------------------------------------------------------- 00222 // Namespace 00223 00224 // add a new namespace entry to this block 00225 // and attach it to m_tenvironment 00226 // return NULL if symbol of same name already declared in this block 00227 TableEntry *newNamespace (const string & name, Y2Namespace *name_space, int line); 00228 00229 //--------------------------------------------------------------- 00230 // symbol handling 00231 00232 // Attach entry (variable, typedef, ...) to local environment 00233 void attachEntry (TableEntry *entry); 00234 00235 // Detach local environment from symbol table 00236 void detachEnvironment (SymbolTable *table); 00237 00238 //--------------------------------------------------------------- 00239 // statement handling 00240 00241 // Attach statement to end of block 00242 void attachStatement (YStatementPtr statement); 00243 00244 // Pretach statement to beginning block 00245 void pretachStatement (YStatementPtr statement); 00246 00247 // count the statements in this block 00248 int statementCount () const; 00249 00250 //--------------------------------------------------------------- 00251 // return 00252 00253 // returns the return statement if the block just consists of a single return 00254 YSReturnPtr justReturn () const; 00255 00256 //--------------------------------------------------------------- 00257 // include 00258 00259 // end of include block, 'pop' head of m_point chain 00260 void endInclude (); 00261 00265 bool isIncluded (string includename) const; 00266 void addIncluded (string includename); 00267 00268 //--------------------------------------------------------------- 00269 // string output 00270 00271 string toString () const; 00272 string environmentToString () const; 00273 string toStringSwitch (map<YCPValue, int, ycpless> cases, int defaultcase) const; 00274 00275 //--------------------------------------------------------------- 00276 // stream output 00277 00278 // write block to stream 00279 std::ostream & toStream (std::ostream & str) const; 00280 00281 }; 00282 00283 00284 #endif // YBlock_h