ncc: new intermediate code
[neatcc.git] / ncc.c
blob175fcbd53d1a7afc298d5d73e1efe1595026507f
1 /*
2 * THE NEATCC C COMPILER
4 * Copyright (C) 2010-2016 Ali Gholami Rudi
6 * This program is released under the Modified BSD license.
7 */
8 /*
9 * neatcc parser
11 * The parser reads tokens from the tokenizer (tok_*) and calls the
12 * appropriate code generation functions (o_*). The generator
13 * maintains a stack of values pushed via, for instance, o_num()
14 * and generates the necessary code for the accesses to the items
15 * in this stack, like o_bop() for performing a binary operations
16 * on the top two items of the stack. The parser maintains the
17 * types of values pushed to the generator stack in its type stack
18 * (ts_*). For instance, for binary operations two types are
19 * popped first and the resulting type is pushed to the type stack
20 * (ts_binop()).
23 #include <ctype.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <stdarg.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdio.h>
30 #include <sys/stat.h>
31 #include <sys/types.h>
32 #include "ncc.h"
34 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
35 #define MIN(a, b) ((a) < (b) ? (a) : (b))
36 #define MAX(a, b) ((a) < (b) ? (b) : (a))
38 #define TYPE_BT(t) ((t)->ptr ? ULNG : (t)->bt)
39 #define TYPE_SZ(t) ((t)->ptr ? ULNG : (t)->bt & T_MSIZE)
40 #define TYPE_VOID(t) (!(t)->bt && !(t)->flags && !(t)->ptr)
42 /* type->flag values */
43 #define T_ARRAY 0x01
44 #define T_STRUCT 0x02
45 #define T_FUNC 0x04
47 /* variable definition flags */
48 #define F_STATIC 0x01
49 #define F_EXTERN 0x02
51 struct type {
52 unsigned bt;
53 unsigned flags;
54 int ptr;
55 int id; /* for structs, functions and arrays */
56 int addr; /* the address is passed to gen.c; deref for value */
59 /* type stack */
60 static struct type ts[NTMPS];
61 static int nts;
63 static void ts_push_bt(unsigned bt)
65 ts[nts].ptr = 0;
66 ts[nts].flags = 0;
67 ts[nts].addr = 0;
68 ts[nts++].bt = bt;
69 #ifdef NCCWORDCAST
70 o_cast(bt); /* casting to architecture word */
71 #endif
74 static void ts_push(struct type *t)
76 struct type *d = &ts[nts++];
77 memcpy(d, t, sizeof(*t));
80 static void ts_push_addr(struct type *t)
82 ts_push(t);
83 ts[nts - 1].addr = 1;
86 static void ts_pop(struct type *type)
88 nts--;
89 if (type)
90 *type = ts[nts];
93 void err(char *fmt, ...)
95 va_list ap;
96 char msg[512];
97 va_start(ap, fmt);
98 vsprintf(msg, fmt, ap);
99 va_end(ap);
100 die("%s: %s", cpp_loc(tok_addr()), msg);
103 void *mextend(void *old, long oldsz, long newsz, long memsz)
105 void *new = malloc(newsz * memsz);
106 memcpy(new, old, oldsz * memsz);
107 memset(new + oldsz * memsz, 0, (newsz - oldsz) * memsz);
108 free(old);
109 return new;
112 struct name {
113 char name[NAMELEN];
114 char elfname[NAMELEN]; /* local elf name for function static variables */
115 struct type type;
116 long addr; /* local stack offset, global data addr, struct offset */
119 static struct name *locals;
120 static int locals_n, locals_sz;
121 static struct name *globals;
122 static int globals_n, globals_sz;
124 static void local_add(struct name *name)
126 if (locals_n >= locals_sz) {
127 locals_sz = MAX(128, locals_sz * 2);
128 locals = mextend(locals, locals_n, locals_sz, sizeof(locals[0]));
130 memcpy(&locals[locals_n++], name, sizeof(*name));
133 static int local_find(char *name)
135 int i;
136 for (i = locals_n - 1; i >= 0; --i)
137 if (!strcmp(locals[i].name, name))
138 return i;
139 return -1;
142 static int global_find(char *name)
144 int i;
145 for (i = globals_n - 1; i >= 0; i--)
146 if (!strcmp(name, globals[i].name))
147 return i;
148 return -1;
151 static void global_add(struct name *name)
153 if (globals_n >= globals_sz) {
154 globals_sz = MAX(128, globals_sz * 2);
155 globals = mextend(globals, globals_n, globals_sz, sizeof(globals[0]));
157 memcpy(&globals[globals_n++], name, sizeof(*name));
160 #define LABEL() (++label)
162 static int label; /* last used label id */
163 static int l_break; /* current break label */
164 static int l_cont; /* current continue label */
166 static struct enumval {
167 char name[NAMELEN];
168 int n;
169 } *enums;
170 static int enums_n, enums_sz;
172 static void enum_add(char *name, int val)
174 struct enumval *ev;
175 if (enums_n >= enums_sz) {
176 enums_sz = MAX(128, enums_sz * 2);
177 enums = mextend(enums, enums_n, enums_sz, sizeof(enums[0]));
179 ev = &enums[enums_n++];
180 strcpy(ev->name, name);
181 ev->n = val;
184 static int enum_find(int *val, char *name)
186 int i;
187 for (i = enums_n - 1; i >= 0; --i)
188 if (!strcmp(name, enums[i].name)) {
189 *val = enums[i].n;
190 return 0;
192 return 1;
195 static struct typdefinfo {
196 char name[NAMELEN];
197 struct type type;
198 } *typedefs;
199 static int typedefs_n, typedefs_sz;
201 static void typedef_add(char *name, struct type *type)
203 struct typdefinfo *ti;
204 if (typedefs_n >= typedefs_sz) {
205 typedefs_sz = MAX(128, typedefs_sz * 2);
206 typedefs = mextend(typedefs, typedefs_n, typedefs_sz,
207 sizeof(typedefs[0]));
209 ti = &typedefs[typedefs_n++];
210 strcpy(ti->name, name);
211 memcpy(&ti->type, type, sizeof(*type));
214 static int typedef_find(char *name)
216 int i;
217 for (i = typedefs_n - 1; i >= 0; --i)
218 if (!strcmp(name, typedefs[i].name))
219 return i;
220 return -1;
223 static struct array {
224 struct type type;
225 int n;
226 } *arrays;
227 static int arrays_n, arrays_sz;
229 static int array_add(struct type *type, int n)
231 struct array *a;
232 if (arrays_n >= arrays_sz) {
233 arrays_sz = MAX(128, arrays_sz * 2);
234 arrays = mextend(arrays, arrays_n, arrays_sz, sizeof(arrays[0]));
236 a = &arrays[arrays_n++];
237 memcpy(&a->type, type, sizeof(*type));
238 a->n = n;
239 return a - arrays;
242 static void array2ptr(struct type *t)
244 if (t->flags & T_ARRAY && !t->ptr) {
245 memcpy(t, &arrays[t->id].type, sizeof(*t));
246 t->ptr++;
250 static struct structinfo {
251 char name[NAMELEN];
252 struct name fields[NFIELDS];
253 int nfields;
254 int isunion;
255 int size;
256 } *structs;
257 static int structs_n, structs_sz;
259 static int struct_find(char *name, int isunion)
261 int i;
262 for (i = structs_n - 1; i >= 0; --i)
263 if (*structs[i].name && !strcmp(name, structs[i].name) &&
264 structs[i].isunion == isunion)
265 return i;
266 if (structs_n >= structs_sz) {
267 structs_sz = MAX(128, structs_sz * 2);
268 structs = mextend(structs, structs_n, structs_sz, sizeof(structs[0]));
270 i = structs_n++;
271 memset(&structs[i], 0, sizeof(structs[i]));
272 strcpy(structs[i].name, name);
273 structs[i].isunion = isunion;
274 return i;
277 static struct name *struct_field(int id, char *name)
279 struct structinfo *si = &structs[id];
280 int i;
281 for (i = 0; i < si->nfields; i++)
282 if (!strcmp(name, si->fields[i].name))
283 return &si->fields[i];
284 err("unknown field <%s>\n", name);
285 return NULL;
288 /* return t's size */
289 static int type_totsz(struct type *t)
291 if (t->ptr)
292 return ULNG;
293 if (t->flags & T_ARRAY)
294 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
295 return t->flags & T_STRUCT ? structs[t->id].size : T_SZ(t->bt);
298 /* return t's dereferenced size */
299 static unsigned type_szde(struct type *t)
301 struct type de = *t;
302 array2ptr(&de);
303 de.ptr--;
304 return type_totsz(&de);
307 /* dereference stack top if t->addr (ie. address is pushed to gen.c) */
308 static void ts_de(int deref)
310 struct type *t = &ts[nts - 1];
311 array2ptr(t);
312 if (deref && t->addr && (t->ptr || !(t->flags & T_FUNC)))
313 o_deref(TYPE_BT(t));
314 t->addr = 0;
317 /* pop stack pop to *t and dereference if t->addr */
318 static void ts_pop_de(struct type *t)
320 ts_de(1);
321 ts_pop(t);
324 /* pop the top 2 stack values and dereference them if t->addr */
325 static void ts_pop_de2(struct type *t1, struct type *t2)
327 ts_pop_de(t1);
328 o_tmpswap();
329 ts_pop_de(t2);
330 o_tmpswap();
333 /* the previous identifier; to handle labels */
334 static char tok_previden[NAMELEN];
336 static char *tok_iden(void)
338 snprintf(tok_previden, sizeof(tok_previden), "%s", tok_get());
339 return tok_previden;
342 static int tok_jmp(char *tok)
344 if (strcmp(tok, tok_see()))
345 return 1;
346 tok_get();
347 return 0;
350 static int tok_comes(char *tok)
352 return !strcmp(tok, tok_see());
355 static void tok_req(char *tok)
357 char *got = tok_get();
358 if (strcmp(tok, got))
359 err("syntax error (expected <%s> but got <%s>)\n", tok, got);
362 static int tok_grp(void)
364 int c = (unsigned char) tok_see()[0];
365 if (c == '"')
366 return '"';
367 if (c == '\'' || isdigit(c))
368 return '0';
369 if (c == '_' || isalpha(c))
370 return 'a';
371 return 0;
374 /* the result of a binary operation on variables of type bt1 and bt2 */
375 static unsigned bt_op(unsigned bt1, unsigned bt2)
377 int sz = MAX(T_SZ(bt1), T_SZ(bt2));
378 return ((bt1 | bt2) & T_MSIGN) | MAX(sz, UINT);
381 /* the result of a unary operation on variables of bt */
382 static unsigned bt_uop(unsigned bt)
384 return bt_op(bt, UINT);
387 /* push the result of a binary operation on the type stack */
388 static void ts_binop(int op)
390 struct type t1, t2;
391 unsigned bt1, bt2, bt;
392 ts_pop_de2(&t1, &t2);
393 bt1 = TYPE_BT(&t1);
394 bt2 = TYPE_BT(&t2);
395 bt = bt_op(bt1, bt2);
396 if (op == O_DIV || op == O_MOD)
397 bt = T_MK(bt2 & T_MSIGN, bt);
398 o_bop(O_MK(op, bt));
399 ts_push_bt(bt);
402 /* push the result of an additive binary operation on the type stack */
403 static void ts_addop(int op)
405 struct type t1, t2;
406 ts_pop_de2(&t1, &t2);
407 if (!t1.ptr && !t2.ptr) {
408 o_bop(op);
409 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
410 return;
412 if (t1.ptr && !t2.ptr)
413 o_tmpswap();
414 if (!t1.ptr && t2.ptr)
415 if (type_szde(&t2) > 1) {
416 o_num(type_szde(&t2));
417 o_bop(O_MUL);
419 if (t1.ptr && !t2.ptr)
420 o_tmpswap();
421 o_bop(op);
422 if (t1.ptr && t2.ptr) {
423 int sz = type_szde(&t1);
424 if (sz > 1) {
425 o_num(sz);
426 o_bop(O_DIV);
428 ts_push_bt(SLNG);
429 } else {
430 ts_push(t1.ptr ? &t1 : &t2);
434 /* function prototypes for parsing function and variable declarations */
435 static int readname(struct type *main, char *name, struct type *base);
436 static int readtype(struct type *type);
437 static int readdefs(void (*def)(long data, struct name *name, unsigned flags),
438 long data);
439 static int readdefs_int(void (*def)(long data, struct name *name, unsigned flags),
440 long data);
442 /* function prototypes for parsing initializer expressions */
443 static int initsize(void);
444 static void initexpr(struct type *t, int off, void *obj,
445 void (*set)(void *obj, int off, struct type *t));
447 static int type_alignment(struct type *t)
449 if (t->flags & T_ARRAY && !t->ptr)
450 return type_alignment(&arrays[t->id].type);
451 if (t->flags & T_STRUCT && !t->ptr)
452 return type_alignment(&structs[t->id].fields[0].type);
453 return MIN(ULNG, type_totsz(t));
456 static void structdef(long data, struct name *name, unsigned flags)
458 struct structinfo *si = &structs[data];
459 if (si->isunion) {
460 name->addr = 0;
461 if (si->size < type_totsz(&name->type))
462 si->size = type_totsz(&name->type);
463 } else {
464 struct type *t = &name->type;
465 int alignment = type_alignment(t);
466 if (t->flags & T_ARRAY && !t->ptr)
467 alignment = MIN(ULNG, type_totsz(&arrays[t->id].type));
468 si->size = ALIGN(si->size, alignment);
469 name->addr = si->size;
470 si->size += type_totsz(&name->type);
472 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
475 static int struct_create(char *name, int isunion)
477 int id = struct_find(name, isunion);
478 tok_req("{");
479 while (tok_jmp("}")) {
480 readdefs(structdef, id);
481 tok_req(";");
483 return id;
486 static void readexpr(void);
488 static void enum_create(void)
490 long n = 0;
491 tok_req("{");
492 while (tok_jmp("}")) {
493 char name[NAMELEN];
494 strcpy(name, tok_get());
495 if (!tok_jmp("=")) {
496 readexpr();
497 ts_pop_de(NULL);
498 if (o_popnum(&n))
499 err("const expr expected!\n");
501 enum_add(name, n++);
502 tok_jmp(",");
506 /* used to differentiate labels from case and cond exprs */
507 static int ncexpr;
508 static int caseexpr;
510 static void readpre(void);
512 static char *tmp_str(char *buf, int len)
514 static char name[NAMELEN];
515 static int id;
516 sprintf(name, "__neatcc.s%d", id++);
517 buf[len] = '\0';
518 o_dscpy(o_dsnew(name, len + 1, 0), buf, len + 1);
519 return name;
522 static void readprimary(void)
524 if (tok_grp() == '0') {
525 long n;
526 int bt = tok_num(tok_get(), &n);
527 o_num(n);
528 ts_push_bt(bt);
529 return;
531 if (tok_grp() == '"') {
532 struct type t = {}; /* char type inside the arrays */
533 struct type a = {}; /* the char array type */
534 char *buf = tok_get() + 1;
535 int len = tok_len() - 2;
536 t.bt = 1 | T_MSIGN;
537 a.id = array_add(&t, len + 1);
538 a.flags = T_ARRAY;
539 o_sym(tmp_str(buf, len));
540 ts_push(&a);
541 return;
543 if (tok_grp() == 'a') {
544 struct name unkn = {""};
545 char *name = unkn.name;
546 int n;
547 strcpy(name, tok_iden());
548 /* don't search for labels here */
549 if (!ncexpr && !caseexpr && tok_comes(":"))
550 return;
551 if ((n = local_find(name)) != -1) {
552 struct name *l = &locals[n];
553 o_local(l->addr);
554 ts_push_addr(&l->type);
555 return;
557 if ((n = global_find(name)) != -1) {
558 struct name *g = &globals[n];
559 o_sym(*g->elfname ? g->elfname : g->name);
560 ts_push_addr(&g->type);
561 return;
563 if (!enum_find(&n, name)) {
564 o_num(n);
565 ts_push_bt(SINT);
566 return;
568 if (!tok_comes("("))
569 err("unknown symbol <%s>\n", name);
570 global_add(&unkn);
571 o_sym(unkn.name);
572 ts_push_bt(ULNG);
573 return;
575 if (!tok_jmp("(")) {
576 struct type t;
577 if (!readtype(&t)) {
578 struct type o;
579 tok_req(")");
580 readpre();
581 ts_pop_de(&o);
582 ts_push(&t);
583 if (!t.ptr || !o.ptr)
584 o_cast(TYPE_BT(&t));
585 } else {
586 readexpr();
587 while (tok_jmp(")")) {
588 tok_req(",");
589 ts_pop(NULL);
590 o_tmpdrop(1);
591 readexpr();
594 return;
598 static void arrayderef(void)
600 struct type t;
601 int sz;
602 ts_pop_de(NULL);
603 ts_pop(&t);
604 if (!(t.flags & T_ARRAY && !t.ptr) && t.addr) {
605 o_tmpswap();
606 o_deref(TYPE_BT(&t));
607 o_tmpswap();
609 array2ptr(&t);
610 t.ptr--;
611 sz = type_totsz(&t);
612 t.addr = 1;
613 if (sz > 1) {
614 o_num(sz);
615 o_bop(O_MUL);
617 o_bop(O_ADD);
618 ts_push(&t);
621 static void inc_post(int op)
623 struct type t = ts[nts - 1];
624 /* pushing the value before inc */
625 o_tmpcopy();
626 ts_de(1);
627 o_tmpswap();
629 /* increment by 1 or pointer size */
630 o_tmpcopy();
631 ts_push(&t);
632 ts_pop_de(&t);
633 o_num(t.ptr > 0 ? type_szde(&t) : 1);
634 o_bop(op);
636 /* assign back */
637 o_assign(TYPE_BT(&t));
638 o_tmpdrop(1);
641 static void readfield(void)
643 struct name *field;
644 struct type t;
645 ts_pop(&t);
646 array2ptr(&t);
647 field = struct_field(t.id, tok_get());
648 if (field->addr) {
649 o_num(field->addr);
650 o_bop(O_ADD);
652 ts_push_addr(&field->type);
655 static struct funcinfo {
656 struct type args[NARGS];
657 struct type ret;
658 int nargs;
659 int varg;
660 /* function and argument names; useful only when defining */
661 char argnames[NARGS][NAMELEN];
662 char name[NAMELEN];
663 } *funcs;
664 static int funcs_n, funcs_sz;
666 static int func_create(struct type *ret, char *name, char argnames[][NAMELEN],
667 struct type *args, int nargs, int varg)
669 struct funcinfo *fi;
670 int i;
671 if (funcs_n >= funcs_sz) {
672 funcs_sz = MAX(128, funcs_sz * 2);
673 funcs = mextend(funcs, funcs_n, funcs_sz, sizeof(funcs[0]));
675 fi = &funcs[funcs_n++];
676 memcpy(&fi->ret, ret, sizeof(*ret));
677 for (i = 0; i < nargs; i++)
678 memcpy(&fi->args[i], &args[i], sizeof(*ret));
679 fi->nargs = nargs;
680 fi->varg = varg;
681 strcpy(fi->name, name ? name : "");
682 for (i = 0; i < nargs; i++)
683 strcpy(fi->argnames[i], argnames[i]);
684 return fi - funcs;
687 static void readcall(void)
689 struct type t;
690 struct funcinfo *fi;
691 int argc = 0;
692 ts_pop(&t);
693 if (t.flags & T_FUNC && t.ptr > 0)
694 o_deref(ULNG);
695 if (!tok_comes(")")) {
696 do {
697 readexpr();
698 ts_pop_de(NULL);
699 argc++;
700 } while (!tok_jmp(","));
702 tok_req(")");
703 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
704 o_call(argc, fi ? TYPE_BT(&fi->ret) : SINT);
705 if (fi) {
706 if (TYPE_BT(&fi->ret))
707 o_cast(TYPE_BT(&fi->ret));
708 ts_push(&fi->ret);
709 } else {
710 ts_push_bt(SINT);
714 static void readpost(void)
716 readprimary();
717 while (1) {
718 if (!tok_jmp("[")) {
719 readexpr();
720 tok_req("]");
721 arrayderef();
722 continue;
724 if (!tok_jmp("(")) {
725 readcall();
726 continue;
728 if (!tok_jmp("++")) {
729 inc_post(O_ADD);
730 continue;
732 if (!tok_jmp("--")) {
733 inc_post(O_SUB);
734 continue;
736 if (!tok_jmp(".")) {
737 readfield();
738 continue;
740 if (!tok_jmp("->")) {
741 ts_de(1);
742 readfield();
743 continue;
745 break;
749 static void inc_pre(int op)
751 struct type t;
752 readpre();
753 /* copy the destination */
754 o_tmpcopy();
755 ts_push(&ts[nts - 1]);
756 /* increment by 1 or pointer size */
757 ts_pop_de(&t);
758 o_num(t.ptr > 0 ? type_szde(&t) : 1);
759 o_bop(op);
760 /* assign the result */
761 o_assign(TYPE_BT(&t));
762 ts_de(0);
765 static void readpre(void)
767 struct type t;
768 if (!tok_jmp("&")) {
769 readpre();
770 ts_pop(&t);
771 if (!t.addr)
772 err("cannot use the address\n");
773 t.ptr++;
774 t.addr = 0;
775 ts_push(&t);
776 return;
778 if (!tok_jmp("*")) {
779 readpre();
780 ts_pop(&t);
781 array2ptr(&t);
782 if (!t.ptr)
783 err("dereferencing non-pointer\n");
784 if (t.addr)
785 o_deref(TYPE_BT(&t));
786 t.ptr--;
787 t.addr = 1;
788 ts_push(&t);
789 return;
791 if (!tok_jmp("!")) {
792 readpre();
793 ts_pop_de(NULL);
794 o_uop(O_LNOT);
795 ts_push_bt(SINT);
796 return;
798 if (!tok_jmp("+")) {
799 readpre();
800 ts_de(1);
801 ts_pop(&t);
802 ts_push_bt(bt_uop(TYPE_BT(&t)));
803 return;
805 if (!tok_jmp("-")) {
806 readpre();
807 ts_de(1);
808 ts_pop(&t);
809 o_uop(O_NEG);
810 ts_push_bt(bt_uop(TYPE_BT(&t)));
811 return;
813 if (!tok_jmp("~")) {
814 readpre();
815 ts_de(1);
816 ts_pop(&t);
817 o_uop(O_NOT);
818 ts_push_bt(bt_uop(TYPE_BT(&t)));
819 return;
821 if (!tok_jmp("++")) {
822 inc_pre(O_ADD);
823 return;
825 if (!tok_jmp("--")) {
826 inc_pre(O_SUB);
827 return;
829 if (!tok_jmp("sizeof")) {
830 struct type t;
831 int op = !tok_jmp("(");
832 if (readtype(&t)) {
833 long m = o_mark();
834 if (op)
835 readexpr();
836 else
837 readpre();
838 o_back(m);
839 ts_pop(&t);
840 o_tmpdrop(1);
842 o_num(type_totsz(&t));
843 ts_push_bt(ULNG);
844 if (op)
845 tok_req(")");
846 return;
848 readpost();
851 static void readmul(void)
853 readpre();
854 while (1) {
855 if (!tok_jmp("*")) {
856 readpre();
857 ts_binop(O_MUL);
858 continue;
860 if (!tok_jmp("/")) {
861 readpre();
862 ts_binop(O_DIV);
863 continue;
865 if (!tok_jmp("%")) {
866 readpre();
867 ts_binop(O_MOD);
868 continue;
870 break;
874 static void readadd(void)
876 readmul();
877 while (1) {
878 if (!tok_jmp("+")) {
879 readmul();
880 ts_addop(O_ADD);
881 continue;
883 if (!tok_jmp("-")) {
884 readmul();
885 ts_addop(O_SUB);
886 continue;
888 break;
892 static void shift(int op)
894 struct type t;
895 readadd();
896 ts_pop_de2(NULL, &t);
897 o_bop(O_MK(op, TYPE_BT(&t)));
898 ts_push_bt(bt_uop(TYPE_BT(&t)));
901 static void readshift(void)
903 readadd();
904 while (1) {
905 if (!tok_jmp("<<")) {
906 shift(O_SHL);
907 continue;
909 if (!tok_jmp(">>")) {
910 shift(O_SHR);
911 continue;
913 break;
917 static void cmp(int op)
919 struct type t1, t2;
920 int bt;
921 readshift();
922 ts_pop_de2(&t1, &t2);
923 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
924 o_bop(O_MK(op, bt));
925 ts_push_bt(SINT);
928 static void readcmp(void)
930 readshift();
931 while (1) {
932 if (!tok_jmp("<")) {
933 cmp(O_LT);
934 continue;
936 if (!tok_jmp(">")) {
937 cmp(O_GT);
938 continue;
940 if (!tok_jmp("<=")) {
941 cmp(O_LE);
942 continue;
944 if (!tok_jmp(">=")) {
945 cmp(O_GE);
946 continue;
948 break;
952 static void eq(int op)
954 readcmp();
955 ts_pop_de2(NULL, NULL);
956 o_bop(op);
957 ts_push_bt(SINT);
960 static void readeq(void)
962 readcmp();
963 while (1) {
964 if (!tok_jmp("==")) {
965 eq(O_EQ);
966 continue;
968 if (!tok_jmp("!=")) {
969 eq(O_NE);
970 continue;
972 break;
976 static void readbitand(void)
978 readeq();
979 while (!tok_jmp("&")) {
980 readeq();
981 ts_binop(O_AND);
985 static void readxor(void)
987 readbitand();
988 while (!tok_jmp("^")) {
989 readbitand();
990 ts_binop(O_XOR);
994 static void readbitor(void)
996 readxor();
997 while (!tok_jmp("|")) {
998 readxor();
999 ts_binop(O_OR);
1003 static void savelocal(long val, int bt)
1005 o_local(val);
1006 o_tmpswap();
1007 o_assign(bt);
1008 o_tmpdrop(1);
1011 static void loadlocal(long val, int bt)
1013 o_local(val);
1014 o_deref(bt);
1015 o_rmlocal(val, bt);
1018 static void readand(void)
1020 int l_out, l_fail;
1021 long val;
1022 readbitor();
1023 if (!tok_comes("&&"))
1024 return;
1025 val = o_mklocal(UINT);
1026 l_out = LABEL();
1027 l_fail = LABEL();
1028 ts_pop_de(NULL);
1029 o_jz(l_fail);
1030 while (!tok_jmp("&&")) {
1031 readbitor();
1032 ts_pop_de(NULL);
1033 o_jz(l_fail);
1035 o_num(1);
1036 savelocal(val, UINT);
1037 o_jmp(l_out);
1038 o_label(l_fail);
1039 o_num(0);
1040 savelocal(val, UINT);
1041 o_label(l_out);
1042 loadlocal(val, SINT);
1043 ts_push_bt(SINT);
1046 static void reador(void)
1048 int l_pass, l_end;
1049 long val;
1050 readand();
1051 if (!tok_comes("||"))
1052 return;
1053 val = o_mklocal(UINT);
1054 l_pass = LABEL();
1055 l_end = LABEL();
1056 ts_pop_de(NULL);
1057 o_uop(O_LNOT);
1058 o_jz(l_pass);
1059 while (!tok_jmp("||")) {
1060 readand();
1061 ts_pop_de(NULL);
1062 o_uop(O_LNOT);
1063 o_jz(l_pass);
1065 o_num(0);
1066 savelocal(val, SINT);
1067 o_jmp(l_end);
1068 o_label(l_pass);
1069 o_num(1);
1070 savelocal(val, SINT);
1071 o_label(l_end);
1072 loadlocal(val, SINT);
1073 ts_push_bt(SINT);
1076 static void readcexpr(void);
1078 static int readcexpr_const(void)
1080 long c, m = 0;
1081 if (o_popnum(&c))
1082 return -1;
1083 if (!c)
1084 m = o_mark();
1085 readcexpr();
1086 /* both branches yield the same type; so ignore the first */
1087 ts_pop_de(NULL);
1088 tok_req(":");
1089 if (!c) {
1090 o_back(m);
1091 o_tmpdrop(1);
1093 if (c)
1094 m = o_mark();
1095 readcexpr();
1096 /* making sure t->addr == 0 on both branches */
1097 ts_de(1);
1098 if (c) {
1099 o_back(m);
1100 o_tmpdrop(1);
1102 return 0;
1105 static void readcexpr(void)
1107 reador();
1108 if (tok_jmp("?"))
1109 return;
1110 ncexpr++;
1111 ts_pop_de(NULL);
1112 if (readcexpr_const()) {
1113 long val = 0;
1114 int l_fail = LABEL();
1115 int l_end = LABEL();
1116 struct type ret;
1117 o_jz(l_fail);
1118 readcexpr();
1119 /* both branches yield the same type; so ignore the first */
1120 ts_pop_de(&ret);
1121 if (!TYPE_VOID(&ret)) {
1122 val = o_mklocal(ULNG);
1123 savelocal(val, ULNG);
1125 o_jmp(l_end);
1127 tok_req(":");
1128 o_label(l_fail);
1129 readcexpr();
1130 /* making sure t->addr == 0 on both branches */
1131 ts_de(1);
1132 if (!TYPE_VOID(&ret)) {
1133 savelocal(val, ULNG);
1135 o_label(l_end);
1136 if (!TYPE_VOID(&ret)) {
1137 loadlocal(val, ULNG);
1140 ncexpr--;
1143 static void opassign(int op, int ptrop)
1145 struct type t = ts[nts - 1];
1146 o_tmpcopy();
1147 ts_push(&t);
1148 readexpr();
1149 if (op == O_ADD || op == O_SUB)
1150 ts_addop(op);
1151 else
1152 ts_binop(op);
1153 o_assign(TYPE_BT(&ts[nts - 2]));
1154 ts_pop(NULL);
1155 ts_de(0);
1158 static void doassign(void)
1160 struct type t = ts[nts - 1];
1161 if (!t.ptr && t.flags & T_STRUCT) {
1162 ts_pop(NULL);
1163 o_num(type_totsz(&t));
1164 o_memcpy();
1165 } else {
1166 ts_pop_de(NULL);
1167 o_assign(TYPE_BT(&ts[nts - 1]));
1168 ts_de(0);
1172 static void readexpr(void)
1174 readcexpr();
1175 if (!tok_jmp("=")) {
1176 readexpr();
1177 doassign();
1178 return;
1180 if (!tok_jmp("+=")) {
1181 opassign(O_ADD, 1);
1182 return;
1184 if (!tok_jmp("-=")) {
1185 opassign(O_SUB, 1);
1186 return;
1188 if (!tok_jmp("*=")) {
1189 opassign(O_MUL, 0);
1190 return;
1192 if (!tok_jmp("/=")) {
1193 opassign(O_DIV, 0);
1194 return;
1196 if (!tok_jmp("%=")) {
1197 opassign(O_MOD, 0);
1198 return;
1200 if (!tok_jmp("<<=")) {
1201 opassign(O_SHL, 0);
1202 return;
1204 if (!tok_jmp(">>=")) {
1205 opassign(O_SHR, 0);
1206 return;
1208 if (!tok_jmp("&=")) {
1209 opassign(O_AND, 0);
1210 return;
1212 if (!tok_jmp("|=")) {
1213 opassign(O_OR, 0);
1214 return;
1216 if (!tok_jmp("^=")) {
1217 opassign(O_XOR, 0);
1218 return;
1222 static void readestmt(void)
1224 do {
1225 o_tmpdrop(-1);
1226 nts = 0;
1227 readexpr();
1228 } while (!tok_jmp(","));
1231 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1233 static void globalinit(void *obj, int off, struct type *t)
1235 struct name *name = obj;
1236 char *elfname = *name->elfname ? name->elfname : name->name;
1237 if (t->flags & T_ARRAY && tok_grp() == '"') {
1238 struct type *t_de = &arrays[t->id].type;
1239 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1240 char *buf = tok_get() + 1;
1241 int len = tok_len() - 2;
1242 buf[len] = '\0';
1243 o_dscpy(name->addr + off, buf, len + 1);
1244 return;
1247 readexpr();
1248 o_dsset(elfname, off, TYPE_BT(t));
1249 ts_pop(NULL);
1252 static void readfunc(struct name *name, int flags);
1254 static void globaldef(long data, struct name *name, unsigned flags)
1256 struct type *t = &name->type;
1257 char *elfname = *name->elfname ? name->elfname : name->name;
1258 int sz;
1259 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1260 if (~flags & F_EXTERN)
1261 arrays[t->id].n = initsize();
1262 sz = type_totsz(t);
1263 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1264 if (tok_comes("="))
1265 name->addr = o_dsnew(elfname, sz, F_GLOBAL(flags));
1266 else
1267 o_bsnew(elfname, sz, F_GLOBAL(flags));
1269 global_add(name);
1270 if (!tok_jmp("="))
1271 initexpr(t, 0, name, globalinit);
1272 if (tok_comes("{") && name->type.flags & T_FUNC)
1273 readfunc(name, flags);
1276 /* generate the address of local + off */
1277 static void o_localoff(long addr, int off)
1279 o_local(addr);
1280 if (off) {
1281 o_num(off);
1282 o_bop(O_ADD);
1286 static void localinit(void *obj, int off, struct type *t)
1288 long addr = *(long *) obj;
1289 if (t->flags & T_ARRAY && tok_grp() == '"') {
1290 struct type *t_de = &arrays[t->id].type;
1291 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1292 char *buf = tok_get() + 1;
1293 int len = tok_len() - 2;
1294 o_localoff(addr, off);
1295 o_sym(tmp_str(buf, len));
1296 o_num(len + 1);
1297 o_memcpy();
1298 o_tmpdrop(1);
1299 return;
1302 o_localoff(addr, off);
1303 ts_push(t);
1304 readexpr();
1305 doassign();
1306 ts_pop(NULL);
1307 o_tmpdrop(1);
1310 /* current function name */
1311 static char func_name[NAMELEN];
1313 static void localdef(long data, struct name *name, unsigned flags)
1315 struct type *t = &name->type;
1316 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1317 global_add(name);
1318 return;
1320 if (flags & F_STATIC) {
1321 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1322 globaldef(data, name, flags);
1323 return;
1325 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1326 arrays[t->id].n = initsize();
1327 name->addr = o_mklocal(type_totsz(&name->type));
1328 local_add(name);
1329 if (!tok_jmp("=")) {
1330 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1331 o_local(name->addr);
1332 o_num(0);
1333 o_num(type_totsz(t));
1334 o_memset();
1335 o_tmpdrop(1);
1337 initexpr(t, 0, &name->addr, localinit);
1341 static void typedefdef(long data, struct name *name, unsigned flags)
1343 typedef_add(name->name, &name->type);
1346 static void readstmt(void);
1348 static void readswitch(void)
1350 int o_break = l_break;
1351 long val_addr = o_mklocal(ULNG);
1352 struct type t;
1353 int ncases = 0; /* number of case labels */
1354 int l_failed = LABEL(); /* address of last failed jmp */
1355 int l_matched = LABEL(); /* address of last walk through jmp */
1356 int l_default = 0; /* default case label */
1357 l_break = LABEL();
1358 tok_req("(");
1359 readexpr();
1360 ts_pop_de(&t);
1361 o_local(val_addr);
1362 o_tmpswap();
1363 o_assign(TYPE_BT(&t));
1364 ts_de(0);
1365 o_tmpdrop(1);
1366 tok_req(")");
1367 tok_req("{");
1368 while (tok_jmp("}")) {
1369 if (!tok_comes("case") && !tok_comes("default")) {
1370 readstmt();
1371 continue;
1373 if (ncases)
1374 o_jmp(l_matched);
1375 if (!strcmp("case", tok_get())) {
1376 o_label(l_failed);
1377 l_failed = LABEL();
1378 caseexpr = 1;
1379 readexpr();
1380 ts_pop_de(NULL);
1381 caseexpr = 0;
1382 o_local(val_addr);
1383 o_deref(TYPE_BT(&t));
1384 o_bop(O_EQ);
1385 o_jz(l_failed);
1386 o_tmpdrop(1);
1387 } else {
1388 if (!ncases)
1389 o_jmp(l_failed);
1390 l_default = LABEL();
1391 o_label(l_default);
1393 tok_req(":");
1394 o_label(l_matched);
1395 l_matched = LABEL();
1396 ncases++;
1398 o_rmlocal(val_addr, ULNG);
1399 o_jmp(l_break);
1400 o_label(l_failed);
1401 if (l_default)
1402 o_jmp(l_default);
1403 o_label(l_break);
1404 l_break = o_break;
1407 static char (*label_name)[NAMELEN];
1408 static int *label_ids;
1409 static int label_n, label_sz;
1411 static int label_id(char *name)
1413 int i;
1414 if (label_n >= label_sz) {
1415 label_sz = MAX(128, label_sz * 2);
1416 label_name = mextend(label_name, label_n, label_sz,
1417 sizeof(label_name[0]));
1418 label_ids = mextend(label_ids, label_n, label_sz,
1419 sizeof(label_ids[0]));
1421 for (i = label_n - 1; i >= 0; --i)
1422 if (!strcmp(label_name[i], name))
1423 return label_ids[i];
1424 strcpy(label_name[label_n], name);
1425 label_ids[label_n] = LABEL();
1426 return label_ids[label_n++];
1429 static void readstmt(void)
1431 o_tmpdrop(-1);
1432 nts = 0;
1433 if (!tok_jmp("{")) {
1434 int _nlocals = locals_n;
1435 int _nglobals = globals_n;
1436 int _nenums = enums_n;
1437 int _ntypedefs = typedefs_n;
1438 int _nstructs = structs_n;
1439 int _nfuncs = funcs_n;
1440 int _narrays = arrays_n;
1441 while (tok_jmp("}"))
1442 readstmt();
1443 locals_n = _nlocals;
1444 enums_n = _nenums;
1445 typedefs_n = _ntypedefs;
1446 structs_n = _nstructs;
1447 funcs_n = _nfuncs;
1448 arrays_n = _narrays;
1449 globals_n = _nglobals;
1450 return;
1452 if (!readdefs(localdef, 0)) {
1453 tok_req(";");
1454 return;
1456 if (!tok_jmp("typedef")) {
1457 readdefs(typedefdef, 0);
1458 tok_req(";");
1459 return;
1461 if (!tok_jmp("if")) {
1462 int l_fail = LABEL();
1463 int l_end = LABEL();
1464 tok_req("(");
1465 readestmt();
1466 tok_req(")");
1467 ts_pop_de(NULL);
1468 o_jz(l_fail);
1469 readstmt();
1470 if (!tok_jmp("else")) {
1471 o_jmp(l_end);
1472 o_label(l_fail);
1473 readstmt();
1474 o_label(l_end);
1475 } else {
1476 o_label(l_fail);
1478 return;
1480 if (!tok_jmp("while")) {
1481 int o_break = l_break;
1482 int o_cont = l_cont;
1483 l_break = LABEL();
1484 l_cont = LABEL();
1485 o_label(l_cont);
1486 tok_req("(");
1487 readestmt();
1488 tok_req(")");
1489 ts_pop_de(NULL);
1490 o_jz(l_break);
1491 readstmt();
1492 o_jmp(l_cont);
1493 o_label(l_break);
1494 l_break = o_break;
1495 l_cont = o_cont;
1496 return;
1498 if (!tok_jmp("do")) {
1499 int o_break = l_break;
1500 int o_cont = l_cont;
1501 int l_beg = LABEL();
1502 l_break = LABEL();
1503 l_cont = LABEL();
1504 o_label(l_beg);
1505 readstmt();
1506 tok_req("while");
1507 tok_req("(");
1508 o_label(l_cont);
1509 readexpr();
1510 ts_pop_de(NULL);
1511 o_uop(O_LNOT);
1512 o_jz(l_beg);
1513 tok_req(")");
1514 o_label(l_break);
1515 tok_req(";");
1516 l_break = o_break;
1517 l_cont = o_cont;
1518 return;
1520 if (!tok_jmp("for")) {
1521 int o_break = l_break;
1522 int o_cont = l_cont;
1523 int l_check = LABEL(); /* for condition label */
1524 int l_body = LABEL(); /* for block label */
1525 l_cont = LABEL();
1526 l_break = LABEL();
1527 tok_req("(");
1528 if (!tok_comes(";"))
1529 readestmt();
1530 tok_req(";");
1531 o_label(l_check);
1532 if (!tok_comes(";")) {
1533 readestmt();
1534 ts_pop_de(NULL);
1535 o_jz(l_break);
1537 tok_req(";");
1538 o_jmp(l_body);
1539 o_label(l_cont);
1540 if (!tok_comes(")"))
1541 readestmt();
1542 tok_req(")");
1543 o_jmp(l_check);
1544 o_label(l_body);
1545 readstmt();
1546 o_jmp(l_cont);
1547 o_label(l_break);
1548 l_break = o_break;
1549 l_cont = o_cont;
1550 return;
1552 if (!tok_jmp("switch")) {
1553 readswitch();
1554 return;
1556 if (!tok_jmp("return")) {
1557 int ret = !tok_comes(";");
1558 if (ret) {
1559 readexpr();
1560 ts_pop_de(NULL);
1562 tok_req(";");
1563 o_ret(ret);
1564 return;
1566 if (!tok_jmp("break")) {
1567 tok_req(";");
1568 o_jmp(l_break);
1569 return;
1571 if (!tok_jmp("continue")) {
1572 tok_req(";");
1573 o_jmp(l_cont);
1574 return;
1576 if (!tok_jmp("goto")) {
1577 o_jmp(label_id(tok_get()));
1578 tok_req(";");
1579 return;
1581 readestmt();
1582 /* labels */
1583 if (!tok_jmp(":")) {
1584 o_label(label_id(tok_previden));
1585 return;
1587 tok_req(";");
1590 static void readfunc(struct name *name, int flags)
1592 struct funcinfo *fi = &funcs[name->type.id];
1593 int i;
1594 strcpy(func_name, fi->name);
1595 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1596 for (i = 0; i < fi->nargs; i++) {
1597 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1598 strcpy(arg.name, fi->argnames[i]);
1599 local_add(&arg);
1601 label = 0;
1602 label_n = 0;
1603 readstmt();
1604 o_func_end();
1605 func_name[0] = '\0';
1606 locals_n = 0;
1609 static void readdecl(void)
1611 if (!tok_jmp("typedef")) {
1612 readdefs(typedefdef, 0);
1613 tok_req(";");
1614 return;
1616 readdefs_int(globaldef, 0);
1617 tok_jmp(";");
1620 static void parse(void)
1622 while (tok_jmp(""))
1623 readdecl();
1626 static void compat_macros(void)
1628 cpp_define("__STDC__", "");
1629 cpp_define("__linux__", "");
1630 cpp_define(I_ARCH, "");
1632 /* ignored keywords */
1633 cpp_define("const", "");
1634 cpp_define("register", "");
1635 cpp_define("volatile", "");
1636 cpp_define("inline", "");
1637 cpp_define("restrict", "");
1638 cpp_define("__inline__", "");
1639 cpp_define("__restrict__", "");
1640 cpp_define("__attribute__(x)", "");
1641 cpp_define("__builtin_va_list__", "long");
1644 int main(int argc, char *argv[])
1646 char obj[128] = "";
1647 int ofd;
1648 int i = 1;
1649 compat_macros();
1650 while (i < argc && argv[i][0] == '-') {
1651 if (argv[i][1] == 'I')
1652 cpp_path(argv[i][2] ? argv[i] + 2 : argv[++i]);
1653 if (argv[i][1] == 'D') {
1654 char *name = argv[i] + 2;
1655 char *def = "";
1656 char *eq = strchr(name, '=');
1657 if (eq) {
1658 *eq = '\0';
1659 def = eq + 1;
1661 cpp_define(name, def);
1663 if (argv[i][1] == 'o')
1664 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1665 i++;
1667 if (i == argc)
1668 die("neatcc: no file given\n");
1669 if (cpp_init(argv[i]))
1670 die("neatcc: cannot open <%s>\n", argv[i]);
1671 out_init(0);
1672 parse();
1673 if (!*obj) {
1674 strcpy(obj, argv[i]);
1675 obj[strlen(obj) - 1] = 'o';
1677 free(locals);
1678 free(globals);
1679 free(label_name);
1680 free(label_ids);
1681 free(funcs);
1682 free(typedefs);
1683 free(structs);
1684 free(arrays);
1685 tok_done();
1686 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1687 o_write(ofd);
1688 close(ofd);
1689 return 0;
1693 /* parsing function and variable declarations */
1695 /* read the base type of a variable */
1696 static int basetype(struct type *type, unsigned *flags)
1698 int sign = 1;
1699 int size = UINT;
1700 int done = 0;
1701 int i = 0;
1702 int isunion;
1703 char name[NAMELEN] = "";
1704 *flags = 0;
1705 type->flags = 0;
1706 type->ptr = 0;
1707 type->addr = 0;
1708 while (!done) {
1709 if (!tok_jmp("static")) {
1710 *flags |= F_STATIC;
1711 } else if (!tok_jmp("extern")) {
1712 *flags |= F_EXTERN;
1713 } else if (!tok_jmp("void")) {
1714 sign = 0;
1715 size = 0;
1716 done = 1;
1717 } else if (!tok_jmp("int")) {
1718 done = 1;
1719 } else if (!tok_jmp("char")) {
1720 size = UCHR;
1721 done = 1;
1722 } else if (!tok_jmp("short")) {
1723 size = USHT;
1724 } else if (!tok_jmp("long")) {
1725 size = ULNG;
1726 } else if (!tok_jmp("signed")) {
1727 sign = 1;
1728 } else if (!tok_jmp("unsigned")) {
1729 sign = 0;
1730 } else if (tok_comes("union") || tok_comes("struct")) {
1731 isunion = !strcmp("union", tok_get());
1732 if (tok_grp() == 'a')
1733 strcpy(name, tok_get());
1734 if (tok_comes("{"))
1735 type->id = struct_create(name, isunion);
1736 else
1737 type->id = struct_find(name, isunion);
1738 type->flags |= T_STRUCT;
1739 type->bt = ULNG;
1740 return 0;
1741 } else if (!tok_jmp("enum")) {
1742 if (tok_grp() == 'a')
1743 tok_get();
1744 if (tok_comes("{"))
1745 enum_create();
1746 type->bt = SINT;
1747 return 0;
1748 } else {
1749 if (tok_grp() == 'a') {
1750 int id = typedef_find(tok_see());
1751 if (id != -1) {
1752 tok_get();
1753 memcpy(type, &typedefs[id].type,
1754 sizeof(*type));
1755 return 0;
1758 if (!i)
1759 return 1;
1760 done = 1;
1761 continue;
1763 i++;
1765 type->bt = size | (sign ? T_MSIGN : 0);
1766 return 0;
1769 static void readptrs(struct type *type)
1771 while (!tok_jmp("*")) {
1772 type->ptr++;
1773 if (!type->bt)
1774 type->bt = 1;
1778 /* read function arguments */
1779 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1781 int nargs = 0;
1782 tok_req("(");
1783 *varg = 0;
1784 while (!tok_comes(")")) {
1785 if (!tok_jmp("...")) {
1786 *varg = 1;
1787 break;
1789 if (readname(&args[nargs], argnames[nargs], NULL)) {
1790 /* argument has no type, assume int */
1791 memset(&args[nargs], 0, sizeof(struct type));
1792 args[nargs].bt = SINT;
1793 strcpy(argnames[nargs], tok_get());
1795 /* argument arrays are pointers */
1796 array2ptr(&args[nargs]);
1797 nargs++;
1798 if (tok_jmp(","))
1799 break;
1801 tok_req(")");
1802 /* void argument */
1803 if (nargs == 1 && !TYPE_BT(&args[0]))
1804 return 0;
1805 return nargs;
1808 /* read K&R function arguments */
1809 static void krdef(long data, struct name *name, unsigned flags)
1811 struct funcinfo *fi = &funcs[data];
1812 int i;
1813 for (i = 0; i < fi->nargs; i++)
1814 if (!strcmp(fi->argnames[i], name->name))
1815 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1819 * readarrays() parses array specifiers when reading a definition in
1820 * readname(). The "type" parameter contains the type contained in the
1821 * inner array; for instance, type in "int *a[10][20]" would be an int
1822 * pointer. When returning, the "type" parameter is changed to point
1823 * to the final array. The function returns a pointer to the type in
1824 * the inner array; this is useful when the type is not complete yet,
1825 * like when creating an array of function pointers as in
1826 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1828 static struct type *readarrays(struct type *type)
1830 long arsz[16];
1831 struct type *inner = NULL;
1832 int nar = 0;
1833 int i;
1834 while (!tok_jmp("[")) {
1835 long n = 0;
1836 if (tok_jmp("]")) {
1837 readexpr();
1838 ts_pop_de(NULL);
1839 if (o_popnum(&n))
1840 err("const expr expected\n");
1841 tok_req("]");
1843 arsz[nar++] = n;
1845 for (i = nar - 1; i >= 0; i--) {
1846 type->id = array_add(type, arsz[i]);
1847 if (!inner)
1848 inner = &arrays[type->id].type;
1849 type->flags = T_ARRAY;
1850 type->bt = ULNG;
1851 type->ptr = 0;
1853 return inner;
1856 static struct type *innertype(struct type *t)
1858 while (t->flags & T_ARRAY && !t->ptr)
1859 t = &arrays[t->id].type;
1860 return t;
1863 static void innertype_modify(struct type *t, struct type *s)
1865 struct type *inner = innertype(t);
1866 int ptr = inner->ptr;
1867 memcpy(inner, s, sizeof(*inner));
1868 inner->ptr = ptr;
1872 * readname() reads a variable definition; the name is copied into
1873 * "name" and the type is copied into "main" argument. The "base"
1874 * argument, if not NULL, indicates the base type of the variable.
1875 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1876 * "int". If NULL, basetype() is called directly to read the base
1877 * type of the variable. readname() returns zero, only if the
1878 * variable can be read.
1880 static int readname(struct type *main, char *name, struct type *base)
1882 struct type type; /* the main type */
1883 struct type btype; /* type before parenthesis; e.g. "int *" in "int *(*p)[10] */
1884 int paren;
1885 unsigned flags;
1886 if (name)
1887 *name = '\0';
1888 if (!base) {
1889 if (basetype(&type, &flags))
1890 return 1;
1891 } else {
1892 type = *base;
1894 readptrs(&type);
1895 paren = !tok_jmp("(");
1896 if (paren) {
1897 btype = type;
1898 readptrs(&type);
1900 if (tok_grp() == 'a' && name)
1901 strcpy(name, tok_get());
1902 readarrays(&type);
1903 if (paren)
1904 tok_req(")");
1905 if (tok_comes("(")) {
1906 struct type args[NARGS];
1907 char argnames[NARGS][NAMELEN];
1908 int varg = 0;
1909 int nargs = readargs(args, argnames, &varg);
1910 struct type rtype = type; /* return type */
1911 struct type ftype = {0}; /* function type */
1912 if (paren)
1913 rtype = btype;
1914 ftype.flags = T_FUNC;
1915 ftype.bt = ULNG;
1916 ftype.id = func_create(&rtype, name, argnames, args, nargs, varg);
1917 if (paren)
1918 innertype_modify(&type, &ftype);
1919 else
1920 type = ftype;
1921 if (!tok_comes(";"))
1922 while (!tok_comes("{") && !readdefs(krdef, type.id))
1923 tok_req(";");
1924 } else {
1925 if (paren && readarrays(&btype))
1926 innertype_modify(&type, &btype);
1928 *main = type;
1929 return 0;
1932 static int readtype(struct type *type)
1934 return readname(type, NULL, NULL);
1938 * readdefs() reads a variable definition statement. The definition
1939 * can appear in different contexts: global variables, function
1940 * local variables, struct fields, and typedefs. For each defined
1941 * variable, def() callback is called with the appropriate name
1942 * struct and flags; the callback should finish parsing the definition
1943 * by possibly reading the initializer expression and saving the name
1944 * struct.
1946 static int readdefs(void (*def)(long data, struct name *name, unsigned flags),
1947 long data)
1949 struct type base;
1950 unsigned base_flags;
1951 if (basetype(&base, &base_flags))
1952 return 1;
1953 if (tok_comes(";") || tok_comes("{"))
1954 return 0;
1955 do {
1956 struct name name = {{""}};
1957 if (readname(&name.type, name.name, &base))
1958 break;
1959 def(data, &name, base_flags);
1960 } while (!tok_jmp(","));
1961 return 0;
1964 /* just like readdefs, but default to int type; for handling K&R functions */
1965 static int readdefs_int(void (*def)(long data, struct name *name, unsigned flags),
1966 long data)
1968 struct type base;
1969 unsigned flags = 0;
1970 if (basetype(&base, &flags)) {
1971 if (tok_grp() != 'a')
1972 return 1;
1973 memset(&base, 0, sizeof(base));
1974 base.bt = SINT;
1976 if (!tok_comes(";")) {
1977 do {
1978 struct name name = {{""}};
1979 if (readname(&name.type, name.name, &base))
1980 break;
1981 def(data, &name, flags);
1982 } while (!tok_jmp(","));
1984 return 0;
1988 /* parsing initializer expressions */
1990 static void jumpbrace(void)
1992 int depth = 0;
1993 while (!tok_comes("}") || depth--)
1994 if (!strcmp("{", tok_get()))
1995 depth++;
1996 tok_req("}");
1999 /* compute the size of the initializer expression */
2000 static int initsize(void)
2002 long addr = tok_addr();
2003 int n = 0;
2004 if (tok_jmp("="))
2005 return 0;
2006 if (tok_grp() == '"') {
2007 tok_get();
2008 n = tok_len() - 2 + 1;
2009 tok_jump(addr);
2010 return n;
2012 tok_req("{");
2013 while (tok_jmp("}")) {
2014 long idx = n;
2015 if (!tok_jmp("[")) {
2016 readexpr();
2017 ts_pop_de(NULL);
2018 o_popnum(&idx);
2019 tok_req("]");
2020 tok_req("=");
2022 if (n < idx + 1)
2023 n = idx + 1;
2024 while (!tok_comes("}") && !tok_comes(","))
2025 if (!strcmp("{", tok_get()))
2026 jumpbrace();
2027 tok_jmp(",");
2029 tok_jump(addr);
2030 return n;
2033 /* read the initializer expression and initialize basic types using set() cb */
2034 static void initexpr(struct type *t, int off, void *obj,
2035 void (*set)(void *obj, int off, struct type *t))
2037 if (tok_jmp("{")) {
2038 set(obj, off, t);
2039 return;
2041 if (!t->ptr && t->flags & T_STRUCT) {
2042 struct structinfo *si = &structs[t->id];
2043 int i;
2044 for (i = 0; i < si->nfields && !tok_comes("}"); i++) {
2045 struct name *field = &si->fields[i];
2046 if (!tok_jmp(".")) {
2047 field = struct_field(t->id, tok_get());
2048 tok_req("=");
2050 initexpr(&field->type, off + field->addr, obj, set);
2051 if (tok_jmp(","))
2052 break;
2054 } else if (t->flags & T_ARRAY) {
2055 struct type t_de = arrays[t->id].type;
2056 int i;
2057 /* handling extra braces as in: char s[] = {"sth"} */
2058 if (TYPE_SZ(&t_de) == 1 && tok_grp() == '"') {
2059 set(obj, off, t);
2060 tok_req("}");
2061 return;
2063 for (i = 0; !tok_comes("}"); i++) {
2064 long idx = i;
2065 struct type it = t_de;
2066 if (!tok_jmp("[")) {
2067 readexpr();
2068 ts_pop_de(NULL);
2069 o_popnum(&idx);
2070 tok_req("]");
2071 tok_req("=");
2073 if (!tok_comes("{") && (tok_grp() != '"' ||
2074 !(it.flags & T_ARRAY)))
2075 it = *innertype(&t_de);
2076 initexpr(&it, off + type_totsz(&it) * idx, obj, set);
2077 if (tok_jmp(","))
2078 break;
2081 tok_req("}");