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