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