%code required{}
[henge/webcc.git] / src / apc / ir-mem.c
1 #include <errno.h>
2 #include <stdio.h>
3 #include <stdint.h> //uint64_t
4 #include <string.h> //memmove
5 #include <stdlib.h> //malloc
6 #include <apc/ir.h>
7
8 #define CURR_CDAT (*cdat_stackp)
9 #define CURR_SET set_list[CURR_CDAT->num_sets]
10 #define CURR_ELE ele_list[CURR_CDAT->CURR_SET.num_ele]
11 #define PREV_REF (ref_buf[num_refs-1])
12 #define CURR_REF (ref_buf[num_refs])
13 #define PREV_ODAT (odat_buf[num_odats-1])
14 #define CURR_ODAT (odat_buf[num_odats])
15 #define CURR_VDAT (vdat_buf[num_vdats])
16 #define PREV_VDAT (vdat_buf[num_vdats-1])
17 #define CURR_MODEL model_list[CURR_VDAT->num_models]
18 #define CURR_LINK (link_buf[num_links])
19 #define CURR_POST (post_buf[num_posts])
20
21 int num_cdats = 0;
22 int curr_max_cdats = PTRS_IN_PAGE;
23
24 int num_odats = 0;
25 int curr_max_odats = PTRS_IN_PAGE;
26
27
28 int num_vdats = 0;
29 int curr_max_vdats = PTRS_IN_PAGE;
30
31 int num_refs = 0;
32 int curr_max_refs = PTRS_IN_PAGE;
33 uint64_t ss_ref_id = 0x00FFFFFF; /* system space for ref_ids */
34
35 int num_links = 0;
36 int curr_max_links = PTRS_IN_PAGE;
37
38 int num_posts = 0;
39 int curr_max_posts = PTRS_IN_PAGE;
40
41 void
42 ir_init()
43 {
44 /* Init root cdat and stack */
45 char root[4] = "root";
46
47 cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof(struct cdat) );
48 cdat_buf[num_cdats]->idx = 0;
49 memmove(cdat_buf[num_cdats]->name, root, 4);
50
51 cdat_stackp = cdat_stack;
52 *cdat_stackp = cdat_buf[num_cdats++];
53
54 /* Init first odat */
55 if( (CURR_ODAT = (struct odat*) malloc(sizeof(struct odat))) == NULL)
56 perror("malloc first odat failed");
57
58 /* init first vdat*/
59 if( (CURR_VDAT = (struct vdat*) malloc(sizeof(struct vdat))) == NULL)
60 perror("malloc first vdat failed");
61
62 /* Init first ref */
63 if( (CURR_REF = (struct ref*) malloc(sizeof(struct ref))) == NULL)
64 perror("malloc first ref failed");
65
66 /* Init first link */
67 if( (CURR_LINK = (struct link*) malloc(sizeof(struct link))) == NULL)
68 perror("malloc first link failed");
69
70 /* Init first post */
71 if( (CURR_POST = (struct ref*) malloc(sizeof(struct ref))) == NULL)
72 perror("malloc first post failed");
73 }
74
75 //TODO: FREE MEMORY!
76 void
77 malloc_cdat()
78 {
79
80 if(curr_max_cdats <= num_cdats)
81 {
82 if( (realloc((void*) cdat_buf, PTRS_IN_PAGE * 4)) == NULL)
83 perror("realloc cdat_buf failed");
84 curr_max_cdats += PTRS_IN_PAGE;
85 if( (realloc( (void*) cdat_stack, PTRS_IN_PAGE * 4)) == NULL) //increase cdat_stack also
86 perror("realloc cdat_stack failed");
87 }
88 if( (cdat_buf[num_cdats] = (struct cdat*) malloc(sizeof (struct cdat)) ) == NULL )
89 perror("malloc cdat failed");
90
91
92 }
93
94 /* Dynamically allocate memory for a class data structure,
95 or cdat, after a class has been identified in a grammar.
96 We also create a stack of class pointers so that
97 we can access the cdat during processing of that
98 cdats sets and elements, a requirement because the
99 nature of recursive classes prevents us from accessing
100 the cdat based on the previous index into cdat_buf,
101 which is a list of all allocated cdats*/
102 void
103 push_cdat(char* name)
104 {
105
106 malloc_cdat();
107
108 memmove(cdat_buf[num_cdats]->name, name, 32);
109 cdat_buf[num_cdats]->idx = num_cdats;
110
111 /* Set the cdat as a class of the previous cdat */
112 (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes++] = cdat_buf[num_cdats];
113
114 /* Push the cdat onto the cdat_stack */
115 *++cdat_stackp = cdat_buf[num_cdats++];
116
117 }
118
119 void
120 pop_cdat()
121 {
122 *cdat_stackp = NULL;
123 cdat_stackp--;
124 }
125
126 void
127 inc_posts()
128 {
129 num_posts++;
130 if(num_posts >= curr_max_posts)
131 {
132 if( (realloc((void*) post_buf, PTRS_IN_PAGE * 4)) == NULL)
133 perror("realloc post_buf failed");
134 curr_max_posts += PTRS_IN_PAGE;
135 }
136 if( (CURR_POST = (struct ref*) malloc(sizeof (struct ref))) == NULL)
137 {
138 perror("malloc post failed");
139 }
140
141 }
142 void
143 inc_odat()
144 {
145 num_odats++;
146 if(num_odats >= curr_max_odats)
147 {
148 if( (realloc((void*) odat_buf, PTRS_IN_PAGE * 4)) == NULL)
149 perror("realloc odat_buf failed");
150 curr_max_odats += PTRS_IN_PAGE;
151 }
152 if( (CURR_ODAT = (struct odat*) malloc(sizeof (struct odat))) == NULL)
153 {
154 perror("malloc odat failed");
155 }
156
157 }
158
159 void
160 inc_vdat()
161 {
162 num_vdats++;
163 if(num_vdats >= curr_max_vdats)
164 {
165 if( (realloc((void*) vdat_buf, PTRS_IN_PAGE * 4)) == NULL)
166 perror("realloc vdat_buf failed");
167 curr_max_vdats += PTRS_IN_PAGE;
168 }
169 if((CURR_VDAT = (struct vdat*) malloc(sizeof (struct vdat))) == NULL)
170 {
171 perror("malloc vdat failed");
172 }
173
174 }
175
176 void
177 inc_link()
178 {
179 num_links++;
180 if(num_links >= curr_max_links)
181 {
182 if( (realloc((void*) link_buf, PTRS_IN_PAGE * 4)) == NULL)
183 perror("realloc vdat_buf failed");
184 curr_max_links += PTRS_IN_PAGE;
185 }
186 if((CURR_LINK = (struct link*) malloc(sizeof (struct link))) == NULL)
187 {
188 perror("malloc link failed");
189 }
190 }
191
192 void
193 inc_ref()
194 {
195
196 if(num_refs % 16 == 0)
197 {
198 CURR_POST = CURR_REF;
199 inc_posts();
200 }
201
202 num_refs++;
203 if(num_refs >= curr_max_refs)
204 {
205 if( (realloc((void*) ref_buf, PTRS_IN_PAGE * 4)) == NULL)
206 perror("realloc ref_buf failed");
207 curr_max_refs += PTRS_IN_PAGE;
208 }
209 if((CURR_REF = (struct ref*) malloc(sizeof (struct ref))) == NULL)
210 perror("malloc ref failed");
211 }
212
213 void
214 insert_set_label(char* name, uint64_t ref_id)
215 {
216
217
218 memmove(CURR_CDAT->CURR_SET.name,name,32);
219 memmove(&CURR_CDAT->CURR_SET.ref_id,&ref_id,64);
220
221 }
222 void
223 insert_set_olink(uint64_t ref_id)
224 {
225 CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx;
226 CURR_CDAT->CURR_SET.ref_id = ref_id; /* Will be resolved to offset
227 when link is processed */
228 CURR_LINK->type = 1;
229 CURR_LINK->link_t.olink.ref_id = ref_id;
230 CURR_LINK->cdat_idx = CURR_CDAT->idx;
231 CURR_LINK->set_idx = CURR_CDAT->num_sets++;
232 CURR_LINK->ele_idx = -1;
233
234 inc_link();
235 }
236
237 void
238 insert_set_vlink(uint64_t ref_id, char* anim_name)
239 {
240 /* Insert vlink into link_stack so that it gets processed at
241 output time */
242 CURR_LINK->cdat_idx = CURR_CDAT->idx;
243 CURR_LINK->set_idx = CURR_CDAT->num_sets;
244 CURR_LINK->type = 2;
245 CURR_LINK->link_t.vlink.ref_id = ref_id;
246 memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32);
247
248
249 }
250
251 void
252 insert_set_svlink(uint64_t ref_id)
253 {
254
255 /* Insert vlink into link_stack so that it gets processed at
256 output time */
257 CURR_LINK->cdat_idx = CURR_CDAT->idx;
258 CURR_LINK->set_idx = CURR_CDAT->num_sets;
259 CURR_LINK->type = 3;
260 CURR_LINK->link_t.svlink.ref_id = ref_id;
261
262 }
263
264 /* At the point of reducing to a set, most of the
265 sets odat information has already been populated
266 during the reduction of its right hand side
267 non terminals (hitbox, root, quad_list). */
268 void
269 insert_set()
270 {
271 uint64_t ref_id;
272
273 ref_id = CURR_CDAT->CURR_SET.ref_id;
274
275 CURR_CDAT->CURR_SET.cdat_idx = CURR_CDAT->idx;
276 memmove(CURR_ODAT->name, CURR_CDAT->CURR_SET.name, 32);
277 CURR_CDAT->num_sets++;
278
279 CURR_ODAT->cdat_idx = CURR_CDAT->idx;
280 CURR_ODAT->refp = CURR_REF;
281
282
283 CURR_REF->lastref = PREV_REF;
284 PREV_REF->nextref = CURR_REF;
285 CURR_REF->odatp = CURR_ODAT;
286
287
288 if(ref_id == -1) /* user did not define a ref_id so */
289 { /* use a ref_id from system_space */
290 ref_id = ss_ref_id;
291 ss_ref_id++;
292 }
293
294 CURR_REF->ref_id = ref_id;
295
296
297
298 inc_ref();
299 inc_odat();
300 }
301
302 void
303 insert_vdat()
304 {
305 PREV_ODAT->vdat_id = num_vdats; //NULL for vlink, svlink
306 inc_vdat();
307 }
308
309 /* Populates both the odat name and ref_id
310 for element. */
311 void
312 insert_ele_label(char* name, uint64_t ref_id)
313 {
314 memmove(CURR_CDAT->CURR_SET.CURR_ELE.name, name, 32);
315 memmove(&CURR_CDAT->CURR_SET.ele_list[CURR_CDAT->CURR_SET.ref_id].ref_id, &ref_id, 64);
316 }
317
318 void
319 insert_ele_olink(uint64_t ref_id)
320 {
321 CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx;
322 CURR_CDAT->CURR_SET.CURR_ELE.ref_id = ref_id; /* Will be resolved to offset
323 when link is processed */
324 CURR_LINK->type = 1;
325 CURR_LINK->link_t.olink.ref_id = ref_id;
326 CURR_LINK->cdat_idx = CURR_CDAT->idx;
327 CURR_LINK->set_idx = CURR_CDAT->num_sets++;
328 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele++;
329
330 }
331 void
332 insert_ele_vlink(uint64_t ref_id, char* anim_name)
333 {
334
335 /* Insert vlink into link_stack so that it gets processed at
336 output time */
337 CURR_LINK->cdat_idx = CURR_CDAT->idx;
338 CURR_LINK->type = 2;
339 CURR_LINK->set_idx = CURR_CDAT->num_sets;
340 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele;
341 CURR_LINK->link_t.vlink.ref_id = ref_id;
342 memmove(CURR_LINK->link_t.vlink.anim_name, anim_name, 32);
343
344
345 }
346 void
347 insert_ele_svlink(uint64_t ref_id)
348 {
349
350 CURR_LINK->cdat_idx = CURR_CDAT->idx;
351 CURR_LINK->type = 3;
352 CURR_LINK->set_idx = CURR_CDAT->num_sets;
353 CURR_LINK->ele_idx = CURR_CDAT->CURR_SET.num_ele;
354 CURR_LINK->link_t.svlink.ref_id = ref_id;
355
356
357 }
358 //Insert element into odat_buf and cdatpages
359 void
360 insert_ele()
361 {
362
363 uint64_t ref_id;
364
365 ref_id = CURR_CDAT->CURR_SET.CURR_ELE.ref_id;
366
367 CURR_CDAT->CURR_SET.CURR_ELE.cdat_idx = CURR_CDAT->idx;
368 memmove(CURR_ODAT->name,CURR_CDAT->CURR_SET.CURR_ELE.name, 32);
369 CURR_CDAT->CURR_SET.num_ele++;
370
371 CURR_ODAT->cdat_idx = CURR_CDAT->idx;
372 CURR_ODAT->refp = CURR_REF;
373
374 if(ref_id == -1) /* user did not define a ref_id so */
375 { /* use a ref_id from system_space */
376 ref_id = ss_ref_id;
377 ss_ref_id++;
378 }
379
380 CURR_REF->ref_id = ref_id;
381
382 inc_odat();
383 inc_ref();
384
385 }
386
387 void
388 insert_framesheet(char direction, char* name, uint64_t ref_id, int height , int width, int num_frames)
389 {
390 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].height = height;
391 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].width = width;
392 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames = num_frames;
393 CURR_VDAT->num_models++;
394 }
395
396 #define CURR_QUAD (CURR_ODAT->quad_list[CURR_ODAT->num_quads])
397 void
398 insert_quad(int x, int y, int z, uint64_t ref_id)
399 {
400 CURR_QUAD.x = x;
401 CURR_QUAD.y = y;
402 CURR_QUAD.z = z;
403 CURR_QUAD.ref_id = ref_id;
404 CURR_ODAT->num_quads++;
405 }
406
407 /* Inserting the hitbox into the set
408 odat. Elements that don't have
409 a hitbox will use the sets root. */
410 void
411 insert_hitbox(int hitbox)
412 {
413 CURR_ODAT->hitbox = hitbox;
414 }
415
416 /* Inserting the root into the set
417 odat. Elements that don't have
418 a root will use the sets root. */
419 void
420 insert_root(int x, int y, int z)
421 {
422
423 CURR_ODAT->root.x = x;
424 CURR_ODAT->root.y = y;
425 CURR_ODAT->root.z = z;
426 }
427
428 void
429 insert_frame_pointer(char direction, void* frame)
430 {
431 CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].frames[CURR_VDAT->CURR_MODEL.spritesheet[(int)direction].num_frames++] = frame;
432 }
433