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 #define PSI_T_LONG_DOUBLE (PSI_T_DOUBLE << 16)
17
18 typedef int token_t;
19
20 size_t psi_t_alignment(token_t);
21 size_t psi_t_size(token_t);
22
23 typedef struct PSI_Token {
24 token_t type;
25 unsigned size, line, col;
26 char *text, *file;
27 char buf[1];
28 } PSI_Token;
29
30 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src);
31
32 typedef union impl_val {
33 char cval;
34 int8_t i8;
35 uint8_t u8;
36 short sval;
37 int16_t i16;
38 uint16_t u16;
39 int ival;
40 int32_t i32;
41 uint32_t u32;
42 long lval;
43 int64_t i64;
44 uint64_t u64;
45 float fval;
46 double dval;
47 #ifdef HAVE_LONG_DOUBLE
48 long double ldval;
49 #endif
50 union {
51 zend_bool bval;
52 zend_long lval;
53 zend_string *str;
54 } zend;
55 void *ptr;
56 uint8_t _dbg[sizeof(void *)];
57 } impl_val;
58
59 typedef struct decl_type {
60 PSI_Token *token;
61 char *name;
62 token_t type;
63 struct decl_type *real;
64 struct decl_struct *strct;
65 struct decl_union *unn;
66 struct decl_enum *enm;
67 struct decl *func;
68 } decl_type;
69
70 static inline decl_type *init_decl_type(token_t type, const char *name) {
71 decl_type *t = calloc(1, sizeof(*t));
72 t->type = type;
73 t->name = strdup(name);
74 return t;
75 }
76
77 static inline decl_type *real_decl_type(decl_type *type) {
78 while (type->real) {
79 type = type->real;
80 }
81 return type;
82 }
83
84 static inline void free_decl(struct decl *decl);
85 static inline void free_decl_type(decl_type *type) {
86 if (type->token) {
87 free(type->token);
88 }
89 if (type->type == PSI_T_FUNCTION) {
90 free_decl(type->func);
91 }
92 free(type->name);
93 free(type);
94 }
95
96 typedef struct decl_var {
97 PSI_Token *token;
98 char *name;
99 unsigned pointer_level;
100 unsigned array_size;
101 struct decl_arg *arg;
102 } decl_var;
103
104 static inline decl_var *init_decl_var(const char *name, unsigned pl, unsigned as) {
105 decl_var *v = calloc(1, sizeof(*v));
106 v->name = (char *) strdup((const char *) name);
107 v->pointer_level = pl;
108 v->array_size = as;
109 return v;
110 }
111
112 static inline decl_var *copy_decl_var(decl_var *src) {
113 decl_var *dest = calloc(1, sizeof(*dest));
114
115 memcpy(dest, src, sizeof(*dest));
116 dest->name = strdup(dest->name);
117 if (dest->token) {
118 dest->token = PSI_TokenCopy(dest->token);
119 }
120 return dest;
121 }
122
123 static inline void free_decl_var(decl_var *var) {
124 if (var->token) {
125 free(var->token);
126 }
127 free(var->name);
128 free(var);
129 }
130
131 typedef struct decl_struct_layout {
132 size_t pos;
133 size_t len;
134 } decl_struct_layout;
135
136 static inline decl_struct_layout *init_decl_struct_layout(size_t pos, size_t len) {
137 decl_struct_layout *l = calloc(1, sizeof(*l));
138 ZEND_ASSERT(pos+len);
139 l->pos = pos;
140 l->len = len;
141 return l;
142 }
143
144 static inline void free_decl_struct_layout(decl_struct_layout *l) {
145 free(l);
146 }
147
148 typedef struct decl_arg {
149 PSI_Token *token;
150 decl_type *type;
151 decl_var *var;
152 decl_struct_layout *layout;
153 struct let_stmt *let;
154 impl_val val;
155 void *ptr;
156 void *mem;
157 } decl_arg;
158
159 static inline decl_arg *init_decl_arg(decl_type *type, decl_var *var) {
160 decl_arg *arg = calloc(1, sizeof(*arg));
161 arg->token = var->token;
162 arg->type = type;
163 arg->var = var;
164 var->arg = arg;
165 arg->ptr = &arg->val;
166 return arg;
167 }
168
169 static inline void free_decl_arg(decl_arg *arg) {
170 if (arg->token && arg->token != arg->var->token) {
171 free(arg->token);
172 }
173 free_decl_type(arg->type);
174 free_decl_var(arg->var);
175 if (arg->layout) {
176 free_decl_struct_layout(arg->layout);
177 }
178 free(arg);
179 }
180
181 typedef struct decl_typedefs {
182 size_t count;
183 decl_arg **list;
184 } decl_typedefs;
185
186 static inline decl_typedefs *add_decl_typedef(decl_typedefs *defs, decl_arg *def) {
187 if (!defs) {
188 defs = calloc(1, sizeof(*defs));
189 }
190 defs->list = realloc(defs->list, ++defs->count * sizeof(*defs->list));
191 defs->list[defs->count-1] = def;
192 return defs;
193 }
194
195 static void free_decl_typedefs(decl_typedefs *defs) {
196 size_t i;
197
198 for (i = 0; i < defs->count; ++i) {
199 free_decl_arg(defs->list[i]);
200 }
201 free(defs->list);
202 free(defs);
203 }
204
205 typedef struct decl_vars {
206 decl_var **vars;
207 size_t count;
208 } decl_vars;
209
210 static inline decl_vars *init_decl_vars(decl_var *var) {
211 decl_vars *vars = calloc(1, sizeof(*vars));
212 if (var) {
213 vars->count = 1;
214 vars->vars = calloc(1, sizeof(*vars->vars));
215 vars->vars[0] = var;
216 }
217 return vars;
218 }
219
220 static inline decl_vars *add_decl_var(decl_vars *vars, decl_var *var) {
221 vars->vars = realloc(vars->vars, ++vars->count * sizeof(*vars->vars));
222 vars->vars[vars->count-1] = var;
223 return vars;
224 }
225
226 static inline void free_decl_vars(decl_vars *vars) {
227 size_t i;
228
229 for (i = 0; i < vars->count; ++i) {
230 free_decl_var(vars->vars[i]);
231 }
232 free(vars->vars);
233 free(vars);
234 }
235
236 typedef struct decl_args {
237 decl_arg **args;
238 size_t count;
239 unsigned varargs:1;
240 } decl_args;
241
242 static inline decl_args *init_decl_args(decl_arg *arg) {
243 decl_args *args = calloc(1, sizeof(*args));
244 if (arg) {
245 args->count = 1;
246 args->args = calloc(1, sizeof(*args->args));
247 args->args[0] = arg;
248 }
249 return args;
250 }
251
252 static inline decl_args *add_decl_arg(decl_args *args, decl_arg *arg) {
253 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
254 args->args[args->count-1] = arg;
255 return args;
256 }
257
258 static inline void free_decl_args(decl_args *args) {
259 size_t i;
260
261 for (i = 0; i < args->count; ++i) {
262 free_decl_arg(args->args[i]);
263 }
264 free(args->args);
265 free(args);
266 }
267
268 typedef struct decl_abi {
269 PSI_Token *token;
270 char *convention;
271 } decl_abi;
272
273 static inline decl_abi *init_decl_abi(const char *convention) {
274 decl_abi *abi = calloc(1, sizeof(*abi));
275 abi->convention = strdup(convention);
276 return abi;
277 }
278
279 static inline void free_decl_abi(decl_abi *abi) {
280 if (abi->token) {
281 free(abi->token);
282 }
283 free(abi->convention);
284 free(abi);
285 }
286
287 typedef struct decl_callinfo {
288 void *sym;
289 void *info;
290 size_t argc;
291 void **args;
292 void **rval;
293 } decl_callinfo;
294
295 typedef struct decl {
296 decl_abi *abi;
297 decl_arg *func;
298 decl_args *args;
299 struct impl *impl;
300 decl_callinfo call;
301 } decl;
302
303 static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
304 decl *d = calloc(1, sizeof(*d));
305 d->abi = abi;
306 d->func = func;
307 d->args = args;
308 return d;
309 }
310
311 static inline void free_decl(decl *d) {
312 free_decl_abi(d->abi);
313 free_decl_arg(d->func);
314 if (d->args) {
315 free_decl_args(d->args);
316 }
317 free(d);
318 }
319
320 typedef struct decls {
321 size_t count;
322 decl **list;
323 } decls;
324
325 static inline decls *add_decl(decls *decls, decl *decl) {
326 if (!decls) {
327 decls = calloc(1, sizeof(*decls));
328 }
329 decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
330 decls->list[decls->count-1] = decl;
331 return decls;
332 }
333
334 static inline void free_decls(decls *decls) {
335 size_t i;
336
337 for (i = 0; i < decls->count; ++i) {
338 free_decl(decls->list[i]);
339 }
340 free(decls->list);
341 free(decls);
342 }
343
344
345 typedef struct decl_struct {
346 PSI_Token *token;
347 char *name;
348 decl_args *args;
349 size_t size;
350 size_t align;
351 struct {
352 void *type;
353 void (*dtor)(void *type);
354 } engine;
355 } decl_struct;
356
357 static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
358 decl_struct *s = calloc(1, sizeof(*s));
359 s->name = strdup(name);
360 s->args = args;
361 return s;
362 }
363
364 static inline void free_decl_struct(decl_struct *s) {
365 if (s->token) {
366 free(s->token);
367 }
368 if (s->args) {
369 free_decl_args(s->args);
370 }
371 if (s->engine.type && s->engine.dtor) {
372 s->engine.dtor(s->engine.type);
373 }
374 free(s->name);
375 free(s);
376 }
377
378 typedef struct decl_structs {
379 size_t count;
380 decl_struct **list;
381 } decl_structs;
382
383 static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
384 if (!ss) {
385 ss = calloc(1, sizeof(*ss));
386 }
387 ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
388 ss->list[ss->count-1] = s;
389 return ss;
390 }
391
392 static inline void free_decl_structs(decl_structs *ss) {
393 size_t i;
394
395 for (i = 0; i < ss->count; ++i) {
396 free_decl_struct(ss->list[i]);
397 }
398 free(ss->list);
399 free(ss);
400 }
401
402 typedef struct decl_union {
403 PSI_Token *token;
404 char *name;
405 decl_args *args;
406 size_t size;
407 size_t align;
408 } decl_union;
409
410 static inline decl_union *init_decl_union(const char *name, decl_args *args) {
411 decl_union *u = calloc(1, sizeof(*u));
412 u->name = strdup(name);
413 u->args = args;
414 return u;
415 }
416
417 static inline void free_decl_union(decl_union *u) {
418 if (u->token) {
419 free(u->token);
420 }
421 if (u->args) {
422 free_decl_args(u->args);
423 }
424 free(u->name);
425 free(u);
426 }
427
428 typedef struct decl_unions {
429 decl_union **list;
430 size_t count;
431 } decl_unions;
432
433 static inline decl_unions *add_decl_union(decl_unions *uu, decl_union *u) {
434 if (!uu) {
435 uu = calloc(1, sizeof(*uu));
436 }
437 uu->list = realloc(uu->list, ++uu->count * sizeof(*uu->list));
438 uu->list[uu->count-1] = u;
439 return uu;
440 }
441
442 static inline void free_decl_unions(decl_unions *uu) {
443 size_t i;
444
445 for (i = 0; i < uu->count; ++i) {
446 free_decl_union(uu->list[i]);
447 }
448 free(uu->list);
449 free(uu);
450 }
451
452 typedef struct impl_type {
453 char *name;
454 token_t type;
455 } impl_type;
456
457 static inline impl_type *init_impl_type(token_t type, const char *name) {
458 impl_type *t = calloc(1, sizeof(*t));
459
460 t->type = type;
461 t->name = strdup(name);
462 return t;
463 }
464
465 static inline void free_impl_type(impl_type *type) {
466 free(type->name);
467 free(type);
468 }
469
470 typedef struct impl_var {
471 PSI_Token *token;
472 char *name;
473 unsigned reference:1;
474 } impl_var;
475
476 static inline impl_var *init_impl_var(const char *name, int is_reference) {
477 impl_var *var = calloc(1, sizeof(*var));
478 var->name = strdup(name);
479 var->reference = is_reference;
480 return var;
481 }
482
483 static inline void free_impl_var(impl_var *var) {
484 if (var->token) {
485 free(var->token);
486 }
487 free(var->name);
488 free(var);
489 }
490
491 typedef struct impl_def_val {
492 token_t type;
493 char *text;
494 } impl_def_val;
495
496 static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
497 impl_def_val *def = calloc(1, sizeof(*def));
498 def->type = t;
499 def->text = strdup(text);
500 return def;
501 }
502
503 static inline void free_impl_def_val(impl_def_val *def) {
504 free(def->text);
505 free(def);
506 }
507
508 typedef struct const_type {
509 token_t type;
510 char *name;
511 } const_type;
512
513 static inline const_type *init_const_type(token_t type, const char *name) {
514 const_type *ct = calloc(1, sizeof(*ct));
515 ct->type = type;
516 ct->name = strdup(name);
517 return ct;
518 }
519
520 static inline void free_const_type(const_type *type) {
521 free(type->name);
522 free(type);
523 }
524
525 typedef struct constant {
526 const_type *type;
527 char *name;
528 impl_def_val *val;
529 } constant;
530
531 static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
532 constant *c = calloc(1, sizeof(*c));
533 c->type = type;
534 c->name = strdup(name);
535 c->val = val;
536 return c;
537 }
538
539 static inline void free_constant(constant *constant) {
540 free_const_type(constant->type);
541 free(constant->name);
542 free_impl_def_val(constant->val);
543 free(constant);
544 }
545
546 typedef struct constants {
547 size_t count;
548 constant **list;
549 } constants;
550
551 static inline constants *add_constant(constants *constants, constant *constant) {
552 if (!constants) {
553 constants = calloc(1, sizeof(*constants));
554 }
555 constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
556 constants->list[constants->count-1] = constant;
557 return constants;
558 }
559
560 static inline void free_constants(constants *c) {
561 size_t i;
562
563 for (i = 0; i < c->count; ++i) {
564 free_constant(c->list[i]);
565 }
566 free(c->list);
567 free(c);
568 }
569
570 typedef struct impl_arg {
571 impl_type *type;
572 impl_var *var;
573 impl_def_val *def;
574 impl_val val;
575 zval *_zv;
576 } impl_arg;
577
578 static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
579 impl_arg *arg = calloc(1, sizeof(*arg));
580 arg->type = type;
581 arg->var = var;
582 arg->def = def;
583 return arg;
584 }
585
586 static inline void free_impl_arg(impl_arg *arg) {
587 free_impl_type(arg->type);
588 free_impl_var(arg->var);
589 if (arg->def) {
590 free_impl_def_val(arg->def);
591 }
592 free(arg);
593 }
594
595 typedef struct impl_vararg {
596 impl_arg *name;
597 struct impl_args *args;
598 token_t *types;
599 impl_val *values;
600 void **free_list;
601 } impl_vararg;
602
603 typedef struct impl_args {
604 impl_arg **args;
605 size_t count;
606 impl_vararg vararg;
607 } impl_args;
608
609 static inline impl_args *init_impl_args(impl_arg *arg) {
610 impl_args *args = calloc(1, sizeof(*args));
611 if (arg) {
612 args->count = 1;
613 args->args = calloc(1, sizeof(*args->args));
614 args->args[0] = arg;
615 }
616 return args;
617 }
618
619 static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
620 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
621 args->args[args->count-1] = arg;
622 return args;
623 }
624
625 static inline void free_impl_args(impl_args *args) {
626 size_t i;
627
628 for (i = 0; i < args->count; ++i) {
629 free_impl_arg(args->args[i]);
630 }
631 if (args->vararg.name) {
632 free_impl_arg(args->vararg.name);
633 }
634 free(args->args);
635 free(args);
636 }
637
638 typedef struct impl_func {
639 PSI_Token *token;
640 char *name;
641 impl_args *args;
642 impl_type *return_type;
643 unsigned return_reference:1;
644 } impl_func;
645
646 static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) {
647 impl_func *func = calloc(1, sizeof(*func));
648 func->name = strdup(name);
649 func->args = args ? args : init_impl_args(NULL);
650 func->return_type = type;
651 func->return_reference = ret_reference;
652 return func;
653 }
654
655 static inline void free_impl_func(impl_func *f) {
656 if (f->token) {
657 free(f->token);
658 }
659 free_impl_type(f->return_type);
660 free_impl_args(f->args);
661 free(f->name);
662 free(f);
663 }
664
665 typedef struct num_exp {
666 PSI_Token *token;
667 token_t t;
668 union {
669 char *numb;
670 constant *cnst;
671 decl_var *dvar;
672 struct decl_enum_item *enm;
673 } u;
674 token_t operator;
675 int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
676 struct num_exp *operand;
677 } num_exp;
678
679 static inline num_exp *init_num_exp(token_t t, void *num) {
680 num_exp *exp = calloc(1, sizeof(*exp));
681 switch (exp->t = t) {
682 case PSI_T_NUMBER:
683 case PSI_T_NSNAME:
684 exp->u.numb = strdup(num);
685 break;
686 case PSI_T_NAME:
687 exp->u.dvar = num;
688 break;
689 EMPTY_SWITCH_DEFAULT_CASE();
690 }
691 return exp;
692 }
693
694 static inline num_exp *copy_num_exp(num_exp *exp) {
695 decl_var *dvar;
696 num_exp *num = calloc(1, sizeof(*num));
697
698 memcpy(num, exp, sizeof(*num));
699
700 if (num->token) {
701 num->token = PSI_TokenCopy(num->token);
702 }
703 if (num->operand) {
704 num->operand = copy_num_exp(num->operand);
705 }
706 switch (num->t) {
707 case PSI_T_NUMBER:
708 case PSI_T_NSNAME:
709 num->u.numb = strdup(num->u.numb);
710 break;
711 case PSI_T_NAME:
712 dvar = init_decl_var(num->u.dvar->name, num->u.dvar->pointer_level, num->u.dvar->array_size);
713 dvar->arg = num->u.dvar->arg;
714 if (num->u.dvar->token) {
715 dvar->token = PSI_TokenCopy(num->u.dvar->token);
716 }
717 num->u.dvar = dvar;
718 break;
719 }
720 return num;
721 }
722
723 static inline void free_num_exp(num_exp *exp) {
724 if (exp->token) {
725 free(exp->token);
726 }
727 switch (exp->t) {
728 case PSI_T_NUMBER:
729 free(exp->u.numb);
730 break;
731 case PSI_T_NSNAME:
732 break;
733 case PSI_T_NAME:
734 free_decl_var(exp->u.dvar);
735 break;
736 case PSI_T_ENUM:
737 break;
738 EMPTY_SWITCH_DEFAULT_CASE();
739 }
740 if (exp->operand) {
741 free_num_exp(exp->operand);
742 }
743 free(exp);
744 }
745
746 typedef struct decl_enum_item {
747 PSI_Token *token;
748 char *name;
749 num_exp *num;
750 num_exp inc;
751 struct decl_enum_item *prev;
752 } decl_enum_item;
753
754 static inline decl_enum_item *init_decl_enum_item(const char *name, num_exp *num) {
755 decl_enum_item *i = calloc(1, sizeof(*i));
756
757 i->name = strdup(name);
758 i->num = num;
759 return i;
760 }
761
762 static inline void free_decl_enum_item(decl_enum_item *i) {
763 if (i->token) {
764 free(i->token);
765 }
766 if (i->num && i->num != &i->inc) {
767 free_num_exp(i->num);
768 }
769 free(i->name);
770 free(i);
771 }
772
773 typedef struct decl_enum_items {
774 decl_enum_item **list;
775 size_t count;
776 } decl_enum_items;
777
778 static inline decl_enum_items *init_decl_enum_items(decl_enum_item *i) {
779 decl_enum_items *l = calloc(1, sizeof(*l));
780
781 if (i) {
782 l->count = 1;
783 l->list = calloc(1, sizeof(*l->list));
784 l->list[0] = i;
785 }
786 return l;
787 }
788
789 static inline decl_enum_items *add_decl_enum_item(decl_enum_items *l, decl_enum_item *i) {
790 l->list = realloc(l->list, sizeof(*l->list) * (l->count + 1));
791 l->list[l->count] = i;
792 if (l->count) {
793 i->prev = l->list[l->count - 1];
794 }
795 ++l->count;
796 return l;
797 }
798
799 static inline void free_decl_enum_items(decl_enum_items *l) {
800 if (l->list) {
801 size_t j;
802
803 for (j = 0; j < l->count; ++j) {
804 free_decl_enum_item(l->list[j]);
805 }
806 free(l->list);
807 }
808 free(l);
809 }
810
811 typedef struct decl_enum {
812 PSI_Token *token;
813 char *name;
814 decl_enum_items *items;
815 } decl_enum;
816
817 static inline decl_enum *init_decl_enum(const char *name, decl_enum_items *l) {
818 decl_enum *e = calloc(1, sizeof(*e));
819
820 e->name = strdup(name);
821 e->items = l;
822 return e;
823 }
824
825 static inline void free_decl_enum(decl_enum *e) {
826 if (e->token) {
827 free(e->token);
828 }
829 if (e->items) {
830 free_decl_enum_items(e->items);
831 }
832 free(e->name);
833 free(e);
834 }
835
836 typedef struct decl_enums {
837 decl_enum **list;
838 size_t count;
839 } decl_enums;
840
841 static inline decl_enums* add_decl_enum(decl_enums *es, decl_enum *e) {
842 if (!es) {
843 es = calloc(1, sizeof(*es));
844 }
845 es->list = realloc(es->list, ++es->count * sizeof(*es->list));
846 es->list[es->count-1] = e;
847 return es;
848 }
849
850 static inline void free_decl_enums(decl_enums *es) {
851 if (es->list) {
852 size_t j;
853
854 for (j = 0; j < es->count; ++j) {
855 free_decl_enum(es->list[j]);
856 }
857 }
858 free(es->list);
859 free(es);
860 }
861
862 typedef struct let_calloc {
863 num_exp *nmemb;
864 num_exp *size;
865 } let_calloc;
866
867 static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
868 let_calloc *alloc = calloc(1, sizeof(*alloc));
869 alloc->nmemb = nmemb;
870 alloc->size = size;
871 return alloc;
872 }
873
874 static inline void free_let_calloc(let_calloc *alloc) {
875 free_num_exp(alloc->nmemb);
876 free_num_exp(alloc->size);
877 free(alloc);
878 }
879
880 typedef struct let_func {
881 token_t type;
882 char *name;
883 impl_var *var;
884 impl_arg *arg;
885 } let_func;
886
887 static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
888 let_func *func = calloc(1, sizeof(*func));
889 func->type = type;
890 func->name = strdup(name);
891 func->var = var;
892 return func;
893 }
894
895 static inline void free_let_func(let_func *func) {
896 free_impl_var(func->var);
897 free(func->name);
898 free(func);
899 }
900
901 #define PSI_LET_REFERENCE 0x1;
902 typedef struct let_val {
903 enum let_val_kind {
904 PSI_LET_NULL,
905 PSI_LET_NUMEXP,
906 PSI_LET_CALLOC,
907 PSI_LET_FUNC,
908 PSI_LET_TMP,
909 } kind;
910 union {
911 num_exp *num;
912 let_calloc *alloc;
913 let_func *func;
914 decl_var *var;
915 } data;
916 union {
917 struct {
918 unsigned is_reference:1;
919 } one;
920 unsigned all;
921 } flags;
922 } let_val;
923
924 static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
925 let_val *let = calloc(1, sizeof(*let));
926 switch (let->kind = kind) {
927 case PSI_LET_NULL:
928 break;
929 case PSI_LET_NUMEXP:
930 let->data.num = data;
931 break;
932 case PSI_LET_CALLOC:
933 let->data.alloc = data;
934 break;
935 case PSI_LET_FUNC:
936 let->data.func = data;
937 break;
938 case PSI_LET_TMP:
939 let->data.var = data;
940 break;
941 EMPTY_SWITCH_DEFAULT_CASE();
942 }
943 return let;
944 }
945
946 static inline void free_let_val(let_val *let) {
947 switch (let->kind) {
948 case PSI_LET_NULL:
949 break;
950 case PSI_LET_NUMEXP:
951 free_num_exp(let->data.num);
952 break;
953 case PSI_LET_CALLOC:
954 free_let_calloc(let->data.alloc);
955 break;
956 case PSI_LET_FUNC:
957 free_let_func(let->data.func);
958 break;
959 case PSI_LET_TMP:
960 free_decl_var(let->data.var);
961 break;
962 EMPTY_SWITCH_DEFAULT_CASE();
963 }
964 free(let);
965 }
966
967 typedef struct let_stmt {
968 decl_var *var;
969 let_val *val;
970
971 void *ptr;
972 } let_stmt;
973
974 static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
975 let_stmt *let = calloc(1, sizeof(*let));
976 let->var = var;
977 let->val = val;
978 return let;
979 }
980
981 static inline void free_let_stmt(let_stmt *stmt) {
982 if (stmt->val) {
983 if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
984 free_decl_arg(stmt->var->arg);
985 }
986 free_let_val(stmt->val);
987 }
988 free_decl_var(stmt->var);
989 free(stmt);
990 }
991
992 struct set_value;
993
994 typedef struct set_func {
995 PSI_Token *token;
996 token_t type;
997 char *name;
998 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
999 } set_func;
1000
1001 static inline set_func *init_set_func(token_t type, const char *name) {
1002 set_func *func = calloc(1, sizeof(*func));
1003 func->type = type;
1004 func->name = strdup(name);
1005 return func;
1006 }
1007
1008 static inline void free_set_func(set_func *func) {
1009 if (func->token) {
1010 free(func->token);
1011 }
1012 free(func->name);
1013 free(func);
1014 }
1015
1016 typedef struct set_value {
1017 set_func *func;
1018 decl_vars *vars;
1019 num_exp *num;
1020 struct {
1021 struct set_value *set;
1022 impl_val *val;
1023 } outer;
1024 struct set_value **inner;
1025 size_t count;
1026 } set_value;
1027
1028 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
1029 set_value *val = calloc(1, sizeof(*val));
1030 val->func = func;
1031 val->vars = vars;
1032 return val;
1033 }
1034 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
1035 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
1036 val->inner[val->count-1] = inner;
1037 inner->outer.set = val;
1038 return val;
1039 }
1040
1041 static inline void free_set_value(set_value *val) {
1042 if (val->func) {
1043 free_set_func(val->func);
1044 }
1045 if (val->vars) {
1046 free_decl_vars(val->vars);
1047 }
1048 if (val->inner && (!val->outer.set || val->outer.set->inner != val->inner)) {
1049 size_t i;
1050 for (i = 0; i < val->count; ++i) {
1051 free_set_value(val->inner[i]);
1052 }
1053 free(val->inner);
1054 }
1055 if (val->num) {
1056 free_num_exp(val->num);
1057 }
1058 free(val);
1059 }
1060
1061 typedef struct set_stmt {
1062 impl_var *var;
1063 set_value *val;
1064 impl_arg *arg;
1065 } set_stmt;
1066
1067 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
1068 set_stmt *set = calloc(1, sizeof(*set));
1069 set->var = var;
1070 set->val = val;
1071 return set;
1072 }
1073
1074 static inline void free_set_stmt(set_stmt *set) {
1075 free_impl_var(set->var);
1076 free_set_value(set->val);
1077 free(set);
1078 }
1079
1080 typedef struct return_stmt {
1081 PSI_Token *token;
1082 set_value *set;
1083 decl_arg *decl;
1084 } return_stmt;
1085
1086 static inline return_stmt *init_return_stmt(set_value *val) {
1087 return_stmt *ret = calloc(1, sizeof(*ret));
1088 ret->set = val;
1089 return ret;
1090 }
1091
1092 static inline void free_return_stmt(return_stmt *ret) {
1093 if (ret->token) {
1094 free(ret->token);
1095 }
1096 free_set_value(ret->set);
1097 free(ret);
1098 }
1099
1100 typedef struct free_call {
1101 PSI_Token *token;
1102 char *func;
1103 decl_vars *vars;
1104 decl *decl;
1105 } free_call;
1106
1107 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
1108 free_call *f = calloc(1, sizeof(*f));
1109 f->func = strdup(func);
1110 f->vars = vars;
1111 return f;
1112 }
1113
1114 static inline void free_free_call(free_call *f) {
1115 if (f->token) {
1116 free(f->token);
1117 }
1118 free(f->func);
1119 free_decl_vars(f->vars);
1120 free(f);
1121 }
1122
1123 typedef struct free_calls {
1124 free_call **list;
1125 size_t count;
1126 } free_calls;
1127
1128 static inline free_calls *init_free_calls(free_call *f) {
1129 free_calls *fcs = calloc(1, sizeof(*fcs));
1130 if (f) {
1131 fcs->count = 1;
1132 fcs->list = calloc(1, sizeof(*fcs->list));
1133 fcs->list[0] = f;
1134 }
1135 return fcs;
1136 }
1137
1138 static inline void free_free_calls(free_calls *fcs) {
1139 size_t i;
1140
1141 for (i = 0; i < fcs->count; ++i) {
1142 free_free_call(fcs->list[i]);
1143 }
1144 free(fcs->list);
1145 free(fcs);
1146 }
1147
1148 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
1149 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
1150 fcs->list[fcs->count-1] = f;
1151 return fcs;
1152 }
1153
1154 typedef struct free_stmt {
1155 free_calls *calls;
1156 } free_stmt;
1157
1158 static inline free_stmt *init_free_stmt(free_calls *calls) {
1159 free_stmt *f = calloc(1, sizeof(*f));
1160 f->calls = calls;
1161 return f;
1162 }
1163
1164 static inline void free_free_stmt(free_stmt *f) {
1165 free_free_calls(f->calls);
1166 free(f);
1167 }
1168
1169 typedef struct impl_stmt {
1170 token_t type;
1171 union {
1172 let_stmt *let;
1173 set_stmt *set;
1174 return_stmt *ret;
1175 free_stmt *fre;
1176 void *ptr;
1177 } s;
1178 } impl_stmt;
1179
1180 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
1181 impl_stmt *stmt = calloc(1, sizeof(*stmt));
1182 stmt->type = type;
1183 stmt->s.ptr = ptr;
1184 return stmt;
1185 }
1186
1187 static inline void free_impl_stmt(impl_stmt *stmt) {
1188 switch (stmt->type) {
1189 case PSI_T_LET:
1190 free_let_stmt(stmt->s.let);
1191 break;
1192 case PSI_T_SET:
1193 free_set_stmt(stmt->s.set);
1194 break;
1195 case PSI_T_RETURN:
1196 free_return_stmt(stmt->s.ret);
1197 break;
1198 case PSI_T_FREE:
1199 free_free_stmt(stmt->s.fre);
1200 break;
1201 }
1202 free(stmt);
1203 }
1204
1205 typedef struct impl_stmts {
1206 struct {
1207 return_stmt **list;
1208 size_t count;
1209 } ret;
1210 struct {
1211 let_stmt **list;
1212 size_t count;
1213 } let;
1214 struct {
1215 set_stmt **list;
1216 size_t count;
1217 } set;
1218 struct {
1219 free_stmt **list;
1220 size_t count;
1221 } fre;
1222 } impl_stmts;
1223
1224 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
1225 list = realloc(list, count * sizeof(list));
1226 ((void **)list)[count-1] = stmt;
1227 return list;
1228 }
1229
1230 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
1231 switch (stmt->type) {
1232 case PSI_T_RETURN:
1233 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
1234 break;
1235 case PSI_T_LET:
1236 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
1237 break;
1238 case PSI_T_SET:
1239 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
1240 break;
1241 case PSI_T_FREE:
1242 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
1243 break;
1244 }
1245 free(stmt);
1246 return stmts;
1247 }
1248
1249 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
1250 impl_stmts *stmts = calloc(1, sizeof(*stmts));
1251 return add_impl_stmt(stmts, stmt);
1252 }
1253
1254 static inline void free_impl_stmts(impl_stmts *stmts) {
1255 size_t i;
1256
1257 for (i = 0; i < stmts->let.count; ++i) {
1258 free_let_stmt(stmts->let.list[i]);
1259 }
1260 free(stmts->let.list);
1261 for (i = 0; i < stmts->ret.count; ++i) {
1262 free_return_stmt(stmts->ret.list[i]);
1263 }
1264 free(stmts->ret.list);
1265 for (i = 0; i < stmts->set.count; ++i) {
1266 free_set_stmt(stmts->set.list[i]);
1267 }
1268 free(stmts->set.list);
1269 for (i = 0; i < stmts->fre.count; ++i) {
1270 free_free_stmt(stmts->fre.list[i]);
1271 }
1272 free(stmts->fre.list);
1273 free(stmts);
1274 }
1275
1276 typedef struct impl {
1277 impl_func *func;
1278 impl_stmts *stmts;
1279 decl *decl;
1280 } impl;
1281
1282 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
1283 impl *i = calloc(1, sizeof(*i));
1284 i->func = func;
1285 i->stmts = stmts;
1286 return i;
1287 }
1288
1289 static inline void free_impl(impl *impl) {
1290 free_impl_func(impl->func);
1291 free_impl_stmts(impl->stmts);
1292 free(impl);
1293 }
1294
1295 typedef struct impls {
1296 size_t count;
1297 impl **list;
1298 } impls;
1299
1300 static inline impls *add_impl(impls *impls, impl *impl) {
1301 if (!impls) {
1302 impls = calloc(1, sizeof(*impls));
1303 }
1304 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
1305 impls->list[impls->count-1] = impl;
1306 return impls;
1307 }
1308
1309 static void free_impls(impls *impls) {
1310 size_t i;
1311
1312 for (i = 0; i < impls->count; ++i) {
1313 free_impl(impls->list[i]);
1314 }
1315 free(impls->list);
1316 free(impls);
1317 }
1318
1319 typedef struct decl_file {
1320 char *ln;
1321 char *fn;
1322 } decl_file;
1323
1324 static inline void free_decl_file(decl_file *file) {
1325 if (file->ln) {
1326 free(file->ln);
1327 }
1328 if (file->fn) {
1329 free(file->fn);
1330 }
1331 memset(file, 0, sizeof(*file));
1332 }
1333
1334 typedef struct decl_libs {
1335 void **dl;
1336 size_t count;
1337 } decl_libs;
1338
1339 static inline void free_decl_libs(decl_libs *libs) {
1340 if (libs->dl) {
1341 size_t i;
1342 for (i = 0; i < libs->count; ++i) {
1343 if (libs->dl[i]) {
1344 dlclose(libs->dl[i]);
1345 }
1346 }
1347 free(libs->dl);
1348 }
1349 memset(libs, 0, sizeof(*libs));
1350 }
1351
1352 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1353 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1354 libs->dl[libs->count-1] = dlopened;
1355 }
1356
1357 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
1358 unsigned i;
1359
1360 ZEND_ASSERT(var->arg->var != var);
1361 #if 0
1362 fprintf(stderr, "deref: %s pl=%u:%u as=%u:%u %p\n",
1363 var->name, var->pointer_level, var->arg->var->pointer_level,
1364 var->array_size, var->arg->var->array_size, ret_val);
1365 #endif
1366 for (i = 0; i < var->pointer_level; ++i) {
1367 #if 0
1368 fprintf(stderr, "-- %p %p %p\n", ret_val, *(void**)ret_val, ret_val->ptr);
1369 #endif
1370 ret_val = *(void **) ret_val;
1371 }
1372 return ret_val;
1373 }
1374
1375 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
1376 impl_val *val, *val_ptr;
1377 unsigned i;
1378
1379 ZEND_ASSERT(var->arg->var == var);
1380 #if 0
1381 fprintf(stderr, "enref: %s pl=%u:%u as=%u:%u\n",
1382 var->name, var->pointer_level, var->arg->var->pointer_level,
1383 var->array_size, var->arg->var->array_size);
1384 #endif
1385 if (!var->pointer_level ){//&& real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1386 return ptr;
1387 }
1388
1389 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
1390 for (i = !var->arg->var->array_size; i < var->pointer_level; ++i) {
1391 #if 0
1392 fprintf(stderr, "++\n");
1393 #endif
1394 val_ptr->ptr = (void **) val_ptr + 1;
1395 val_ptr = val_ptr->ptr;
1396 }
1397 val_ptr->ptr = ptr;
1398 return val;
1399 }
1400
1401 static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
1402 void *ptr = (char *) struct_ptr + set_arg->layout->pos;
1403 #if 0
1404 fprintf(stderr, "struct member %s: %p\n", set_arg->var->name, ptr);
1405 #endif
1406 return ptr;
1407 }
1408
1409
1410 #define PSI_ERROR 16
1411 #define PSI_WARNING 32
1412 typedef void (*psi_error_cb)(void *context, PSI_Token *token, int type, const char *msg, ...);
1413
1414 #define PSI_DATA(D) ((PSI_Data *) (D))
1415 #define PSI_DATA_MEMBERS \
1416 constants *consts; \
1417 decl_typedefs *defs; \
1418 decl_structs *structs; \
1419 decl_unions *unions; \
1420 decl_enums *enums; \
1421 decls *decls; \
1422 impls *impls; \
1423 union { \
1424 decl_file file; \
1425 decl_libs libs; \
1426 } psi; \
1427 psi_error_cb error; \
1428 unsigned errors; \
1429 unsigned flags
1430 typedef struct PSI_Data {
1431 PSI_DATA_MEMBERS;
1432 } PSI_Data;
1433
1434 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1435 if (!dest) {
1436 dest = malloc(sizeof(*dest));
1437 }
1438 memcpy(dest, src, sizeof(*dest));
1439 memset(src, 0, sizeof(*src));
1440 return dest;
1441 }
1442
1443 static inline void PSI_DataDtor(PSI_Data *data) {
1444 if (data->consts) {
1445 free_constants(data->consts);
1446 }
1447 if (data->defs) {
1448 free_decl_typedefs(data->defs);
1449 }
1450 if (data->structs) {
1451 free_decl_structs(data->structs);
1452 }
1453 if (data->unions) {
1454 free_decl_unions(data->unions);
1455 }
1456 if (data->enums) {
1457 free_decl_enums(data->enums);
1458 }
1459 if (data->decls) {
1460 free_decls(data->decls);
1461 }
1462 if (data->impls) {
1463 free_impls(data->impls);
1464 }
1465 free_decl_file(&data->psi.file);
1466 }
1467
1468 typedef struct PSI_Parser {
1469 PSI_DATA_MEMBERS;
1470 FILE *fp;
1471 token_t num;
1472 void *proc;
1473 unsigned line, col;
1474 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1475 } PSI_Parser;
1476
1477 static inline size_t PSI_TokenAllocSize(size_t token_len, size_t fname_len) {
1478 return sizeof(PSI_Token) + token_len + fname_len + 2;
1479 }
1480
1481 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1482 PSI_Token *T;
1483 size_t token_len, fname_len;
1484 token_t token_typ;
1485
1486 if (P->cur < P->tok) {
1487 return NULL;
1488 }
1489
1490 token_typ = P->num;
1491 token_len = P->cur - P->tok;
1492 fname_len = strlen(P->psi.file.fn);
1493
1494 T = calloc(1, PSI_TokenAllocSize(token_len, fname_len));
1495 T->type = token_typ;
1496 T->size = token_len;
1497 T->text = &T->buf[0];
1498 T->file = &T->buf[token_len + 1];
1499 T->line = P->line;
1500 T->col = P->col;
1501
1502 memcpy(T->text, P->tok, token_len);
1503 memcpy(T->file, P->psi.file.fn, fname_len);
1504
1505 return T;
1506 }
1507
1508 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
1509 size_t strct_len = PSI_TokenAllocSize(src->size, strlen(src->file));
1510 PSI_Token *ptr = malloc(strct_len);
1511
1512 memcpy(ptr, src, strct_len);
1513
1514 ptr->text = &ptr->buf[0];
1515 ptr->file = &ptr->buf[ptr->size + 1];
1516
1517 return ptr;
1518 }
1519
1520 static inline PSI_Token *PSI_TokenCat(unsigned argc, ...) {
1521 va_list argv;
1522 unsigned i;
1523 PSI_Token *T = NULL;
1524
1525 va_start(argv, argc);
1526 for (i = 0; i < argc; ++i) {
1527 PSI_Token *arg = va_arg(argv, PSI_Token *);
1528
1529 if (T) {
1530 size_t token_len = T->size, fname_len = strlen(T->file);
1531
1532 T = realloc(T, PSI_TokenAllocSize(T->size += arg->size + 1, fname_len));
1533 T->text = &T->buf[0];
1534 T->file = &T->buf[T->size + 1];
1535 T->buf[token_len] = ' ';
1536 memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
1537 memcpy(&T->buf[token_len + 1], arg->text, arg->size + 1);
1538 } else {
1539 T = PSI_TokenCopy(arg);
1540 T->type = PSI_T_NAME;
1541 }
1542 }
1543 va_end(argv);
1544
1545 return T;
1546 }
1547
1548 static inline PSI_Token *PSI_TokenAppend(PSI_Token *T, unsigned argc, ...) {
1549 va_list argv;
1550 unsigned i;
1551
1552 va_start(argv, argc);
1553 for (i = 0; i < argc; ++i) {
1554 char *str = va_arg(argv, char *);
1555 size_t str_len = strlen(str), token_len = T->size, fname_len = strlen(T->file);
1556
1557 T = realloc(T, PSI_TokenAllocSize(T->size += str_len + 1, fname_len));
1558 T->text = &T->buf[0];
1559 T->file = &T->buf[T->size + 1];
1560 T->buf[token_len] = ' ';
1561 memmove(&T->buf[T->size + 1], &T->buf[token_len + 1], fname_len + 1);
1562 memcpy(&T->buf[token_len + 1], str, str_len + 1);
1563 }
1564 va_end(argv);
1565
1566 return T;
1567 }
1568
1569 char *php_strtr(char *str, size_t len, char *str_from, char *str_to, size_t trlen);
1570 static inline PSI_Token *PSI_TokenTranslit(PSI_Token *T, char *from, char *to) {
1571 php_strtr(T->text, T->size, from, to, MIN(strlen(from), strlen(to)));
1572 return T;
1573 }
1574
1575 static inline uint64_t psi_hash(char *digest_buf, ...)
1576 {
1577 uint64_t hash = 5381;
1578 uint8_t c;
1579 const uint8_t *ptr;
1580 va_list argv;
1581
1582 va_start(argv, digest_buf);
1583 while ((ptr = va_arg(argv, const uint8_t *))) {
1584 while ((c = *ptr++)) {
1585 hash = ((hash << 5) + hash) + c;
1586 }
1587 }
1588 va_end(argv);
1589
1590 if (digest_buf) {
1591 sprintf(digest_buf, "%" PRIx64, hash);
1592 }
1593
1594 return hash;
1595 }
1596
1597 static inline uint64_t PSI_TokenHash(PSI_Token *t, char *digest_buf) {
1598 char loc_buf[48];
1599
1600 sprintf(loc_buf, "%u%u", t->line, t->col);
1601 return psi_hash(digest_buf, t->file, loc_buf, NULL);
1602 }
1603
1604 #define PSI_PARSER_DEBUG 0x1
1605 #define PSI_PARSER_SILENT 0x2
1606
1607 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1608 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1609 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1610 token_t PSI_ParserScan(PSI_Parser *P);
1611 void PSI_ParserParse(PSI_Parser *P, PSI_Token *src);
1612 void PSI_ParserDtor(PSI_Parser *P);
1613 void PSI_ParserFree(PSI_Parser **P);
1614
1615 #endif