ncc.h: move array limits to ncc.h
[neatcc/cc.git] / ncc.c
blobf52b74aeb55731e807db468785366e0d92b412c1
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 void *dat;
467 sprintf(name, "__neatcc.s%d", id++);
468 dat = o_mkdat(name, len, 0);
469 memcpy(dat, buf, len);
470 return name;
473 static void readprimary(void)
475 if (!tok_jmp(TOK_NUM)) {
476 long n;
477 int bt = tok_num(&n);
478 ts_push_bt(bt);
479 o_num(n);
480 return;
482 if (!tok_jmp(TOK_STR)) {
483 struct type t = {}; /* char type inside the arrays */
484 struct type a = {}; /* the char array type */
485 char buf[STRLEN];
486 int len = tok_str(buf);
487 t.bt = 1 | BT_SIGNED;
488 a.id = array_add(&t, len);
489 a.flags = T_ARRAY;
490 ts_push(&a);
491 o_sym(tmp_str(buf, len));
492 return;
494 if (!tok_jmp(TOK_NAME)) {
495 struct name unkn = {""};
496 char *name = unkn.name;
497 int n;
498 strcpy(name, tok_id());
499 /* don't search for labels here */
500 if (!ncexpr && !caseexpr && tok_see() == ':')
501 return;
502 if ((n = local_find(name)) != -1) {
503 struct name *l = &locals[n];
504 o_local(l->addr);
505 ts_push_addr(&l->type);
506 return;
508 if ((n = global_find(name)) != -1) {
509 struct name *g = &globals[n];
510 o_sym(*g->elfname ? g->elfname : g->name);
511 ts_push_addr(&g->type);
512 return;
514 if (!enum_find(&n, name)) {
515 ts_push_bt(4 | BT_SIGNED);
516 o_num(n);
517 return;
519 if (tok_see() != '(')
520 err("unknown symbol <%s>\n", name);
521 global_add(&unkn);
522 ts_push_bt(LONGSZ);
523 o_sym(unkn.name);
524 return;
526 if (!tok_jmp('(')) {
527 struct type t;
528 if (!readtype(&t)) {
529 struct type o;
530 tok_expect(')');
531 readpre();
532 ts_pop_de(&o);
533 ts_push(&t);
534 if (!t.ptr || !o.ptr)
535 o_cast(TYPE_BT(&t));
536 } else {
537 readexpr();
538 while (tok_jmp(')')) {
539 tok_expect(',');
540 ts_pop(NULL);
541 o_tmpdrop(1);
542 readexpr();
545 return;
549 static void arrayderef(void)
551 struct type t;
552 int sz;
553 ts_pop_de(NULL);
554 ts_pop(&t);
555 if (!(t.flags & T_ARRAY && !t.ptr) && t.addr) {
556 o_tmpswap();
557 o_deref(TYPE_BT(&t));
558 o_tmpswap();
560 array2ptr(&t);
561 t.ptr--;
562 sz = type_totsz(&t);
563 t.addr = 1;
564 if (sz > 1) {
565 o_num(sz);
566 o_bop(O_MUL);
568 o_bop(O_ADD);
569 ts_push(&t);
572 static void inc_post(int op)
574 struct type t = ts[nts - 1];
575 /* pushing the value before inc */
576 o_tmpcopy();
577 ts_de(1);
578 o_load();
579 o_tmpswap();
581 /* increment by 1 or pointer size */
582 o_tmpcopy();
583 ts_push(&t);
584 ts_pop_de(&t);
585 o_num(t.ptr > 0 ? type_szde(&t) : 1);
586 o_bop(op);
588 /* assign back */
589 o_assign(TYPE_BT(&t));
590 o_tmpdrop(1);
593 static void readfield(void)
595 struct name *field;
596 struct type t;
597 tok_expect(TOK_NAME);
598 ts_pop(&t);
599 array2ptr(&t);
600 field = struct_field(t.id, tok_id());
601 if (field->addr) {
602 o_num(field->addr);
603 o_bop(O_ADD);
605 ts_push_addr(&field->type);
608 static struct funcinfo {
609 struct type args[NARGS];
610 struct type ret;
611 int nargs;
612 int varg;
613 /* function and argument names; useful only when defining */
614 char argnames[NARGS][NAMELEN];
615 char name[NAMELEN];
616 } funcs[NFUNCS];
617 static int nfuncs;
619 static int func_create(struct type *ret, char *name, char argnames[][NAMELEN],
620 struct type *args, int nargs, int varg)
622 struct funcinfo *fi = &funcs[nfuncs++];
623 int i;
624 if (nfuncs >= NFUNCS)
625 err("nomem: NFUNCS reached!\n");
626 memcpy(&fi->ret, ret, sizeof(*ret));
627 for (i = 0; i < nargs; i++)
628 memcpy(&fi->args[i], &args[i], sizeof(*ret));
629 fi->nargs = nargs;
630 fi->varg = varg;
631 strcpy(fi->name, name ? name : "");
632 for (i = 0; i < nargs; i++)
633 strcpy(fi->argnames[i], argnames[i]);
634 return fi - funcs;
637 static void readcall(void)
639 struct type t;
640 struct funcinfo *fi;
641 int argc = 0;
642 ts_pop(&t);
643 if (t.flags & T_FUNC && t.ptr > 0)
644 o_deref(LONGSZ);
645 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
646 if (tok_see() != ')') {
647 do {
648 readexpr();
649 ts_pop_de(NULL);
650 argc++;
651 } while (!tok_jmp(','));
653 tok_expect(')');
654 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
655 if (fi) {
656 if (TYPE_BT(&fi->ret))
657 o_cast(TYPE_BT(&fi->ret));
658 ts_push(&fi->ret);
659 } else {
660 ts_push_bt(4 | BT_SIGNED);
664 static void readpost(void)
666 readprimary();
667 while (1) {
668 if (!tok_jmp('[')) {
669 readexpr();
670 tok_expect(']');
671 arrayderef();
672 continue;
674 if (!tok_jmp('(')) {
675 readcall();
676 continue;
678 if (!tok_jmp(TOK2("++"))) {
679 inc_post(O_ADD);
680 continue;
682 if (!tok_jmp(TOK2("--"))) {
683 inc_post(O_SUB);
684 continue;
686 if (!tok_jmp('.')) {
687 readfield();
688 continue;
690 if (!tok_jmp(TOK2("->"))) {
691 ts_de(1);
692 readfield();
693 continue;
695 break;
699 static void inc_pre(int op)
701 struct type t;
702 readpre();
703 /* copy the destination */
704 o_tmpcopy();
705 ts_push(&ts[nts - 1]);
706 /* increment by 1 or pointer size */
707 ts_pop_de(&t);
708 o_num(t.ptr > 0 ? type_szde(&t) : 1);
709 o_bop(op);
710 /* assign the result */
711 o_assign(TYPE_BT(&t));
712 ts_de(0);
715 static void readpre(void)
717 if (!tok_jmp('&')) {
718 struct type type;
719 readpre();
720 ts_pop(&type);
721 if (!type.addr)
722 err("cannot use the address\n");
723 type.ptr++;
724 type.addr = 0;
725 ts_push(&type);
726 return;
728 if (!tok_jmp('*')) {
729 struct type t;
730 readpre();
731 ts_pop(&t);
732 array2ptr(&t);
733 if (!t.ptr)
734 err("dereferencing non-pointer\n");
735 if (t.addr)
736 o_deref(TYPE_BT(&t));
737 t.ptr--;
738 t.addr = 1;
739 ts_push(&t);
740 return;
742 if (!tok_jmp('!')) {
743 readpre();
744 ts_pop_de(NULL);
745 o_uop(O_LNOT);
746 ts_push_bt(4 | BT_SIGNED);
747 return;
749 if (!tok_jmp('+')) {
750 readpre();
751 return;
753 if (!tok_jmp('-')) {
754 readpre();
755 ts_de(1);
756 o_uop(O_NEG);
757 return;
759 if (!tok_jmp('~')) {
760 readpre();
761 ts_de(1);
762 o_uop(O_NOT);
763 return;
765 if (!tok_jmp(TOK2("++"))) {
766 inc_pre(O_ADD);
767 return;
769 if (!tok_jmp(TOK2("--"))) {
770 inc_pre(O_SUB);
771 return;
773 if (!tok_jmp(TOK_SIZEOF)) {
774 struct type t;
775 int op = !tok_jmp('(');
776 if (readtype(&t)) {
777 nogen++;
778 if (op)
779 readexpr();
780 else
781 readpre();
782 nogen--;
783 ts_pop(&t);
785 ts_push_bt(4);
786 o_num(type_totsz(&t));
787 if (op)
788 tok_expect(')');
789 return;
791 readpost();
794 static void readmul(void)
796 readpre();
797 while (1) {
798 if (!tok_jmp('*')) {
799 readpre();
800 ts_binop(O_MUL);
801 continue;
803 if (!tok_jmp('/')) {
804 readpre();
805 ts_binop(O_DIV);
806 continue;
808 if (!tok_jmp('%')) {
809 readpre();
810 ts_binop(O_MOD);
811 continue;
813 break;
817 static void readadd(void)
819 readmul();
820 while (1) {
821 if (!tok_jmp('+')) {
822 readmul();
823 ts_addop(O_ADD);
824 continue;
826 if (!tok_jmp('-')) {
827 readmul();
828 ts_addop(O_SUB);
829 continue;
831 break;
835 static void shift(int op)
837 struct type t;
838 readadd();
839 ts_pop_de2(NULL, &t);
840 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
841 ts_push_bt(TYPE_BT(&t));
844 static void readshift(void)
846 readadd();
847 while (1) {
848 if (!tok_jmp(TOK2("<<"))) {
849 shift(O_SHL);
850 continue;
852 if (!tok_jmp(TOK2(">>"))) {
853 shift(O_SHR);
854 continue;
856 break;
860 static void cmp(int op)
862 struct type t1, t2;
863 int bt;
864 readshift();
865 ts_pop_de2(&t1, &t2);
866 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
867 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
868 ts_push_bt(4 | BT_SIGNED);
871 static void readcmp(void)
873 readshift();
874 while (1) {
875 if (!tok_jmp('<')) {
876 cmp(O_LT);
877 continue;
879 if (!tok_jmp('>')) {
880 cmp(O_GT);
881 continue;
883 if (!tok_jmp(TOK2("<="))) {
884 cmp(O_LE);
885 continue;
887 if (!tok_jmp(TOK2(">="))) {
888 cmp(O_GE);
889 continue;
891 break;
895 static void eq(int op)
897 readcmp();
898 ts_pop_de2(NULL, NULL);
899 o_bop(op);
900 ts_push_bt(4 | BT_SIGNED);
903 static void readeq(void)
905 readcmp();
906 while (1) {
907 if (!tok_jmp(TOK2("=="))) {
908 eq(O_EQ);
909 continue;
911 if (!tok_jmp(TOK2("!="))) {
912 eq(O_NEQ);
913 continue;
915 break;
919 static void readbitand(void)
921 readeq();
922 while (!tok_jmp('&')) {
923 readeq();
924 ts_binop(O_AND);
928 static void readxor(void)
930 readbitand();
931 while (!tok_jmp('^')) {
932 readbitand();
933 ts_binop(O_XOR);
937 static void readbitor(void)
939 readxor();
940 while (!tok_jmp('|')) {
941 readxor();
942 ts_binop(O_OR);
946 static void readand(void)
948 int l_out = LABEL();
949 int l_fail = LABEL();
950 readbitor();
951 if (tok_see() != TOK2("&&"))
952 return;
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 = LABEL();
975 int l_end = LABEL();
976 readand();
977 if (tok_see() != TOK2("||"))
978 return;
979 o_fork();
980 ts_pop_de(NULL);
981 o_jnz(l_pass);
982 while (!tok_jmp(TOK2("||"))) {
983 readand();
984 ts_pop_de(NULL);
985 o_jnz(l_pass);
987 o_num(0);
988 o_forkpush();
989 o_jmp(l_end);
990 o_label(l_pass);
991 o_num(1);
992 o_forkpush();
993 o_forkjoin();
994 o_label(l_end);
995 ts_push_bt(4 | BT_SIGNED);
998 static void readcexpr(void);
1000 static int readcexpr_const(void)
1002 long c;
1003 if (o_popnum(&c))
1004 return -1;
1005 if (!c)
1006 nogen++;
1007 readcexpr();
1008 /* both branches yield the same type; so ignore the first */
1009 ts_pop_de(NULL);
1010 tok_expect(':');
1011 if (c)
1012 nogen++;
1013 else
1014 nogen--;
1015 readcexpr();
1016 /* making sure t->addr == 0 on both branches */
1017 ts_de(1);
1018 if (c)
1019 nogen--;
1020 return 0;
1023 static void readcexpr(void)
1025 reador();
1026 if (tok_jmp('?'))
1027 return;
1028 ncexpr++;
1029 ts_pop_de(NULL);
1030 o_fork();
1031 if (readcexpr_const()) {
1032 int l_fail = LABEL();
1033 int l_end = LABEL();
1034 struct type ret;
1035 o_jz(l_fail);
1036 readcexpr();
1037 /* both branches yield the same type; so ignore the first */
1038 ts_pop_de(&ret);
1039 if (!TYPE_VOID(&ret))
1040 o_forkpush();
1041 o_jmp(l_end);
1043 tok_expect(':');
1044 o_label(l_fail);
1045 readcexpr();
1046 /* making sure t->addr == 0 on both branches */
1047 ts_de(1);
1048 if (!TYPE_VOID(&ret)) {
1049 o_forkpush();
1050 o_forkjoin();
1052 o_label(l_end);
1054 ncexpr--;
1057 static void opassign(int op, int ptrop)
1059 struct type t = ts[nts - 1];
1060 o_tmpcopy();
1061 ts_push(&t);
1062 readexpr();
1063 if (op == O_ADD || op == O_SUB)
1064 ts_addop(op);
1065 else
1066 ts_binop(op);
1067 o_assign(TYPE_BT(&ts[nts - 2]));
1068 ts_pop(NULL);
1069 ts_de(0);
1072 static void doassign(void)
1074 struct type t = ts[nts - 1];
1075 if (!t.ptr && t.flags & T_STRUCT) {
1076 ts_pop(NULL);
1077 o_num(type_totsz(&t));
1078 o_memcpy();
1079 } else {
1080 ts_pop_de(NULL);
1081 o_assign(TYPE_BT(&ts[nts - 1]));
1082 ts_de(0);
1086 static void readexpr(void)
1088 readcexpr();
1089 if (!tok_jmp('=')) {
1090 readexpr();
1091 doassign();
1092 return;
1094 if (!tok_jmp(TOK2("+="))) {
1095 opassign(O_ADD, 1);
1096 return;
1098 if (!tok_jmp(TOK2("-="))) {
1099 opassign(O_SUB, 1);
1100 return;
1102 if (!tok_jmp(TOK2("*="))) {
1103 opassign(O_MUL, 0);
1104 return;
1106 if (!tok_jmp(TOK2("/="))) {
1107 opassign(O_DIV, 0);
1108 return;
1110 if (!tok_jmp(TOK2("%="))) {
1111 opassign(O_MOD, 0);
1112 return;
1114 if (!tok_jmp(TOK3("<<="))) {
1115 opassign(O_SHL, 0);
1116 return;
1118 if (!tok_jmp(TOK3(">>="))) {
1119 opassign(O_SHR, 0);
1120 return;
1122 if (!tok_jmp(TOK3("&="))) {
1123 opassign(O_AND, 0);
1124 return;
1126 if (!tok_jmp(TOK3("|="))) {
1127 opassign(O_OR, 0);
1128 return;
1130 if (!tok_jmp(TOK3("^="))) {
1131 opassign(O_XOR, 0);
1132 return;
1136 static void readestmt(void)
1138 do {
1139 o_tmpdrop(-1);
1140 nts = 0;
1141 readexpr();
1142 } while (!tok_jmp(','));
1145 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1147 static void globalinit(void *obj, int off, struct type *t)
1149 struct name *name = obj;
1150 char *elfname = *name->elfname ? name->elfname : name->name;
1151 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1152 struct type *t_de = &arrays[t->id].type;
1153 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1154 char buf[STRLEN];
1155 int len;
1156 tok_expect(TOK_STR);
1157 len = tok_str(buf);
1158 memcpy((void *) name->addr + off, buf, len);
1159 return;
1162 readexpr();
1163 o_datset(elfname, off, TYPE_BT(t));
1164 ts_pop(NULL);
1167 static void readfunc(struct name *name, int flags);
1169 static void globaldef(void *data, struct name *name, unsigned flags)
1171 struct type *t = &name->type;
1172 char *elfname = *name->elfname ? name->elfname : name->name;
1173 int sz;
1174 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1175 if (~flags & F_EXTERN)
1176 arrays[t->id].n = initsize();
1177 sz = type_totsz(t);
1178 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1179 if (tok_see() == '=')
1180 name->addr = (long) o_mkdat(elfname, sz, F_GLOBAL(flags));
1181 else
1182 o_mkbss(elfname, sz, F_GLOBAL(flags));
1184 global_add(name);
1185 if (!tok_jmp('='))
1186 initexpr(t, 0, name, globalinit);
1187 if (tok_see() == '{' && name->type.flags & T_FUNC)
1188 readfunc(name, flags);
1191 /* generate the address of local + off */
1192 static void o_localoff(long addr, int off)
1194 o_local(addr);
1195 if (off) {
1196 o_num(off);
1197 o_bop(O_ADD);
1201 static void localinit(void *obj, int off, struct type *t)
1203 long addr = *(long *) obj;
1204 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1205 struct type *t_de = &arrays[t->id].type;
1206 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1207 char buf[STRLEN];
1208 int len;
1209 tok_expect(TOK_STR);
1210 len = tok_str(buf);
1211 o_localoff(addr, off);
1212 o_sym(tmp_str(buf, len));
1213 o_num(len);
1214 o_memcpy();
1215 o_tmpdrop(1);
1216 return;
1219 o_localoff(addr, off);
1220 ts_push(t);
1221 readexpr();
1222 doassign();
1223 ts_pop(NULL);
1224 o_tmpdrop(1);
1227 /* current function name */
1228 static char func_name[NAMELEN];
1230 static void localdef(void *data, struct name *name, unsigned flags)
1232 struct type *t = &name->type;
1233 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1234 global_add(name);
1235 return;
1237 if (flags & F_STATIC) {
1238 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1239 globaldef(data, name, flags);
1240 return;
1242 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1243 arrays[t->id].n = initsize();
1244 name->addr = o_mklocal(type_totsz(&name->type));
1245 local_add(name);
1246 if (!tok_jmp('=')) {
1247 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1248 o_local(name->addr);
1249 o_num(0);
1250 o_num(type_totsz(t));
1251 o_memset();
1252 o_tmpdrop(1);
1254 initexpr(t, 0, &name->addr, localinit);
1258 static void typedefdef(void *data, struct name *name, unsigned flags)
1260 typedef_add(name->name, &name->type);
1263 static void readstmt(void);
1265 static void readswitch(void)
1267 int o_break = l_break;
1268 long val_addr = o_mklocal(LONGSZ);
1269 struct type t;
1270 int ncases = 0; /* number of case labels */
1271 int l_failed = LABEL(); /* address of last failed jmp */
1272 int l_matched = LABEL(); /* address of last walk through jmp */
1273 int l_default = 0; /* default case label */
1274 l_break = LABEL();
1275 tok_expect('(');
1276 readexpr();
1277 ts_pop_de(&t);
1278 o_local(val_addr);
1279 o_tmpswap();
1280 o_assign(TYPE_BT(&t));
1281 ts_de(0);
1282 o_tmpdrop(1);
1283 tok_expect(')');
1284 tok_expect('{');
1285 while (tok_jmp('}')) {
1286 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1287 readstmt();
1288 continue;
1290 if (ncases)
1291 o_jmp(l_matched);
1292 if (tok_get() == TOK_CASE) {
1293 o_label(l_failed);
1294 l_failed = LABEL();
1295 caseexpr = 1;
1296 readexpr();
1297 ts_pop_de(NULL);
1298 caseexpr = 0;
1299 o_local(val_addr);
1300 o_deref(TYPE_BT(&t));
1301 o_bop(O_EQ);
1302 o_jz(l_failed);
1303 o_tmpdrop(1);
1304 } else {
1305 if (!ncases)
1306 o_jmp(l_failed);
1307 l_default = LABEL();
1308 o_label(l_default);
1310 tok_expect(':');
1311 o_label(l_matched);
1312 l_matched = LABEL();
1313 ncases++;
1315 o_rmlocal(val_addr, LONGSZ);
1316 o_jmp(l_break);
1317 o_label(l_failed);
1318 if (l_default)
1319 o_jmp(l_default);
1320 o_label(l_break);
1321 l_break = o_break;
1324 static char label_name[NLABELS][NAMELEN];
1325 static int label_ids[NLABELS];
1326 static int nlabels;
1328 static int label_id(char *name)
1330 int i;
1331 for (i = nlabels - 1; i >= 0; --i)
1332 if (!strcmp(label_name[i], name))
1333 return label_ids[i];
1334 strcpy(label_name[nlabels], name);
1335 label_ids[nlabels] = LABEL();
1336 return label_ids[nlabels++];
1339 static void readstmt(void)
1341 o_tmpdrop(-1);
1342 nts = 0;
1343 if (!tok_jmp('{')) {
1344 int _nlocals = nlocals;
1345 int _nglobals = nglobals;
1346 int _nenums = nenums;
1347 int _ntypedefs = ntypedefs;
1348 int _nstructs = nstructs;
1349 int _nfuncs = nfuncs;
1350 int _narrays = narrays;
1351 while (tok_jmp('}'))
1352 readstmt();
1353 nlocals = _nlocals;
1354 nenums = _nenums;
1355 ntypedefs = _ntypedefs;
1356 nstructs = _nstructs;
1357 nfuncs = _nfuncs;
1358 narrays = _narrays;
1359 nglobals = _nglobals;
1360 return;
1362 if (!readdefs(localdef, NULL)) {
1363 tok_expect(';');
1364 return;
1366 if (!tok_jmp(TOK_TYPEDEF)) {
1367 readdefs(typedefdef, NULL);
1368 tok_expect(';');
1369 return;
1371 if (!tok_jmp(TOK_IF)) {
1372 int l_fail = LABEL();
1373 int l_end = LABEL();
1374 tok_expect('(');
1375 readexpr();
1376 tok_expect(')');
1377 ts_pop_de(NULL);
1378 o_jz(l_fail);
1379 readstmt();
1380 if (!tok_jmp(TOK_ELSE)) {
1381 o_jmp(l_end);
1382 o_label(l_fail);
1383 readstmt();
1384 o_label(l_end);
1385 } else {
1386 o_label(l_fail);
1388 return;
1390 if (!tok_jmp(TOK_WHILE)) {
1391 int o_break = l_break;
1392 int o_cont = l_cont;
1393 l_break = LABEL();
1394 l_cont = LABEL();
1395 o_label(l_cont);
1396 tok_expect('(');
1397 readexpr();
1398 tok_expect(')');
1399 ts_pop_de(NULL);
1400 o_jz(l_break);
1401 readstmt();
1402 o_jmp(l_cont);
1403 o_label(l_break);
1404 l_break = o_break;
1405 l_cont = o_cont;
1406 return;
1408 if (!tok_jmp(TOK_DO)) {
1409 int o_break = l_break;
1410 int o_cont = l_cont;
1411 int l_beg = LABEL();
1412 l_break = LABEL();
1413 l_cont = LABEL();
1414 o_label(l_beg);
1415 readstmt();
1416 tok_expect(TOK_WHILE);
1417 tok_expect('(');
1418 o_label(l_cont);
1419 readexpr();
1420 ts_pop_de(NULL);
1421 o_jnz(l_beg);
1422 tok_expect(')');
1423 o_label(l_break);
1424 tok_expect(';');
1425 l_break = o_break;
1426 l_cont = o_cont;
1427 return;
1429 if (!tok_jmp(TOK_FOR)) {
1430 int o_break = l_break;
1431 int o_cont = l_cont;
1432 int l_check = LABEL(); /* for condition label */
1433 int l_body = LABEL(); /* for block label */
1434 l_cont = LABEL();
1435 l_break = LABEL();
1436 tok_expect('(');
1437 if (tok_see() != ';')
1438 readestmt();
1439 tok_expect(';');
1440 o_label(l_check);
1441 if (tok_see() != ';') {
1442 readestmt();
1443 ts_pop_de(NULL);
1444 o_jz(l_break);
1446 tok_expect(';');
1447 o_jmp(l_body);
1448 o_label(l_cont);
1449 if (tok_see() != ')')
1450 readestmt();
1451 tok_expect(')');
1452 o_jmp(l_check);
1453 o_label(l_body);
1454 readstmt();
1455 o_jmp(l_cont);
1456 o_label(l_break);
1457 l_break = o_break;
1458 l_cont = o_cont;
1459 return;
1461 if (!tok_jmp(TOK_SWITCH)) {
1462 readswitch();
1463 return;
1465 if (!tok_jmp(TOK_RETURN)) {
1466 int ret = tok_see() != ';';
1467 if (ret) {
1468 readexpr();
1469 ts_pop_de(NULL);
1471 tok_expect(';');
1472 o_ret(ret);
1473 return;
1475 if (!tok_jmp(TOK_BREAK)) {
1476 tok_expect(';');
1477 o_jmp(l_break);
1478 return;
1480 if (!tok_jmp(TOK_CONTINUE)) {
1481 tok_expect(';');
1482 o_jmp(l_cont);
1483 return;
1485 if (!tok_jmp(TOK_GOTO)) {
1486 tok_expect(TOK_NAME);
1487 o_jmp(label_id(tok_id()));
1488 tok_expect(';');
1489 return;
1491 readestmt();
1492 /* labels */
1493 if (!tok_jmp(':')) {
1494 o_label(label_id(tok_id()));
1495 return;
1497 tok_expect(';');
1500 static void readfunc(struct name *name, int flags)
1502 struct funcinfo *fi = &funcs[name->type.id];
1503 long beg = tok_addr();
1504 int i;
1505 strcpy(func_name, fi->name);
1506 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1507 for (i = 0; i < fi->nargs; i++) {
1508 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1509 strcpy(arg.name, fi->argnames[i]);
1510 local_add(&arg);
1512 /* first pass: collecting statistics */
1513 o_pass1();
1514 readstmt();
1515 tok_jump(beg);
1516 /* second pass: generating code */
1517 o_pass2();
1518 readstmt();
1519 o_func_end();
1520 func_name[0] = '\0';
1521 nlocals = 0;
1522 label = 0;
1523 nlabels = 0;
1526 static void readdecl(void)
1528 if (!tok_jmp(TOK_TYPEDEF)) {
1529 readdefs(typedefdef, NULL);
1530 tok_expect(';');
1531 return;
1533 readdefs_int(globaldef, NULL);
1534 tok_jmp(';');
1537 static void parse(void)
1539 while (tok_see() != TOK_EOF)
1540 readdecl();
1543 static void compat_macros(void)
1545 cpp_define("__STDC__", "");
1546 cpp_define("__linux__", "");
1547 cpp_define(I_ARCH, "");
1549 /* ignored keywords */
1550 cpp_define("const", "");
1551 cpp_define("register", "");
1552 cpp_define("volatile", "");
1553 cpp_define("inline", "");
1554 cpp_define("restrict", "");
1555 cpp_define("__inline__", "");
1556 cpp_define("__restrict__", "");
1557 cpp_define("__attribute__(x)", "");
1558 cpp_define("__builtin_va_list__", "long");
1561 int main(int argc, char *argv[])
1563 char obj[128] = "";
1564 int ofd;
1565 int i = 1;
1566 compat_macros();
1567 while (i < argc && argv[i][0] == '-') {
1568 if (argv[i][1] == 'I')
1569 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1570 if (argv[i][1] == 'D') {
1571 char *name = argv[i] + 2;
1572 char *def = "";
1573 char *eq = strchr(name, '=');
1574 if (eq) {
1575 *eq = '\0';
1576 def = eq + 1;
1578 cpp_define(name, def);
1580 if (argv[i][1] == 'o')
1581 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1582 i++;
1584 if (i == argc)
1585 die("neatcc: no file given\n");
1586 if (cpp_init(argv[i]))
1587 die("neatcc: cannot open <%s>\n", argv[i]);
1588 parse();
1589 if (!*obj) {
1590 strcpy(obj, argv[i]);
1591 obj[strlen(obj) - 1] = 'o';
1593 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1594 o_write(ofd);
1595 close(ofd);
1596 return 0;
1600 /* parsing function and variable declarations */
1602 /* read the base type of a variable */
1603 static int basetype(struct type *type, unsigned *flags)
1605 int sign = 1;
1606 int size = 4;
1607 int done = 0;
1608 int i = 0;
1609 int isunion;
1610 char name[NAMELEN] = "";
1611 *flags = 0;
1612 type->flags = 0;
1613 type->ptr = 0;
1614 type->addr = 0;
1615 while (!done) {
1616 switch (tok_see()) {
1617 case TOK_STATIC:
1618 *flags |= F_STATIC;
1619 break;
1620 case TOK_EXTERN:
1621 *flags |= F_EXTERN;
1622 break;
1623 case TOK_VOID:
1624 sign = 0;
1625 size = 0;
1626 done = 1;
1627 break;
1628 case TOK_INT:
1629 done = 1;
1630 break;
1631 case TOK_CHAR:
1632 size = 1;
1633 done = 1;
1634 break;
1635 case TOK_SHORT:
1636 size = 2;
1637 break;
1638 case TOK_LONG:
1639 size = LONGSZ;
1640 break;
1641 case TOK_SIGNED:
1642 break;
1643 case TOK_UNSIGNED:
1644 sign = 0;
1645 break;
1646 case TOK_UNION:
1647 case TOK_STRUCT:
1648 isunion = tok_get() == TOK_UNION;
1649 if (!tok_jmp(TOK_NAME))
1650 strcpy(name, tok_id());
1651 if (tok_see() == '{')
1652 type->id = struct_create(name, isunion);
1653 else
1654 type->id = struct_find(name, isunion);
1655 type->flags |= T_STRUCT;
1656 type->bt = LONGSZ;
1657 return 0;
1658 case TOK_ENUM:
1659 tok_get();
1660 tok_jmp(TOK_NAME);
1661 if (tok_see() == '{')
1662 enum_create();
1663 type->bt = 4 | BT_SIGNED;
1664 return 0;
1665 default:
1666 if (tok_see() == TOK_NAME) {
1667 int id = typedef_find(tok_id());
1668 if (id != -1) {
1669 tok_get();
1670 memcpy(type, &typedefs[id].type,
1671 sizeof(*type));
1672 return 0;
1675 if (!i)
1676 return 1;
1677 done = 1;
1678 continue;
1680 i++;
1681 tok_get();
1683 type->bt = size | (sign ? BT_SIGNED : 0);
1684 return 0;
1687 static void readptrs(struct type *type)
1689 while (!tok_jmp('*')) {
1690 type->ptr++;
1691 if (!type->bt)
1692 type->bt = 1;
1696 /* read function arguments */
1697 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1699 int nargs = 0;
1700 tok_expect('(');
1701 *varg = 0;
1702 while (tok_see() != ')') {
1703 if (!tok_jmp(TOK3("..."))) {
1704 *varg = 1;
1705 break;
1707 if (readname(&args[nargs], argnames[nargs], NULL)) {
1708 /* argument has no type, assume int */
1709 tok_expect(TOK_NAME);
1710 memset(&args[nargs], 0, sizeof(struct type));
1711 args[nargs].bt = 4 | BT_SIGNED;
1712 strcpy(argnames[nargs], tok_id());
1714 /* argument arrays are pointers */
1715 array2ptr(&args[nargs]);
1716 nargs++;
1717 if (tok_jmp(','))
1718 break;
1720 tok_expect(')');
1721 /* void argument */
1722 if (nargs == 1 && !TYPE_BT(&args[0]))
1723 return 0;
1724 return nargs;
1727 /* read K&R function arguments */
1728 static void krdef(void *data, struct name *name, unsigned flags)
1730 struct funcinfo *fi = data;
1731 int i;
1732 for (i = 0; i < fi->nargs; i++)
1733 if (!strcmp(fi->argnames[i], name->name))
1734 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1738 * readarrays() parses array specifiers when reading a definition in
1739 * readname(). The "type" parameter contains the type contained in the
1740 * inner array; for instance, type in "int *a[10][20]" would be an int
1741 * pointer. When returning, the "type" parameter is changed to point
1742 * to the final array. The function returns a pointer to the type in
1743 * the inner array; this is useful when the type is not complete yet,
1744 * like when creating an array of function pointers as in
1745 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1747 static struct type *readarrays(struct type *type)
1749 long arsz[16];
1750 struct type *inner = NULL;
1751 int nar = 0;
1752 int i;
1753 while (!tok_jmp('[')) {
1754 long n = 0;
1755 if (tok_jmp(']')) {
1756 readexpr();
1757 ts_pop_de(NULL);
1758 if (o_popnum(&n))
1759 err("const expr expected\n");
1760 tok_expect(']');
1762 arsz[nar++] = n;
1764 for (i = nar - 1; i >= 0; i--) {
1765 type->id = array_add(type, arsz[i]);
1766 if (!inner)
1767 inner = &arrays[type->id].type;
1768 type->flags = T_ARRAY;
1769 type->bt = LONGSZ;
1770 type->ptr = 0;
1772 return inner;
1776 * readname() reads a variable definition; the name is copied into
1777 * "name" and the type is copied into "main" argument. The "base"
1778 * argument, if not NULL, indicates the base type of the variable.
1779 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1780 * "int". If NULL, basetype() is called directly to read the base
1781 * type of the variable. readname() returns zero, only if the
1782 * variable can be read.
1784 static int readname(struct type *main, char *name, struct type *base)
1786 struct type tpool[3];
1787 int npool = 0;
1788 struct type *type = &tpool[npool++];
1789 struct type *ptype = NULL; /* type inside parenthesis */
1790 struct type *btype = NULL; /* type before parenthesis */
1791 struct type *inner;
1792 unsigned flags;
1793 memset(tpool, 0, sizeof(tpool));
1794 if (name)
1795 *name = '\0';
1796 if (!base) {
1797 if (basetype(type, &flags))
1798 return 1;
1799 } else {
1800 memcpy(type, base, sizeof(*base));
1802 readptrs(type);
1803 if (!tok_jmp('(')) {
1804 btype = type;
1805 type = &tpool[npool++];
1806 ptype = type;
1807 readptrs(type);
1809 if (!tok_jmp(TOK_NAME) && name)
1810 strcpy(name, tok_id());
1811 inner = readarrays(type);
1812 if (ptype && inner)
1813 ptype = inner;
1814 if (ptype)
1815 tok_expect(')');
1816 if (tok_see() == '(') {
1817 struct type args[NARGS];
1818 char argnames[NARGS][NAMELEN];
1819 int varg = 0;
1820 int nargs = readargs(args, argnames, &varg);
1821 if (!ptype) {
1822 btype = type;
1823 type = &tpool[npool++];
1824 ptype = type;
1826 ptype->flags = T_FUNC;
1827 ptype->bt = LONGSZ;
1828 ptype->id = func_create(btype, name, argnames, args, nargs, varg);
1829 if (tok_see() != ';')
1830 while (tok_see() != '{' && !readdefs(krdef, &funcs[ptype->id]))
1831 tok_expect(';');
1832 } else {
1833 if (ptype && readarrays(type))
1834 array2ptr(type);
1836 memcpy(main, type, sizeof(*type));
1837 return 0;
1840 static int readtype(struct type *type)
1842 return readname(type, NULL, NULL);
1846 * readdef() reads a variable definitions statement. The definition
1847 * statement can appear in anywhere: global variables, function
1848 * local variables, struct fields, and typedefs. For each defined
1849 * variable, def() callback is called with the appropriate name
1850 * struct and flags; the callback should finish parsing the definition
1851 * by possibly reading the initializer expression and saving the name
1852 * struct.
1854 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1855 void *data)
1857 struct type base;
1858 unsigned base_flags;
1859 if (basetype(&base, &base_flags))
1860 return 1;
1861 if (tok_see() == ';' || tok_see() == '{')
1862 return 0;
1863 do {
1864 struct name name = {{""}};
1865 if (readname(&name.type, name.name, &base))
1866 break;
1867 def(data, &name, base_flags);
1868 } while (!tok_jmp(','));
1869 return 0;
1872 /* just like readdefs, but default to int type; for handling K&R functions */
1873 static int readdefs_int(void (*def)(void *data, struct name *name, unsigned flags),
1874 void *data)
1876 struct type base;
1877 unsigned flags = 0;
1878 if (basetype(&base, &flags)) {
1879 if (tok_see() != TOK_NAME)
1880 return 1;
1881 memset(&base, 0, sizeof(base));
1882 base.bt = 4 | BT_SIGNED;
1884 if (tok_see() != ';') {
1885 do {
1886 struct name name = {{""}};
1887 if (readname(&name.type, name.name, &base))
1888 break;
1889 def(data, &name, flags);
1890 } while (!tok_jmp(','));
1892 return 0;
1896 /* parsing initializer expressions */
1898 static void jumpbrace(void)
1900 int depth = 0;
1901 while (tok_see() != '}' || depth--)
1902 if (tok_get() == '{')
1903 depth++;
1904 tok_expect('}');
1907 /* compute the size of the initializer expression */
1908 static int initsize(void)
1910 long addr = tok_addr();
1911 int n = 0;
1912 if (tok_jmp('='))
1913 return 0;
1914 if (!tok_jmp(TOK_STR)) {
1915 n = tok_str(NULL);
1916 tok_jump(addr);
1917 return n;
1919 tok_expect('{');
1920 while (tok_jmp('}')) {
1921 long idx = n;
1922 if (!tok_jmp('[')) {
1923 readexpr();
1924 ts_pop_de(NULL);
1925 o_popnum(&idx);
1926 tok_expect(']');
1927 tok_expect('=');
1929 if (n < idx + 1)
1930 n = idx + 1;
1931 while (tok_see() != '}' && tok_see() != ',')
1932 if (tok_get() == '{')
1933 jumpbrace();
1934 tok_jmp(',');
1936 tok_jump(addr);
1937 return n;
1940 static struct type *innertype(struct type *t)
1942 if (t->flags & T_ARRAY && !t->ptr)
1943 return innertype(&arrays[t->id].type);
1944 return t;
1947 /* read the initializer expression and initialize basic types using set() cb */
1948 static void initexpr(struct type *t, int off, void *obj,
1949 void (*set)(void *obj, int off, struct type *t))
1951 if (tok_jmp('{')) {
1952 set(obj, off, t);
1953 return;
1955 if (!t->ptr && t->flags & T_STRUCT) {
1956 struct structinfo *si = &structs[t->id];
1957 int i;
1958 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1959 struct name *field = &si->fields[i];
1960 if (!tok_jmp('.')) {
1961 tok_expect(TOK_NAME);
1962 field = struct_field(t->id, tok_id());
1963 tok_expect('=');
1965 initexpr(&field->type, off + field->addr, obj, set);
1966 if (tok_jmp(','))
1967 break;
1969 } else if (t->flags & T_ARRAY) {
1970 struct type *t_de = &arrays[t->id].type;
1971 int i;
1972 /* handling extra braces as in: char s[] = {"sth"} */
1973 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1974 set(obj, off, t);
1975 tok_expect('}');
1976 return;
1978 for (i = 0; tok_see() != '}'; i++) {
1979 long idx = i;
1980 struct type *it = t_de;
1981 if (!tok_jmp('[')) {
1982 readexpr();
1983 ts_pop_de(NULL);
1984 o_popnum(&idx);
1985 tok_expect(']');
1986 tok_expect('=');
1988 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1989 !(it->flags & T_ARRAY)))
1990 it = innertype(t_de);
1991 initexpr(it, off + type_totsz(it) * idx, obj, set);
1992 if (tok_jmp(','))
1993 break;
1996 tok_expect('}');