-
Notifications
You must be signed in to change notification settings - Fork 1
/
compiler.h
293 lines (248 loc) · 9.11 KB
/
compiler.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#ifndef COMPILER_H
#define COMPILER_H
#include "trees.h"
#include "lex.h"
#include "program.h"
#define _YACC_
#define YYMAXDEPTH 600
/*
* Information for allocating a block that can grow dynamically
* using realloc. That means that no pointers should be kept into such
* an area, as it might be moved.
*/
typedef struct {
char *block;
int current_size;
int max_size;
} mem_block_t;
#define START_BLOCK_SIZE 4096
/* NUMPAREAS ares are saved with the program code after compilation,
* the rest are only temporary.
*/
#define A_PROGRAM 0 /* executable code */
#define A_FUNCTIONS 1
#define A_STRINGS 2 /* table of strings */
#define A_VAR_NAME 3
#define A_VAR_TYPE 4
#define A_LINENUMBERS 5 /* linenumber information */
#define A_FILE_INFO 6 /* start of file line nos */
#define A_INHERITS 7 /* table of inherited progs */
#define A_CLASS_DEF 8
#define A_CLASS_MEMBER 9
#define A_ARGUMENT_TYPES 10 /* */
#define A_ARGUMENT_INDEX 11 /* */
#define NUMPAREAS 12
#define A_CASES 13 /* keep track of cases */
#define A_STRING_NEXT 14 /* next prog string in hash chain */
#define A_STRING_REFS 15 /* reference count of prog string */
#define A_INCLUDES 16 /* list of included files */
#define A_PATCH 17 /* for save_binary() */
#define A_FUNCTIONALS 18
#define A_FUNCTION_DEFS 19
#define A_VAR_TEMP 20 /* table of variables */
#define NUMAREAS 22
#define TREE_MAIN 0
#define TREE_INIT 1
#define NUMTREES 2
#define CURRENT_PROGRAM_SIZE (prog_code - mem_block[A_PROGRAM].block)
#define UPDATE_PROGRAM_SIZE mem_block[A_PROGRAM].current_size = CURRENT_PROGRAM_SIZE
/*
* Types available. The number '0' is valid as any type. These types
* are only used by the compiler, when type checks are enabled. Compare with
* the run-time types, named T_ interpret.h.
*/
#define TYPE_UNKNOWN 0 /* This type must be casted */
#define TYPE_ANY 1 /* Will match any type */
#define TYPE_NOVALUE 2
#define TYPE_VOID 3
#define TYPE_NUMBER 4
#define TYPE_STRING 5
#define TYPE_OBJECT 6
#define TYPE_MAPPING 7
#define TYPE_FUNCTION 8
#define TYPE_REAL 9
#define TYPE_BUFFER 10
#define TYPE_MASK 0xf
typedef struct {
int runtime_index;
ident_hash_elem_t *ihe;
} local_info_t;
extern mem_block_t mem_block[NUMAREAS];
extern char *compiler_type_names[];
#define LOOP_CONTEXT 0x1
#define SWITCH_CONTEXT 0x2
#define SWITCH_STRINGS 0x4
#define SWITCH_NUMBERS 0x8
#define SWITCH_DEFAULT 0x10
#define SWITCH_RANGES 0x20
#define LOOP_FOREACH 0x40
#define SPECIAL_CONTEXT 0x80
#define ARG_LIST 0x100
typedef struct function_context_s {
parse_node_t *values_list;
short bindable;
short num_parameters;
short num_locals;
struct function_context_s *parent;
} function_context_t;
extern function_context_t *current_function_context;
extern int var_defined;
extern parse_node_t *comp_trees[NUMTREES];
extern unsigned short *comp_def_index_map;
extern unsigned short *func_index_map;
typedef struct compiler_temp_t {
unsigned short flags;
unsigned short offset;
unsigned short function_index_offset;
struct program_s *prog; /* inherited if nonzero */
union {
function_t *func;
int index;
} u;
struct compiler_temp_t *next;
} compiler_temp_t;
/*
* Some good macros to have.
*/
#define IS_CLASS(t) ((t & (TYPE_MOD_ARRAY | TYPE_MOD_CLASS)) == TYPE_MOD_CLASS)
#define CLASS_IDX(t) (t & ~(DECL_MODS | TYPE_MOD_CLASS))
#define COMP_TYPE(e, t) (!(e & (TYPE_MOD_ARRAY | TYPE_MOD_CLASS)) \
&& (compatible[(unsigned char)(e & ~DECL_MODS)] & (1 << (t))))
#define IS_TYPE(e, t) (!(e & (TYPE_MOD_ARRAY | TYPE_MOD_CLASS)) \
&& (is_type[(unsigned char)(e & ~DECL_MODS)] & (1 << (t))))
#define FUNCTION_TEMP(n) ((compiler_temp_t *)mem_block[A_FUNCTION_DEFS].block + (n))
#define FUNCTION_NEXT(n) (FUNCTION_TEMP(n)->next)
/* function_t from A_FUNCTIONS index */
#define FUNC(n) ((function_t *)mem_block[A_FUNCTIONS].block + (n))
/* program for inherited entry from full function index */
#define FUNCTION_PROG(n) (FUNCTION_TEMP(n)->prog)
#define FUNCTION_ALIAS(n) (FUNCTION_TEMP(n)->alias_for)
/* function_t from full function index */
#define FUNCTION_DEF(n) (FUNCTION_PROG(n) ? FUNCTION_TEMP(n)->u.func : FUNC(FUNCTION_TEMP(n)->u.index))
/* flags from full function index */
#define FUNCTION_FLAGS(n) (FUNCTION_TEMP(n)->flags)
#define NUM_INHERITS (mem_block[A_INHERITS].current_size / sizeof(inherit_t))
#define INHERIT(n) ((inherit_t *)mem_block[A_INHERITS].block + (n))
#define VAR_TEMP(n) ((variable_t *)mem_block[A_VAR_TEMP].block + (n))
#define SIMUL(n) (simuls[n].func)
#define PROG_STRING(n) (((char **)mem_block[A_STRINGS].block)[n])
#define CLASS(n) ((class_def_t *)mem_block[A_CLASS_DEF].block + (n))
#if !defined(__alpha) && !defined(cray)
#define align(x) (((x) + 3) & ~3)
#else
#define align(x) (((x) + 7) & ~7)
#endif
#define SOME_NUMERIC_CASE_LABELS 0x40000
#define NO_STRING_CASE_LABELS 0x80000
#define ARG_IS_PROTO 1
#define ARG_IS_VARARGS 2
#define NOVALUE_USED_FLAG 1024
int validate_function_call PROT((int, parse_node_t *));
parse_node_t *validate_efun_call PROT((int, parse_node_t *));
extern mem_block_t mem_block[];
extern int exact_types, global_modifiers;
extern int current_type;
extern char *prog_code;
extern char *prog_code_max;
extern program_t NULL_program;
extern unsigned char string_tags[0x20];
extern short freed_string;
extern local_info_t *locals, *locals_ptr;
extern unsigned short *type_of_locals, *type_of_locals_ptr;
extern int current_number_of_locals;
extern int max_num_locals;
extern int current_tree;
extern int type_of_locals_size;
extern int locals_size;
extern int current_number_of_locals;
extern int max_num_locals;
extern short compatible[11];
extern short is_type[11];
extern int comp_last_inherited;
char *get_type_modifiers PROT((char *, char *, int));
char *get_two_types PROT((char *, char *, int, int));
char *get_type_name PROT((char *, char *, int));
void init_locals PROT((void));
void save_file_info PROT((int, int));
int add_program_file PROT((char *, int));
void yyerror PROT((char *));
void yywarn PROT((char *));
void switch_to_block PROT((int));
char *the_file_name PROT((char *));
void free_all_local_names PROT((int));
void pop_n_locals PROT((int));
void reactivate_current_locals PROT((void));
void clean_up_locals PROT((void));
void deactivate_current_locals PROT((void));
int add_local_name PROT((char *, int));
void reallocate_locals PROT((void));
void initialize_locals PROT((void));
int get_id_number PROT((void));
program_t *compile_file PROT((int, char *));
void reset_function_blocks PROT((void));
void copy_variables PROT((program_t *, int));
void copy_structures PROT((program_t *));
int copy_functions PROT((program_t *, int));
void type_error PROT((char *, int));
int compatible_types PROT((int, int));
int compatible_types2 PROT((int, int));
int arrange_call_inherited PROT((char *, parse_node_t *));
void add_arg_type PROT((unsigned short));
int define_new_function PROT((char *, int, int, int, int));
int define_variable PROT((char *, int));
int define_new_variable PROT((char *, int));
short store_prog_string PROT((char *));
void free_prog_string PROT((short));
#ifdef DEBUG
int dump_function_table PROT((void));
#endif
void prepare_cases PROT((parse_node_t *, int));
void push_func_block PROT((void));
void pop_func_block PROT((void));
int decl_fix PROT((int));
parse_node_t *check_refs PROT((int, parse_node_t *, parse_node_t *));
int lookup_any_class_member PROT((char *, unsigned char *));
int lookup_class_member PROT((int, char *, unsigned char *));
parse_node_t *reorder_class_values PROT((int, parse_node_t *));
parse_node_t *promote_to_float PROT((parse_node_t *));
parse_node_t *promote_to_int PROT((parse_node_t *));
parse_node_t *do_promotions PROT((parse_node_t *, int));
parse_node_t *throw_away_call PROT((parse_node_t *));
parse_node_t *throw_away_mapping PROT((parse_node_t *));
#define realloc_mem_block(m) do { \
mem_block_t *M = m; \
M->max_size <<= 1; \
M->block = DREALLOC(M->block, M->max_size, TAG_COMPILER, "realloc_mem_block"); \
} while (0)
#define add_to_mem_block(n, data, size) do { \
mem_block_t *mbp = &mem_block[n]; \
int Size = size; \
\
if (mbp->current_size + Size > mbp->max_size) { \
do { \
mbp->max_size <<= 1; \
} while (mbp->current_size + Size > mbp->max_size); \
\
mbp->block = DREALLOC(mbp->block, mbp->max_size, TAG_COMPILER, "insert_in_mem_block"); \
} \
memcpy(mbp->block + mbp->current_size, data, Size); \
mbp->current_size += Size; \
} while (0)
#ifndef SUPPRESS_COMPILER_INLINES
INLINE_STATIC
char *allocate_in_mem_block P2(int, n, int, size)
{
mem_block_t *mbp = &mem_block[n];
char *ret;
if (mbp->current_size + size > mbp->max_size) {
do {
mbp->max_size <<= 1;
} while (mbp->current_size + size > mbp->max_size);
mbp->block = DREALLOC(mbp->block, mbp->max_size, TAG_COMPILER, "insert_in_mem_block");
}
ret = mbp->block + mbp->current_size;
mbp->current_size += size;
return ret;
}
#endif
#endif