ncc: use label identifiers more carefully
[neatcc/cc.git] / ncc.c
blob66d958ed4fef16751095c8223862883e8023eede
1 /*
2 * neatcc - the neatcc compiler
4 * Copyright (C) 2010-2013 Ali Gholami Rudi
6 * This program is released under the Modified BSD license.
7 */
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <stdarg.h>
11 #include <stdlib.h>
12 #include <string.h>
13 #include <stdio.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include "gen.h"
17 #include "ncc.h"
18 #include "out.h"
19 #include "tok.h"
21 static int nogen; /* do not generate code, if set */
22 #define o_bop(op) {if (!nogen) o_bop(op);}
23 #define o_uop(op) {if (!nogen) o_uop(op);}
24 #define o_cast(bt) {if (!nogen) o_cast(bt);}
25 #define o_memcpy() {if (!nogen) o_memcpy();}
26 #define o_memset() {if (!nogen) o_memset();}
27 #define o_call(argc, ret) {if (!nogen) o_call(argc, ret);}
28 #define o_ret(ret) {if (!nogen) o_ret(ret);}
29 #define o_assign(bt) {if (!nogen) o_assign(bt);}
30 #define o_deref(bt) {if (!nogen) o_deref(bt);}
31 #define o_load() {if (!nogen) o_load();}
32 #define o_popnum(c) (nogen ? 0 : o_popnum(c))
33 #define o_num(n) {if (!nogen) o_num(n);}
34 #define o_local(addr) {if (!nogen) o_local(addr);}
35 #define o_sym(sym) {if (!nogen) o_sym(sym);}
36 #define o_tmpdrop(n) {if (!nogen) o_tmpdrop(n);}
37 #define o_tmpswap() {if (!nogen) o_tmpswap();}
38 #define o_tmpcopy() {if (!nogen) o_tmpcopy();}
39 #define o_label(id) {if (!nogen) o_label(id);}
40 #define o_jz(id) {if (!nogen) o_jz(id);}
41 #define o_jnz(id) {if (!nogen) o_jnz(id);}
42 #define o_jmp(id) {if (!nogen) o_jmp(id);}
43 #define o_fork() {if (!nogen) o_fork();}
44 #define o_forkpush() {if (!nogen) o_forkpush();}
45 #define o_forkjoin() {if (!nogen) o_forkjoin();}
47 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
48 #define MIN(a, b) ((a) < (b) ? (a) : (b))
50 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
51 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
52 #define TYPE_VOID(t) (!(t)->bt && !(t)->flags && !(t)->ptr)
54 /* type->flag values */
55 #define T_ARRAY 0x01
56 #define T_STRUCT 0x02
57 #define T_FUNC 0x04
59 /* variable definition flags */
60 #define F_STATIC 0x01
61 #define F_EXTERN 0x02
63 struct type {
64 unsigned bt;
65 unsigned flags;
66 int ptr;
67 int id; /* for structs, functions and arrays */
68 int addr; /* the address is passed to gen.c; deref for value */
71 /* type stack */
72 static struct type ts[NTMPS];
73 static int nts;
75 static void ts_push_bt(unsigned bt)
77 ts[nts].ptr = 0;
78 ts[nts].flags = 0;
79 ts[nts].addr = 0;
80 ts[nts++].bt = bt;
83 static void ts_push(struct type *t)
85 struct type *d = &ts[nts++];
86 memcpy(d, t, sizeof(*t));
89 static void ts_push_addr(struct type *t)
91 ts_push(t);
92 ts[nts - 1].addr = 1;
95 static void ts_pop(struct type *type)
97 nts--;
98 if (type)
99 *type = ts[nts];
102 void err(char *fmt, ...)
104 va_list ap;
105 char msg[512];
106 va_start(ap, fmt);
107 vsprintf(msg, fmt, ap);
108 va_end(ap);
109 die("%s: %s", cpp_loc(tok_addr()), msg);
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[NLOCALS];
120 static int nlocals;
121 static struct name globals[NGLOBALS];
122 static int nglobals;
124 static void local_add(struct name *name)
126 if (nlocals >= NLOCALS)
127 err("nomem: NLOCALS reached!\n");
128 memcpy(&locals[nlocals++], name, sizeof(*name));
131 static int local_find(char *name)
133 int i;
134 for (i = nlocals - 1; i >= 0; --i)
135 if (!strcmp(locals[i].name, name))
136 return i;
137 return -1;
140 static int global_find(char *name)
142 int i;
143 for (i = nglobals - 1; i >= 0; i--)
144 if (!strcmp(name, globals[i].name))
145 return i;
146 return -1;
149 static void global_add(struct name *name)
151 if (nglobals >= NGLOBALS)
152 err("nomem: NGLOBALS reached!\n");
153 memcpy(&globals[nglobals++], name, sizeof(*name));
156 #define LABEL() (++label)
158 static int label; /* last used label id */
159 static int l_break; /* current break label */
160 static int l_cont; /* current continue label */
162 static struct enumval {
163 char name[NAMELEN];
164 int n;
165 } enums[NENUMS];
166 static int nenums;
168 static void enum_add(char *name, int val)
170 struct enumval *ev = &enums[nenums++];
171 if (nenums >= NENUMS)
172 err("nomem: NENUMS reached!\n");
173 strcpy(ev->name, name);
174 ev->n = val;
177 static int enum_find(int *val, char *name)
179 int i;
180 for (i = nenums - 1; i >= 0; --i)
181 if (!strcmp(name, enums[i].name)) {
182 *val = enums[i].n;
183 return 0;
185 return 1;
188 static struct typdefinfo {
189 char name[NAMELEN];
190 struct type type;
191 } typedefs[NTYPEDEFS];
192 static int ntypedefs;
194 static void typedef_add(char *name, struct type *type)
196 struct typdefinfo *ti = &typedefs[ntypedefs++];
197 if (ntypedefs >= NTYPEDEFS)
198 err("nomem: NTYPEDEFS reached!\n");
199 strcpy(ti->name, name);
200 memcpy(&ti->type, type, sizeof(*type));
203 static int typedef_find(char *name)
205 int i;
206 for (i = ntypedefs - 1; i >= 0; --i)
207 if (!strcmp(name, typedefs[i].name))
208 return i;
209 return -1;
212 static struct array {
213 struct type type;
214 int n;
215 } arrays[NARRAYS];
216 static int narrays;
218 static int array_add(struct type *type, int n)
220 struct array *a = &arrays[narrays++];
221 if (narrays >= NARRAYS)
222 err("nomem: NARRAYS reached!\n");
223 memcpy(&a->type, type, sizeof(*type));
224 a->n = n;
225 return a - arrays;
228 static void array2ptr(struct type *t)
230 if (t->flags & T_ARRAY && !t->ptr) {
231 memcpy(t, &arrays[t->id].type, sizeof(*t));
232 t->ptr++;
236 static struct structinfo {
237 char name[NAMELEN];
238 struct name fields[NFIELDS];
239 int nfields;
240 int isunion;
241 int size;
242 } structs[NSTRUCTS];
243 static int nstructs;
245 static int struct_find(char *name, int isunion)
247 int i;
248 for (i = nstructs - 1; i >= 0; --i)
249 if (*structs[i].name && !strcmp(name, structs[i].name) &&
250 structs[i].isunion == isunion)
251 return i;
252 i = nstructs++;
253 if (nstructs >= NSTRUCTS)
254 err("nomem: NSTRUCTS reached!\n");
255 memset(&structs[i], 0, sizeof(structs[i]));
256 strcpy(structs[i].name, name);
257 structs[i].isunion = isunion;
258 return i;
261 static struct name *struct_field(int id, char *name)
263 struct structinfo *si = &structs[id];
264 int i;
265 for (i = 0; i < si->nfields; i++)
266 if (!strcmp(name, si->fields[i].name))
267 return &si->fields[i];
268 err("field not found\n");
269 return NULL;
272 /* return t's size */
273 static int type_totsz(struct type *t)
275 if (t->ptr)
276 return LONGSZ;
277 if (t->flags & T_ARRAY)
278 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
279 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
282 /* return t's dereferenced size */
283 static unsigned type_szde(struct type *t)
285 struct type de = *t;
286 array2ptr(&de);
287 de.ptr--;
288 return type_totsz(&de);
291 /* dereference stack top if t->addr (ie. address is pushed to gen.c) */
292 static void ts_de(int deref)
294 struct type *t = &ts[nts - 1];
295 array2ptr(t);
296 if (deref && t->addr && (t->ptr || !(t->flags & T_FUNC)))
297 o_deref(TYPE_BT(t));
298 t->addr = 0;
301 /* pop stack pop to *t and dereference if t->addr */
302 static void ts_pop_de(struct type *t)
304 ts_de(1);
305 ts_pop(t);
308 /* pop the top 2 stack values and dereference them if t->addr */
309 static void ts_pop_de2(struct type *t1, struct type *t2)
311 ts_pop_de(t1);
312 o_tmpswap();
313 ts_pop_de(t2);
314 o_tmpswap();
317 static int tok_jmp(int tok)
319 if (tok_see() != tok)
320 return 1;
321 tok_get();
322 return 0;
325 static void tok_expect(int tok)
327 if (tok_get() != tok)
328 err("syntax error\n");
331 static unsigned bt_op(unsigned bt1, unsigned bt2)
333 unsigned s1 = BT_SZ(bt1);
334 unsigned s2 = BT_SZ(bt2);
335 return ((bt1 | bt2) & BT_SIGNED) | (s1 > s2 ? s1 : s2);
338 static void ts_binop(int op)
340 struct type t1, t2;
341 int bt;
342 ts_pop_de2(&t1, &t2);
343 if (op == O_DIV || op == O_MOD)
344 bt = TYPE_BT(&t2);
345 else
346 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
347 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
348 ts_push_bt(bt);
351 static void ts_addop(int op)
353 struct type t1, t2;
354 ts_pop_de2(&t1, &t2);
355 if (!t1.ptr && !t2.ptr) {
356 o_bop(op);
357 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
358 return;
360 if (t1.ptr && !t2.ptr)
361 o_tmpswap();
362 if (!t1.ptr && t2.ptr)
363 if (type_szde(&t2) > 1) {
364 o_num(type_szde(&t2));
365 o_bop(O_MUL);
367 if (t1.ptr && !t2.ptr)
368 o_tmpswap();
369 o_bop(op);
370 if (t1.ptr && t2.ptr) {
371 int sz = type_szde(&t1);
372 if (sz > 1) {
373 o_num(sz);
374 o_bop(O_DIV);
376 ts_push_bt(4 | BT_SIGNED);
377 } else {
378 ts_push(t1.ptr ? &t1 : &t2);
382 /* function prototypes for parsing function and variable declarations */
383 static int readname(struct type *main, char *name, struct type *base);
384 static int readtype(struct type *type);
385 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
386 void *data);
387 static int readdefs_int(void (*def)(void *data, struct name *name, unsigned flags),
388 void *data);
390 /* function prototypes for parsing initializer expressions */
391 static int initsize(void);
392 static void initexpr(struct type *t, int off, void *obj,
393 void (*set)(void *obj, int off, struct type *t));
395 static int type_alignment(struct type *t)
397 if (t->flags & T_ARRAY && !t->ptr)
398 return type_alignment(&arrays[t->id].type);
399 if (t->flags & T_STRUCT && !t->ptr)
400 return type_alignment(&structs[t->id].fields[0].type);
401 return MIN(LONGSZ, type_totsz(t));
404 static void structdef(void *data, struct name *name, unsigned flags)
406 struct structinfo *si = data;
407 if (si->isunion) {
408 name->addr = 0;
409 if (si->size < type_totsz(&name->type))
410 si->size = type_totsz(&name->type);
411 } else {
412 struct type *t = &name->type;
413 int alignment = type_alignment(t);
414 if (t->flags & T_ARRAY && !t->ptr)
415 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
416 si->size = ALIGN(si->size, alignment);
417 name->addr = si->size;
418 si->size += type_totsz(&name->type);
420 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
423 static int struct_create(char *name, int isunion)
425 int id = struct_find(name, isunion);
426 struct structinfo *si = &structs[id];
427 tok_expect('{');
428 while (tok_jmp('}')) {
429 readdefs(structdef, si);
430 tok_expect(';');
432 return id;
435 static void readexpr(void);
437 static void enum_create(void)
439 long n = 0;
440 tok_expect('{');
441 while (tok_jmp('}')) {
442 char name[NAMELEN];
443 tok_expect(TOK_NAME);
444 strcpy(name, tok_id());
445 if (!tok_jmp('=')) {
446 readexpr();
447 ts_pop_de(NULL);
448 if (o_popnum(&n))
449 err("const expr expected!\n");
451 enum_add(name, n++);
452 tok_jmp(',');
456 /* used to differenciate labels from case and cond exprs */
457 static int ncexpr;
458 static int caseexpr;
460 static void readpre(void);
462 static char *tmp_str(char *buf, int len)
464 static char name[NAMELEN];
465 static int id;
466 sprintf(name, "__neatcc.s%d", id++);
467 o_dscpy(o_dsnew(name, len, 0), buf, len);
468 return name;
471 static void readprimary(void)
473 if (!tok_jmp(TOK_NUM)) {
474 long n;
475 int bt = tok_num(&n);
476 ts_push_bt(bt);
477 o_num(n);
478 return;
480 if (!tok_jmp(TOK_STR)) {
481 struct type t = {}; /* char type inside the arrays */
482 struct type a = {}; /* the char array type */
483 char *buf;
484 int len;
485 tok_str(&buf, &len);
486 t.bt = 1 | BT_SIGNED;
487 a.id = array_add(&t, len);
488 a.flags = T_ARRAY;
489 ts_push(&a);
490 o_sym(tmp_str(buf, len));
491 return;
493 if (!tok_jmp(TOK_NAME)) {
494 struct name unkn = {""};
495 char *name = unkn.name;
496 int n;
497 strcpy(name, tok_id());
498 /* don't search for labels here */
499 if (!ncexpr && !caseexpr && tok_see() == ':')
500 return;
501 if ((n = local_find(name)) != -1) {
502 struct name *l = &locals[n];
503 o_local(l->addr);
504 ts_push_addr(&l->type);
505 return;
507 if ((n = global_find(name)) != -1) {
508 struct name *g = &globals[n];
509 o_sym(*g->elfname ? g->elfname : g->name);
510 ts_push_addr(&g->type);
511 return;
513 if (!enum_find(&n, name)) {
514 ts_push_bt(4 | BT_SIGNED);
515 o_num(n);
516 return;
518 if (tok_see() != '(')
519 err("unknown symbol <%s>\n", name);
520 global_add(&unkn);
521 ts_push_bt(LONGSZ);
522 o_sym(unkn.name);
523 return;
525 if (!tok_jmp('(')) {
526 struct type t;
527 if (!readtype(&t)) {
528 struct type o;
529 tok_expect(')');
530 readpre();
531 ts_pop_de(&o);
532 ts_push(&t);
533 if (!t.ptr || !o.ptr)
534 o_cast(TYPE_BT(&t));
535 } else {
536 readexpr();
537 while (tok_jmp(')')) {
538 tok_expect(',');
539 ts_pop(NULL);
540 o_tmpdrop(1);
541 readexpr();
544 return;
548 static void arrayderef(void)
550 struct type t;
551 int sz;
552 ts_pop_de(NULL);
553 ts_pop(&t);
554 if (!(t.flags & T_ARRAY && !t.ptr) && t.addr) {
555 o_tmpswap();
556 o_deref(TYPE_BT(&t));
557 o_tmpswap();
559 array2ptr(&t);
560 t.ptr--;
561 sz = type_totsz(&t);
562 t.addr = 1;
563 if (sz > 1) {
564 o_num(sz);
565 o_bop(O_MUL);
567 o_bop(O_ADD);
568 ts_push(&t);
571 static void inc_post(int op)
573 struct type t = ts[nts - 1];
574 /* pushing the value before inc */
575 o_tmpcopy();
576 ts_de(1);
577 o_load();
578 o_tmpswap();
580 /* increment by 1 or pointer size */
581 o_tmpcopy();
582 ts_push(&t);
583 ts_pop_de(&t);
584 o_num(t.ptr > 0 ? type_szde(&t) : 1);
585 o_bop(op);
587 /* assign back */
588 o_assign(TYPE_BT(&t));
589 o_tmpdrop(1);
592 static void readfield(void)
594 struct name *field;
595 struct type t;
596 tok_expect(TOK_NAME);
597 ts_pop(&t);
598 array2ptr(&t);
599 field = struct_field(t.id, tok_id());
600 if (field->addr) {
601 o_num(field->addr);
602 o_bop(O_ADD);
604 ts_push_addr(&field->type);
607 static struct funcinfo {
608 struct type args[NARGS];
609 struct type ret;
610 int nargs;
611 int varg;
612 /* function and argument names; useful only when defining */
613 char argnames[NARGS][NAMELEN];
614 char name[NAMELEN];
615 } funcs[NFUNCS];
616 static int nfuncs;
618 static int func_create(struct type *ret, char *name, char argnames[][NAMELEN],
619 struct type *args, int nargs, int varg)
621 struct funcinfo *fi = &funcs[nfuncs++];
622 int i;
623 if (nfuncs >= NFUNCS)
624 err("nomem: NFUNCS reached!\n");
625 memcpy(&fi->ret, ret, sizeof(*ret));
626 for (i = 0; i < nargs; i++)
627 memcpy(&fi->args[i], &args[i], sizeof(*ret));
628 fi->nargs = nargs;
629 fi->varg = varg;
630 strcpy(fi->name, name ? name : "");
631 for (i = 0; i < nargs; i++)
632 strcpy(fi->argnames[i], argnames[i]);
633 return fi - funcs;
636 static void readcall(void)
638 struct type t;
639 struct funcinfo *fi;
640 int argc = 0;
641 ts_pop(&t);
642 if (t.flags & T_FUNC && t.ptr > 0)
643 o_deref(LONGSZ);
644 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
645 if (tok_see() != ')') {
646 do {
647 readexpr();
648 ts_pop_de(NULL);
649 argc++;
650 } while (!tok_jmp(','));
652 tok_expect(')');
653 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
654 if (fi) {
655 if (TYPE_BT(&fi->ret))
656 o_cast(TYPE_BT(&fi->ret));
657 ts_push(&fi->ret);
658 } else {
659 ts_push_bt(4 | BT_SIGNED);
663 static void readpost(void)
665 readprimary();
666 while (1) {
667 if (!tok_jmp('[')) {
668 readexpr();
669 tok_expect(']');
670 arrayderef();
671 continue;
673 if (!tok_jmp('(')) {
674 readcall();
675 continue;
677 if (!tok_jmp(TOK2("++"))) {
678 inc_post(O_ADD);
679 continue;
681 if (!tok_jmp(TOK2("--"))) {
682 inc_post(O_SUB);
683 continue;
685 if (!tok_jmp('.')) {
686 readfield();
687 continue;
689 if (!tok_jmp(TOK2("->"))) {
690 ts_de(1);
691 readfield();
692 continue;
694 break;
698 static void inc_pre(int op)
700 struct type t;
701 readpre();
702 /* copy the destination */
703 o_tmpcopy();
704 ts_push(&ts[nts - 1]);
705 /* increment by 1 or pointer size */
706 ts_pop_de(&t);
707 o_num(t.ptr > 0 ? type_szde(&t) : 1);
708 o_bop(op);
709 /* assign the result */
710 o_assign(TYPE_BT(&t));
711 ts_de(0);
714 static void readpre(void)
716 if (!tok_jmp('&')) {
717 struct type type;
718 readpre();
719 ts_pop(&type);
720 if (!type.addr)
721 err("cannot use the address\n");
722 type.ptr++;
723 type.addr = 0;
724 ts_push(&type);
725 return;
727 if (!tok_jmp('*')) {
728 struct type t;
729 readpre();
730 ts_pop(&t);
731 array2ptr(&t);
732 if (!t.ptr)
733 err("dereferencing non-pointer\n");
734 if (t.addr)
735 o_deref(TYPE_BT(&t));
736 t.ptr--;
737 t.addr = 1;
738 ts_push(&t);
739 return;
741 if (!tok_jmp('!')) {
742 readpre();
743 ts_pop_de(NULL);
744 o_uop(O_LNOT);
745 ts_push_bt(4 | BT_SIGNED);
746 return;
748 if (!tok_jmp('+')) {
749 readpre();
750 return;
752 if (!tok_jmp('-')) {
753 readpre();
754 ts_de(1);
755 o_uop(O_NEG);
756 return;
758 if (!tok_jmp('~')) {
759 readpre();
760 ts_de(1);
761 o_uop(O_NOT);
762 return;
764 if (!tok_jmp(TOK2("++"))) {
765 inc_pre(O_ADD);
766 return;
768 if (!tok_jmp(TOK2("--"))) {
769 inc_pre(O_SUB);
770 return;
772 if (!tok_jmp(TOK_SIZEOF)) {
773 struct type t;
774 int op = !tok_jmp('(');
775 if (readtype(&t)) {
776 nogen++;
777 if (op)
778 readexpr();
779 else
780 readpre();
781 nogen--;
782 ts_pop(&t);
784 ts_push_bt(4);
785 o_num(type_totsz(&t));
786 if (op)
787 tok_expect(')');
788 return;
790 readpost();
793 static void readmul(void)
795 readpre();
796 while (1) {
797 if (!tok_jmp('*')) {
798 readpre();
799 ts_binop(O_MUL);
800 continue;
802 if (!tok_jmp('/')) {
803 readpre();
804 ts_binop(O_DIV);
805 continue;
807 if (!tok_jmp('%')) {
808 readpre();
809 ts_binop(O_MOD);
810 continue;
812 break;
816 static void readadd(void)
818 readmul();
819 while (1) {
820 if (!tok_jmp('+')) {
821 readmul();
822 ts_addop(O_ADD);
823 continue;
825 if (!tok_jmp('-')) {
826 readmul();
827 ts_addop(O_SUB);
828 continue;
830 break;
834 static void shift(int op)
836 struct type t;
837 readadd();
838 ts_pop_de2(NULL, &t);
839 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
840 ts_push_bt(TYPE_BT(&t));
843 static void readshift(void)
845 readadd();
846 while (1) {
847 if (!tok_jmp(TOK2("<<"))) {
848 shift(O_SHL);
849 continue;
851 if (!tok_jmp(TOK2(">>"))) {
852 shift(O_SHR);
853 continue;
855 break;
859 static void cmp(int op)
861 struct type t1, t2;
862 int bt;
863 readshift();
864 ts_pop_de2(&t1, &t2);
865 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
866 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
867 ts_push_bt(4 | BT_SIGNED);
870 static void readcmp(void)
872 readshift();
873 while (1) {
874 if (!tok_jmp('<')) {
875 cmp(O_LT);
876 continue;
878 if (!tok_jmp('>')) {
879 cmp(O_GT);
880 continue;
882 if (!tok_jmp(TOK2("<="))) {
883 cmp(O_LE);
884 continue;
886 if (!tok_jmp(TOK2(">="))) {
887 cmp(O_GE);
888 continue;
890 break;
894 static void eq(int op)
896 readcmp();
897 ts_pop_de2(NULL, NULL);
898 o_bop(op);
899 ts_push_bt(4 | BT_SIGNED);
902 static void readeq(void)
904 readcmp();
905 while (1) {
906 if (!tok_jmp(TOK2("=="))) {
907 eq(O_EQ);
908 continue;
910 if (!tok_jmp(TOK2("!="))) {
911 eq(O_NEQ);
912 continue;
914 break;
918 static void readbitand(void)
920 readeq();
921 while (!tok_jmp('&')) {
922 readeq();
923 ts_binop(O_AND);
927 static void readxor(void)
929 readbitand();
930 while (!tok_jmp('^')) {
931 readbitand();
932 ts_binop(O_XOR);
936 static void readbitor(void)
938 readxor();
939 while (!tok_jmp('|')) {
940 readxor();
941 ts_binop(O_OR);
945 static void readand(void)
947 int l_out, l_fail;
948 readbitor();
949 if (tok_see() != TOK2("&&"))
950 return;
951 l_out = LABEL();
952 l_fail = LABEL();
953 o_fork();
954 ts_pop_de(NULL);
955 o_jz(l_fail);
956 while (!tok_jmp(TOK2("&&"))) {
957 readbitor();
958 ts_pop_de(NULL);
959 o_jz(l_fail);
961 o_num(1);
962 o_forkpush();
963 o_jmp(l_out);
964 o_label(l_fail);
965 o_num(0);
966 o_forkpush();
967 o_forkjoin();
968 o_label(l_out);
969 ts_push_bt(4 | BT_SIGNED);
972 static void reador(void)
974 int l_pass, l_end;
975 readand();
976 if (tok_see() != TOK2("||"))
977 return;
978 l_pass = LABEL();
979 l_end = LABEL();
980 o_fork();
981 ts_pop_de(NULL);
982 o_jnz(l_pass);
983 while (!tok_jmp(TOK2("||"))) {
984 readand();
985 ts_pop_de(NULL);
986 o_jnz(l_pass);
988 o_num(0);
989 o_forkpush();
990 o_jmp(l_end);
991 o_label(l_pass);
992 o_num(1);
993 o_forkpush();
994 o_forkjoin();
995 o_label(l_end);
996 ts_push_bt(4 | BT_SIGNED);
999 static void readcexpr(void);
1001 static int readcexpr_const(void)
1003 long c;
1004 if (o_popnum(&c))
1005 return -1;
1006 if (!c)
1007 nogen++;
1008 readcexpr();
1009 /* both branches yield the same type; so ignore the first */
1010 ts_pop_de(NULL);
1011 tok_expect(':');
1012 if (c)
1013 nogen++;
1014 else
1015 nogen--;
1016 readcexpr();
1017 /* making sure t->addr == 0 on both branches */
1018 ts_de(1);
1019 if (c)
1020 nogen--;
1021 return 0;
1024 static void readcexpr(void)
1026 reador();
1027 if (tok_jmp('?'))
1028 return;
1029 ncexpr++;
1030 ts_pop_de(NULL);
1031 o_fork();
1032 if (readcexpr_const()) {
1033 int l_fail = LABEL();
1034 int l_end = LABEL();
1035 struct type ret;
1036 o_jz(l_fail);
1037 readcexpr();
1038 /* both branches yield the same type; so ignore the first */
1039 ts_pop_de(&ret);
1040 if (!TYPE_VOID(&ret))
1041 o_forkpush();
1042 o_jmp(l_end);
1044 tok_expect(':');
1045 o_label(l_fail);
1046 readcexpr();
1047 /* making sure t->addr == 0 on both branches */
1048 ts_de(1);
1049 if (!TYPE_VOID(&ret)) {
1050 o_forkpush();
1051 o_forkjoin();
1053 o_label(l_end);
1055 ncexpr--;
1058 static void opassign(int op, int ptrop)
1060 struct type t = ts[nts - 1];
1061 o_tmpcopy();
1062 ts_push(&t);
1063 readexpr();
1064 if (op == O_ADD || op == O_SUB)
1065 ts_addop(op);
1066 else
1067 ts_binop(op);
1068 o_assign(TYPE_BT(&ts[nts - 2]));
1069 ts_pop(NULL);
1070 ts_de(0);
1073 static void doassign(void)
1075 struct type t = ts[nts - 1];
1076 if (!t.ptr && t.flags & T_STRUCT) {
1077 ts_pop(NULL);
1078 o_num(type_totsz(&t));
1079 o_memcpy();
1080 } else {
1081 ts_pop_de(NULL);
1082 o_assign(TYPE_BT(&ts[nts - 1]));
1083 ts_de(0);
1087 static void readexpr(void)
1089 readcexpr();
1090 if (!tok_jmp('=')) {
1091 readexpr();
1092 doassign();
1093 return;
1095 if (!tok_jmp(TOK2("+="))) {
1096 opassign(O_ADD, 1);
1097 return;
1099 if (!tok_jmp(TOK2("-="))) {
1100 opassign(O_SUB, 1);
1101 return;
1103 if (!tok_jmp(TOK2("*="))) {
1104 opassign(O_MUL, 0);
1105 return;
1107 if (!tok_jmp(TOK2("/="))) {
1108 opassign(O_DIV, 0);
1109 return;
1111 if (!tok_jmp(TOK2("%="))) {
1112 opassign(O_MOD, 0);
1113 return;
1115 if (!tok_jmp(TOK3("<<="))) {
1116 opassign(O_SHL, 0);
1117 return;
1119 if (!tok_jmp(TOK3(">>="))) {
1120 opassign(O_SHR, 0);
1121 return;
1123 if (!tok_jmp(TOK3("&="))) {
1124 opassign(O_AND, 0);
1125 return;
1127 if (!tok_jmp(TOK3("|="))) {
1128 opassign(O_OR, 0);
1129 return;
1131 if (!tok_jmp(TOK3("^="))) {
1132 opassign(O_XOR, 0);
1133 return;
1137 static void readestmt(void)
1139 do {
1140 o_tmpdrop(-1);
1141 nts = 0;
1142 readexpr();
1143 } while (!tok_jmp(','));
1146 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1148 static void globalinit(void *obj, int off, struct type *t)
1150 struct name *name = obj;
1151 char *elfname = *name->elfname ? name->elfname : name->name;
1152 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1153 struct type *t_de = &arrays[t->id].type;
1154 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1155 char *buf;
1156 int len;
1157 tok_expect(TOK_STR);
1158 tok_str(&buf, &len);
1159 o_dscpy(name->addr + off, buf, len);
1160 return;
1163 readexpr();
1164 o_dsset(elfname, off, TYPE_BT(t));
1165 ts_pop(NULL);
1168 static void readfunc(struct name *name, int flags);
1170 static void globaldef(void *data, struct name *name, unsigned flags)
1172 struct type *t = &name->type;
1173 char *elfname = *name->elfname ? name->elfname : name->name;
1174 int sz;
1175 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1176 if (~flags & F_EXTERN)
1177 arrays[t->id].n = initsize();
1178 sz = type_totsz(t);
1179 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1180 if (tok_see() == '=')
1181 name->addr = o_dsnew(elfname, sz, F_GLOBAL(flags));
1182 else
1183 o_bsnew(elfname, sz, F_GLOBAL(flags));
1185 global_add(name);
1186 if (!tok_jmp('='))
1187 initexpr(t, 0, name, globalinit);
1188 if (tok_see() == '{' && name->type.flags & T_FUNC)
1189 readfunc(name, flags);
1192 /* generate the address of local + off */
1193 static void o_localoff(long addr, int off)
1195 o_local(addr);
1196 if (off) {
1197 o_num(off);
1198 o_bop(O_ADD);
1202 static void localinit(void *obj, int off, struct type *t)
1204 long addr = *(long *) obj;
1205 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1206 struct type *t_de = &arrays[t->id].type;
1207 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1208 char *buf;
1209 int len;
1210 tok_expect(TOK_STR);
1211 tok_str(&buf, &len);
1212 o_localoff(addr, off);
1213 o_sym(tmp_str(buf, len));
1214 o_num(len);
1215 o_memcpy();
1216 o_tmpdrop(1);
1217 return;
1220 o_localoff(addr, off);
1221 ts_push(t);
1222 readexpr();
1223 doassign();
1224 ts_pop(NULL);
1225 o_tmpdrop(1);
1228 /* current function name */
1229 static char func_name[NAMELEN];
1231 static void localdef(void *data, struct name *name, unsigned flags)
1233 struct type *t = &name->type;
1234 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1235 global_add(name);
1236 return;
1238 if (flags & F_STATIC) {
1239 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1240 globaldef(data, name, flags);
1241 return;
1243 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1244 arrays[t->id].n = initsize();
1245 name->addr = o_mklocal(type_totsz(&name->type));
1246 local_add(name);
1247 if (!tok_jmp('=')) {
1248 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1249 o_local(name->addr);
1250 o_num(0);
1251 o_num(type_totsz(t));
1252 o_memset();
1253 o_tmpdrop(1);
1255 initexpr(t, 0, &name->addr, localinit);
1259 static void typedefdef(void *data, struct name *name, unsigned flags)
1261 typedef_add(name->name, &name->type);
1264 static void readstmt(void);
1266 static void readswitch(void)
1268 int o_break = l_break;
1269 long val_addr = o_mklocal(LONGSZ);
1270 struct type t;
1271 int ncases = 0; /* number of case labels */
1272 int l_failed = LABEL(); /* address of last failed jmp */
1273 int l_matched = LABEL(); /* address of last walk through jmp */
1274 int l_default = 0; /* default case label */
1275 l_break = LABEL();
1276 tok_expect('(');
1277 readexpr();
1278 ts_pop_de(&t);
1279 o_local(val_addr);
1280 o_tmpswap();
1281 o_assign(TYPE_BT(&t));
1282 ts_de(0);
1283 o_tmpdrop(1);
1284 tok_expect(')');
1285 tok_expect('{');
1286 while (tok_jmp('}')) {
1287 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1288 readstmt();
1289 continue;
1291 if (ncases)
1292 o_jmp(l_matched);
1293 if (tok_get() == TOK_CASE) {
1294 o_label(l_failed);
1295 l_failed = LABEL();
1296 caseexpr = 1;
1297 readexpr();
1298 ts_pop_de(NULL);
1299 caseexpr = 0;
1300 o_local(val_addr);
1301 o_deref(TYPE_BT(&t));
1302 o_bop(O_EQ);
1303 o_jz(l_failed);
1304 o_tmpdrop(1);
1305 } else {
1306 if (!ncases)
1307 o_jmp(l_failed);
1308 l_default = LABEL();
1309 o_label(l_default);
1311 tok_expect(':');
1312 o_label(l_matched);
1313 l_matched = LABEL();
1314 ncases++;
1316 o_rmlocal(val_addr, LONGSZ);
1317 o_jmp(l_break);
1318 o_label(l_failed);
1319 if (l_default)
1320 o_jmp(l_default);
1321 o_label(l_break);
1322 l_break = o_break;
1325 static char label_name[NLABELS][NAMELEN];
1326 static int label_ids[NLABELS];
1327 static int nlabels;
1329 static int label_id(char *name)
1331 int i;
1332 for (i = nlabels - 1; i >= 0; --i)
1333 if (!strcmp(label_name[i], name))
1334 return label_ids[i];
1335 strcpy(label_name[nlabels], name);
1336 label_ids[nlabels] = LABEL();
1337 return label_ids[nlabels++];
1340 static void readstmt(void)
1342 o_tmpdrop(-1);
1343 nts = 0;
1344 if (!tok_jmp('{')) {
1345 int _nlocals = nlocals;
1346 int _nglobals = nglobals;
1347 int _nenums = nenums;
1348 int _ntypedefs = ntypedefs;
1349 int _nstructs = nstructs;
1350 int _nfuncs = nfuncs;
1351 int _narrays = narrays;
1352 while (tok_jmp('}'))
1353 readstmt();
1354 nlocals = _nlocals;
1355 nenums = _nenums;
1356 ntypedefs = _ntypedefs;
1357 nstructs = _nstructs;
1358 nfuncs = _nfuncs;
1359 narrays = _narrays;
1360 nglobals = _nglobals;
1361 return;
1363 if (!readdefs(localdef, NULL)) {
1364 tok_expect(';');
1365 return;
1367 if (!tok_jmp(TOK_TYPEDEF)) {
1368 readdefs(typedefdef, NULL);
1369 tok_expect(';');
1370 return;
1372 if (!tok_jmp(TOK_IF)) {
1373 int l_fail = LABEL();
1374 int l_end = LABEL();
1375 tok_expect('(');
1376 readexpr();
1377 tok_expect(')');
1378 ts_pop_de(NULL);
1379 o_jz(l_fail);
1380 readstmt();
1381 if (!tok_jmp(TOK_ELSE)) {
1382 o_jmp(l_end);
1383 o_label(l_fail);
1384 readstmt();
1385 o_label(l_end);
1386 } else {
1387 o_label(l_fail);
1389 return;
1391 if (!tok_jmp(TOK_WHILE)) {
1392 int o_break = l_break;
1393 int o_cont = l_cont;
1394 l_break = LABEL();
1395 l_cont = LABEL();
1396 o_label(l_cont);
1397 tok_expect('(');
1398 readexpr();
1399 tok_expect(')');
1400 ts_pop_de(NULL);
1401 o_jz(l_break);
1402 readstmt();
1403 o_jmp(l_cont);
1404 o_label(l_break);
1405 l_break = o_break;
1406 l_cont = o_cont;
1407 return;
1409 if (!tok_jmp(TOK_DO)) {
1410 int o_break = l_break;
1411 int o_cont = l_cont;
1412 int l_beg = LABEL();
1413 l_break = LABEL();
1414 l_cont = LABEL();
1415 o_label(l_beg);
1416 readstmt();
1417 tok_expect(TOK_WHILE);
1418 tok_expect('(');
1419 o_label(l_cont);
1420 readexpr();
1421 ts_pop_de(NULL);
1422 o_jnz(l_beg);
1423 tok_expect(')');
1424 o_label(l_break);
1425 tok_expect(';');
1426 l_break = o_break;
1427 l_cont = o_cont;
1428 return;
1430 if (!tok_jmp(TOK_FOR)) {
1431 int o_break = l_break;
1432 int o_cont = l_cont;
1433 int l_check = LABEL(); /* for condition label */
1434 int l_body = LABEL(); /* for block label */
1435 l_cont = LABEL();
1436 l_break = LABEL();
1437 tok_expect('(');
1438 if (tok_see() != ';')
1439 readestmt();
1440 tok_expect(';');
1441 o_label(l_check);
1442 if (tok_see() != ';') {
1443 readestmt();
1444 ts_pop_de(NULL);
1445 o_jz(l_break);
1447 tok_expect(';');
1448 o_jmp(l_body);
1449 o_label(l_cont);
1450 if (tok_see() != ')')
1451 readestmt();
1452 tok_expect(')');
1453 o_jmp(l_check);
1454 o_label(l_body);
1455 readstmt();
1456 o_jmp(l_cont);
1457 o_label(l_break);
1458 l_break = o_break;
1459 l_cont = o_cont;
1460 return;
1462 if (!tok_jmp(TOK_SWITCH)) {
1463 readswitch();
1464 return;
1466 if (!tok_jmp(TOK_RETURN)) {
1467 int ret = tok_see() != ';';
1468 if (ret) {
1469 readexpr();
1470 ts_pop_de(NULL);
1472 tok_expect(';');
1473 o_ret(ret);
1474 return;
1476 if (!tok_jmp(TOK_BREAK)) {
1477 tok_expect(';');
1478 o_jmp(l_break);
1479 return;
1481 if (!tok_jmp(TOK_CONTINUE)) {
1482 tok_expect(';');
1483 o_jmp(l_cont);
1484 return;
1486 if (!tok_jmp(TOK_GOTO)) {
1487 tok_expect(TOK_NAME);
1488 o_jmp(label_id(tok_id()));
1489 tok_expect(';');
1490 return;
1492 readestmt();
1493 /* labels */
1494 if (!tok_jmp(':')) {
1495 o_label(label_id(tok_id()));
1496 return;
1498 tok_expect(';');
1501 static void readfunc(struct name *name, int flags)
1503 struct funcinfo *fi = &funcs[name->type.id];
1504 long beg = tok_addr();
1505 int i;
1506 strcpy(func_name, fi->name);
1507 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1508 for (i = 0; i < fi->nargs; i++) {
1509 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1510 strcpy(arg.name, fi->argnames[i]);
1511 local_add(&arg);
1513 /* first pass: collecting statistics */
1514 label = 0;
1515 nlabels = 0;
1516 o_pass1();
1517 readstmt();
1518 tok_jump(beg);
1519 /* second pass: generating code */
1520 label = 0;
1521 nlabels = 0;
1522 o_pass2();
1523 readstmt();
1524 o_func_end();
1525 func_name[0] = '\0';
1526 nlocals = 0;
1529 static void readdecl(void)
1531 if (!tok_jmp(TOK_TYPEDEF)) {
1532 readdefs(typedefdef, NULL);
1533 tok_expect(';');
1534 return;
1536 readdefs_int(globaldef, NULL);
1537 tok_jmp(';');
1540 static void parse(void)
1542 while (tok_see() != TOK_EOF)
1543 readdecl();
1546 static void compat_macros(void)
1548 cpp_define("__STDC__", "");
1549 cpp_define("__linux__", "");
1550 cpp_define(I_ARCH, "");
1552 /* ignored keywords */
1553 cpp_define("const", "");
1554 cpp_define("register", "");
1555 cpp_define("volatile", "");
1556 cpp_define("inline", "");
1557 cpp_define("restrict", "");
1558 cpp_define("__inline__", "");
1559 cpp_define("__restrict__", "");
1560 cpp_define("__attribute__(x)", "");
1561 cpp_define("__builtin_va_list__", "long");
1564 int main(int argc, char *argv[])
1566 char obj[128] = "";
1567 int ofd;
1568 int i = 1;
1569 compat_macros();
1570 while (i < argc && argv[i][0] == '-') {
1571 if (argv[i][1] == 'I')
1572 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1573 if (argv[i][1] == 'D') {
1574 char *name = argv[i] + 2;
1575 char *def = "";
1576 char *eq = strchr(name, '=');
1577 if (eq) {
1578 *eq = '\0';
1579 def = eq + 1;
1581 cpp_define(name, def);
1583 if (argv[i][1] == 'o')
1584 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1585 i++;
1587 if (i == argc)
1588 die("neatcc: no file given\n");
1589 if (cpp_init(argv[i]))
1590 die("neatcc: cannot open <%s>\n", argv[i]);
1591 parse();
1592 if (!*obj) {
1593 strcpy(obj, argv[i]);
1594 obj[strlen(obj) - 1] = 'o';
1596 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1597 o_write(ofd);
1598 close(ofd);
1599 return 0;
1603 /* parsing function and variable declarations */
1605 /* read the base type of a variable */
1606 static int basetype(struct type *type, unsigned *flags)
1608 int sign = 1;
1609 int size = 4;
1610 int done = 0;
1611 int i = 0;
1612 int isunion;
1613 char name[NAMELEN] = "";
1614 *flags = 0;
1615 type->flags = 0;
1616 type->ptr = 0;
1617 type->addr = 0;
1618 while (!done) {
1619 switch (tok_see()) {
1620 case TOK_STATIC:
1621 *flags |= F_STATIC;
1622 break;
1623 case TOK_EXTERN:
1624 *flags |= F_EXTERN;
1625 break;
1626 case TOK_VOID:
1627 sign = 0;
1628 size = 0;
1629 done = 1;
1630 break;
1631 case TOK_INT:
1632 done = 1;
1633 break;
1634 case TOK_CHAR:
1635 size = 1;
1636 done = 1;
1637 break;
1638 case TOK_SHORT:
1639 size = 2;
1640 break;
1641 case TOK_LONG:
1642 size = LONGSZ;
1643 break;
1644 case TOK_SIGNED:
1645 break;
1646 case TOK_UNSIGNED:
1647 sign = 0;
1648 break;
1649 case TOK_UNION:
1650 case TOK_STRUCT:
1651 isunion = tok_get() == TOK_UNION;
1652 if (!tok_jmp(TOK_NAME))
1653 strcpy(name, tok_id());
1654 if (tok_see() == '{')
1655 type->id = struct_create(name, isunion);
1656 else
1657 type->id = struct_find(name, isunion);
1658 type->flags |= T_STRUCT;
1659 type->bt = LONGSZ;
1660 return 0;
1661 case TOK_ENUM:
1662 tok_get();
1663 tok_jmp(TOK_NAME);
1664 if (tok_see() == '{')
1665 enum_create();
1666 type->bt = 4 | BT_SIGNED;
1667 return 0;
1668 default:
1669 if (tok_see() == TOK_NAME) {
1670 int id = typedef_find(tok_id());
1671 if (id != -1) {
1672 tok_get();
1673 memcpy(type, &typedefs[id].type,
1674 sizeof(*type));
1675 return 0;
1678 if (!i)
1679 return 1;
1680 done = 1;
1681 continue;
1683 i++;
1684 tok_get();
1686 type->bt = size | (sign ? BT_SIGNED : 0);
1687 return 0;
1690 static void readptrs(struct type *type)
1692 while (!tok_jmp('*')) {
1693 type->ptr++;
1694 if (!type->bt)
1695 type->bt = 1;
1699 /* read function arguments */
1700 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1702 int nargs = 0;
1703 tok_expect('(');
1704 *varg = 0;
1705 while (tok_see() != ')') {
1706 if (!tok_jmp(TOK3("..."))) {
1707 *varg = 1;
1708 break;
1710 if (readname(&args[nargs], argnames[nargs], NULL)) {
1711 /* argument has no type, assume int */
1712 tok_expect(TOK_NAME);
1713 memset(&args[nargs], 0, sizeof(struct type));
1714 args[nargs].bt = 4 | BT_SIGNED;
1715 strcpy(argnames[nargs], tok_id());
1717 /* argument arrays are pointers */
1718 array2ptr(&args[nargs]);
1719 nargs++;
1720 if (tok_jmp(','))
1721 break;
1723 tok_expect(')');
1724 /* void argument */
1725 if (nargs == 1 && !TYPE_BT(&args[0]))
1726 return 0;
1727 return nargs;
1730 /* read K&R function arguments */
1731 static void krdef(void *data, struct name *name, unsigned flags)
1733 struct funcinfo *fi = data;
1734 int i;
1735 for (i = 0; i < fi->nargs; i++)
1736 if (!strcmp(fi->argnames[i], name->name))
1737 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1741 * readarrays() parses array specifiers when reading a definition in
1742 * readname(). The "type" parameter contains the type contained in the
1743 * inner array; for instance, type in "int *a[10][20]" would be an int
1744 * pointer. When returning, the "type" parameter is changed to point
1745 * to the final array. The function returns a pointer to the type in
1746 * the inner array; this is useful when the type is not complete yet,
1747 * like when creating an array of function pointers as in
1748 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1750 static struct type *readarrays(struct type *type)
1752 long arsz[16];
1753 struct type *inner = NULL;
1754 int nar = 0;
1755 int i;
1756 while (!tok_jmp('[')) {
1757 long n = 0;
1758 if (tok_jmp(']')) {
1759 readexpr();
1760 ts_pop_de(NULL);
1761 if (o_popnum(&n))
1762 err("const expr expected\n");
1763 tok_expect(']');
1765 arsz[nar++] = n;
1767 for (i = nar - 1; i >= 0; i--) {
1768 type->id = array_add(type, arsz[i]);
1769 if (!inner)
1770 inner = &arrays[type->id].type;
1771 type->flags = T_ARRAY;
1772 type->bt = LONGSZ;
1773 type->ptr = 0;
1775 return inner;
1779 * readname() reads a variable definition; the name is copied into
1780 * "name" and the type is copied into "main" argument. The "base"
1781 * argument, if not NULL, indicates the base type of the variable.
1782 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1783 * "int". If NULL, basetype() is called directly to read the base
1784 * type of the variable. readname() returns zero, only if the
1785 * variable can be read.
1787 static int readname(struct type *main, char *name, struct type *base)
1789 struct type tpool[3];
1790 int npool = 0;
1791 struct type *type = &tpool[npool++];
1792 struct type *ptype = NULL; /* type inside parenthesis */
1793 struct type *btype = NULL; /* type before parenthesis */
1794 struct type *inner;
1795 unsigned flags;
1796 memset(tpool, 0, sizeof(tpool));
1797 if (name)
1798 *name = '\0';
1799 if (!base) {
1800 if (basetype(type, &flags))
1801 return 1;
1802 } else {
1803 memcpy(type, base, sizeof(*base));
1805 readptrs(type);
1806 if (!tok_jmp('(')) {
1807 btype = type;
1808 type = &tpool[npool++];
1809 ptype = type;
1810 readptrs(type);
1812 if (!tok_jmp(TOK_NAME) && name)
1813 strcpy(name, tok_id());
1814 inner = readarrays(type);
1815 if (ptype && inner)
1816 ptype = inner;
1817 if (ptype)
1818 tok_expect(')');
1819 if (tok_see() == '(') {
1820 struct type args[NARGS];
1821 char argnames[NARGS][NAMELEN];
1822 int varg = 0;
1823 int nargs = readargs(args, argnames, &varg);
1824 if (!ptype) {
1825 btype = type;
1826 type = &tpool[npool++];
1827 ptype = type;
1829 ptype->flags = T_FUNC;
1830 ptype->bt = LONGSZ;
1831 ptype->id = func_create(btype, name, argnames, args, nargs, varg);
1832 if (tok_see() != ';')
1833 while (tok_see() != '{' && !readdefs(krdef, &funcs[ptype->id]))
1834 tok_expect(';');
1835 } else {
1836 if (ptype && readarrays(type))
1837 array2ptr(type);
1839 memcpy(main, type, sizeof(*type));
1840 return 0;
1843 static int readtype(struct type *type)
1845 return readname(type, NULL, NULL);
1849 * readdef() reads a variable definitions statement. The definition
1850 * statement can appear in anywhere: global variables, function
1851 * local variables, struct fields, and typedefs. For each defined
1852 * variable, def() callback is called with the appropriate name
1853 * struct and flags; the callback should finish parsing the definition
1854 * by possibly reading the initializer expression and saving the name
1855 * struct.
1857 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1858 void *data)
1860 struct type base;
1861 unsigned base_flags;
1862 if (basetype(&base, &base_flags))
1863 return 1;
1864 if (tok_see() == ';' || tok_see() == '{')
1865 return 0;
1866 do {
1867 struct name name = {{""}};
1868 if (readname(&name.type, name.name, &base))
1869 break;
1870 def(data, &name, base_flags);
1871 } while (!tok_jmp(','));
1872 return 0;
1875 /* just like readdefs, but default to int type; for handling K&R functions */
1876 static int readdefs_int(void (*def)(void *data, struct name *name, unsigned flags),
1877 void *data)
1879 struct type base;
1880 unsigned flags = 0;
1881 if (basetype(&base, &flags)) {
1882 if (tok_see() != TOK_NAME)
1883 return 1;
1884 memset(&base, 0, sizeof(base));
1885 base.bt = 4 | BT_SIGNED;
1887 if (tok_see() != ';') {
1888 do {
1889 struct name name = {{""}};
1890 if (readname(&name.type, name.name, &base))
1891 break;
1892 def(data, &name, flags);
1893 } while (!tok_jmp(','));
1895 return 0;
1899 /* parsing initializer expressions */
1901 static void jumpbrace(void)
1903 int depth = 0;
1904 while (tok_see() != '}' || depth--)
1905 if (tok_get() == '{')
1906 depth++;
1907 tok_expect('}');
1910 /* compute the size of the initializer expression */
1911 static int initsize(void)
1913 long addr = tok_addr();
1914 int n = 0;
1915 if (tok_jmp('='))
1916 return 0;
1917 if (!tok_jmp(TOK_STR)) {
1918 tok_str(NULL, &n);
1919 tok_jump(addr);
1920 return n;
1922 tok_expect('{');
1923 while (tok_jmp('}')) {
1924 long idx = n;
1925 if (!tok_jmp('[')) {
1926 readexpr();
1927 ts_pop_de(NULL);
1928 o_popnum(&idx);
1929 tok_expect(']');
1930 tok_expect('=');
1932 if (n < idx + 1)
1933 n = idx + 1;
1934 while (tok_see() != '}' && tok_see() != ',')
1935 if (tok_get() == '{')
1936 jumpbrace();
1937 tok_jmp(',');
1939 tok_jump(addr);
1940 return n;
1943 static struct type *innertype(struct type *t)
1945 if (t->flags & T_ARRAY && !t->ptr)
1946 return innertype(&arrays[t->id].type);
1947 return t;
1950 /* read the initializer expression and initialize basic types using set() cb */
1951 static void initexpr(struct type *t, int off, void *obj,
1952 void (*set)(void *obj, int off, struct type *t))
1954 if (tok_jmp('{')) {
1955 set(obj, off, t);
1956 return;
1958 if (!t->ptr && t->flags & T_STRUCT) {
1959 struct structinfo *si = &structs[t->id];
1960 int i;
1961 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1962 struct name *field = &si->fields[i];
1963 if (!tok_jmp('.')) {
1964 tok_expect(TOK_NAME);
1965 field = struct_field(t->id, tok_id());
1966 tok_expect('=');
1968 initexpr(&field->type, off + field->addr, obj, set);
1969 if (tok_jmp(','))
1970 break;
1972 } else if (t->flags & T_ARRAY) {
1973 struct type *t_de = &arrays[t->id].type;
1974 int i;
1975 /* handling extra braces as in: char s[] = {"sth"} */
1976 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1977 set(obj, off, t);
1978 tok_expect('}');
1979 return;
1981 for (i = 0; tok_see() != '}'; i++) {
1982 long idx = i;
1983 struct type *it = t_de;
1984 if (!tok_jmp('[')) {
1985 readexpr();
1986 ts_pop_de(NULL);
1987 o_popnum(&idx);
1988 tok_expect(']');
1989 tok_expect('=');
1991 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1992 !(it->flags & T_ARRAY)))
1993 it = innertype(t_de);
1994 initexpr(it, off + type_totsz(it) * idx, obj, set);
1995 if (tok_jmp(','))
1996 break;
1999 tok_expect('}');