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