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