fix macro decl
[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 let_calloc *alloc;
621 } let_func;
622
623 static inline let_func *init_let_func(token_t type, const char *name, let_calloc *alloc) {
624 let_func *func = calloc(1, sizeof(*func));
625 func->type = type;
626 func->name = strdup(name);
627 func->alloc = alloc;
628 return func;
629 }
630
631 static inline void free_let_func(let_func *func) {
632 if (func->alloc) {
633 free_let_calloc(func->alloc);
634 }
635 free(func->name);
636 free(func);
637 }
638
639 typedef struct let_value {
640 let_func *func;
641 impl_var *var;
642 unsigned is_reference:1;
643 } let_value;
644
645 static inline let_value *init_let_value(let_func *func, impl_var *var, int is_reference) {
646 let_value *val = calloc(1, sizeof(*val));
647 val->is_reference = is_reference;
648 val->func = func;
649 val->var = var;
650 return val;
651 }
652
653 static inline void free_let_value(let_value *val) {
654 if (val->func) {
655 free_let_func(val->func);
656 }
657 if (val->var) {
658 free_impl_var(val->var);
659 }
660 free(val);
661 }
662
663 typedef struct let_stmt {
664 decl_var *var;
665 let_value *val;
666 impl_arg *arg;
667 void *ptr;
668 } let_stmt;
669
670 static inline let_stmt *init_let_stmt(decl_var *var, let_value *val) {
671 let_stmt *let = calloc(1, sizeof(*let));
672 let->var = var;
673 let->val = val;
674 return let;
675 }
676
677 static inline void free_let_stmt(let_stmt *stmt) {
678 free_decl_var(stmt->var);
679 if (stmt->val) {
680 free_let_value(stmt->val);
681 }
682 free(stmt);
683 }
684
685 struct set_value;
686
687 typedef struct set_func {
688 token_t type;
689 char *name;
690 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
691 } set_func;
692
693 static inline set_func *init_set_func(token_t type, const char *name) {
694 set_func *func = calloc(1, sizeof(*func));
695 func->type = type;
696 func->name = strdup(name);
697 return func;
698 }
699
700 static inline void free_set_func(set_func *func) {
701 free(func->name);
702 free(func);
703 }
704
705 typedef struct set_value {
706 set_func *func;
707 decl_vars *vars;
708 num_exp *num;
709 struct {
710 struct set_value *set;
711 impl_val *val;
712 } outer;
713 struct set_value **inner;
714 size_t count;
715 } set_value;
716
717 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
718 set_value *val = calloc(1, sizeof(*val));
719 val->func = func;
720 val->vars = vars;
721 return val;
722 }
723 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
724 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
725 val->inner[val->count-1] = inner;
726 return val;
727 }
728
729 static inline void free_set_value(set_value *val) {
730 free_set_func(val->func);
731 free_decl_vars(val->vars);
732 if (val->inner) {
733 size_t i;
734 for (i = 0; i < val->count; ++i) {
735 free_set_value(val->inner[i]);
736 }
737 free(val->inner);
738 }
739 free(val);
740 }
741
742 typedef struct set_stmt {
743 impl_var *var;
744 set_value *val;
745 impl_arg *arg;
746 } set_stmt;
747
748 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
749 set_stmt *set = calloc(1, sizeof(*set));
750 set->var = var;
751 set->val = val;
752 return set;
753 }
754
755 static inline void free_set_stmt(set_stmt *set) {
756 free_impl_var(set->var);
757 free_set_value(set->val);
758 free(set);
759 }
760
761 typedef struct return_stmt {
762 set_value *set;
763 decl_arg *decl;
764 } return_stmt;
765
766 static inline return_stmt *init_return_stmt(set_value *val) {
767 return_stmt *ret = calloc(1, sizeof(*ret));
768 ret->set = val;
769 return ret;
770 }
771
772 static inline void free_return_stmt(return_stmt *ret) {
773 //free_set_func(ret->func);
774 //free_decl_var(ret->decl);
775 free_set_value(ret->set);
776 free(ret);
777 }
778
779 typedef struct free_call {
780 char *func;
781 decl_vars *vars;
782 decl *decl;
783 } free_call;
784
785 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
786 free_call *f = calloc(1, sizeof(*f));
787 f->func = strdup(func);
788 f->vars = vars;
789 return f;
790 }
791
792 static inline void free_free_call(free_call *f) {
793 free(f->func);
794 free(f);
795 }
796
797 typedef struct free_calls {
798 free_call **list;
799 size_t count;
800 } free_calls;
801
802 static inline free_calls *init_free_calls(free_call *f) {
803 free_calls *fcs = calloc(1, sizeof(*fcs));
804 if (f) {
805 fcs->count = 1;
806 fcs->list = calloc(1, sizeof(*fcs->list));
807 fcs->list[0] = f;
808 }
809 return fcs;
810 }
811
812 static inline void free_free_calls(free_calls *fcs) {
813 size_t i;
814
815 for (i = 0; i < fcs->count; ++i) {
816 free_free_call(fcs->list[i]);
817 }
818 free(fcs->list);
819 free(fcs);
820 }
821
822 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
823 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
824 fcs->list[fcs->count-1] = f;
825 return fcs;
826 }
827
828 typedef struct free_stmt {
829 free_calls *calls;
830 } free_stmt;
831
832 static inline free_stmt *init_free_stmt(free_calls *calls) {
833 free_stmt *f = calloc(1, sizeof(*f));
834 f->calls = calls;
835 return f;
836 }
837
838 static inline void free_free_stmt(free_stmt *f) {
839 free_free_calls(f->calls);
840 free(f);
841 }
842
843 typedef struct impl_stmt {
844 token_t type;
845 union {
846 let_stmt *let;
847 set_stmt *set;
848 return_stmt *ret;
849 free_stmt *fre;
850 void *ptr;
851 } s;
852 } impl_stmt;
853
854 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
855 impl_stmt *stmt = calloc(1, sizeof(*stmt));
856 stmt->type = type;
857 stmt->s.ptr = ptr;
858 return stmt;
859 }
860
861 static inline void free_impl_stmt(impl_stmt *stmt) {
862 switch (stmt->type) {
863 case PSI_T_LET:
864 free_let_stmt(stmt->s.let);
865 break;
866 case PSI_T_SET:
867 free_set_stmt(stmt->s.set);
868 break;
869 case PSI_T_RETURN:
870 free_return_stmt(stmt->s.ret);
871 break;
872 case PSI_T_FREE:
873 free_free_stmt(stmt->s.fre);
874 break;
875 }
876 free(stmt);
877 }
878
879 typedef struct impl_stmts {
880 struct {
881 return_stmt **list;
882 size_t count;
883 } ret;
884 struct {
885 let_stmt **list;
886 size_t count;
887 } let;
888 struct {
889 set_stmt **list;
890 size_t count;
891 } set;
892 struct {
893 free_stmt **list;
894 size_t count;
895 } fre;
896 } impl_stmts;
897
898 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
899 list = realloc(list, count * sizeof(list));
900 ((void **)list)[count-1] = stmt;
901 return list;
902 }
903
904 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
905 switch (stmt->type) {
906 case PSI_T_RETURN:
907 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
908 break;
909 case PSI_T_LET:
910 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
911 break;
912 case PSI_T_SET:
913 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
914 break;
915 case PSI_T_FREE:
916 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
917 break;
918 }
919 free(stmt);
920 return stmts;
921 }
922
923 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
924 impl_stmts *stmts = calloc(1, sizeof(*stmts));
925 return add_impl_stmt(stmts, stmt);
926 }
927
928 static inline void free_impl_stmts(impl_stmts *stmts) {
929 size_t i;
930
931 for (i = 0; i < stmts->let.count; ++i) {
932 free_let_stmt(stmts->let.list[i]);
933 }
934 free(stmts->let.list);
935 for (i = 0; i < stmts->ret.count; ++i) {
936 free_return_stmt(stmts->ret.list[i]);
937 }
938 free(stmts->ret.list);
939 for (i = 0; i < stmts->set.count; ++i) {
940 free_set_stmt(stmts->set.list[i]);
941 }
942 free(stmts->set.list);
943 for (i = 0; i < stmts->fre.count; ++i) {
944 free_free_stmt(stmts->fre.list[i]);
945 }
946 free(stmts->fre.list);
947 free(stmts);
948 }
949
950 typedef struct impl {
951 impl_func *func;
952 impl_stmts *stmts;
953 decl *decl;
954 } impl;
955
956 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
957 impl *i = calloc(1, sizeof(*i));
958 i->func = func;
959 i->stmts = stmts;
960 return i;
961 }
962
963 static inline void free_impl(impl *impl) {
964 free_impl_func(impl->func);
965 free_impl_stmts(impl->stmts);
966 free(impl);
967 }
968
969 typedef struct impls {
970 size_t count;
971 impl **list;
972 } impls;
973
974 static inline impls *add_impl(impls *impls, impl *impl) {
975 if (!impls) {
976 impls = calloc(1, sizeof(*impls));
977 }
978 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
979 impls->list[impls->count-1] = impl;
980 return impls;
981 }
982
983 static void free_impls(impls *impls) {
984 size_t i;
985
986 for (i = 0; i < impls->count; ++i) {
987 free_impl(impls->list[i]);
988 }
989 free(impls->list);
990 free(impls);
991 }
992
993 typedef struct decl_file {
994 char *ln;
995 char *fn;
996 } decl_file;
997
998 static inline void free_decl_file(decl_file *file) {
999 if (file->ln) {
1000 free(file->ln);
1001 }
1002 if (file->fn) {
1003 free(file->fn);
1004 }
1005 memset(file, 0, sizeof(*file));
1006 }
1007
1008 typedef struct decl_libs {
1009 void **dl;
1010 size_t count;
1011 } decl_libs;
1012
1013 static inline void free_decl_libs(decl_libs *libs) {
1014 if (libs->dl) {
1015 size_t i;
1016 for (i = 0; i < libs->count; ++i) {
1017 if (libs->dl[i]) {
1018 dlclose(libs->dl[i]);
1019 }
1020 }
1021 free(libs->dl);
1022 }
1023 memset(libs, 0, sizeof(*libs));
1024 }
1025
1026 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1027 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1028 libs->dl[libs->count-1] = dlopened;
1029 }
1030
1031 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
1032 unsigned i;
1033
1034 if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) {
1035 ret_val = *(void **) ret_val;
1036 }
1037 return ret_val;
1038 }
1039
1040 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
1041 impl_val *val, *val_ptr;
1042 unsigned i;
1043
1044 if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1045 return ptr;
1046 }
1047 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
1048 for (i = 1; i < var->pointer_level; ++i) {
1049 val_ptr->ptr = (void **) val_ptr + 1;
1050 val_ptr = val_ptr->ptr;
1051 }
1052 val_ptr->ptr = ptr;
1053 return val;
1054 }
1055
1056 static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
1057 void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos;
1058 impl_val *val = enref_impl_val(ptr, set_arg->var);
1059
1060 if (val != ptr) {
1061 *to_free = val;
1062 }
1063
1064 return val;
1065 }
1066
1067 #define PSI_ERROR 16
1068 #define PSI_WARNING 32
1069 typedef void (*psi_error_cb)(int type, const char *msg, ...);
1070
1071 #define PSI_DATA(D) ((PSI_Data *) (D))
1072 #define PSI_DATA_MEMBERS \
1073 constants *consts; \
1074 decl_typedefs *defs; \
1075 decl_structs *structs; \
1076 decls *decls; \
1077 impls *impls; \
1078 union { \
1079 decl_file file; \
1080 decl_libs libs; \
1081 } psi; \
1082 psi_error_cb error
1083 typedef struct PSI_Data {
1084 PSI_DATA_MEMBERS;
1085 } PSI_Data;
1086
1087 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1088 if (!dest) {
1089 dest = malloc(sizeof(*dest));
1090 }
1091 memcpy(dest, src, sizeof(*dest));
1092 memset(src, 0, sizeof(*src));
1093 return dest;
1094 }
1095
1096 static inline void PSI_DataDtor(PSI_Data *data) {
1097 if (data->consts) {
1098 free_constants(data->consts);
1099 }
1100 if (data->defs) {
1101 free_decl_typedefs(data->defs);
1102 }
1103 if (data->structs) {
1104 free_decl_structs(data->structs);
1105 }
1106 if (data->decls) {
1107 free_decls(data->decls);
1108 }
1109 if (data->impls) {
1110 free_impls(data->impls);
1111 }
1112 free_decl_file(&data->psi.file);
1113 }
1114
1115 typedef struct PSI_Parser {
1116 PSI_DATA_MEMBERS;
1117 FILE *fp;
1118 unsigned flags;
1119 unsigned errors;
1120 void *proc;
1121 size_t line;
1122 token_t num;
1123 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1124 } PSI_Parser;
1125
1126 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1127 PSI_Token *T;
1128 size_t token_len;
1129
1130 if (P->cur < P->tok) {
1131 return NULL;
1132 }
1133
1134 token_len = P->cur - P->tok;
1135
1136 T = calloc(1, sizeof(*T) + token_len);
1137 T->type = P->num;
1138 T->line = P->line;
1139 T->size = token_len;
1140 T->text[token_len] = 0;
1141 memcpy(T->text, P->tok, token_len);
1142
1143 return T;
1144 }
1145
1146 #define PSI_PARSER_DEBUG 0x1
1147
1148 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1149 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1150 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1151 token_t PSI_ParserScan(PSI_Parser *P);
1152 void PSI_ParserParse(PSI_Parser *P, PSI_Token *T);
1153 void PSI_ParserDtor(PSI_Parser *P);
1154 void PSI_ParserFree(PSI_Parser **P);
1155
1156 #endif