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