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 {
266 decl_abi *abi;
267 decl_arg *func;
268 decl_args *args;
269 struct impl *impl;
270 struct {
271 void *sym;
272 void *info;
273 void **args;
274 } call;
275 } decl;
276
277 static inline decl* init_decl(decl_abi *abi, decl_arg *func, decl_args *args) {
278 decl *d = calloc(1, sizeof(*d));
279 d->abi = abi;
280 d->func = func;
281 d->args = args;
282 return d;
283 }
284
285 static inline void free_decl(decl *d) {
286 free_decl_abi(d->abi);
287 free_decl_arg(d->func);
288 if (d->args) {
289 free_decl_args(d->args);
290 }
291 free(d);
292 }
293
294 typedef struct decls {
295 size_t count;
296 decl **list;
297 } decls;
298
299 static inline decls *add_decl(decls *decls, decl *decl) {
300 if (!decls) {
301 decls = calloc(1, sizeof(*decls));
302 }
303 decls->list = realloc(decls->list, ++decls->count * sizeof(*decls->list));
304 decls->list[decls->count-1] = decl;
305 return decls;
306 }
307
308 static inline void free_decls(decls *decls) {
309 size_t i;
310
311 for (i = 0; i < decls->count; ++i) {
312 free_decl(decls->list[i]);
313 }
314 free(decls->list);
315 free(decls);
316 }
317
318 typedef struct decl_struct {
319 char *name;
320 decl_args *args;
321 size_t size;
322 } decl_struct;
323
324 static inline decl_struct *init_decl_struct(const char *name, decl_args *args) {
325 decl_struct *s = calloc(1, sizeof(*s));
326 s->name = strdup(name);
327 s->args = args;
328 return s;
329 }
330
331 static inline void free_decl_struct(decl_struct *s) {
332 if (s->args) {
333 free_decl_args(s->args);
334 }
335 free(s->name);
336 free(s);
337 }
338
339 typedef struct decl_structs {
340 size_t count;
341 decl_struct **list;
342 } decl_structs;
343
344 static inline decl_structs *add_decl_struct(decl_structs *ss, decl_struct *s) {
345 if (!ss) {
346 ss = calloc(1, sizeof(*ss));
347 }
348 ss->list = realloc(ss->list, ++ss->count * sizeof(*ss->list));
349 ss->list[ss->count-1] = s;
350 return ss;
351 }
352
353 static inline void free_decl_structs(decl_structs *ss) {
354 size_t i;
355
356 for (i = 0; i < ss->count; ++i) {
357 free_decl_struct(ss->list[i]);
358 }
359 free(ss->list);
360 free(ss);
361 }
362
363 typedef struct impl_type {
364 char *name;
365 token_t type;
366 } impl_type;
367
368 static inline impl_type *init_impl_type(token_t type, const char *name) {
369 impl_type *t = calloc(1, sizeof(*t));
370
371 t->type = type;
372 t->name = strdup(name);
373 return t;
374 }
375
376 static inline void free_impl_type(impl_type *type) {
377 free(type->name);
378 free(type);
379 }
380
381 typedef struct impl_var {
382 char *name;
383 unsigned reference:1;
384 } impl_var;
385
386 static inline impl_var *init_impl_var(const char *name, int is_reference) {
387 impl_var *var = calloc(1, sizeof(*var));
388 var->name = strdup(name);
389 var->reference = is_reference;
390 return var;
391 }
392
393 static inline void free_impl_var(impl_var *var) {
394 free(var->name);
395 free(var);
396 }
397
398 typedef struct impl_def_val {
399 token_t type;
400 char *text;
401 } impl_def_val;
402
403 static inline impl_def_val *init_impl_def_val(token_t t, const char *text) {
404 impl_def_val *def = calloc(1, sizeof(*def));
405 def->type = t;
406 def->text = strdup(text);
407 return def;
408 }
409
410 static inline void free_impl_def_val(impl_def_val *def) {
411 free(def->text);
412 free(def);
413 }
414
415 typedef struct const_type {
416 token_t type;
417 char *name;
418 } const_type;
419
420 static inline const_type *init_const_type(token_t type, const char *name) {
421 const_type *ct = calloc(1, sizeof(*ct));
422 ct->type = type;
423 ct->name = strdup(name);
424 return ct;
425 }
426
427 static inline void free_const_type(const_type *type) {
428 free(type->name);
429 free(type);
430 }
431
432 typedef struct constant {
433 const_type *type;
434 char *name;
435 impl_def_val *val;
436 } constant;
437
438 static inline constant *init_constant(const_type *type, const char *name, impl_def_val *val) {
439 constant *c = calloc(1, sizeof(*c));
440 c->type = type;
441 c->name = strdup(name);
442 c->val = val;
443 return c;
444 }
445
446 static inline void free_constant(constant *constant) {
447 free_const_type(constant->type);
448 free(constant->name);
449 free_impl_def_val(constant->val);
450 free(constant);
451 }
452
453 typedef struct constants {
454 size_t count;
455 constant **list;
456 } constants;
457
458 static inline constants *add_constant(constants *constants, constant *constant) {
459 if (!constants) {
460 constants = calloc(1, sizeof(*constants));
461 }
462 constants->list = realloc(constants->list, ++constants->count * sizeof(*constants->list));
463 constants->list[constants->count-1] = constant;
464 return constants;
465 }
466
467 static inline void free_constants(constants *c) {
468 size_t i;
469
470 for (i = 0; i < c->count; ++i) {
471 free_constant(c->list[i]);
472 }
473 free(c->list);
474 free(c);
475 }
476
477 typedef struct impl_arg {
478 impl_type *type;
479 impl_var *var;
480 impl_def_val *def;
481 impl_val val;
482 zval *_zv;
483 } impl_arg;
484
485 static inline impl_arg *init_impl_arg(impl_type *type, impl_var *var, impl_def_val *def) {
486 impl_arg *arg = calloc(1, sizeof(*arg));
487 arg->type = type;
488 arg->var = var;
489 arg->def = def;
490 return arg;
491 }
492
493 static inline void free_impl_arg(impl_arg *arg) {
494 free_impl_type(arg->type);
495 free_impl_var(arg->var);
496 if (arg->def) {
497 free_impl_def_val(arg->def);
498 }
499 free(arg);
500 }
501
502 typedef struct impl_args {
503 impl_arg **args;
504 size_t count;
505 impl_arg *vararg;
506 } impl_args;
507
508 static inline impl_args *init_impl_args(impl_arg *arg) {
509 impl_args *args = calloc(1, sizeof(*args));
510 if (arg) {
511 args->count = 1;
512 args->args = calloc(1, sizeof(*args->args));
513 args->args[0] = arg;
514 }
515 return args;
516 }
517
518 static inline impl_args *add_impl_arg(impl_args *args, impl_arg *arg) {
519 args->args = realloc(args->args, ++args->count * sizeof(*args->args));
520 args->args[args->count-1] = arg;
521 return args;
522 }
523
524 static inline void free_impl_args(impl_args *args) {
525 size_t i;
526
527 for (i = 0; i < args->count; ++i) {
528 free_impl_arg(args->args[i]);
529 }
530 free(args->args);
531 free(args);
532 }
533
534 typedef struct impl_func {
535 char *name;
536 impl_args *args;
537 impl_type *return_type;
538 unsigned return_reference:1;
539 } impl_func;
540
541 static inline impl_func *init_impl_func(char *name, impl_args *args, impl_type *type, int ret_reference) {
542 impl_func *func = calloc(1, sizeof(*func));
543 func->name = strdup(name);
544 func->args = args ? args : init_impl_args(NULL);
545 func->return_type = type;
546 func->return_reference = ret_reference;
547 return func;
548 }
549
550 static inline void free_impl_func(impl_func *f) {
551 free_impl_type(f->return_type);
552 free_impl_args(f->args);
553 free(f->name);
554 free(f);
555 }
556
557 typedef struct num_exp {
558 token_t t;
559 union {
560 char *numb;
561 constant *cnst;
562 decl_var *dvar;
563 } u;
564 token_t operator;
565 int (*calculator)(int t1, impl_val *v1, int t2, impl_val *v2, impl_val *res);
566 struct num_exp *operand;
567 } num_exp;
568
569 static inline num_exp *init_num_exp(token_t t, void *num) {
570 num_exp *exp = calloc(1, sizeof(*exp));
571 switch (exp->t = t) {
572 case PSI_T_NUMBER:
573 case PSI_T_NSNAME:
574 exp->u.numb = strdup(num);
575 break;
576 case PSI_T_NAME:
577 exp->u.dvar = num;
578 break;
579 EMPTY_SWITCH_DEFAULT_CASE();
580 }
581 return exp;
582 }
583
584 static inline void free_num_exp(num_exp *exp) {
585 switch (exp->t) {
586 case PSI_T_NUMBER:
587 free(exp->u.numb);
588 break;
589 case PSI_T_NSNAME:
590 break;
591 case PSI_T_NAME:
592 free_decl_var(exp->u.dvar);
593 break;
594 EMPTY_SWITCH_DEFAULT_CASE();
595 }
596 if (exp->operand) {
597 free_num_exp(exp->operand);
598 }
599 free(exp);
600 }
601
602 typedef struct let_calloc {
603 num_exp *nmemb;
604 num_exp *size;
605 } let_calloc;
606
607 static inline let_calloc *init_let_calloc(num_exp *nmemb, num_exp *size) {
608 let_calloc *alloc = calloc(1, sizeof(*alloc));
609 alloc->nmemb = nmemb;
610 alloc->size = size;
611 return alloc;
612 }
613
614 static inline void free_let_calloc(let_calloc *alloc) {
615 free_num_exp(alloc->nmemb);
616 free_num_exp(alloc->size);
617 free(alloc);
618 }
619
620 typedef struct let_func {
621 token_t type;
622 char *name;
623 impl_var *var;
624 impl_arg *arg;
625 } let_func;
626
627 static inline let_func *init_let_func(token_t type, const char *name, impl_var *var) {
628 let_func *func = calloc(1, sizeof(*func));
629 func->type = type;
630 func->name = strdup(name);
631 func->var = var;
632 return func;
633 }
634
635 static inline void free_let_func(let_func *func) {
636 free_impl_var(func->var);
637 free(func->name);
638 free(func);
639 }
640
641 #define PSI_LET_REFERENCE 0x1;
642 typedef struct let_val {
643 enum let_val_kind {
644 PSI_LET_NULL,
645 PSI_LET_NUMEXP,
646 PSI_LET_CALLOC,
647 PSI_LET_FUNC,
648 PSI_LET_TMP,
649 } kind;
650 union {
651 num_exp *num;
652 let_calloc *alloc;
653 let_func *func;
654 decl_var *var;
655 } data;
656 union {
657 struct {
658 unsigned is_reference:1;
659 } one;
660 unsigned all;
661 } flags;
662 } let_val;
663
664 static inline let_val *init_let_val(enum let_val_kind kind, void *data) {
665 let_val *let = calloc(1, sizeof(*let));
666 switch (let->kind = kind) {
667 case PSI_LET_NULL:
668 break;
669 case PSI_LET_NUMEXP:
670 let->data.num = data;
671 break;
672 case PSI_LET_CALLOC:
673 let->data.alloc = data;
674 break;
675 case PSI_LET_FUNC:
676 let->data.func = data;
677 break;
678 case PSI_LET_TMP:
679 let->data.var = data;
680 break;
681 EMPTY_SWITCH_DEFAULT_CASE();
682 }
683 return let;
684 }
685
686 static inline void free_let_val(let_val *let) {
687 switch (let->kind) {
688 case PSI_LET_NULL:
689 break;
690 case PSI_LET_NUMEXP:
691 free_num_exp(let->data.num);
692 break;
693 case PSI_LET_CALLOC:
694 free_let_calloc(let->data.alloc);
695 break;
696 case PSI_LET_FUNC:
697 free_let_func(let->data.func);
698 break;
699 case PSI_LET_TMP:
700 free_decl_var(let->data.var);
701 break;
702 EMPTY_SWITCH_DEFAULT_CASE();
703 }
704 free(let);
705 }
706
707 typedef struct let_stmt {
708 decl_var *var;
709 let_val *val;
710
711 void *ptr;
712 } let_stmt;
713
714 static inline let_stmt *init_let_stmt(decl_var *var, let_val *val) {
715 let_stmt *let = calloc(1, sizeof(*let));
716 let->var = var;
717 let->val = val;
718 return let;
719 }
720
721 static inline void free_let_stmt(let_stmt *stmt) {
722 if (stmt->val) {
723 if (stmt->val->kind == PSI_LET_TMP && stmt->var->arg) {
724 free_decl_arg(stmt->var->arg);
725 }
726 free_let_val(stmt->val);
727 }
728 free_decl_var(stmt->var);
729 free(stmt);
730 }
731
732 struct set_value;
733
734 typedef struct set_func {
735 token_t type;
736 char *name;
737 void (*handler)(zval *, struct set_value *set, impl_val *ret_val);
738 } set_func;
739
740 static inline set_func *init_set_func(token_t type, const char *name) {
741 set_func *func = calloc(1, sizeof(*func));
742 func->type = type;
743 func->name = strdup(name);
744 return func;
745 }
746
747 static inline void free_set_func(set_func *func) {
748 free(func->name);
749 free(func);
750 }
751
752 typedef struct set_value {
753 set_func *func;
754 decl_vars *vars;
755 num_exp *num;
756 struct {
757 struct set_value *set;
758 impl_val *val;
759 } outer;
760 struct set_value **inner;
761 size_t count;
762 } set_value;
763
764 static inline set_value *init_set_value(set_func *func, decl_vars *vars) {
765 set_value *val = calloc(1, sizeof(*val));
766 val->func = func;
767 val->vars = vars;
768 return val;
769 }
770 static inline set_value *add_inner_set_value(set_value *val, set_value *inner) {
771 val->inner = realloc(val->inner, ++val->count * sizeof(*val->inner));
772 val->inner[val->count-1] = inner;
773 return val;
774 }
775
776 static inline void free_set_value(set_value *val) {
777 free_set_func(val->func);
778 free_decl_vars(val->vars);
779 if (val->inner) {
780 size_t i;
781 for (i = 0; i < val->count; ++i) {
782 free_set_value(val->inner[i]);
783 }
784 free(val->inner);
785 }
786 if (val->num) {
787 free_num_exp(val->num);
788 }
789 free(val);
790 }
791
792 typedef struct set_stmt {
793 impl_var *var;
794 set_value *val;
795 impl_arg *arg;
796 } set_stmt;
797
798 static inline set_stmt *init_set_stmt(impl_var *var, set_value *val) {
799 set_stmt *set = calloc(1, sizeof(*set));
800 set->var = var;
801 set->val = val;
802 return set;
803 }
804
805 static inline void free_set_stmt(set_stmt *set) {
806 free_impl_var(set->var);
807 free_set_value(set->val);
808 free(set);
809 }
810
811 typedef struct return_stmt {
812 set_value *set;
813 decl_arg *decl;
814 } return_stmt;
815
816 static inline return_stmt *init_return_stmt(set_value *val) {
817 return_stmt *ret = calloc(1, sizeof(*ret));
818 ret->set = val;
819 return ret;
820 }
821
822 static inline void free_return_stmt(return_stmt *ret) {
823 //free_set_func(ret->func);
824 //free_decl_var(ret->decl);
825 free_set_value(ret->set);
826 free(ret);
827 }
828
829 typedef struct free_call {
830 char *func;
831 decl_vars *vars;
832 decl *decl;
833 } free_call;
834
835 static inline free_call *init_free_call(const char *func, decl_vars *vars) {
836 free_call *f = calloc(1, sizeof(*f));
837 f->func = strdup(func);
838 f->vars = vars;
839 return f;
840 }
841
842 static inline void free_free_call(free_call *f) {
843 free(f->func);
844 free_decl_vars(f->vars);
845 free(f);
846 }
847
848 typedef struct free_calls {
849 free_call **list;
850 size_t count;
851 } free_calls;
852
853 static inline free_calls *init_free_calls(free_call *f) {
854 free_calls *fcs = calloc(1, sizeof(*fcs));
855 if (f) {
856 fcs->count = 1;
857 fcs->list = calloc(1, sizeof(*fcs->list));
858 fcs->list[0] = f;
859 }
860 return fcs;
861 }
862
863 static inline void free_free_calls(free_calls *fcs) {
864 size_t i;
865
866 for (i = 0; i < fcs->count; ++i) {
867 free_free_call(fcs->list[i]);
868 }
869 free(fcs->list);
870 free(fcs);
871 }
872
873 static inline free_calls *add_free_call(free_calls *fcs, free_call *f) {
874 fcs->list = realloc(fcs->list, ++fcs->count * sizeof(*fcs->list));
875 fcs->list[fcs->count-1] = f;
876 return fcs;
877 }
878
879 typedef struct free_stmt {
880 free_calls *calls;
881 } free_stmt;
882
883 static inline free_stmt *init_free_stmt(free_calls *calls) {
884 free_stmt *f = calloc(1, sizeof(*f));
885 f->calls = calls;
886 return f;
887 }
888
889 static inline void free_free_stmt(free_stmt *f) {
890 free_free_calls(f->calls);
891 free(f);
892 }
893
894 typedef struct impl_stmt {
895 token_t type;
896 union {
897 let_stmt *let;
898 set_stmt *set;
899 return_stmt *ret;
900 free_stmt *fre;
901 void *ptr;
902 } s;
903 } impl_stmt;
904
905 static inline impl_stmt *init_impl_stmt(token_t type, void *ptr) {
906 impl_stmt *stmt = calloc(1, sizeof(*stmt));
907 stmt->type = type;
908 stmt->s.ptr = ptr;
909 return stmt;
910 }
911
912 static inline void free_impl_stmt(impl_stmt *stmt) {
913 switch (stmt->type) {
914 case PSI_T_LET:
915 free_let_stmt(stmt->s.let);
916 break;
917 case PSI_T_SET:
918 free_set_stmt(stmt->s.set);
919 break;
920 case PSI_T_RETURN:
921 free_return_stmt(stmt->s.ret);
922 break;
923 case PSI_T_FREE:
924 free_free_stmt(stmt->s.fre);
925 break;
926 }
927 free(stmt);
928 }
929
930 typedef struct impl_stmts {
931 struct {
932 return_stmt **list;
933 size_t count;
934 } ret;
935 struct {
936 let_stmt **list;
937 size_t count;
938 } let;
939 struct {
940 set_stmt **list;
941 size_t count;
942 } set;
943 struct {
944 free_stmt **list;
945 size_t count;
946 } fre;
947 } impl_stmts;
948
949 static inline void *add_impl_stmt_ex(void *list, size_t count, void *stmt) {
950 list = realloc(list, count * sizeof(list));
951 ((void **)list)[count-1] = stmt;
952 return list;
953 }
954
955 static inline impl_stmts *add_impl_stmt(impl_stmts *stmts, impl_stmt *stmt) {
956 switch (stmt->type) {
957 case PSI_T_RETURN:
958 stmts->ret.list = add_impl_stmt_ex(stmts->ret.list, ++stmts->ret.count, stmt->s.ret);
959 break;
960 case PSI_T_LET:
961 stmts->let.list = add_impl_stmt_ex(stmts->let.list, ++stmts->let.count, stmt->s.let);
962 break;
963 case PSI_T_SET:
964 stmts->set.list = add_impl_stmt_ex(stmts->set.list, ++stmts->set.count, stmt->s.set);
965 break;
966 case PSI_T_FREE:
967 stmts->fre.list = add_impl_stmt_ex(stmts->fre.list, ++stmts->fre.count, stmt->s.fre);
968 break;
969 }
970 free(stmt);
971 return stmts;
972 }
973
974 static inline impl_stmts *init_impl_stmts(impl_stmt *stmt) {
975 impl_stmts *stmts = calloc(1, sizeof(*stmts));
976 return add_impl_stmt(stmts, stmt);
977 }
978
979 static inline void free_impl_stmts(impl_stmts *stmts) {
980 size_t i;
981
982 for (i = 0; i < stmts->let.count; ++i) {
983 free_let_stmt(stmts->let.list[i]);
984 }
985 free(stmts->let.list);
986 for (i = 0; i < stmts->ret.count; ++i) {
987 free_return_stmt(stmts->ret.list[i]);
988 }
989 free(stmts->ret.list);
990 for (i = 0; i < stmts->set.count; ++i) {
991 free_set_stmt(stmts->set.list[i]);
992 }
993 free(stmts->set.list);
994 for (i = 0; i < stmts->fre.count; ++i) {
995 free_free_stmt(stmts->fre.list[i]);
996 }
997 free(stmts->fre.list);
998 free(stmts);
999 }
1000
1001 typedef struct impl {
1002 impl_func *func;
1003 impl_stmts *stmts;
1004 decl *decl;
1005 } impl;
1006
1007 static inline impl *init_impl(impl_func *func, impl_stmts *stmts) {
1008 impl *i = calloc(1, sizeof(*i));
1009 i->func = func;
1010 i->stmts = stmts;
1011 return i;
1012 }
1013
1014 static inline void free_impl(impl *impl) {
1015 free_impl_func(impl->func);
1016 free_impl_stmts(impl->stmts);
1017 free(impl);
1018 }
1019
1020 typedef struct impls {
1021 size_t count;
1022 impl **list;
1023 } impls;
1024
1025 static inline impls *add_impl(impls *impls, impl *impl) {
1026 if (!impls) {
1027 impls = calloc(1, sizeof(*impls));
1028 }
1029 impls->list = realloc(impls->list, ++impls->count * sizeof(*impls->list));
1030 impls->list[impls->count-1] = impl;
1031 return impls;
1032 }
1033
1034 static void free_impls(impls *impls) {
1035 size_t i;
1036
1037 for (i = 0; i < impls->count; ++i) {
1038 free_impl(impls->list[i]);
1039 }
1040 free(impls->list);
1041 free(impls);
1042 }
1043
1044 typedef struct decl_file {
1045 char *ln;
1046 char *fn;
1047 } decl_file;
1048
1049 static inline void free_decl_file(decl_file *file) {
1050 if (file->ln) {
1051 free(file->ln);
1052 }
1053 if (file->fn) {
1054 free(file->fn);
1055 }
1056 memset(file, 0, sizeof(*file));
1057 }
1058
1059 typedef struct decl_libs {
1060 void **dl;
1061 size_t count;
1062 } decl_libs;
1063
1064 static inline void free_decl_libs(decl_libs *libs) {
1065 if (libs->dl) {
1066 size_t i;
1067 for (i = 0; i < libs->count; ++i) {
1068 if (libs->dl[i]) {
1069 dlclose(libs->dl[i]);
1070 }
1071 }
1072 free(libs->dl);
1073 }
1074 memset(libs, 0, sizeof(*libs));
1075 }
1076
1077 static inline void add_decl_lib(decl_libs *libs, void *dlopened) {
1078 libs->dl = realloc(libs->dl, ++libs->count * sizeof(*libs->dl));
1079 libs->dl[libs->count-1] = dlopened;
1080 }
1081
1082 static inline impl_val *deref_impl_val(impl_val *ret_val, decl_var *var) {
1083 unsigned i;
1084
1085 if (var->arg->var != var) for (i = 1; i < var->pointer_level; ++i) {
1086 ret_val = *(void **) ret_val;
1087 }
1088 return ret_val;
1089 }
1090
1091 static inline impl_val *enref_impl_val(void *ptr, decl_var *var) {
1092 impl_val *val, *val_ptr;
1093 unsigned i;
1094
1095 if (!var->pointer_level && real_decl_type(var->arg->type)->type != PSI_T_STRUCT) {
1096 return ptr;
1097 }
1098 val = val_ptr = calloc(var->pointer_level + 1, sizeof(void *));
1099 for (i = 1; i < var->pointer_level; ++i) {
1100 val_ptr->ptr = (void **) val_ptr + 1;
1101 val_ptr = val_ptr->ptr;
1102 }
1103 val_ptr->ptr = ptr;
1104 return val;
1105 }
1106
1107 static inline impl_val *struct_member_ref(decl_arg *set_arg, impl_val *struct_ptr, impl_val **to_free) {
1108 void *ptr = (char *) struct_ptr->ptr + set_arg->layout->pos;
1109 impl_val *val = enref_impl_val(ptr, set_arg->var);
1110
1111 if (val != ptr) {
1112 *to_free = val;
1113 }
1114
1115 return val;
1116 }
1117
1118 #define PSI_ERROR 16
1119 #define PSI_WARNING 32
1120 typedef void (*psi_error_cb)(int type, const char *msg, ...);
1121
1122 #define PSI_DATA(D) ((PSI_Data *) (D))
1123 #define PSI_DATA_MEMBERS \
1124 constants *consts; \
1125 decl_typedefs *defs; \
1126 decl_structs *structs; \
1127 decls *decls; \
1128 impls *impls; \
1129 union { \
1130 decl_file file; \
1131 decl_libs libs; \
1132 } psi; \
1133 psi_error_cb error
1134 typedef struct PSI_Data {
1135 PSI_DATA_MEMBERS;
1136 } PSI_Data;
1137
1138 static inline PSI_Data *PSI_DataExchange(PSI_Data *dest, PSI_Data *src) {
1139 if (!dest) {
1140 dest = malloc(sizeof(*dest));
1141 }
1142 memcpy(dest, src, sizeof(*dest));
1143 memset(src, 0, sizeof(*src));
1144 return dest;
1145 }
1146
1147 static inline void PSI_DataDtor(PSI_Data *data) {
1148 if (data->consts) {
1149 free_constants(data->consts);
1150 }
1151 if (data->defs) {
1152 free_decl_typedefs(data->defs);
1153 }
1154 if (data->structs) {
1155 free_decl_structs(data->structs);
1156 }
1157 if (data->decls) {
1158 free_decls(data->decls);
1159 }
1160 if (data->impls) {
1161 free_impls(data->impls);
1162 }
1163 free_decl_file(&data->psi.file);
1164 }
1165
1166 typedef struct PSI_Parser {
1167 PSI_DATA_MEMBERS;
1168 FILE *fp;
1169 unsigned flags;
1170 unsigned errors;
1171 void *proc;
1172 size_t line, col;
1173 token_t num;
1174 char *cur, *tok, *lim, *eof, *ctx, *mrk, buf[BSIZE];
1175 } PSI_Parser;
1176
1177 static inline PSI_Token *PSI_TokenAlloc(PSI_Parser *P) {
1178 PSI_Token *T;
1179 size_t token_len, fname_len;
1180 token_t token_typ;
1181
1182 if (P->cur < P->tok) {
1183 return NULL;
1184 }
1185
1186 token_typ = P->num;
1187 token_len = P->cur - P->tok;
1188 fname_len = strlen(P->psi.file.fn);
1189
1190 T = calloc(1, sizeof(*T) + token_len + fname_len + 1);
1191 T->type = token_typ;
1192 T->size = token_len;
1193 T->line = P->line;
1194 T->col = P->col;
1195 T->file = &T->buf[0];
1196 T->text = &T->buf[fname_len + 1];
1197
1198 memcpy(T->file, P->psi.file.fn, fname_len);
1199 memcpy(T->text, P->tok, token_len);
1200
1201 return T;
1202 }
1203
1204 static inline PSI_Token *PSI_TokenCopy(PSI_Token *src) {
1205 size_t fname_len = strlen(src->file);
1206 size_t strct_len = sizeof(*src) + src->size + fname_len + 1;
1207 PSI_Token *ptr = malloc(strct_len);
1208
1209 memcpy(ptr, src, strct_len);
1210
1211 ptr->file = &ptr->buf[0];
1212 ptr->text = &ptr->buf[fname_len + 1];
1213
1214 return ptr;
1215 }
1216
1217 #define PSI_PARSER_DEBUG 0x1
1218
1219 PSI_Parser *PSI_ParserInit(PSI_Parser *P, const char *filename, psi_error_cb error, unsigned flags);
1220 void PSI_ParserSyntaxError(PSI_Parser *P, const char *fn, size_t ln, const char *msg, ...);
1221 size_t PSI_ParserFill(PSI_Parser *P, size_t n);
1222 token_t PSI_ParserScan(PSI_Parser *P);
1223 void PSI_ParserParse(PSI_Parser *P, PSI_Token *src);
1224 void PSI_ParserDtor(PSI_Parser *P);
1225 void PSI_ParserFree(PSI_Parser **P);
1226
1227 #endif