basix_doc 0.1
|
00001 00002 /****************************************************************************** 00003 * MODULE : source_track.hpp 00004 * DESCRIPTION: Tracking the source location of a generic object 00005 * COPYRIGHT : (C) 2007 Gregoire Lecerf and Joris van der Hoeven 00006 ******************************************************************************* 00007 * This software falls under the GNU general public license and comes WITHOUT 00008 * ANY WARRANTY WHATSOEVER. See the file $TEXMACS_PATH/LICENSE for more details. 00009 * If you don't have this file, write to the Free Software Foundation, Inc., 00010 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00011 ******************************************************************************/ 00012 00013 #ifndef __MMX_SOURCE_TRACK_HPP 00014 #define __MMX_SOURCE_TRACK_HPP 00015 #include <basix/string.hpp> 00016 #include <basix/identifiers.hpp> 00017 00019 00020 namespace mmx { 00021 00022 /****************************************************************************** 00023 * Positions in source files 00024 * IMPORTANT: all positions are counted from 0 internally. 00025 ******************************************************************************/ 00026 00027 class source_position { 00028 MMX_ALLOCATORS 00029 public: 00030 // This storage is redundant but helpful. 00031 nat position; 00032 nat line; 00033 nat column; 00034 source_position (void) : position (0), line (0), column (0) {} 00035 source_position (nat p, nat l, nat c): 00036 position (p), line (l), column (c) {} 00037 source_position (const source_position& p): 00038 position (p.position), line (p.line), column (p.column) {} 00039 inline source_position& operator= (const source_position& p) { 00040 position = p.position; 00041 line = p.line; 00042 column = p.column; 00043 return *this; 00044 } 00045 }; 00046 00047 inline source_position 00048 min (const source_position& p1, const source_position& p2) { 00049 return p1.position < p2.position? p1: p2; 00050 }; 00051 00052 inline source_position 00053 max (const source_position& p1, const source_position& p2) { 00054 return p1.position > p2.position? p1: p2; 00055 }; 00056 00057 /****************************************************************************** 00058 * Locations in source files (object + file name + range) 00059 ******************************************************************************/ 00060 00061 class source_location { 00062 MMX_ALLOCATORS 00063 public: 00064 generic obj; // located object 00065 string file_name; // file_name of the source_location 00066 nat input_number; // input number if file is stdin 00067 source_position begin; 00068 source_position end; 00069 00070 inline source_location () : obj (), file_name (""), 00071 input_number (0), begin (), end () {} 00072 inline source_location (generic g, string f, nat i, 00073 const source_position& b, 00074 const source_position& e) : 00075 obj (g), file_name (f), 00076 input_number (i), begin (b), end(e) {} 00077 inline source_location (const source_location& l) : 00078 obj (l.obj), file_name (l.file_name), 00079 input_number (l.input_number), 00080 begin (l.begin), end (l.end) {} 00081 inline source_location& operator= (const source_location& l) { 00082 obj = l.obj; 00083 file_name = l.file_name; 00084 input_number = l.input_number; 00085 begin = l.begin; 00086 end = l.end; 00087 return *this; 00088 } 00089 }; 00090 00091 inline bool 00092 is_nil (const source_location& l) { 00093 return (l.end.line == 0 && l.end.position == 0); 00094 }; 00095 00096 inline syntactic 00097 flatten (const source_location& l) { 00098 return flatten (gen (GEN_TUPLE, l.obj, l.file_name, l.input_number, 00099 gen (GEN_TUPLE, l.begin.line, l.begin.column), 00100 gen (GEN_TUPLE, l.end.line, l.end.column))); 00101 } 00102 00103 /****************************************************************************** 00104 * Keeping track of all source files 00105 ******************************************************************************/ 00106 00107 void store_interactive_number (nat n); 00108 // set the current input number 00109 00110 nat get_interactive_number (void); 00111 // retrieve the current interactive input number 00112 00113 void store_interactive_source (const string& data, 00114 nat n= get_interactive_number ()); 00115 // store next interactive input 00116 00117 string get_interactive_source (nat i); 00118 // return a specific innteractive source 00119 00120 void store_file_source (const string& file_name, const string& data); 00121 // store source 'data' for 'file_name' 00122 00123 string get_file_source (const string& file_name); 00124 // retrieve stored source for 'file_name' 00125 00126 string get_source (const string& file_name, nat input_number, nat line); 00127 // return a line in a file. 00128 // Empty file_name means interactive input. In this only situation 00129 // we use the input_number. 00130 00131 /****************************************************************************** 00132 * Associating source locations to objects 00133 ******************************************************************************/ 00134 00135 void source_insert (const generic& g, const source_location& l); 00136 // Insert g into source_source_location with source_location l. 00137 00138 void source_delete (const generic& g); 00139 // Delete g from source_source_location. 00140 00141 generic source_extend (const generic& g1, const generic& g2); 00142 // Set the source_location of g1 in order to contain g1 and g2. 00143 // Delete g2 in source_source_location and return g1. 00144 00145 inline generic 00146 source_extend (const generic& g1, const generic& g2, const generic& g3) { 00147 return source_extend (source_extend (g1, g2), g3); 00148 } 00149 00150 /****************************************************************************** 00151 * Tracking the source locations of objects 00152 ******************************************************************************/ 00153 00154 void source_locate (const generic& g, source_location& l); 00155 // Return the source_location of g in l. If l is already a valid 00156 // source_location in input, then the returned value for l is the 00157 // minimal interval containing both g and l. 00158 // WARNING: g must not share subexpressions in different files or inputs 00159 00160 source_location source_locate (const generic& g); 00161 // Return the source_location of g or nil. 00162 00163 bool source_exists (const generic& g); 00164 // Can we find a source location for g? 00165 00166 string source_file (const generic& g); 00167 // The source file for g occurs or "" 00168 00169 int source_line (const generic& g, const bool& last); 00170 // The first or last source line for g or 0 00171 00172 int source_column (const generic& g, const bool& last); 00173 // The first or last source column for g or 0 00174 00175 string source_begin (const generic& g); 00176 // String with starting position of source or "unknown" 00177 00178 string source_end (const generic& g); 00179 // String with end position of source or "unknown" 00180 00181 string source_string (const generic& g); 00182 // The source string for g or "" 00183 00184 string source_string_unindented (const generic& g); 00185 // The unindented source string for g or "" 00186 00187 string source_underlined (const generic& g); 00188 // The source string for g, underlined within its context, or "" 00189 00190 string source_error (const string& msg, const generic& where); 00191 // Build an error message which occurred in 'where' 00192 00193 string source_exception (const exception& e); 00194 // Build (backtraced) error message for the exception 'e' 00195 00196 } // namespace mmx 00197 #endif // __MMX_SOURCE_TRACK_HPP