gen: move the management of ds[] to gen.c
[neatcc.git] / ncc.c
blob1c1799e0d079ba53c939f8acaf73dd417754bf27
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[STRLEN];
484 int len = tok_str(buf);
485 t.bt = 1 | BT_SIGNED;
486 a.id = array_add(&t, len);
487 a.flags = T_ARRAY;
488 ts_push(&a);
489 o_sym(tmp_str(buf, len));
490 return;
492 if (!tok_jmp(TOK_NAME)) {
493 struct name unkn = {""};
494 char *name = unkn.name;
495 int n;
496 strcpy(name, tok_id());
497 /* don't search for labels here */
498 if (!ncexpr && !caseexpr && tok_see() == ':')
499 return;
500 if ((n = local_find(name)) != -1) {
501 struct name *l = &locals[n];
502 o_local(l->addr);
503 ts_push_addr(&l->type);
504 return;
506 if ((n = global_find(name)) != -1) {
507 struct name *g = &globals[n];
508 o_sym(*g->elfname ? g->elfname : g->name);
509 ts_push_addr(&g->type);
510 return;
512 if (!enum_find(&n, name)) {
513 ts_push_bt(4 | BT_SIGNED);
514 o_num(n);
515 return;
517 if (tok_see() != '(')
518 err("unknown symbol <%s>\n", name);
519 global_add(&unkn);
520 ts_push_bt(LONGSZ);
521 o_sym(unkn.name);
522 return;
524 if (!tok_jmp('(')) {
525 struct type t;
526 if (!readtype(&t)) {
527 struct type o;
528 tok_expect(')');
529 readpre();
530 ts_pop_de(&o);
531 ts_push(&t);
532 if (!t.ptr || !o.ptr)
533 o_cast(TYPE_BT(&t));
534 } else {
535 readexpr();
536 while (tok_jmp(')')) {
537 tok_expect(',');
538 ts_pop(NULL);
539 o_tmpdrop(1);
540 readexpr();
543 return;
547 static void arrayderef(void)
549 struct type t;
550 int sz;
551 ts_pop_de(NULL);
552 ts_pop(&t);
553 if (!(t.flags & T_ARRAY && !t.ptr) && t.addr) {
554 o_tmpswap();
555 o_deref(TYPE_BT(&t));
556 o_tmpswap();
558 array2ptr(&t);
559 t.ptr--;
560 sz = type_totsz(&t);
561 t.addr = 1;
562 if (sz > 1) {
563 o_num(sz);
564 o_bop(O_MUL);
566 o_bop(O_ADD);
567 ts_push(&t);
570 static void inc_post(int op)
572 struct type t = ts[nts - 1];
573 /* pushing the value before inc */
574 o_tmpcopy();
575 ts_de(1);
576 o_load();
577 o_tmpswap();
579 /* increment by 1 or pointer size */
580 o_tmpcopy();
581 ts_push(&t);
582 ts_pop_de(&t);
583 o_num(t.ptr > 0 ? type_szde(&t) : 1);
584 o_bop(op);
586 /* assign back */
587 o_assign(TYPE_BT(&t));
588 o_tmpdrop(1);
591 static void readfield(void)
593 struct name *field;
594 struct type t;
595 tok_expect(TOK_NAME);
596 ts_pop(&t);
597 array2ptr(&t);
598 field = struct_field(t.id, tok_id());
599 if (field->addr) {
600 o_num(field->addr);
601 o_bop(O_ADD);
603 ts_push_addr(&field->type);
606 static struct funcinfo {
607 struct type args[NARGS];
608 struct type ret;
609 int nargs;
610 int varg;
611 /* function and argument names; useful only when defining */
612 char argnames[NARGS][NAMELEN];
613 char name[NAMELEN];
614 } funcs[NFUNCS];
615 static int nfuncs;
617 static int func_create(struct type *ret, char *name, char argnames[][NAMELEN],
618 struct type *args, int nargs, int varg)
620 struct funcinfo *fi = &funcs[nfuncs++];
621 int i;
622 if (nfuncs >= NFUNCS)
623 err("nomem: NFUNCS reached!\n");
624 memcpy(&fi->ret, ret, sizeof(*ret));
625 for (i = 0; i < nargs; i++)
626 memcpy(&fi->args[i], &args[i], sizeof(*ret));
627 fi->nargs = nargs;
628 fi->varg = varg;
629 strcpy(fi->name, name ? name : "");
630 for (i = 0; i < nargs; i++)
631 strcpy(fi->argnames[i], argnames[i]);
632 return fi - funcs;
635 static void readcall(void)
637 struct type t;
638 struct funcinfo *fi;
639 int argc = 0;
640 ts_pop(&t);
641 if (t.flags & T_FUNC && t.ptr > 0)
642 o_deref(LONGSZ);
643 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
644 if (tok_see() != ')') {
645 do {
646 readexpr();
647 ts_pop_de(NULL);
648 argc++;
649 } while (!tok_jmp(','));
651 tok_expect(')');
652 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
653 if (fi) {
654 if (TYPE_BT(&fi->ret))
655 o_cast(TYPE_BT(&fi->ret));
656 ts_push(&fi->ret);
657 } else {
658 ts_push_bt(4 | BT_SIGNED);
662 static void readpost(void)
664 readprimary();
665 while (1) {
666 if (!tok_jmp('[')) {
667 readexpr();
668 tok_expect(']');
669 arrayderef();
670 continue;
672 if (!tok_jmp('(')) {
673 readcall();
674 continue;
676 if (!tok_jmp(TOK2("++"))) {
677 inc_post(O_ADD);
678 continue;
680 if (!tok_jmp(TOK2("--"))) {
681 inc_post(O_SUB);
682 continue;
684 if (!tok_jmp('.')) {
685 readfield();
686 continue;
688 if (!tok_jmp(TOK2("->"))) {
689 ts_de(1);
690 readfield();
691 continue;
693 break;
697 static void inc_pre(int op)
699 struct type t;
700 readpre();
701 /* copy the destination */
702 o_tmpcopy();
703 ts_push(&ts[nts - 1]);
704 /* increment by 1 or pointer size */
705 ts_pop_de(&t);
706 o_num(t.ptr > 0 ? type_szde(&t) : 1);
707 o_bop(op);
708 /* assign the result */
709 o_assign(TYPE_BT(&t));
710 ts_de(0);
713 static void readpre(void)
715 if (!tok_jmp('&')) {
716 struct type type;
717 readpre();
718 ts_pop(&type);
719 if (!type.addr)
720 err("cannot use the address\n");
721 type.ptr++;
722 type.addr = 0;
723 ts_push(&type);
724 return;
726 if (!tok_jmp('*')) {
727 struct type t;
728 readpre();
729 ts_pop(&t);
730 array2ptr(&t);
731 if (!t.ptr)
732 err("dereferencing non-pointer\n");
733 if (t.addr)
734 o_deref(TYPE_BT(&t));
735 t.ptr--;
736 t.addr = 1;
737 ts_push(&t);
738 return;
740 if (!tok_jmp('!')) {
741 readpre();
742 ts_pop_de(NULL);
743 o_uop(O_LNOT);
744 ts_push_bt(4 | BT_SIGNED);
745 return;
747 if (!tok_jmp('+')) {
748 readpre();
749 return;
751 if (!tok_jmp('-')) {
752 readpre();
753 ts_de(1);
754 o_uop(O_NEG);
755 return;
757 if (!tok_jmp('~')) {
758 readpre();
759 ts_de(1);
760 o_uop(O_NOT);
761 return;
763 if (!tok_jmp(TOK2("++"))) {
764 inc_pre(O_ADD);
765 return;
767 if (!tok_jmp(TOK2("--"))) {
768 inc_pre(O_SUB);
769 return;
771 if (!tok_jmp(TOK_SIZEOF)) {
772 struct type t;
773 int op = !tok_jmp('(');
774 if (readtype(&t)) {
775 nogen++;
776 if (op)
777 readexpr();
778 else
779 readpre();
780 nogen--;
781 ts_pop(&t);
783 ts_push_bt(4);
784 o_num(type_totsz(&t));
785 if (op)
786 tok_expect(')');
787 return;
789 readpost();
792 static void readmul(void)
794 readpre();
795 while (1) {
796 if (!tok_jmp('*')) {
797 readpre();
798 ts_binop(O_MUL);
799 continue;
801 if (!tok_jmp('/')) {
802 readpre();
803 ts_binop(O_DIV);
804 continue;
806 if (!tok_jmp('%')) {
807 readpre();
808 ts_binop(O_MOD);
809 continue;
811 break;
815 static void readadd(void)
817 readmul();
818 while (1) {
819 if (!tok_jmp('+')) {
820 readmul();
821 ts_addop(O_ADD);
822 continue;
824 if (!tok_jmp('-')) {
825 readmul();
826 ts_addop(O_SUB);
827 continue;
829 break;
833 static void shift(int op)
835 struct type t;
836 readadd();
837 ts_pop_de2(NULL, &t);
838 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
839 ts_push_bt(TYPE_BT(&t));
842 static void readshift(void)
844 readadd();
845 while (1) {
846 if (!tok_jmp(TOK2("<<"))) {
847 shift(O_SHL);
848 continue;
850 if (!tok_jmp(TOK2(">>"))) {
851 shift(O_SHR);
852 continue;
854 break;
858 static void cmp(int op)
860 struct type t1, t2;
861 int bt;
862 readshift();
863 ts_pop_de2(&t1, &t2);
864 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
865 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
866 ts_push_bt(4 | BT_SIGNED);
869 static void readcmp(void)
871 readshift();
872 while (1) {
873 if (!tok_jmp('<')) {
874 cmp(O_LT);
875 continue;
877 if (!tok_jmp('>')) {
878 cmp(O_GT);
879 continue;
881 if (!tok_jmp(TOK2("<="))) {
882 cmp(O_LE);
883 continue;
885 if (!tok_jmp(TOK2(">="))) {
886 cmp(O_GE);
887 continue;
889 break;
893 static void eq(int op)
895 readcmp();
896 ts_pop_de2(NULL, NULL);
897 o_bop(op);
898 ts_push_bt(4 | BT_SIGNED);
901 static void readeq(void)
903 readcmp();
904 while (1) {
905 if (!tok_jmp(TOK2("=="))) {
906 eq(O_EQ);
907 continue;
909 if (!tok_jmp(TOK2("!="))) {
910 eq(O_NEQ);
911 continue;
913 break;
917 static void readbitand(void)
919 readeq();
920 while (!tok_jmp('&')) {
921 readeq();
922 ts_binop(O_AND);
926 static void readxor(void)
928 readbitand();
929 while (!tok_jmp('^')) {
930 readbitand();
931 ts_binop(O_XOR);
935 static void readbitor(void)
937 readxor();
938 while (!tok_jmp('|')) {
939 readxor();
940 ts_binop(O_OR);
944 static void readand(void)
946 int l_out = LABEL();
947 int l_fail = LABEL();
948 readbitor();
949 if (tok_see() != TOK2("&&"))
950 return;
951 o_fork();
952 ts_pop_de(NULL);
953 o_jz(l_fail);
954 while (!tok_jmp(TOK2("&&"))) {
955 readbitor();
956 ts_pop_de(NULL);
957 o_jz(l_fail);
959 o_num(1);
960 o_forkpush();
961 o_jmp(l_out);
962 o_label(l_fail);
963 o_num(0);
964 o_forkpush();
965 o_forkjoin();
966 o_label(l_out);
967 ts_push_bt(4 | BT_SIGNED);
970 static void reador(void)
972 int l_pass = LABEL();
973 int l_end = LABEL();
974 readand();
975 if (tok_see() != TOK2("||"))
976 return;
977 o_fork();
978 ts_pop_de(NULL);
979 o_jnz(l_pass);
980 while (!tok_jmp(TOK2("||"))) {
981 readand();
982 ts_pop_de(NULL);
983 o_jnz(l_pass);
985 o_num(0);
986 o_forkpush();
987 o_jmp(l_end);
988 o_label(l_pass);
989 o_num(1);
990 o_forkpush();
991 o_forkjoin();
992 o_label(l_end);
993 ts_push_bt(4 | BT_SIGNED);
996 static void readcexpr(void);
998 static int readcexpr_const(void)
1000 long c;
1001 if (o_popnum(&c))
1002 return -1;
1003 if (!c)
1004 nogen++;
1005 readcexpr();
1006 /* both branches yield the same type; so ignore the first */
1007 ts_pop_de(NULL);
1008 tok_expect(':');
1009 if (c)
1010 nogen++;
1011 else
1012 nogen--;
1013 readcexpr();
1014 /* making sure t->addr == 0 on both branches */
1015 ts_de(1);
1016 if (c)
1017 nogen--;
1018 return 0;
1021 static void readcexpr(void)
1023 reador();
1024 if (tok_jmp('?'))
1025 return;
1026 ncexpr++;
1027 ts_pop_de(NULL);
1028 o_fork();
1029 if (readcexpr_const()) {
1030 int l_fail = LABEL();
1031 int l_end = LABEL();
1032 struct type ret;
1033 o_jz(l_fail);
1034 readcexpr();
1035 /* both branches yield the same type; so ignore the first */
1036 ts_pop_de(&ret);
1037 if (!TYPE_VOID(&ret))
1038 o_forkpush();
1039 o_jmp(l_end);
1041 tok_expect(':');
1042 o_label(l_fail);
1043 readcexpr();
1044 /* making sure t->addr == 0 on both branches */
1045 ts_de(1);
1046 if (!TYPE_VOID(&ret)) {
1047 o_forkpush();
1048 o_forkjoin();
1050 o_label(l_end);
1052 ncexpr--;
1055 static void opassign(int op, int ptrop)
1057 struct type t = ts[nts - 1];
1058 o_tmpcopy();
1059 ts_push(&t);
1060 readexpr();
1061 if (op == O_ADD || op == O_SUB)
1062 ts_addop(op);
1063 else
1064 ts_binop(op);
1065 o_assign(TYPE_BT(&ts[nts - 2]));
1066 ts_pop(NULL);
1067 ts_de(0);
1070 static void doassign(void)
1072 struct type t = ts[nts - 1];
1073 if (!t.ptr && t.flags & T_STRUCT) {
1074 ts_pop(NULL);
1075 o_num(type_totsz(&t));
1076 o_memcpy();
1077 } else {
1078 ts_pop_de(NULL);
1079 o_assign(TYPE_BT(&ts[nts - 1]));
1080 ts_de(0);
1084 static void readexpr(void)
1086 readcexpr();
1087 if (!tok_jmp('=')) {
1088 readexpr();
1089 doassign();
1090 return;
1092 if (!tok_jmp(TOK2("+="))) {
1093 opassign(O_ADD, 1);
1094 return;
1096 if (!tok_jmp(TOK2("-="))) {
1097 opassign(O_SUB, 1);
1098 return;
1100 if (!tok_jmp(TOK2("*="))) {
1101 opassign(O_MUL, 0);
1102 return;
1104 if (!tok_jmp(TOK2("/="))) {
1105 opassign(O_DIV, 0);
1106 return;
1108 if (!tok_jmp(TOK2("%="))) {
1109 opassign(O_MOD, 0);
1110 return;
1112 if (!tok_jmp(TOK3("<<="))) {
1113 opassign(O_SHL, 0);
1114 return;
1116 if (!tok_jmp(TOK3(">>="))) {
1117 opassign(O_SHR, 0);
1118 return;
1120 if (!tok_jmp(TOK3("&="))) {
1121 opassign(O_AND, 0);
1122 return;
1124 if (!tok_jmp(TOK3("|="))) {
1125 opassign(O_OR, 0);
1126 return;
1128 if (!tok_jmp(TOK3("^="))) {
1129 opassign(O_XOR, 0);
1130 return;
1134 static void readestmt(void)
1136 do {
1137 o_tmpdrop(-1);
1138 nts = 0;
1139 readexpr();
1140 } while (!tok_jmp(','));
1143 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1145 static void globalinit(void *obj, int off, struct type *t)
1147 struct name *name = obj;
1148 char *elfname = *name->elfname ? name->elfname : name->name;
1149 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1150 struct type *t_de = &arrays[t->id].type;
1151 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1152 char buf[STRLEN];
1153 int len;
1154 tok_expect(TOK_STR);
1155 len = tok_str(buf);
1156 o_dscpy(name->addr + off, buf, len);
1157 return;
1160 readexpr();
1161 o_dsset(elfname, off, TYPE_BT(t));
1162 ts_pop(NULL);
1165 static void readfunc(struct name *name, int flags);
1167 static void globaldef(void *data, struct name *name, unsigned flags)
1169 struct type *t = &name->type;
1170 char *elfname = *name->elfname ? name->elfname : name->name;
1171 int sz;
1172 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1173 if (~flags & F_EXTERN)
1174 arrays[t->id].n = initsize();
1175 sz = type_totsz(t);
1176 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1177 if (tok_see() == '=')
1178 name->addr = o_dsnew(elfname, sz, F_GLOBAL(flags));
1179 else
1180 o_bsnew(elfname, sz, F_GLOBAL(flags));
1182 global_add(name);
1183 if (!tok_jmp('='))
1184 initexpr(t, 0, name, globalinit);
1185 if (tok_see() == '{' && name->type.flags & T_FUNC)
1186 readfunc(name, flags);
1189 /* generate the address of local + off */
1190 static void o_localoff(long addr, int off)
1192 o_local(addr);
1193 if (off) {
1194 o_num(off);
1195 o_bop(O_ADD);
1199 static void localinit(void *obj, int off, struct type *t)
1201 long addr = *(long *) obj;
1202 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1203 struct type *t_de = &arrays[t->id].type;
1204 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1205 char buf[STRLEN];
1206 int len;
1207 tok_expect(TOK_STR);
1208 len = tok_str(buf);
1209 o_localoff(addr, off);
1210 o_sym(tmp_str(buf, len));
1211 o_num(len);
1212 o_memcpy();
1213 o_tmpdrop(1);
1214 return;
1217 o_localoff(addr, off);
1218 ts_push(t);
1219 readexpr();
1220 doassign();
1221 ts_pop(NULL);
1222 o_tmpdrop(1);
1225 /* current function name */
1226 static char func_name[NAMELEN];
1228 static void localdef(void *data, struct name *name, unsigned flags)
1230 struct type *t = &name->type;
1231 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1232 global_add(name);
1233 return;
1235 if (flags & F_STATIC) {
1236 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1237 globaldef(data, name, flags);
1238 return;
1240 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1241 arrays[t->id].n = initsize();
1242 name->addr = o_mklocal(type_totsz(&name->type));
1243 local_add(name);
1244 if (!tok_jmp('=')) {
1245 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1246 o_local(name->addr);
1247 o_num(0);
1248 o_num(type_totsz(t));
1249 o_memset();
1250 o_tmpdrop(1);
1252 initexpr(t, 0, &name->addr, localinit);
1256 static void typedefdef(void *data, struct name *name, unsigned flags)
1258 typedef_add(name->name, &name->type);
1261 static void readstmt(void);
1263 static void readswitch(void)
1265 int o_break = l_break;
1266 long val_addr = o_mklocal(LONGSZ);
1267 struct type t;
1268 int ncases = 0; /* number of case labels */
1269 int l_failed = LABEL(); /* address of last failed jmp */
1270 int l_matched = LABEL(); /* address of last walk through jmp */
1271 int l_default = 0; /* default case label */
1272 l_break = LABEL();
1273 tok_expect('(');
1274 readexpr();
1275 ts_pop_de(&t);
1276 o_local(val_addr);
1277 o_tmpswap();
1278 o_assign(TYPE_BT(&t));
1279 ts_de(0);
1280 o_tmpdrop(1);
1281 tok_expect(')');
1282 tok_expect('{');
1283 while (tok_jmp('}')) {
1284 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1285 readstmt();
1286 continue;
1288 if (ncases)
1289 o_jmp(l_matched);
1290 if (tok_get() == TOK_CASE) {
1291 o_label(l_failed);
1292 l_failed = LABEL();
1293 caseexpr = 1;
1294 readexpr();
1295 ts_pop_de(NULL);
1296 caseexpr = 0;
1297 o_local(val_addr);
1298 o_deref(TYPE_BT(&t));
1299 o_bop(O_EQ);
1300 o_jz(l_failed);
1301 o_tmpdrop(1);
1302 } else {
1303 if (!ncases)
1304 o_jmp(l_failed);
1305 l_default = LABEL();
1306 o_label(l_default);
1308 tok_expect(':');
1309 o_label(l_matched);
1310 l_matched = LABEL();
1311 ncases++;
1313 o_rmlocal(val_addr, LONGSZ);
1314 o_jmp(l_break);
1315 o_label(l_failed);
1316 if (l_default)
1317 o_jmp(l_default);
1318 o_label(l_break);
1319 l_break = o_break;
1322 static char label_name[NLABELS][NAMELEN];
1323 static int label_ids[NLABELS];
1324 static int nlabels;
1326 static int label_id(char *name)
1328 int i;
1329 for (i = nlabels - 1; i >= 0; --i)
1330 if (!strcmp(label_name[i], name))
1331 return label_ids[i];
1332 strcpy(label_name[nlabels], name);
1333 label_ids[nlabels] = LABEL();
1334 return label_ids[nlabels++];
1337 static void readstmt(void)
1339 o_tmpdrop(-1);
1340 nts = 0;
1341 if (!tok_jmp('{')) {
1342 int _nlocals = nlocals;
1343 int _nglobals = nglobals;
1344 int _nenums = nenums;
1345 int _ntypedefs = ntypedefs;
1346 int _nstructs = nstructs;
1347 int _nfuncs = nfuncs;
1348 int _narrays = narrays;
1349 while (tok_jmp('}'))
1350 readstmt();
1351 nlocals = _nlocals;
1352 nenums = _nenums;
1353 ntypedefs = _ntypedefs;
1354 nstructs = _nstructs;
1355 nfuncs = _nfuncs;
1356 narrays = _narrays;
1357 nglobals = _nglobals;
1358 return;
1360 if (!readdefs(localdef, NULL)) {
1361 tok_expect(';');
1362 return;
1364 if (!tok_jmp(TOK_TYPEDEF)) {
1365 readdefs(typedefdef, NULL);
1366 tok_expect(';');
1367 return;
1369 if (!tok_jmp(TOK_IF)) {
1370 int l_fail = LABEL();
1371 int l_end = LABEL();
1372 tok_expect('(');
1373 readexpr();
1374 tok_expect(')');
1375 ts_pop_de(NULL);
1376 o_jz(l_fail);
1377 readstmt();
1378 if (!tok_jmp(TOK_ELSE)) {
1379 o_jmp(l_end);
1380 o_label(l_fail);
1381 readstmt();
1382 o_label(l_end);
1383 } else {
1384 o_label(l_fail);
1386 return;
1388 if (!tok_jmp(TOK_WHILE)) {
1389 int o_break = l_break;
1390 int o_cont = l_cont;
1391 l_break = LABEL();
1392 l_cont = LABEL();
1393 o_label(l_cont);
1394 tok_expect('(');
1395 readexpr();
1396 tok_expect(')');
1397 ts_pop_de(NULL);
1398 o_jz(l_break);
1399 readstmt();
1400 o_jmp(l_cont);
1401 o_label(l_break);
1402 l_break = o_break;
1403 l_cont = o_cont;
1404 return;
1406 if (!tok_jmp(TOK_DO)) {
1407 int o_break = l_break;
1408 int o_cont = l_cont;
1409 int l_beg = LABEL();
1410 l_break = LABEL();
1411 l_cont = LABEL();
1412 o_label(l_beg);
1413 readstmt();
1414 tok_expect(TOK_WHILE);
1415 tok_expect('(');
1416 o_label(l_cont);
1417 readexpr();
1418 ts_pop_de(NULL);
1419 o_jnz(l_beg);
1420 tok_expect(')');
1421 o_label(l_break);
1422 tok_expect(';');
1423 l_break = o_break;
1424 l_cont = o_cont;
1425 return;
1427 if (!tok_jmp(TOK_FOR)) {
1428 int o_break = l_break;
1429 int o_cont = l_cont;
1430 int l_check = LABEL(); /* for condition label */
1431 int l_body = LABEL(); /* for block label */
1432 l_cont = LABEL();
1433 l_break = LABEL();
1434 tok_expect('(');
1435 if (tok_see() != ';')
1436 readestmt();
1437 tok_expect(';');
1438 o_label(l_check);
1439 if (tok_see() != ';') {
1440 readestmt();
1441 ts_pop_de(NULL);
1442 o_jz(l_break);
1444 tok_expect(';');
1445 o_jmp(l_body);
1446 o_label(l_cont);
1447 if (tok_see() != ')')
1448 readestmt();
1449 tok_expect(')');
1450 o_jmp(l_check);
1451 o_label(l_body);
1452 readstmt();
1453 o_jmp(l_cont);
1454 o_label(l_break);
1455 l_break = o_break;
1456 l_cont = o_cont;
1457 return;
1459 if (!tok_jmp(TOK_SWITCH)) {
1460 readswitch();
1461 return;
1463 if (!tok_jmp(TOK_RETURN)) {
1464 int ret = tok_see() != ';';
1465 if (ret) {
1466 readexpr();
1467 ts_pop_de(NULL);
1469 tok_expect(';');
1470 o_ret(ret);
1471 return;
1473 if (!tok_jmp(TOK_BREAK)) {
1474 tok_expect(';');
1475 o_jmp(l_break);
1476 return;
1478 if (!tok_jmp(TOK_CONTINUE)) {
1479 tok_expect(';');
1480 o_jmp(l_cont);
1481 return;
1483 if (!tok_jmp(TOK_GOTO)) {
1484 tok_expect(TOK_NAME);
1485 o_jmp(label_id(tok_id()));
1486 tok_expect(';');
1487 return;
1489 readestmt();
1490 /* labels */
1491 if (!tok_jmp(':')) {
1492 o_label(label_id(tok_id()));
1493 return;
1495 tok_expect(';');
1498 static void readfunc(struct name *name, int flags)
1500 struct funcinfo *fi = &funcs[name->type.id];
1501 long beg = tok_addr();
1502 int i;
1503 strcpy(func_name, fi->name);
1504 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1505 for (i = 0; i < fi->nargs; i++) {
1506 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1507 strcpy(arg.name, fi->argnames[i]);
1508 local_add(&arg);
1510 /* first pass: collecting statistics */
1511 o_pass1();
1512 readstmt();
1513 tok_jump(beg);
1514 /* second pass: generating code */
1515 o_pass2();
1516 readstmt();
1517 o_func_end();
1518 func_name[0] = '\0';
1519 nlocals = 0;
1520 label = 0;
1521 nlabels = 0;
1524 static void readdecl(void)
1526 if (!tok_jmp(TOK_TYPEDEF)) {
1527 readdefs(typedefdef, NULL);
1528 tok_expect(';');
1529 return;
1531 readdefs_int(globaldef, NULL);
1532 tok_jmp(';');
1535 static void parse(void)
1537 while (tok_see() != TOK_EOF)
1538 readdecl();
1541 static void compat_macros(void)
1543 cpp_define("__STDC__", "");
1544 cpp_define("__linux__", "");
1545 cpp_define(I_ARCH, "");
1547 /* ignored keywords */
1548 cpp_define("const", "");
1549 cpp_define("register", "");
1550 cpp_define("volatile", "");
1551 cpp_define("inline", "");
1552 cpp_define("restrict", "");
1553 cpp_define("__inline__", "");
1554 cpp_define("__restrict__", "");
1555 cpp_define("__attribute__(x)", "");
1556 cpp_define("__builtin_va_list__", "long");
1559 int main(int argc, char *argv[])
1561 char obj[128] = "";
1562 int ofd;
1563 int i = 1;
1564 compat_macros();
1565 while (i < argc && argv[i][0] == '-') {
1566 if (argv[i][1] == 'I')
1567 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1568 if (argv[i][1] == 'D') {
1569 char *name = argv[i] + 2;
1570 char *def = "";
1571 char *eq = strchr(name, '=');
1572 if (eq) {
1573 *eq = '\0';
1574 def = eq + 1;
1576 cpp_define(name, def);
1578 if (argv[i][1] == 'o')
1579 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1580 i++;
1582 if (i == argc)
1583 die("neatcc: no file given\n");
1584 if (cpp_init(argv[i]))
1585 die("neatcc: cannot open <%s>\n", argv[i]);
1586 parse();
1587 if (!*obj) {
1588 strcpy(obj, argv[i]);
1589 obj[strlen(obj) - 1] = 'o';
1591 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1592 o_write(ofd);
1593 close(ofd);
1594 return 0;
1598 /* parsing function and variable declarations */
1600 /* read the base type of a variable */
1601 static int basetype(struct type *type, unsigned *flags)
1603 int sign = 1;
1604 int size = 4;
1605 int done = 0;
1606 int i = 0;
1607 int isunion;
1608 char name[NAMELEN] = "";
1609 *flags = 0;
1610 type->flags = 0;
1611 type->ptr = 0;
1612 type->addr = 0;
1613 while (!done) {
1614 switch (tok_see()) {
1615 case TOK_STATIC:
1616 *flags |= F_STATIC;
1617 break;
1618 case TOK_EXTERN:
1619 *flags |= F_EXTERN;
1620 break;
1621 case TOK_VOID:
1622 sign = 0;
1623 size = 0;
1624 done = 1;
1625 break;
1626 case TOK_INT:
1627 done = 1;
1628 break;
1629 case TOK_CHAR:
1630 size = 1;
1631 done = 1;
1632 break;
1633 case TOK_SHORT:
1634 size = 2;
1635 break;
1636 case TOK_LONG:
1637 size = LONGSZ;
1638 break;
1639 case TOK_SIGNED:
1640 break;
1641 case TOK_UNSIGNED:
1642 sign = 0;
1643 break;
1644 case TOK_UNION:
1645 case TOK_STRUCT:
1646 isunion = tok_get() == TOK_UNION;
1647 if (!tok_jmp(TOK_NAME))
1648 strcpy(name, tok_id());
1649 if (tok_see() == '{')
1650 type->id = struct_create(name, isunion);
1651 else
1652 type->id = struct_find(name, isunion);
1653 type->flags |= T_STRUCT;
1654 type->bt = LONGSZ;
1655 return 0;
1656 case TOK_ENUM:
1657 tok_get();
1658 tok_jmp(TOK_NAME);
1659 if (tok_see() == '{')
1660 enum_create();
1661 type->bt = 4 | BT_SIGNED;
1662 return 0;
1663 default:
1664 if (tok_see() == TOK_NAME) {
1665 int id = typedef_find(tok_id());
1666 if (id != -1) {
1667 tok_get();
1668 memcpy(type, &typedefs[id].type,
1669 sizeof(*type));
1670 return 0;
1673 if (!i)
1674 return 1;
1675 done = 1;
1676 continue;
1678 i++;
1679 tok_get();
1681 type->bt = size | (sign ? BT_SIGNED : 0);
1682 return 0;
1685 static void readptrs(struct type *type)
1687 while (!tok_jmp('*')) {
1688 type->ptr++;
1689 if (!type->bt)
1690 type->bt = 1;
1694 /* read function arguments */
1695 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1697 int nargs = 0;
1698 tok_expect('(');
1699 *varg = 0;
1700 while (tok_see() != ')') {
1701 if (!tok_jmp(TOK3("..."))) {
1702 *varg = 1;
1703 break;
1705 if (readname(&args[nargs], argnames[nargs], NULL)) {
1706 /* argument has no type, assume int */
1707 tok_expect(TOK_NAME);
1708 memset(&args[nargs], 0, sizeof(struct type));
1709 args[nargs].bt = 4 | BT_SIGNED;
1710 strcpy(argnames[nargs], tok_id());
1712 /* argument arrays are pointers */
1713 array2ptr(&args[nargs]);
1714 nargs++;
1715 if (tok_jmp(','))
1716 break;
1718 tok_expect(')');
1719 /* void argument */
1720 if (nargs == 1 && !TYPE_BT(&args[0]))
1721 return 0;
1722 return nargs;
1725 /* read K&R function arguments */
1726 static void krdef(void *data, struct name *name, unsigned flags)
1728 struct funcinfo *fi = data;
1729 int i;
1730 for (i = 0; i < fi->nargs; i++)
1731 if (!strcmp(fi->argnames[i], name->name))
1732 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1736 * readarrays() parses array specifiers when reading a definition in
1737 * readname(). The "type" parameter contains the type contained in the
1738 * inner array; for instance, type in "int *a[10][20]" would be an int
1739 * pointer. When returning, the "type" parameter is changed to point
1740 * to the final array. The function returns a pointer to the type in
1741 * the inner array; this is useful when the type is not complete yet,
1742 * like when creating an array of function pointers as in
1743 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1745 static struct type *readarrays(struct type *type)
1747 long arsz[16];
1748 struct type *inner = NULL;
1749 int nar = 0;
1750 int i;
1751 while (!tok_jmp('[')) {
1752 long n = 0;
1753 if (tok_jmp(']')) {
1754 readexpr();
1755 ts_pop_de(NULL);
1756 if (o_popnum(&n))
1757 err("const expr expected\n");
1758 tok_expect(']');
1760 arsz[nar++] = n;
1762 for (i = nar - 1; i >= 0; i--) {
1763 type->id = array_add(type, arsz[i]);
1764 if (!inner)
1765 inner = &arrays[type->id].type;
1766 type->flags = T_ARRAY;
1767 type->bt = LONGSZ;
1768 type->ptr = 0;
1770 return inner;
1774 * readname() reads a variable definition; the name is copied into
1775 * "name" and the type is copied into "main" argument. The "base"
1776 * argument, if not NULL, indicates the base type of the variable.
1777 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1778 * "int". If NULL, basetype() is called directly to read the base
1779 * type of the variable. readname() returns zero, only if the
1780 * variable can be read.
1782 static int readname(struct type *main, char *name, struct type *base)
1784 struct type tpool[3];
1785 int npool = 0;
1786 struct type *type = &tpool[npool++];
1787 struct type *ptype = NULL; /* type inside parenthesis */
1788 struct type *btype = NULL; /* type before parenthesis */
1789 struct type *inner;
1790 unsigned flags;
1791 memset(tpool, 0, sizeof(tpool));
1792 if (name)
1793 *name = '\0';
1794 if (!base) {
1795 if (basetype(type, &flags))
1796 return 1;
1797 } else {
1798 memcpy(type, base, sizeof(*base));
1800 readptrs(type);
1801 if (!tok_jmp('(')) {
1802 btype = type;
1803 type = &tpool[npool++];
1804 ptype = type;
1805 readptrs(type);
1807 if (!tok_jmp(TOK_NAME) && name)
1808 strcpy(name, tok_id());
1809 inner = readarrays(type);
1810 if (ptype && inner)
1811 ptype = inner;
1812 if (ptype)
1813 tok_expect(')');
1814 if (tok_see() == '(') {
1815 struct type args[NARGS];
1816 char argnames[NARGS][NAMELEN];
1817 int varg = 0;
1818 int nargs = readargs(args, argnames, &varg);
1819 if (!ptype) {
1820 btype = type;
1821 type = &tpool[npool++];
1822 ptype = type;
1824 ptype->flags = T_FUNC;
1825 ptype->bt = LONGSZ;
1826 ptype->id = func_create(btype, name, argnames, args, nargs, varg);
1827 if (tok_see() != ';')
1828 while (tok_see() != '{' && !readdefs(krdef, &funcs[ptype->id]))
1829 tok_expect(';');
1830 } else {
1831 if (ptype && readarrays(type))
1832 array2ptr(type);
1834 memcpy(main, type, sizeof(*type));
1835 return 0;
1838 static int readtype(struct type *type)
1840 return readname(type, NULL, NULL);
1844 * readdef() reads a variable definitions statement. The definition
1845 * statement can appear in anywhere: global variables, function
1846 * local variables, struct fields, and typedefs. For each defined
1847 * variable, def() callback is called with the appropriate name
1848 * struct and flags; the callback should finish parsing the definition
1849 * by possibly reading the initializer expression and saving the name
1850 * struct.
1852 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1853 void *data)
1855 struct type base;
1856 unsigned base_flags;
1857 if (basetype(&base, &base_flags))
1858 return 1;
1859 if (tok_see() == ';' || tok_see() == '{')
1860 return 0;
1861 do {
1862 struct name name = {{""}};
1863 if (readname(&name.type, name.name, &base))
1864 break;
1865 def(data, &name, base_flags);
1866 } while (!tok_jmp(','));
1867 return 0;
1870 /* just like readdefs, but default to int type; for handling K&R functions */
1871 static int readdefs_int(void (*def)(void *data, struct name *name, unsigned flags),
1872 void *data)
1874 struct type base;
1875 unsigned flags = 0;
1876 if (basetype(&base, &flags)) {
1877 if (tok_see() != TOK_NAME)
1878 return 1;
1879 memset(&base, 0, sizeof(base));
1880 base.bt = 4 | BT_SIGNED;
1882 if (tok_see() != ';') {
1883 do {
1884 struct name name = {{""}};
1885 if (readname(&name.type, name.name, &base))
1886 break;
1887 def(data, &name, flags);
1888 } while (!tok_jmp(','));
1890 return 0;
1894 /* parsing initializer expressions */
1896 static void jumpbrace(void)
1898 int depth = 0;
1899 while (tok_see() != '}' || depth--)
1900 if (tok_get() == '{')
1901 depth++;
1902 tok_expect('}');
1905 /* compute the size of the initializer expression */
1906 static int initsize(void)
1908 long addr = tok_addr();
1909 int n = 0;
1910 if (tok_jmp('='))
1911 return 0;
1912 if (!tok_jmp(TOK_STR)) {
1913 n = tok_str(NULL);
1914 tok_jump(addr);
1915 return n;
1917 tok_expect('{');
1918 while (tok_jmp('}')) {
1919 long idx = n;
1920 if (!tok_jmp('[')) {
1921 readexpr();
1922 ts_pop_de(NULL);
1923 o_popnum(&idx);
1924 tok_expect(']');
1925 tok_expect('=');
1927 if (n < idx + 1)
1928 n = idx + 1;
1929 while (tok_see() != '}' && tok_see() != ',')
1930 if (tok_get() == '{')
1931 jumpbrace();
1932 tok_jmp(',');
1934 tok_jump(addr);
1935 return n;
1938 static struct type *innertype(struct type *t)
1940 if (t->flags & T_ARRAY && !t->ptr)
1941 return innertype(&arrays[t->id].type);
1942 return t;
1945 /* read the initializer expression and initialize basic types using set() cb */
1946 static void initexpr(struct type *t, int off, void *obj,
1947 void (*set)(void *obj, int off, struct type *t))
1949 if (tok_jmp('{')) {
1950 set(obj, off, t);
1951 return;
1953 if (!t->ptr && t->flags & T_STRUCT) {
1954 struct structinfo *si = &structs[t->id];
1955 int i;
1956 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1957 struct name *field = &si->fields[i];
1958 if (!tok_jmp('.')) {
1959 tok_expect(TOK_NAME);
1960 field = struct_field(t->id, tok_id());
1961 tok_expect('=');
1963 initexpr(&field->type, off + field->addr, obj, set);
1964 if (tok_jmp(','))
1965 break;
1967 } else if (t->flags & T_ARRAY) {
1968 struct type *t_de = &arrays[t->id].type;
1969 int i;
1970 /* handling extra braces as in: char s[] = {"sth"} */
1971 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1972 set(obj, off, t);
1973 tok_expect('}');
1974 return;
1976 for (i = 0; tok_see() != '}'; i++) {
1977 long idx = i;
1978 struct type *it = t_de;
1979 if (!tok_jmp('[')) {
1980 readexpr();
1981 ts_pop_de(NULL);
1982 o_popnum(&idx);
1983 tok_expect(']');
1984 tok_expect('=');
1986 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1987 !(it->flags & T_ARRAY)))
1988 it = innertype(t_de);
1989 initexpr(it, off + type_totsz(it) * idx, obj, set);
1990 if (tok_jmp(','))
1991 break;
1994 tok_expect('}');