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