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