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