1 #ifndef LEX_H__ 2 #define LEX_H__ 1 3 4 #include "driver.h" 5 #include "typedefs.h" 6 #ifndef USE_NEW_INLINES 7 #include "strfuns.h" 8 #endif 9 10 /* --- Types --- */ 11 12 typedef struct source_file_s source_file_t; /* forward */ 13 14 /* --- struct source_loc_s: location within a source file --- 15 * 16 * This structure is used to identify the location of lexical elements 17 * in the input source. The pointers contained become invalid after 18 * a compilation has finished. 19 */ 20 21 typedef struct source_loc_s 22 { 23 source_file_t * file; /* The source file, if any, or NULL */ 24 int line; /* The source line */ 25 } source_loc_t; 26 27 28 /* --- struct source_file_s: a source file --- 29 * 30 * This structure is used to describe a source file used in the compilation. 31 * The embedded source_loc_t structure references the file this particular 32 * source file was included from. 33 * 34 * Together the structures form a tree, describing the include structure 35 * of the compiled program. With the end of the compilation, all contained 36 * pointers become invalid. 37 * 38 * The structures are additionally linked together into a singly linked list 39 * in order of allocation; the list is used by the lexer to deallocate the 40 * tree. 41 */ 42 43 struct source_file_s 44 { 45 source_file_t * next; /* next source_file structure, or NULL */ 46 char * name; /* Allocated: the name of the file */ 47 source_loc_t parent; /* the file/line this source was included from; 48 * or NULL if none. 49 */ 50 }; 51 52 53 /* --- struct lpc_predef_s: predefined preprocessor macros --- 54 * 55 * The structures are used in a list to store macro definitions 56 * given to the driver on the commandline. The list is evaluated 57 * when the lexer is first initialised. 58 */ 59 60 struct lpc_predef_s 61 { 62 char * flag; 63 /* The raw text of the definition in the form 'NAME' or 'NAME=<value>' 64 * in its own allocated memory. 65 */ 66 struct lpc_predef_s *next; 67 /* Next predefinition in the list, or NULL. 68 */ 69 }; 70 71 72 /* --- typedef defn_fun: dynamic macro expansion --- 73 * 74 * Functions of this type are used to provide dynamic macro expansions. 75 * When used in a macro definition instead of a static replacement text, 76 * they are called at every point of macro use. 77 * 78 * If the implemented macro takes no argument, NULL is passed 79 * in the call and the function has to return a fresh allocation of 80 * the replacement text. 81 * 82 * If the macro takes arguments, they are passed as char** with as 83 * many arguments as the definition requires. The macro has to add 84 * the replacement text via add_input() and return NULL. 85 * 86 * TODO: Also, the different handling of the replacement text is ugly. 87 */ 88 89 typedef char * (*defn_fun)(char **); 90 91 92 /* --- struct defn: definition of a macro --- 93 * 94 * Macros are stored in the ident_table[] as I_TYPE_DEFINEs. Their replacement 95 * can be given as literal text, or as the result of a function called every 96 * time the macro is used. 97 * 98 * The function is passed an char*[] with the current macro argument values, 99 * terminated with a NULL, and has to return an allocated c-string with 100 * the replacement text. 101 * 102 * The replacement text must not contain comments. 103 * 104 * Function macros (.nargs >= 0) expect the replacement text to contain 105 * special MARKS sequences ('@' followed by another character) to mark 106 * the places where the function arguments are to be inserted. The code 107 * of the second character minus ('@'+1) gives the number of the argument 108 * to insert. The sequence '@@' stands for the literal '@' character. 109 * 110 * Plain macros (.nargs < 0) take the replacement text as it is. 111 */ 112 113 struct defn 114 { 115 union { /* The replacement text: */ 116 char *str; /* given as tabled literal (.special is false) */ 117 defn_fun fun; /* return by fun() (.special is true) */ 118 } exps; 119 short nargs; /* Number of arguments, 0 for non-function macros 120 */ 121 SBool permanent; /* true: permanent define */ 122 SBool special; /* true: <fun> returns the replacement text */ 123 source_loc_t loc; /* location of the definition, 124 * NULL for predefined macros. 125 */ 126 }; 127 128 129 /* --- struct ident_s: known identifiers --- 130 * 131 * The structure is used to keep the information about all identifiers 132 * encountered so far (including reserved words, efuns, etc). 133 * 134 * There can several entries for the same identifier name but with 135 * different types in the table. These entries are put into a list formed 136 * by their .inferior pointers, sorted by falling type values. The entry 137 * with the highest type is the one linked into the hash chain. 138 * 139 * The identifiers are stored in a table of chains, hashed over their names. 140 * The most recently identifier always brought to the head of its hash-chain. 141 * 142 * Additionally, all efuns and defines are stored in their 143 * own 'all_...' lists, linked by the '.next_all' field. 144 */ 145 146 struct ident_s 147 { 148 string_t *name; /* Name of the identifier (tabled string) 149 * The inferiour structures (if any) and this 150 * structure all share the same reference to 151 * the string. */ 152 short type; /* Type of this entry */ 153 short hash; /* Hashvalue of this identifier */ 154 ident_t *next; /* Next in hash chain */ 155 ident_t *inferior; /* Ident of same name, but lower type */ 156 union { /* Type-depend data: */ 157 struct defn define; /* Macro definition */ 158 int code; /* Reserved word: lexem code */ 159 struct { /* Global identifier: */ 160 short function; 161 /* >= 0: lfun: Index number of the lfun in den function table, 162 * < 0: Undefined 163 */ 164 short variable; 165 /* >= 0: variable: Index number in the variable table. 166 * During compilation, virtual variables are offset 167 * by VIRTUAL_VAR_TAG. 168 * < 0: -2: efun/sefun, -1: lfun/inherited hidden var 169 */ 170 short efun; 171 /* efun: Index in instrs[], negative else 172 * < 0: -1: gvar/sefun 173 */ 174 short sim_efun; 175 /* simul-efun: Index in simul_efun[], negative else 176 * < 0: -1: efun/gvar 177 */ 178 #ifdef USE_STRUCTS 179 short struct_id; 180 /* struct index ('id') in the current program's struct table. 181 * < 0: undefined 182 */ 183 #endif 184 } global; 185 struct { /* Local identifier: */ 186 int num; /* Number, also the index on the stack */ 187 int context; /* -1 for normal locals, or the index 188 * in the context frame. In that case, 189 * .num is either -1 or the index 190 * of the related local of the defining 191 * function. 192 */ 193 int depth; /* Definition depth */ 194 } local; 195 } u; 196 ident_t *next_all; /* 'all_...' list link */ 197 }; 198 199 /* ident_t.type values: */ 200 201 #define I_TYPE_UNKNOWN 0 202 #define I_TYPE_GLOBAL 2 /* function, variable or efuns/simul_efuns */ 203 #define I_TYPE_LOCAL 3 204 #define I_TYPE_RESWORD 4 /* reserved word */ 205 #define I_TYPE_DEFINE 5 206 207 /* ident_t.global magic values */ 208 209 #define I_GLOBAL_FUNCTION_OTHER (-1) 210 #define I_GLOBAL_VARIABLE_OTHER (-1) 211 #define I_GLOBAL_VARIABLE_FUN (-2) 212 #define I_GLOBAL_EFUN_OTHER (-1) 213 #define I_GLOBAL_SEFUN_OTHER (-1) 214 #ifdef USE_STRUCTS 215 #define I_GLOBAL_STRUCT_NONE (-1) 216 #endif 217 218 219 #define lookup_predef(p) (p->type == I_TYPE_GLOBAL ? p->u.global.efun : -1) 220 221 222 #ifndef USE_NEW_INLINES 223 /* --- struct inline_fun: linked list element of saved function texts --- 224 * 225 * The functions inlined by (: ... :) have their code (plus the function 226 * header and trailer) saved for later parsing in a list of these 227 * structures. 228 */ 229 230 struct inline_fun 231 { 232 strbuf_t buf; /* the complete function text */ 233 struct inline_fun * next; /* next list element */ 234 }; 235 #endif /* USE_NEW_INLINES */ 236 237 238 /* --- Variables --- */ 239 240 extern struct lpc_predef_s * lpc_predefs; 241 extern int total_lines; 242 extern source_loc_t current_loc; 243 extern Bool pragma_strict_types; 244 extern Bool pragma_use_local_scopes; 245 extern Bool pragma_save_types; 246 extern Bool pragma_combine_strings; 247 extern Bool pragma_verbose_errors; 248 extern Bool pragma_no_clone; 249 extern Bool pragma_no_inherit; 250 extern Bool pragma_no_shadow; 251 extern Bool pragma_pedantic; 252 extern Bool pragma_range_check; 253 extern Bool pragma_warn_missing_return; 254 extern Bool pragma_warn_deprecated; 255 extern Bool pragma_warn_empty_casts; 256 extern Bool pragma_check_overloads; 257 extern Bool pragma_share_variables; 258 extern string_t *last_lex_string; 259 extern ident_t *all_efuns; 260 #ifndef USE_NEW_INLINES 261 extern struct inline_fun * first_inline_fun; 262 extern Bool insert_inline_fun_now; 263 extern unsigned int next_inline_fun; 264 #endif /* USE_NEW_INLINES */ 265 266 /* Values of pragma_strict_types */ 267 268 #define PRAGMA_WEAK_TYPES 0 269 #define PRAGMA_STRONG_TYPES 1 270 #define PRAGMA_STRICT_TYPES 2 271 272 273 /* --- Prototypes --- */ 274 275 extern void init_lexer(void); 276 extern int symbol_operator(const char *symbol, const char **endp); 277 extern void symbol_efun_str(const char *str, size_t len, svalue_t *sp, Bool is_efun); 278 extern void symbol_efun(string_t *name, svalue_t *sp); 279 extern void init_global_identifier (ident_t * ident, Bool bVariable); 280 extern ident_t *lookfor_shared_identifier(const char *, size_t, int, int, Bool); 281 #define make_shared_identifier(s,n,d) lookfor_shared_identifier(s,strlen(s),n,d, MY_TRUE) 282 #define find_shared_identifier(s,n,d) lookfor_shared_identifier(s,strlen(s),n,d, MY_FALSE) 283 #define make_shared_identifier_n(s,l,n,d) lookfor_shared_identifier(s,l,n,d, MY_TRUE) 284 #define find_shared_identifier_n(s,l,n,d) lookfor_shared_identifier(s,l,n,d, MY_FALSE) 285 #define make_shared_identifier_mstr(s,n,d) lookfor_shared_identifier(get_txt(s),mstrsize(s),n,d, MY_TRUE) 286 #define find_shared_identifier_mstr(s,n,d) lookfor_shared_identifier(get_txt(s),mstrsize(s),n,d, MY_FALSE) 287 extern ident_t *make_global_identifier(char *, int); 288 extern void free_shared_identifier(ident_t*); 289 extern int yylex(void); 290 extern void end_new_file(void); 291 extern void lex_close(char *msg); 292 extern void start_new_file(int fd, const char * fname); 293 extern char *get_f_name(int n); 294 extern void free_defines(void); 295 extern size_t show_lexer_status (strbuf_t * sbuf, Bool verbose); 296 extern void set_inc_list(vector_t *v); 297 extern void remove_unknown_identifier(void); 298 extern char *lex_error_context(void); 299 extern svalue_t *f_expand_define(svalue_t *sp); 300 extern char * lex_parse_number (char * cp, unsigned long * p_num, Bool * p_overflow); 301 #ifdef USE_NEW_INLINES 302 extern void * get_include_handle (void); 303 #endif /* USE_NEW_INLINES */ 304 305 #ifdef GC_SUPPORT 306 extern void count_lex_refs(void); 307 #endif /* GC_SUPPORT */ 308 309 #endif /* LEX_H__ */ 310