updated lexer_lex and ir
[henge/webcc.git] / src / apc / ir.c
1 /*!@file
2 \brief IR Memory Implementation
3 \details Intermediary memory management
4 \author Jordan Lavatai
5 \date Aug 2016
6 ----------------------------------------------------------------------------*/
7 #include <errno.h>
8 #include <stdio.h>
9 #include <stdint.h> //uint64_t
10 #include <string.h> //memmove
11 #include <stdlib.h> //malloc
12 #include <apc/ir.h>
13
14
15
16 /* functions needed from irmem.c */
17 extern
18 void
19 ir_init(void);
20
21 extern
22 struct cdat*
23 alloc_cdat(void);
24
25 extern
26 struct odat*
27 alloc_odat(void);
28
29 extern
30 void
31 alloc_vdat(void);
32
33 extern
34 struct link*
35 alloc_link(void);
36
37 extern
38 struct ref*
39 alloc_ref(void);
40
41 extern
42 struct cdat*
43 curr_cdat(void);
44
45 extern
46 struct odat*
47 curr_odat(void);
48
49 extern
50 struct vdat*
51 curr_vdat(void);
52
53 extern
54 struct set*
55 curr_set(void);
56
57 extern
58 struct ref*
59 curr_ref(void);
60
61 extern
62 struct quad*
63 curr_quad(void);
64
65 extern
66 struct model*
67 curr_model(void);
68
69 /* struct definitions needed from irmem.c */
70 extern int num_cdats;
71 extern struct cdat** cdat_stackp;
72 extern struct odat* curr_set_odatp;
73 extern uint64_t ss_ref_id;
74
75 extern int num_vdats;
76 /* Dynamically allocate memory for a class data structure,
77 or cdat, after a class has been identified in a grammar.
78 We also create a stack of class pointers so that
79 we can access the cdat during processing of that
80 cdats sets and elements, a requirement because the
81 nature of recursive classes prevents us from accessing
82 the cdat based on the previous index into cdat_buf,
83 which is a list of all allocated cdats*/
84 void
85 push_cdat
86 ( char* name
87 )
88 {
89 struct cdat* curr_cdatp;
90
91 curr_cdatp = alloc_cdat();
92
93 memmove(curr_cdatp->name, name, 32);
94 curr_cdatp->idx = num_cdats;
95
96 /* Set the cdat as a subclass of the previous cdat */
97 (*cdat_stackp)->class_list[(*cdat_stackp)->num_classes] = curr_cdatp;
98 /* Push the cdat onto the cdat_stack */
99 *++cdat_stackp = curr_cdatp;
100
101 }
102
103 void
104 pop_cdat
105 ()
106 {
107 cdat_stackp--;
108 }
109
110 /* Called in the reduction of a set. While both odats (eles and sets)
111 have identical label terminals, we are unable to give a single grammatical rule
112 for both due to how we allocate odats in the odat buf. Due to the
113 nature of bottom up parsing, the set label is recognized first, and then the
114 sets elements are recognized. This means that after we have processed the sets elemenets,
115 the curr_odat is going to be the last element and NOT the set that was first allocated.
116 To get around this, we create a global variable set_odatp that will store the pointer
117 to the odat when it is first allocated (in insert_set_label()) so that insert_set() can
118 have access to it. Curr set points the sets representation in the cdat, curr_set_odatp
119 points to the sets representation as an odat*/
120
121 void
122 insert_set_label
123 ( char* name,
124 uint64_t ref_id
125 )
126 {
127
128 struct set* curr_setp;
129
130 curr_setp = curr_set();
131 curr_set_odatp = alloc_odat();
132
133 memmove(curr_set_odatp->name, name, 32);
134 memmove(curr_setp->name, name, 32);
135
136 if(ref_id != -1)
137 { curr_set_odatp->ref_id = ref_id;
138 curr_setp->ref_id = ref_id;
139 }
140 else
141 { curr_setp->ref_id = ss_ref_id;
142 curr_set_odatp->ref_id = ss_ref_id++;
143 }
144
145 }
146
147 /* Inserting a olink instead of a set. Set is really just a placeholder
148 for another set. Allocate the memory for the set so taht it can be populated*/
149 void
150 insert_set_olink
151 ( uint64_t ref_id
152 )
153 {
154 struct cdat* curr_cdatp;
155 struct link* curr_linkp;
156 struct odat* curr_setp;
157
158 curr_cdatp = curr_cdat();
159 curr_setp = alloc_odat();
160 curr_linkp = alloc_link();
161
162 curr_setp->cdat_idx = curr_cdatp->idx;
163 curr_setp->ref_id = ref_id; /* Will be resolved to offset
164 when link is processed */
165 curr_linkp->type = 1;
166 curr_linkp->link_t.olink.ref_id = ref_id;
167 curr_linkp->classp = curr_cdatp;
168 curr_linkp->set_idx = curr_cdatp->num_sets++;
169 curr_linkp->ele_idx = -1;
170
171 }
172
173 void
174 insert_set_vlink
175 ( uint64_t ref_id,
176 char* anim_name
177 )
178 {
179 struct cdat* curr_cdatp;
180 struct link* curr_linkp;
181
182 curr_cdatp = curr_cdat();
183 curr_linkp = alloc_link();
184
185 /* Insert vlink into link_stack so that it gets processed at
186 output time */
187 curr_linkp->type = 2;
188 curr_linkp->link_t.vlink.ref_id = ref_id;
189 curr_linkp->classp = curr_cdatp;
190 curr_linkp->set_idx = curr_cdatp->num_sets;
191 curr_linkp->ele_idx = -1;
192 memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
193
194 }
195
196 /* Svlinks dont have animation names */
197 void
198 insert_set_svlink
199 ( uint64_t ref_id
200 )
201 {
202 struct cdat* curr_cdatp;
203 struct link* curr_linkp;
204
205 curr_cdatp = curr_cdat();
206 curr_linkp = alloc_link();
207
208 /* Insert svlink into link_stack so that it gets processed at
209 output time */
210 curr_linkp->type = 3;
211 curr_linkp->classp = curr_cdatp;
212 curr_linkp->set_idx = curr_cdatp->num_sets;
213 curr_linkp->ele_idx = -1;
214 curr_linkp->link_t.svlink.ref_id = ref_id;
215
216 }
217
218 /* At the point of reducing to a set, most of the
219 sets odat information has already been populated
220 during the reduction of its right hand side
221 non terminals (hitbox, root, quad_list). */
222 void
223 insert_set
224 ()
225 { uint64_t ref_id;
226 struct odat* curr_odatp;
227 struct cdat* curr_cdatp;
228 struct set* curr_setp;
229 struct ref* prev_refp;
230 struct ref* curr_refp;
231 struct vdat* curr_vdatp;
232
233 curr_odatp = curr_set_odatp; //allocated at insert_set_label, preserved in global space
234 curr_cdatp = curr_cdat();
235 curr_setp = curr_set();
236 prev_refp = curr_ref();
237 curr_refp = alloc_ref();
238 curr_vdatp = curr_vdat();
239
240 curr_vdatp->creator = curr_set_odatp;
241
242 curr_setp->cdat_idx = curr_cdatp->idx; //does a set need its class idx?
243 memmove(curr_setp->name, curr_odatp->name, 32);
244 curr_cdatp->num_sets++;
245
246 curr_odatp->cdat_idx = curr_cdatp->idx;
247 curr_odatp->refp = curr_refp;
248
249 ref_id = curr_setp->ref_id; // ref_id set by insert_set_label(name, ref_id)
250
251 curr_refp->ref_id = ref_id;
252 curr_refp->lastref = prev_refp;
253 curr_refp->odatp = curr_odatp;
254 prev_refp->nextref = curr_refp;
255
256
257
258 }
259 /* Created as a seperate function, instead of setting the ODATS vdat_id and
260 calling inc_vdat() inside of insert_set(), to account for the set reduction
261 where a vdat is not created (o/v/svlinks). */
262 void
263 insert_set_vdatid
264 ()
265 {
266 struct vdat* curr_vdatp;
267
268 curr_vdatp = curr_vdat();
269
270 curr_set_odatp->vdat_id = num_vdats; //no vdat_id for odats that have vlinks/svlinks
271 curr_set_odatp->vdatp = curr_vdatp;
272 curr_set_odatp = NULL; //This sets odat shouldnt be modified after populating odats vdat info
273 }
274
275 /* Populates the odat name and ref_id for odat, allocate the odat here for the rest of
276 the functions to use via curr_odat(). */
277 void
278 insert_ele_label
279 ( char* name,
280 uint64_t ref_id
281 )
282 {
283 struct odat* curr_odatp;
284
285 curr_odatp = alloc_odat();
286
287 memmove(curr_odatp->name, name, 32);
288
289 if(ref_id != -1)
290 curr_odatp->ref_id = ref_id;
291 else
292 curr_odatp->ref_id = ss_ref_id++;
293
294 }
295
296 /* We don't make an odat here, at output time we will resolve
297 the ref_id to the corresponding odat. */
298 void
299 insert_ele_olink
300 ( uint64_t ref_id
301 )
302 {
303 struct cdat* curr_cdatp;
304 struct set* curr_setp;
305 struct ele* curr_elep;
306 struct link* curr_linkp;
307
308 curr_cdatp = curr_cdat();
309 //curr_elep = curr_ele();
310 curr_linkp = alloc_link();
311
312 //curr_elep->cdat_idx = curr_cdatp;
313 //curr_elep->ref_id = ref_id;
314
315 curr_linkp->type = 1;
316 curr_linkp->link_t.olink.ref_id = ref_id;
317 curr_linkp->classp = curr_cdatp;
318 curr_linkp->set_idx = curr_cdatp->num_sets++;
319 //curr_linkp->ele_idx = curr_setp->num_ele++;
320
321 }
322
323 void
324 insert_ele_vlink
325 ( uint64_t ref_id,
326 char* anim_name
327 )
328 {
329 struct cdat* curr_cdatp;
330 struct set* curr_setp;
331 struct link* curr_linkp;
332
333 curr_cdatp = curr_cdat();
334 curr_setp = curr_set();
335 curr_linkp = alloc_link();
336
337 /* Insert vlink into link_stack so that it gets processed at
338 output time */
339 curr_linkp->classp = curr_cdatp;
340 curr_linkp->type = 2;
341 curr_linkp->set_idx = curr_cdatp->num_sets;
342 //curr_linkp->ele_idx = curr_setp->num_ele;
343 curr_linkp->link_t.vlink.ref_id = ref_id;
344 memmove(curr_linkp->link_t.vlink.anim_name, anim_name, 32);
345
346 }
347
348 void
349 insert_ele_svlink
350 ( uint64_t ref_id
351 )
352 {
353 struct cdat* curr_cdatp;
354 struct set* curr_setp;
355 struct link* curr_linkp;
356
357 curr_cdatp = curr_cdat();
358 curr_setp = curr_set();
359 curr_linkp = alloc_link();
360
361 curr_linkp->classp = curr_cdatp;
362 curr_linkp->type = 3;
363
364 //curr_linkp->ele_idx = curr_setp->num_ele;
365 curr_linkp->link_t.svlink.ref_id = ref_id;
366
367
368 }
369
370 //Insert element into odat_buf and cdatpages
371 void
372 insert_ele()
373 {
374 uint64_t ref_id;
375 struct cdat* curr_cdatp;
376 struct odat* curr_odatp;
377 struct vdat* curr_vdatp;
378 struct set* curr_setp;
379 struct ele* curr_elep;
380 struct ref* curr_refp;
381 struct ref* prev_refp;
382
383
384 curr_odatp = curr_odat(); //malloced @ insert_ele_label
385 curr_vdatp = curr_vdat();
386 curr_setp = curr_set();
387 prev_refp = curr_ref();
388 curr_refp = alloc_ref();
389
390 curr_vdatp->creator = curr_odatp;
391
392 /* Populate odat for ele */
393 curr_odatp->cdat_idx = curr_cdatp->idx;
394 curr_odatp->refp = curr_refp;
395
396 ref_id = curr_odatp->ref_id;
397
398 curr_refp->ref_id = ref_id;
399 curr_refp->lastref = prev_refp;
400 curr_refp->odatp = curr_odatp;
401 prev_refp->nextref = curr_refp;
402
403 }
404
405 void
406 insert_ele_vdatid
407 ()
408 { struct odat* curr_odatp;
409 curr_odatp = curr_odat();
410 curr_odatp->vdat_id = num_vdats;
411 }
412
413 void
414 insert_quad
415 ( void* quad_filep
416 )
417 {
418 struct odat* curr_odatp;
419
420 curr_odatp->quad_filep = quad_filep;
421 }
422
423 /* Inserting the hitbox into the set
424 odat. Elements that don't have
425 a hitbox will use the sets root. */
426 void
427 insert_hitbox
428 ( int hitbox
429 )
430 { struct odat* curr_odatp;
431
432 curr_odatp = curr_odat();
433 curr_odatp->hitbox = hitbox;
434 }
435
436 /* Inserting the root into the set
437 odat. Elements that don't have
438 a root will use the sets root. */
439 void
440 insert_root
441 ( int x,
442 int y,
443 int z
444 )
445 { struct odat* curr_odatp;
446
447 curr_odatp = curr_odat();
448 curr_odatp->root.x = x;
449 curr_odatp->root.y = y;
450 curr_odatp->root.z = z;
451 }
452
453
454 void
455 insert_framesheet
456 ( char direction,
457 char* name,
458 uint64_t ref_id,
459 int height ,
460 int width,
461 int num_frames
462 )
463 { struct vdat* curr_vdatp;
464 struct model* curr_modelp;
465
466 curr_vdatp = curr_vdat();
467 curr_modelp = curr_model();
468
469 curr_modelp->spritesheet[(int)direction].height = height;
470 curr_modelp->spritesheet[(int)direction].width = width;
471 curr_modelp->spritesheet[(int)direction].num_frames = num_frames;
472 curr_vdatp->num_models++;
473 }
474
475 void
476 insert_frame_pointer
477 ( char direction,
478 void* frame
479 )
480 { struct model* curr_modelp;
481
482 curr_modelp = curr_model();
483
484 curr_modelp->spritesheet[(int)direction].frames[curr_modelp->spritesheet[(int)direction].num_frames++] = frame;
485 }
486