fix memleaks
[m6w6/ext-psi] / src / parser.h
1 #ifndef _PSI_PARSER_H
2 #define _PSI_PARSER_H
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <stdarg.h>
7 #include <string.h>
8
9 #include <Zend/zend_types.h>
10
11 #include "parser_proc.h"
12
13 #define BSIZE 256
14
15 #define PSI_T_POINTER PSI_T_ASTERISK
16 typedef int token_t;
17
18 /* in php_psi.h */
19 size_t psi_t_alignment(token_t);
20 size_t psi_t_size(token_t);
21
22 typedef struct PSI_Token {
23 token_t type;
24 unsigned line;
25 size_t size;
26 char text[1];
27 } PSI_Token;
28
29 typedef union impl_val {
30 char cval;
31 int8_t i8;
32 uint8_t u8;
33 short sval;
34 int16_t i16;
35 uint16_t u16;
36 int ival;
37 int32_t i32;
38 uint32_t u32;
39 long lval;
40 int64_t i64;
41 uint64_t u64;
42 float fval;
43 double dval;
44 union {
45 zend_bool bval;
46 zend_long lval;
47 zend_string *str;
48 } zend;
49 void *ptr;
50 uint8_t _dbg[sizeof(void *)];
51 } impl_val;
52
53 typedef struct decl_type {
54 char *name;
55 token_t type;
56 struct decl_type *real;
57 struct decl_struct *strct;
58 } decl_type;
59
60 static inline decl_type *init_decl_type(token_t type, const char *name) {
61 decl_type *t = calloc(1, sizeof(*t));
62 t->type = type;
63 t->name = strdup(name);
64 return t;
65 }
66
67 static inline decl_type *real_decl_type(decl_type *type) {
68 while (type->real) {
69 type = type->real;
70 }
71 return type;
72 }
73
74 static inline void free_decl_type(decl_type *type) {
75 free(type->name);
76 free(type);
77 }
78
79 typedef struct decl_typedef {
80 char *alias;
81 decl_type *type;
82 } decl_typedef;
83
84 static inline decl_typedef *init_decl_typedef(const char *name, decl_type *type) {
85 decl_typedef *t = calloc(1, sizeof(*t));
86 t->alias = strdup(name);
87 t->type = type;
88 return t;
89 }
90
91 static inline void free_decl_typedef(decl_typedef *t) {
92 free(t->alias);
93 free_decl_type(t->type);
94 free(t);
95 }
96
97 typedef struct decl_typedefs {
98 size_t count;
99 decl_typedef **list;
100 } decl_typedefs;
101
102 static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_typedef *def) {
103 if (!defs) {
104 defs = calloc(1, sizeof(*defs));
105 }
106 defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
107 defs->list[defs->count-1] = def;
108 return defs;
109 }
110
111 static void free_decl_typedefs(decl_typedefs *defs) {
112 size_t i;
113
114 for (i = 0; i < defs->count; ++i) {
115 free_decl_typedef(defs->list[i]);
116 }
117 free(defs->list);
118 free(defs);
119 }
120
121 typedef struct decl_var {
122 char *name;
123 unsigned pointer_level;
124 unsigned array_size;
125 struct decl_arg *arg;
126 } decl_var;
127
128 static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
129 decl_var *v = calloc(1, sizeof(*v));
130 v->name = (char *) strdup((const char *) name);
131 v->pointer_level = pl;
132 v->array_size = as;
133 return v;
134 }
135
136 static inline void free_decl_var(decl_var *var) {
137 free(var->name);
138 free(var);
139 }
140
141 typedef struct decl_struct_layout {
142 size_t pos;
143 size_t len;
144 } decl_struct_layout;
145
146 static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
147 decl_struct_layout *l = calloc(1, sizeof(*l));
148
149 l->pos = pos;
150 l->len = len;
151 return l;
152 }
153
154 static inline void free_decl_struct_layout(decl_struct_layout *l) {
155 free(l);
156 }
157
158 typedef struct decl_arg {
159 decl_type *type;
160 decl_var *var;
161 decl_struct_layout *layout;
162 struct let_stmt *let;
163 impl_val val;
164 void *ptr;
165 void *mem;
166 } decl_arg;
167
168 static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
169 decl_arg *arg = calloc(1, sizeof(*arg));
170 arg->type = type;
171 arg->var = var;
172 var->arg = arg;
173 arg->ptr = &arg->val;
174 return arg;
175 }
176
177 static inline void free_decl_arg(decl_arg *arg) {
178 free_decl_type(arg->type);
179 free_decl_var(arg->var);
180 if (arg->layout) {
181 free_decl_struct_layout(arg->layout);
182 }
183 free(arg);
184 }
185
186 typedef struct decl_vars {
187 decl_var **vars;
188 size_t count;
189 } decl_vars;
190
191 static inline decl_vars *init_decl_vars(decl_var *var) {
192 decl_vars *vars = calloc(1, sizeof(*vars));
193 if (var) {
194 vars->count = 1;
195 vars->vars = calloc(1, sizeof(*vars->vars));
196 vars->vars[0] = var;
197 }
198 return vars;
199 }
200
201 static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
202 vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
203 vars->vars[vars->count-1] = var;
204 return vars;
205 }
206
207 static inline void free_decl_vars(decl_vars *vars) {
208 size_t i;
209
210 for (i = 0; i < vars->count; ++i) {
211 free_decl_var(vars->vars[i]);
212 }
213 free(vars->vars);
214 free(vars);
215 }
216
217 typedef struct decl_args {
218 decl_arg **args;
219 size_t count;
220 } decl_args;
221
222 static inline decl_args *init_decl_args(decl_arg *arg) {
223 decl_args *args = calloc(1, sizeof(*args));
224 if (arg) {
225 args->count = 1;
226 args->args = calloc(1, sizeof(*args->args));
227 args->args[0] = arg;
228 }
229 return args;
230 }
231
232 static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
233 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
234 args->args[args->count-1] = arg;
235 return args;
236 }
237
238 static inline void free_decl_args(decl_args *args) {
239 size_t i;
240
241 for (i = 0; i < args->count; ++i) {
242 free_decl_arg(args->args[i]);
243 }
244 free(args->args);
245 free(args);
246 }
247
248 typedef struct decl_abi {
249 char *convention;
250 } decl_abi;
251
252 static inline decl_abi *init_decl_abi(const char *convention) {
253 decl_abi *abi = calloc(1, sizeof(*abi));
254 abi->convention = strdup(convention);
255 return abi;
256 }
257
258 static inline void free_decl_abi(decl_abi *abi) {
259 free(abi->convention);
260 free(abi);
261 }
262
263 typedef struct decl {
264 decl_abi *abi;
265 decl_arg *func;
266 decl_args *args;
267 struct impl *impl;
268 struct {
269 void *sym;
270 void *info;
271 void **args;
272 } call;
273 } decl;
274
275 static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
276 decl *d = calloc(1, sizeof(*d));
277 d->abi = abi;
278 d->func = func;
279 d->args = args;
280 return d;
281 }
282
283 static inline void free_decl(decl *d) {
284 free_decl_abi(d->abi);
285 free_decl_arg(d->func);
286 if (d->args) {
287 free_decl_args(d->args);
288 }
289 free(d);
290 }
291
292 typedef struct decls {
293 size_t count;
294 decl **list;
295 } decls;
296
297 static inline decls *add_decl(decls *decls, decl *decl) {
298 if (!decls) {
299 decls = calloc(1, sizeof(*decls));
300 }
301 decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
302 decls->list[decls->count-1] = decl;
303 return decls;
304 }
305
306 static inline void free_decls(decls *decls) {
307 size_t i;
308
309 for (i = 0; i < decls->count; ++i) {
310 free_decl(decls->list[i]);
311 }
312 free(decls->list);
313 free(decls);
314 }
315
316 typedef struct decl_struct {
317 char *name;
318 decl_args *args;
319 size_t size;
320 } decl_struct;
321
322 static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
323 decl_struct *s = calloc(1, sizeof(*s));
324 s->name = strdup(name);
325 s->args = args;
326 return s;
327 }
328
329 static inline void free_decl_struct(decl_struct *s) {
330 if (s->args) {
331 free_decl_args(s->args);
332 }
333 free(s->name);
334 free(s);
335 }
336
337 typedef struct decl_structs {
338 size_t count;
339 decl_struct **list;
340 } decl_structs;
341
342 static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
343 if (!ss) {
344 ss = calloc(1, sizeof(*ss));
345 }
346 ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
347 ss->list[ss->count-1] = s;
348 return ss;
349 }
350
351 static inline void free_decl_structs(decl_structs *ss) {
352 size_t i;
353
354 for (i = 0; i < ss->count; ++i) {
355 free_decl_struct(ss->list[i]);
356 }
357 free(ss->list);
358 free(ss);
359 }
360
361 typedef struct impl_type {
362 char *name;
363 token_t type;
364 } impl_type;
365
366 static inline impl_type *init_impl_type(token_t type, const char *name) {
367 impl_type *t = calloc(1, sizeof(*t));
368
369 t->type = type;
370 t->name = strdup(name);
371 return t;
372 }
373
374 static inline void free_impl_type(impl_type *type) {
375 free(type->name);
376 free(type);
377 }
378
379 typedef struct impl_var {
380 char *name;
381 unsigned reference:1;
382 } impl_var;
383
384 static inline impl_var *init_impl_var(const char *name, int is_reference) {
385 impl_var *var = calloc(1, sizeof(*var));
386 var->name = strdup(name);
387 var->reference = is_reference;
388 return var;
389 }
390
391 static inline void free_impl_var(impl_var *var) {
392 free(var->name);
393 free(var);
394 }
395
396 typedef struct impl_def_val {
397 token_t type;
398 char *text;
399 } impl_def_val;
400
401 static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
402 impl_def_val *def = calloc(1, sizeof(*def));
403 def->type = t;
404 def->text = strdup(text);
405 return def;
406 }
407
408 static inline void free_impl_def_val(impl_def_val *def) {
409 free(def->text);
410 free(def);
411 }
412
413 typedef struct const_type {
414 token_t type;
415 char *name;
416 } const_type;
417
418 static inline const_type *init_const_type(token_t type, const char *name) {
419 const_type *ct = calloc(1, sizeof(*ct));
420 ct->type = type;
421 ct->name = strdup(name);
422 return ct;
423 }
424
425 static inline void free_const_type(const_type *type) {
426 free(type->name);
427 free(type);
428 }
429
430 typedef struct constant {
431 const_type *type;
432 char *name;
433 impl_def_val *val;
434 } constant;
435
436 static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
437 constant *c = calloc(1, sizeof(*c));
438 c->type = type;
439 c->name = strdup(name);
440 c->val = val;
441 return c;
442 }
443
444 static inline void free_constant(constant *constant) {
445 free_const_type(constant->type);
446 free(constant->name);
447 free_impl_def_val(constant->val);
448 free(constant);
449 }
450
451 typedef struct constants {
452 size_t count;
453 constant **list;
454 } constants;
455
456 static inline constants *add_constant(constants *constants, constant *constant) {
457 if (!constants) {
458 constants = calloc(1, sizeof(*constants));
459 }
460 constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
461 constants->list[constants->count-1] = constant;
462 return constants;
463 }
464
465 static inline void free_constants(constants *c) {
466 size_t i;
467
468 for (i = 0; i < c->count; ++i) {
469 free_constant(c->list[i]);
470 }
471 free(c->list);
472 free(c);
473 }
474
475 typedef struct impl_arg {
476 impl_type *type;
477 impl_var *var;
478 impl_def_val *def;
479 impl_val val;
480 zval *_zv;
481 } impl_arg;
482
483 static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
484 impl_arg *arg = calloc(1, sizeof(*arg));
485 arg->type = type;
486 arg->var = var;
487 arg->def = def;
488 return arg;
489 }
490
491 static inline void free_impl_arg(impl_arg *arg) {
492 free_impl_type(arg->type);
493 free_impl_var(arg->var);
494 if (arg->def) {
495 free_impl_def_val(arg->def);
496 }
497 free(arg);
498 }
499
500 typedef struct impl_args {
501 impl_arg **args;
502 size_t count;
503 } impl_args;
504
505 static inline impl_args *init_impl_args(impl_arg *arg) {
506 impl_args *args = calloc(1, sizeof(*args));
507 if (arg) {
508 args->count = 1;
509 args->args = calloc(1, sizeof(*args->args));
510 args->args[0] = arg;
511 }
512 return args;
513 }
514
515 static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
516 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
517 args->args[args->count-1] = arg;
518 return args;
519 }
520
521 static inline void free_impl_args(impl_args *args) {
522 size_t i;
523
524 for (i = 0; i < args->count; ++i) {
525 free_impl_arg(args->args[i]);
526 }
527 free(args->args);
528 free(args);
529 }
530
531 typedef struct impl_func {
532 char *name;
533 impl_args *args;
534 impl_type *return_type;
535 unsigned return_reference:1;
536 } impl_func;
537
538 static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) {
539 impl_func *func = calloc(1, sizeof(*func));
540 func->name = strdup(name);
541 func->args = args ? args : init_impl_args(NULL);
542 func->return_type = type;
543 func->return_reference = ret_reference;
544 return func;
545 }
546
547 static inline void free_impl_func(impl_func *f) {
548 free_impl_type(f->return_type);
549 free_impl_args(f->args);
550 free(f->name);
551 free(f);
552 }
553
554 typedef struct num_exp {
555 token_t t;
556 union {
557 char *numb;
558 constant *cnst;
559 decl_var *dvar;
560 } u;
561 token_t operator;
562 int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
563 struct num_exp *operand;
564 } num_exp;
565
566 static inline num_exp *init_num_exp(token_t t, void *num) {
567 num_exp *exp = calloc(1, sizeof(*exp));
568 switch (exp->t = t) {
569 case PSI_T_NUMBER:
570 case PSI_T_NSNAME:
571 exp->u.numb = strdup(num);
572 break;
573 case PSI_T_NAME:
574 exp->u.dvar = num;
575 break;
576 EMPTY_SWITCH_DEFAULT_CASE();
577 }
578 return exp;
579 }
580
581 static inline void free_num_exp(num_exp *exp) {
582 switch (exp->t) {
583 case PSI_T_NUMBER:
584 free(exp->u.numb);
585 break;
586 case PSI_T_NSNAME:
587 break;
588 case PSI_T_NAME:
589 free_decl_var(exp->u.dvar);
590 break;
591 EMPTY_SWITCH_DEFAULT_CASE();
592 }
593 if (exp->operand) {
594 free_num_exp(exp->operand);
595 }
596 free(exp);
597 }
598
599 typedef struct let_calloc {
600 num_exp *nmemb;
601 num_exp *size;
602 } let_calloc;
603
604 static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
605 let_calloc *alloc = calloc(1, sizeof(*alloc));
606 alloc->nmemb = nmemb;
607 alloc->size = size;
608 return alloc;
609 }
610
611 static inline void free_let_calloc(let_calloc *alloc) {
612 free_num_exp(alloc->nmemb);
613 free_num_exp(alloc->size);
614 free(alloc);
615 }
616
617 typedef struct let_func {
618 token_t type;
619 char *name;
620 impl_var *var;
621 impl_arg *arg;
622 } let_func;
623
624 static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
625 let_func *func = calloc(1, sizeof(*func));
626 func->type = type;
627 func->name = strdup(name);
628 func->var = var;
629 return func;
630 }
631
632 static inline void free_let_func(let_func *func) {
633 free_impl_var(func->var);
634 free(func->name);
635 free(func);
636 }
637
638 #define PSI_LET_REFERENCE 0x1;
639 typedef struct let_val {
640 enum let_val_kind {
641 PSI_LET_NULL,
642 PSI_LET_NUMEXP,
643 PSI_LET_CALLOC,
644 PSI_LET_FUNC,
645 PSI_LET_TMP,
646 } kind;
647 union {
648 num_exp *num;
649 let_calloc *alloc;
650 let_func *func;
651 decl_var *var;
652 } data;
653 union {
654 struct {
655 unsigned is_reference:1;
656 } one;
657 unsigned all;
658 } flags;
659 } let_val;
660
661 static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
662 let_val *let = calloc(1, sizeof(*let));
663 switch (let->kind = kind) {
664 case PSI_LET_NULL:
665 break;
666 case PSI_LET_NUMEXP:
667 let->data.num = data;
668 break;
669 case PSI_LET_CALLOC:
670 let->data.alloc = data;
671 break;
672 case PSI_LET_FUNC:
673 let->data.func = data;
674 break;
675 case PSI_LET_TMP:
676 let->data.var = data;
677 break;
678 EMPTY_SWITCH_DEFAULT_CASE();
679 }
680 return let;
681 }
682
683 static inline void free_let_val(let_val *let) {
684 switch (let->kind) {
685 case PSI_LET_NULL:
686 break;
687 case PSI_LET_NUMEXP:
688 free_num_exp(let->data.num);
689 break;
690 case PSI_LET_CALLOC:
691 free_let_calloc(let->data.alloc);
692 break;
693 case PSI_LET_FUNC:
694 free_let_func(let->data.func);
695 break;
696 case PSI_LET_TMP:
697 free_decl_var(let->data.var);
698 break;
699 EMPTY_SWITCH_DEFAULT_CASE();
700 }
701 free(let);
702 }
703
704 typedef struct let_stmt {
705 decl_var *var;
706 let_val *val;
707
708 void *ptr;
709 } let_stmt;
710
711 static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
712 let_stmt *let = calloc(1, sizeof(*let));
713 let->var = var;
714 let->val = val;
715 return let;
716 }
717
718 static inline void free_let_stmt(let_stmt *stmt) {
719 if (stmt->val) {
720 if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
721 free_decl_arg(stmt->var->arg);
722 }
723 free_let_val(stmt->val);
724 }
725 free_decl_var(stmt->var);
726 free(stmt);
727 }
728
729 struct set_value;
730
731 typedef struct set_func {
732 token_t type;
733 char *name;
734 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
735 } set_func;
736
737 static inline set_func *init_set_func(token_t type, const char *name) {
738 set_func *func = calloc(1, sizeof(*func));
739 func->type = type;
740 func->name = strdup(name);
741 return func;
742 }
743
744 static inline void free_set_func(set_func *func) {
745 free(func->name);
746 free(func);
747 }
748
749 typedef struct set_value {
750 set_func *func;
751 decl_vars *vars;
752 num_exp *num;
753 struct {
754 struct set_value *set;
755 impl_val *val;
756 } outer;
757 struct set_value **inner;
758 size_t count;
759 } set_value;
760
761 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
762 set_value *val = calloc(1, sizeof(*val));
763 val->func = func;
764 val->vars = vars;
765 return val;
766 }
767 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
768 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
769 val->inner[val->count-1] = inner;
770 return val;
771 }
772
773 static inline void free_set_value(set_value *val) {
774 free_set_func(val->func);
775 free_decl_vars(val->vars);
776 if (val->inner) {
777 size_t i;
778 for (i = 0; i < val->count; ++i) {
779 free_set_value(val->inner[i]);
780 }
781 free(val->inner);
782 }
783 if (val->num) {
784 free_num_exp(val->num);
785 }
786 free(val);
787 }
788
789 typedef struct set_stmt {
790 impl_var *var;
791 set_value *val;
792 impl_arg *arg;
793 } set_stmt;
794
795 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
796 set_stmt *set = calloc(1, sizeof(*set));
797 set->var = var;
798 set->val = val;
799 return set;
800 }
801
802 static inline void free_set_stmt(set_stmt *set) {
803 free_impl_var(set->var);
804 free_set_value(set->val);
805 free(set);
806 }
807
808 typedef struct return_stmt {
809 set_value *set;
810 decl_arg *decl;
811 } return_stmt;
812
813 static inline return_stmt *init_return_stmt(set_value *val) {
814 return_stmt *ret = calloc(1, sizeof(*ret));
815 ret->set = val;
816 return ret;
817 }
818
819 static inline void free_return_stmt(return_stmt *ret) {
820 //free_set_func(ret->func);
821 //free_decl_var(ret->decl);
822 free_set_value(ret->set);
823 free(ret);
824 }
825
826 typedef struct free_call {
827 char *func;
828 decl_vars *vars;
829 decl *decl;
830 } free_call;
831
832 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
833 free_call *f = calloc(1, sizeof(*f));
834 f->func = strdup(func);
835 f->vars = vars;
836 return f;
837 }
838
839 static inline void free_free_call(free_call *f) {
840 free(f->func);
841 free_decl_vars(f->vars);
842 free(f);
843 }
844
845 typedef struct free_calls {
846 free_call **list;
847 size_t count;
848 } free_calls;
849
850 static inline free_calls *init_free_calls(free_call *f) {
851 free_calls *fcs = calloc(1, sizeof(*fcs));
852 if (f) {
853 fcs->count = 1;
854 fcs->list = calloc(1, sizeof(*fcs->list));
855 fcs->list[0] = f;
856 }
857 return fcs;
858 }
859
860 static inline void free_free_calls(free_calls *fcs) {
861 size_t i;
862
863 for (i = 0; i < fcs->count; ++i) {
864 free_free_call(fcs->list[i]);
865 }
866 free(fcs->list);
867 free(fcs);
868 }
869
870 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
871 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
872 fcs->list[fcs->count-1] = f;
873 return fcs;
874 }
875
876 typedef struct free_stmt {
877 free_calls *calls;
878 } free_stmt;
879
880 static inline free_stmt *init_free_stmt(free_calls *calls) {
881 free_stmt *f = calloc(1, sizeof(*f));
882 f->calls = calls;
883 return f;
884 }
885
886 static inline void free_free_stmt(free_stmt *f) {
887 free_free_calls(f->calls);
888 free(f);
889 }
890
891 typedef struct impl_stmt {
892 token_t type;
893 union {
894 let_stmt *let;
895 set_stmt *set;
896 return_stmt *ret;
897 free_stmt *fre;
898 void *ptr;
899 } s;
900 } impl_stmt;
901
902 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
903 impl_stmt *stmt = calloc(1, sizeof(*stmt));
904 stmt->type = type;
905 stmt->s.ptr = ptr;
906 return stmt;
907 }
908
909 static inline void free_impl_stmt(impl_stmt *stmt) {
910 switch (stmt->type) {
911 case PSI_T_LET:
912 free_let_stmt(stmt->s.let);
913 break;
914 case PSI_T_SET:
915 free_set_stmt(stmt->s.set);
916 break;
917 case PSI_T_RETURN:
918 free_return_stmt(stmt->s.ret);
919 break;
920 case PSI_T_FREE:
921 free_free_stmt(stmt->s.fre);
922 break;
923 }
924 free(stmt);
925 }
926
927 typedef struct impl_stmts {
928 struct {
929 return_stmt **list;
930 size_t count;
931 } ret;
932 struct {
933 let_stmt **list;
934 size_t count;
935 } let;
936 struct {
937 set_stmt **list;
938 size_t count;
939 } set;
940 struct {
941 free_stmt **list;
942 size_t count;
943 } fre;
944 } impl_stmts;
945
946 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
947 list = realloc(list, count * sizeof(list));
948 ((void **)list)[count-1] = stmt;
949 return list;
950 }
951
952 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
953 switch (stmt->type) {
954 case PSI_T_RETURN:
955 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
956 break;
957 case PSI_T_LET:
958 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
959 break;
960 case PSI_T_SET:
961 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
962 break;
963 case PSI_T_FREE:
964 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
965 break;
966 }
967 free(stmt);
968 return stmts;
969 }
970
971 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
972 impl_stmts *stmts = calloc(1, sizeof(*stmts));
973 return add_impl_stmt(stmts, stmt);
974 }
975
976 static inline void free_impl_stmts(impl_stmts *stmts) {
977 size_t i;
978
979 for (i = 0; i < stmts->let.count; ++i) {
980 free_let_stmt(stmts->let.list[i]);
981 }
982 free(stmts->let.list);
983 for (i = 0; i < stmts->ret.count; ++i) {
984 free_return_stmt(stmts->ret.list[i]);
985 }
986 free(stmts->ret.list);
987 for (i = 0; i < stmts->set.count; ++i) {
988 free_set_stmt(stmts->set.list[i]);
989 }
990 free(stmts->set.list);
991 for (i = 0; i < stmts->fre.count; ++i) {
992 free_free_stmt(stmts->fre.list[i]);
993 }
994 free(stmts->fre.list);
995 free(stmts);
996 }
997
998 typedef struct impl {
999 impl_func *func;
1000 impl_stmts *stmts;
1001 decl *decl;
1002 } impl;
1003
1004 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
1005 impl *i = calloc(1, sizeof(*i));
1006 i->func = func;
1007 i->stmts = stmts;
1008 return i;
1009 }
1010
1011 static inline void free_impl(impl *impl) {
1012 free_impl_func(impl->func);
1013 free_impl_stmts(impl->stmts);
1014 free(impl);
1015 }
1016
1017 typedef struct impls {
1018 size_t count;
1019 impl **list;
1020 } impls;
1021
1022 static inline impls *add_impl(impls *impls, impl *impl) {
1023 if (!impls) {
1024 impls = calloc(1, sizeof(*impls));
1025 }
1026 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
1027 impls->list[impls->count-1] = impl;
1028 return impls;
1029 }
1030
1031 static void free_impls(impls *impls) {
1032 size_t i;
1033
1034 for (i = 0; i < impls->count; ++i) {
1035 free_impl(impls->list[i]);
1036 }
1037 free(impls->list);
1038 free(impls);
1039 }
1040
1041 typedef struct decl_file {
1042 char *ln;
1043 char *fn;
1044 } decl_file;
1045
1046 static inline void free_decl_file(decl_file *file) {
1047 if (file->ln) {
1048 free(file->ln);
1049 }
1050 if (file->fn) {
1051 free(file->fn);
1052 }
1053 memset(file, 0, sizeof(*file));
1054 }
1055
1056 typedef struct decl_libs {
1057 void **dl;
1058 size_t count;
1059 } decl_libs;
1060
1061 static inline void free_decl_libs(decl_libs *libs) {
1062 if (libs->dl) {
1063 size_t i;
1064 for (i = 0; i < libs->count; ++i) {
1065 if (libs->dl[i]) {
1066 dlclose(libs->dl[i]);
1067 }
1068 }
1069 free(libs->dl);
1070 }
1071 memset(libs, 0, sizeof(*libs));
1072 }
1073
1074 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1075 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1076 libs->dl[libs->count-1] = dlopened;
1077 }
1078
1079 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
1080 unsigned i;
1081
1082 if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) {
1083 ret_val = *(void **) ret_val;
1084 }
1085 return ret_val;
1086 }
1087
1088 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
1089 impl_val *val, *val_ptr;
1090 unsigned i;
1091
1092 if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1093 return ptr;
1094 }
1095 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
1096 for (i = 1; i < var->pointer_level; ++i) {
1097 val_ptr->ptr = (void **) val_ptr + 1;
1098 val_ptr = val_ptr->ptr;
1099 }
1100 val_ptr->ptr = ptr;
1101 return val;
1102 }
1103
1104 static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
1105 void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos;
1106 impl_val *val = enref_impl_val(ptr, set_arg->var);
1107
1108 if (val != ptr) {
1109 *to_free = val;
1110 }
1111
1112 return val;
1113 }
1114
1115 #define PSI_ERROR 16
1116 #define PSI_WARNING 32
1117 typedef void (*psi_error_cb)(int type, const char *msg, ...);
1118
1119 #define PSI_DATA(D) ((PSI_Data *) (D))
1120 #define PSI_DATA_MEMBERS \
1121 constants *consts; \
1122 decl_typedefs *defs; \
1123 decl_structs *structs; \
1124 decls *decls; \
1125 impls *impls; \
1126 union { \
1127 decl_file file; \
1128 decl_libs libs; \
1129 } psi; \
1130 psi_error_cb error
1131 typedef struct PSI_Data {
1132 PSI_DATA_MEMBERS;
1133 } PSI_Data;
1134
1135 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1136 if (!dest) {
1137 dest = malloc(sizeof(*dest));
1138 }
1139 memcpy(dest, src, sizeof(*dest));
1140 memset(src, 0, sizeof(*src));
1141 return dest;
1142 }
1143
1144 static inline void PSI_DataDtor(PSI_Data *data) {
1145 if (data->consts) {
1146 free_constants(data->consts);
1147 }
1148 if (data->defs) {
1149 free_decl_typedefs(data->defs);
1150 }
1151 if (data->structs) {
1152 free_decl_structs(data->structs);
1153 }
1154 if (data->decls) {
1155 free_decls(data->decls);
1156 }
1157 if (data->impls) {
1158 free_impls(data->impls);
1159 }
1160 free_decl_file(&data->psi.file);
1161 }
1162
1163 typedef struct PSI_Parser {
1164 PSI_DATA_MEMBERS;
1165 FILE *fp;
1166 unsigned flags;
1167 unsigned errors;
1168 void *proc;
1169 size_t line;
1170 token_t num;
1171 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1172 } PSI_Parser;
1173
1174 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1175 PSI_Token *T;
1176 size_t token_len;
1177
1178 if (P->cur < P->tok) {
1179 return NULL;
1180 }
1181
1182 token_len = P->cur - P->tok;
1183
1184 T = calloc(1, sizeof(*T) + token_len);
1185 T->type = P->num;
1186 T->line = P->line;
1187 T->size = token_len;
1188 T->text[token_len] = 0;
1189 memcpy(T->text, P->tok, token_len);
1190
1191 return T;
1192 }
1193
1194 #define PSI_PARSER_DEBUG 0x1
1195
1196 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1197 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1198 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1199 token_t PSI_ParserScan(PSI_Parser *P);
1200 void PSI_ParserParse(PSI_Parser *P, PSI_Token *T);
1201 void PSI_ParserDtor(PSI_Parser *P);
1202 void PSI_ParserFree(PSI_Parser **P);
1203
1204 #endif