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