cpp: use a simple hash table instead of tab struct
[neatcc.git] / ncc.c
blobc8f35e358ef4c306e57814e3ac910295105101d7
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 = LABEL();
948 int l_fail = LABEL();
949 readbitor();
950 if (tok_see() != TOK2("&&"))
951 return;
952 o_fork();
953 ts_pop_de(NULL);
954 o_jz(l_fail);
955 while (!tok_jmp(TOK2("&&"))) {
956 readbitor();
957 ts_pop_de(NULL);
958 o_jz(l_fail);
960 o_num(1);
961 o_forkpush();
962 o_jmp(l_out);
963 o_label(l_fail);
964 o_num(0);
965 o_forkpush();
966 o_forkjoin();
967 o_label(l_out);
968 ts_push_bt(4 | BT_SIGNED);
971 static void reador(void)
973 int l_pass = LABEL();
974 int l_end = LABEL();
975 readand();
976 if (tok_see() != TOK2("||"))
977 return;
978 o_fork();
979 ts_pop_de(NULL);
980 o_jnz(l_pass);
981 while (!tok_jmp(TOK2("||"))) {
982 readand();
983 ts_pop_de(NULL);
984 o_jnz(l_pass);
986 o_num(0);
987 o_forkpush();
988 o_jmp(l_end);
989 o_label(l_pass);
990 o_num(1);
991 o_forkpush();
992 o_forkjoin();
993 o_label(l_end);
994 ts_push_bt(4 | BT_SIGNED);
997 static void readcexpr(void);
999 static int readcexpr_const(void)
1001 long c;
1002 if (o_popnum(&c))
1003 return -1;
1004 if (!c)
1005 nogen++;
1006 readcexpr();
1007 /* both branches yield the same type; so ignore the first */
1008 ts_pop_de(NULL);
1009 tok_expect(':');
1010 if (c)
1011 nogen++;
1012 else
1013 nogen--;
1014 readcexpr();
1015 /* making sure t->addr == 0 on both branches */
1016 ts_de(1);
1017 if (c)
1018 nogen--;
1019 return 0;
1022 static void readcexpr(void)
1024 reador();
1025 if (tok_jmp('?'))
1026 return;
1027 ncexpr++;
1028 ts_pop_de(NULL);
1029 o_fork();
1030 if (readcexpr_const()) {
1031 int l_fail = LABEL();
1032 int l_end = LABEL();
1033 struct type ret;
1034 o_jz(l_fail);
1035 readcexpr();
1036 /* both branches yield the same type; so ignore the first */
1037 ts_pop_de(&ret);
1038 if (!TYPE_VOID(&ret))
1039 o_forkpush();
1040 o_jmp(l_end);
1042 tok_expect(':');
1043 o_label(l_fail);
1044 readcexpr();
1045 /* making sure t->addr == 0 on both branches */
1046 ts_de(1);
1047 if (!TYPE_VOID(&ret)) {
1048 o_forkpush();
1049 o_forkjoin();
1051 o_label(l_end);
1053 ncexpr--;
1056 static void opassign(int op, int ptrop)
1058 struct type t = ts[nts - 1];
1059 o_tmpcopy();
1060 ts_push(&t);
1061 readexpr();
1062 if (op == O_ADD || op == O_SUB)
1063 ts_addop(op);
1064 else
1065 ts_binop(op);
1066 o_assign(TYPE_BT(&ts[nts - 2]));
1067 ts_pop(NULL);
1068 ts_de(0);
1071 static void doassign(void)
1073 struct type t = ts[nts - 1];
1074 if (!t.ptr && t.flags & T_STRUCT) {
1075 ts_pop(NULL);
1076 o_num(type_totsz(&t));
1077 o_memcpy();
1078 } else {
1079 ts_pop_de(NULL);
1080 o_assign(TYPE_BT(&ts[nts - 1]));
1081 ts_de(0);
1085 static void readexpr(void)
1087 readcexpr();
1088 if (!tok_jmp('=')) {
1089 readexpr();
1090 doassign();
1091 return;
1093 if (!tok_jmp(TOK2("+="))) {
1094 opassign(O_ADD, 1);
1095 return;
1097 if (!tok_jmp(TOK2("-="))) {
1098 opassign(O_SUB, 1);
1099 return;
1101 if (!tok_jmp(TOK2("*="))) {
1102 opassign(O_MUL, 0);
1103 return;
1105 if (!tok_jmp(TOK2("/="))) {
1106 opassign(O_DIV, 0);
1107 return;
1109 if (!tok_jmp(TOK2("%="))) {
1110 opassign(O_MOD, 0);
1111 return;
1113 if (!tok_jmp(TOK3("<<="))) {
1114 opassign(O_SHL, 0);
1115 return;
1117 if (!tok_jmp(TOK3(">>="))) {
1118 opassign(O_SHR, 0);
1119 return;
1121 if (!tok_jmp(TOK3("&="))) {
1122 opassign(O_AND, 0);
1123 return;
1125 if (!tok_jmp(TOK3("|="))) {
1126 opassign(O_OR, 0);
1127 return;
1129 if (!tok_jmp(TOK3("^="))) {
1130 opassign(O_XOR, 0);
1131 return;
1135 static void readestmt(void)
1137 do {
1138 o_tmpdrop(-1);
1139 nts = 0;
1140 readexpr();
1141 } while (!tok_jmp(','));
1144 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1146 static void globalinit(void *obj, int off, struct type *t)
1148 struct name *name = obj;
1149 char *elfname = *name->elfname ? name->elfname : name->name;
1150 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1151 struct type *t_de = &arrays[t->id].type;
1152 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1153 char *buf;
1154 int len;
1155 tok_expect(TOK_STR);
1156 tok_str(&buf, &len);
1157 o_dscpy(name->addr + off, buf, len);
1158 return;
1161 readexpr();
1162 o_dsset(elfname, off, TYPE_BT(t));
1163 ts_pop(NULL);
1166 static void readfunc(struct name *name, int flags);
1168 static void globaldef(void *data, struct name *name, unsigned flags)
1170 struct type *t = &name->type;
1171 char *elfname = *name->elfname ? name->elfname : name->name;
1172 int sz;
1173 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1174 if (~flags & F_EXTERN)
1175 arrays[t->id].n = initsize();
1176 sz = type_totsz(t);
1177 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1178 if (tok_see() == '=')
1179 name->addr = o_dsnew(elfname, sz, F_GLOBAL(flags));
1180 else
1181 o_bsnew(elfname, sz, F_GLOBAL(flags));
1183 global_add(name);
1184 if (!tok_jmp('='))
1185 initexpr(t, 0, name, globalinit);
1186 if (tok_see() == '{' && name->type.flags & T_FUNC)
1187 readfunc(name, flags);
1190 /* generate the address of local + off */
1191 static void o_localoff(long addr, int off)
1193 o_local(addr);
1194 if (off) {
1195 o_num(off);
1196 o_bop(O_ADD);
1200 static void localinit(void *obj, int off, struct type *t)
1202 long addr = *(long *) obj;
1203 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1204 struct type *t_de = &arrays[t->id].type;
1205 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1206 char *buf;
1207 int len;
1208 tok_expect(TOK_STR);
1209 tok_str(&buf, &len);
1210 o_localoff(addr, off);
1211 o_sym(tmp_str(buf, len));
1212 o_num(len);
1213 o_memcpy();
1214 o_tmpdrop(1);
1215 return;
1218 o_localoff(addr, off);
1219 ts_push(t);
1220 readexpr();
1221 doassign();
1222 ts_pop(NULL);
1223 o_tmpdrop(1);
1226 /* current function name */
1227 static char func_name[NAMELEN];
1229 static void localdef(void *data, struct name *name, unsigned flags)
1231 struct type *t = &name->type;
1232 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1233 global_add(name);
1234 return;
1236 if (flags & F_STATIC) {
1237 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1238 globaldef(data, name, flags);
1239 return;
1241 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1242 arrays[t->id].n = initsize();
1243 name->addr = o_mklocal(type_totsz(&name->type));
1244 local_add(name);
1245 if (!tok_jmp('=')) {
1246 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1247 o_local(name->addr);
1248 o_num(0);
1249 o_num(type_totsz(t));
1250 o_memset();
1251 o_tmpdrop(1);
1253 initexpr(t, 0, &name->addr, localinit);
1257 static void typedefdef(void *data, struct name *name, unsigned flags)
1259 typedef_add(name->name, &name->type);
1262 static void readstmt(void);
1264 static void readswitch(void)
1266 int o_break = l_break;
1267 long val_addr = o_mklocal(LONGSZ);
1268 struct type t;
1269 int ncases = 0; /* number of case labels */
1270 int l_failed = LABEL(); /* address of last failed jmp */
1271 int l_matched = LABEL(); /* address of last walk through jmp */
1272 int l_default = 0; /* default case label */
1273 l_break = LABEL();
1274 tok_expect('(');
1275 readexpr();
1276 ts_pop_de(&t);
1277 o_local(val_addr);
1278 o_tmpswap();
1279 o_assign(TYPE_BT(&t));
1280 ts_de(0);
1281 o_tmpdrop(1);
1282 tok_expect(')');
1283 tok_expect('{');
1284 while (tok_jmp('}')) {
1285 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1286 readstmt();
1287 continue;
1289 if (ncases)
1290 o_jmp(l_matched);
1291 if (tok_get() == TOK_CASE) {
1292 o_label(l_failed);
1293 l_failed = LABEL();
1294 caseexpr = 1;
1295 readexpr();
1296 ts_pop_de(NULL);
1297 caseexpr = 0;
1298 o_local(val_addr);
1299 o_deref(TYPE_BT(&t));
1300 o_bop(O_EQ);
1301 o_jz(l_failed);
1302 o_tmpdrop(1);
1303 } else {
1304 if (!ncases)
1305 o_jmp(l_failed);
1306 l_default = LABEL();
1307 o_label(l_default);
1309 tok_expect(':');
1310 o_label(l_matched);
1311 l_matched = LABEL();
1312 ncases++;
1314 o_rmlocal(val_addr, LONGSZ);
1315 o_jmp(l_break);
1316 o_label(l_failed);
1317 if (l_default)
1318 o_jmp(l_default);
1319 o_label(l_break);
1320 l_break = o_break;
1323 static char label_name[NLABELS][NAMELEN];
1324 static int label_ids[NLABELS];
1325 static int nlabels;
1327 static int label_id(char *name)
1329 int i;
1330 for (i = nlabels - 1; i >= 0; --i)
1331 if (!strcmp(label_name[i], name))
1332 return label_ids[i];
1333 strcpy(label_name[nlabels], name);
1334 label_ids[nlabels] = LABEL();
1335 return label_ids[nlabels++];
1338 static void readstmt(void)
1340 o_tmpdrop(-1);
1341 nts = 0;
1342 if (!tok_jmp('{')) {
1343 int _nlocals = nlocals;
1344 int _nglobals = nglobals;
1345 int _nenums = nenums;
1346 int _ntypedefs = ntypedefs;
1347 int _nstructs = nstructs;
1348 int _nfuncs = nfuncs;
1349 int _narrays = narrays;
1350 while (tok_jmp('}'))
1351 readstmt();
1352 nlocals = _nlocals;
1353 nenums = _nenums;
1354 ntypedefs = _ntypedefs;
1355 nstructs = _nstructs;
1356 nfuncs = _nfuncs;
1357 narrays = _narrays;
1358 nglobals = _nglobals;
1359 return;
1361 if (!readdefs(localdef, NULL)) {
1362 tok_expect(';');
1363 return;
1365 if (!tok_jmp(TOK_TYPEDEF)) {
1366 readdefs(typedefdef, NULL);
1367 tok_expect(';');
1368 return;
1370 if (!tok_jmp(TOK_IF)) {
1371 int l_fail = LABEL();
1372 int l_end = LABEL();
1373 tok_expect('(');
1374 readexpr();
1375 tok_expect(')');
1376 ts_pop_de(NULL);
1377 o_jz(l_fail);
1378 readstmt();
1379 if (!tok_jmp(TOK_ELSE)) {
1380 o_jmp(l_end);
1381 o_label(l_fail);
1382 readstmt();
1383 o_label(l_end);
1384 } else {
1385 o_label(l_fail);
1387 return;
1389 if (!tok_jmp(TOK_WHILE)) {
1390 int o_break = l_break;
1391 int o_cont = l_cont;
1392 l_break = LABEL();
1393 l_cont = LABEL();
1394 o_label(l_cont);
1395 tok_expect('(');
1396 readexpr();
1397 tok_expect(')');
1398 ts_pop_de(NULL);
1399 o_jz(l_break);
1400 readstmt();
1401 o_jmp(l_cont);
1402 o_label(l_break);
1403 l_break = o_break;
1404 l_cont = o_cont;
1405 return;
1407 if (!tok_jmp(TOK_DO)) {
1408 int o_break = l_break;
1409 int o_cont = l_cont;
1410 int l_beg = LABEL();
1411 l_break = LABEL();
1412 l_cont = LABEL();
1413 o_label(l_beg);
1414 readstmt();
1415 tok_expect(TOK_WHILE);
1416 tok_expect('(');
1417 o_label(l_cont);
1418 readexpr();
1419 ts_pop_de(NULL);
1420 o_jnz(l_beg);
1421 tok_expect(')');
1422 o_label(l_break);
1423 tok_expect(';');
1424 l_break = o_break;
1425 l_cont = o_cont;
1426 return;
1428 if (!tok_jmp(TOK_FOR)) {
1429 int o_break = l_break;
1430 int o_cont = l_cont;
1431 int l_check = LABEL(); /* for condition label */
1432 int l_body = LABEL(); /* for block label */
1433 l_cont = LABEL();
1434 l_break = LABEL();
1435 tok_expect('(');
1436 if (tok_see() != ';')
1437 readestmt();
1438 tok_expect(';');
1439 o_label(l_check);
1440 if (tok_see() != ';') {
1441 readestmt();
1442 ts_pop_de(NULL);
1443 o_jz(l_break);
1445 tok_expect(';');
1446 o_jmp(l_body);
1447 o_label(l_cont);
1448 if (tok_see() != ')')
1449 readestmt();
1450 tok_expect(')');
1451 o_jmp(l_check);
1452 o_label(l_body);
1453 readstmt();
1454 o_jmp(l_cont);
1455 o_label(l_break);
1456 l_break = o_break;
1457 l_cont = o_cont;
1458 return;
1460 if (!tok_jmp(TOK_SWITCH)) {
1461 readswitch();
1462 return;
1464 if (!tok_jmp(TOK_RETURN)) {
1465 int ret = tok_see() != ';';
1466 if (ret) {
1467 readexpr();
1468 ts_pop_de(NULL);
1470 tok_expect(';');
1471 o_ret(ret);
1472 return;
1474 if (!tok_jmp(TOK_BREAK)) {
1475 tok_expect(';');
1476 o_jmp(l_break);
1477 return;
1479 if (!tok_jmp(TOK_CONTINUE)) {
1480 tok_expect(';');
1481 o_jmp(l_cont);
1482 return;
1484 if (!tok_jmp(TOK_GOTO)) {
1485 tok_expect(TOK_NAME);
1486 o_jmp(label_id(tok_id()));
1487 tok_expect(';');
1488 return;
1490 readestmt();
1491 /* labels */
1492 if (!tok_jmp(':')) {
1493 o_label(label_id(tok_id()));
1494 return;
1496 tok_expect(';');
1499 static void readfunc(struct name *name, int flags)
1501 struct funcinfo *fi = &funcs[name->type.id];
1502 long beg = tok_addr();
1503 int i;
1504 strcpy(func_name, fi->name);
1505 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1506 for (i = 0; i < fi->nargs; i++) {
1507 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1508 strcpy(arg.name, fi->argnames[i]);
1509 local_add(&arg);
1511 /* first pass: collecting statistics */
1512 o_pass1();
1513 readstmt();
1514 tok_jump(beg);
1515 /* second pass: generating code */
1516 o_pass2();
1517 readstmt();
1518 o_func_end();
1519 func_name[0] = '\0';
1520 nlocals = 0;
1521 label = 0;
1522 nlabels = 0;
1525 static void readdecl(void)
1527 if (!tok_jmp(TOK_TYPEDEF)) {
1528 readdefs(typedefdef, NULL);
1529 tok_expect(';');
1530 return;
1532 readdefs_int(globaldef, NULL);
1533 tok_jmp(';');
1536 static void parse(void)
1538 while (tok_see() != TOK_EOF)
1539 readdecl();
1542 static void compat_macros(void)
1544 cpp_define("__STDC__", "");
1545 cpp_define("__linux__", "");
1546 cpp_define(I_ARCH, "");
1548 /* ignored keywords */
1549 cpp_define("const", "");
1550 cpp_define("register", "");
1551 cpp_define("volatile", "");
1552 cpp_define("inline", "");
1553 cpp_define("restrict", "");
1554 cpp_define("__inline__", "");
1555 cpp_define("__restrict__", "");
1556 cpp_define("__attribute__(x)", "");
1557 cpp_define("__builtin_va_list__", "long");
1560 int main(int argc, char *argv[])
1562 char obj[128] = "";
1563 int ofd;
1564 int i = 1;
1565 compat_macros();
1566 while (i < argc && argv[i][0] == '-') {
1567 if (argv[i][1] == 'I')
1568 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1569 if (argv[i][1] == 'D') {
1570 char *name = argv[i] + 2;
1571 char *def = "";
1572 char *eq = strchr(name, '=');
1573 if (eq) {
1574 *eq = '\0';
1575 def = eq + 1;
1577 cpp_define(name, def);
1579 if (argv[i][1] == 'o')
1580 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1581 i++;
1583 if (i == argc)
1584 die("neatcc: no file given\n");
1585 if (cpp_init(argv[i]))
1586 die("neatcc: cannot open <%s>\n", argv[i]);
1587 parse();
1588 if (!*obj) {
1589 strcpy(obj, argv[i]);
1590 obj[strlen(obj) - 1] = 'o';
1592 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1593 o_write(ofd);
1594 close(ofd);
1595 return 0;
1599 /* parsing function and variable declarations */
1601 /* read the base type of a variable */
1602 static int basetype(struct type *type, unsigned *flags)
1604 int sign = 1;
1605 int size = 4;
1606 int done = 0;
1607 int i = 0;
1608 int isunion;
1609 char name[NAMELEN] = "";
1610 *flags = 0;
1611 type->flags = 0;
1612 type->ptr = 0;
1613 type->addr = 0;
1614 while (!done) {
1615 switch (tok_see()) {
1616 case TOK_STATIC:
1617 *flags |= F_STATIC;
1618 break;
1619 case TOK_EXTERN:
1620 *flags |= F_EXTERN;
1621 break;
1622 case TOK_VOID:
1623 sign = 0;
1624 size = 0;
1625 done = 1;
1626 break;
1627 case TOK_INT:
1628 done = 1;
1629 break;
1630 case TOK_CHAR:
1631 size = 1;
1632 done = 1;
1633 break;
1634 case TOK_SHORT:
1635 size = 2;
1636 break;
1637 case TOK_LONG:
1638 size = LONGSZ;
1639 break;
1640 case TOK_SIGNED:
1641 break;
1642 case TOK_UNSIGNED:
1643 sign = 0;
1644 break;
1645 case TOK_UNION:
1646 case TOK_STRUCT:
1647 isunion = tok_get() == TOK_UNION;
1648 if (!tok_jmp(TOK_NAME))
1649 strcpy(name, tok_id());
1650 if (tok_see() == '{')
1651 type->id = struct_create(name, isunion);
1652 else
1653 type->id = struct_find(name, isunion);
1654 type->flags |= T_STRUCT;
1655 type->bt = LONGSZ;
1656 return 0;
1657 case TOK_ENUM:
1658 tok_get();
1659 tok_jmp(TOK_NAME);
1660 if (tok_see() == '{')
1661 enum_create();
1662 type->bt = 4 | BT_SIGNED;
1663 return 0;
1664 default:
1665 if (tok_see() == TOK_NAME) {
1666 int id = typedef_find(tok_id());
1667 if (id != -1) {
1668 tok_get();
1669 memcpy(type, &typedefs[id].type,
1670 sizeof(*type));
1671 return 0;
1674 if (!i)
1675 return 1;
1676 done = 1;
1677 continue;
1679 i++;
1680 tok_get();
1682 type->bt = size | (sign ? BT_SIGNED : 0);
1683 return 0;
1686 static void readptrs(struct type *type)
1688 while (!tok_jmp('*')) {
1689 type->ptr++;
1690 if (!type->bt)
1691 type->bt = 1;
1695 /* read function arguments */
1696 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1698 int nargs = 0;
1699 tok_expect('(');
1700 *varg = 0;
1701 while (tok_see() != ')') {
1702 if (!tok_jmp(TOK3("..."))) {
1703 *varg = 1;
1704 break;
1706 if (readname(&args[nargs], argnames[nargs], NULL)) {
1707 /* argument has no type, assume int */
1708 tok_expect(TOK_NAME);
1709 memset(&args[nargs], 0, sizeof(struct type));
1710 args[nargs].bt = 4 | BT_SIGNED;
1711 strcpy(argnames[nargs], tok_id());
1713 /* argument arrays are pointers */
1714 array2ptr(&args[nargs]);
1715 nargs++;
1716 if (tok_jmp(','))
1717 break;
1719 tok_expect(')');
1720 /* void argument */
1721 if (nargs == 1 && !TYPE_BT(&args[0]))
1722 return 0;
1723 return nargs;
1726 /* read K&R function arguments */
1727 static void krdef(void *data, struct name *name, unsigned flags)
1729 struct funcinfo *fi = data;
1730 int i;
1731 for (i = 0; i < fi->nargs; i++)
1732 if (!strcmp(fi->argnames[i], name->name))
1733 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1737 * readarrays() parses array specifiers when reading a definition in
1738 * readname(). The "type" parameter contains the type contained in the
1739 * inner array; for instance, type in "int *a[10][20]" would be an int
1740 * pointer. When returning, the "type" parameter is changed to point
1741 * to the final array. The function returns a pointer to the type in
1742 * the inner array; this is useful when the type is not complete yet,
1743 * like when creating an array of function pointers as in
1744 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1746 static struct type *readarrays(struct type *type)
1748 long arsz[16];
1749 struct type *inner = NULL;
1750 int nar = 0;
1751 int i;
1752 while (!tok_jmp('[')) {
1753 long n = 0;
1754 if (tok_jmp(']')) {
1755 readexpr();
1756 ts_pop_de(NULL);
1757 if (o_popnum(&n))
1758 err("const expr expected\n");
1759 tok_expect(']');
1761 arsz[nar++] = n;
1763 for (i = nar - 1; i >= 0; i--) {
1764 type->id = array_add(type, arsz[i]);
1765 if (!inner)
1766 inner = &arrays[type->id].type;
1767 type->flags = T_ARRAY;
1768 type->bt = LONGSZ;
1769 type->ptr = 0;
1771 return inner;
1775 * readname() reads a variable definition; the name is copied into
1776 * "name" and the type is copied into "main" argument. The "base"
1777 * argument, if not NULL, indicates the base type of the variable.
1778 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1779 * "int". If NULL, basetype() is called directly to read the base
1780 * type of the variable. readname() returns zero, only if the
1781 * variable can be read.
1783 static int readname(struct type *main, char *name, struct type *base)
1785 struct type tpool[3];
1786 int npool = 0;
1787 struct type *type = &tpool[npool++];
1788 struct type *ptype = NULL; /* type inside parenthesis */
1789 struct type *btype = NULL; /* type before parenthesis */
1790 struct type *inner;
1791 unsigned flags;
1792 memset(tpool, 0, sizeof(tpool));
1793 if (name)
1794 *name = '\0';
1795 if (!base) {
1796 if (basetype(type, &flags))
1797 return 1;
1798 } else {
1799 memcpy(type, base, sizeof(*base));
1801 readptrs(type);
1802 if (!tok_jmp('(')) {
1803 btype = type;
1804 type = &tpool[npool++];
1805 ptype = type;
1806 readptrs(type);
1808 if (!tok_jmp(TOK_NAME) && name)
1809 strcpy(name, tok_id());
1810 inner = readarrays(type);
1811 if (ptype && inner)
1812 ptype = inner;
1813 if (ptype)
1814 tok_expect(')');
1815 if (tok_see() == '(') {
1816 struct type args[NARGS];
1817 char argnames[NARGS][NAMELEN];
1818 int varg = 0;
1819 int nargs = readargs(args, argnames, &varg);
1820 if (!ptype) {
1821 btype = type;
1822 type = &tpool[npool++];
1823 ptype = type;
1825 ptype->flags = T_FUNC;
1826 ptype->bt = LONGSZ;
1827 ptype->id = func_create(btype, name, argnames, args, nargs, varg);
1828 if (tok_see() != ';')
1829 while (tok_see() != '{' && !readdefs(krdef, &funcs[ptype->id]))
1830 tok_expect(';');
1831 } else {
1832 if (ptype && readarrays(type))
1833 array2ptr(type);
1835 memcpy(main, type, sizeof(*type));
1836 return 0;
1839 static int readtype(struct type *type)
1841 return readname(type, NULL, NULL);
1845 * readdef() reads a variable definitions statement. The definition
1846 * statement can appear in anywhere: global variables, function
1847 * local variables, struct fields, and typedefs. For each defined
1848 * variable, def() callback is called with the appropriate name
1849 * struct and flags; the callback should finish parsing the definition
1850 * by possibly reading the initializer expression and saving the name
1851 * struct.
1853 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1854 void *data)
1856 struct type base;
1857 unsigned base_flags;
1858 if (basetype(&base, &base_flags))
1859 return 1;
1860 if (tok_see() == ';' || tok_see() == '{')
1861 return 0;
1862 do {
1863 struct name name = {{""}};
1864 if (readname(&name.type, name.name, &base))
1865 break;
1866 def(data, &name, base_flags);
1867 } while (!tok_jmp(','));
1868 return 0;
1871 /* just like readdefs, but default to int type; for handling K&R functions */
1872 static int readdefs_int(void (*def)(void *data, struct name *name, unsigned flags),
1873 void *data)
1875 struct type base;
1876 unsigned flags = 0;
1877 if (basetype(&base, &flags)) {
1878 if (tok_see() != TOK_NAME)
1879 return 1;
1880 memset(&base, 0, sizeof(base));
1881 base.bt = 4 | BT_SIGNED;
1883 if (tok_see() != ';') {
1884 do {
1885 struct name name = {{""}};
1886 if (readname(&name.type, name.name, &base))
1887 break;
1888 def(data, &name, flags);
1889 } while (!tok_jmp(','));
1891 return 0;
1895 /* parsing initializer expressions */
1897 static void jumpbrace(void)
1899 int depth = 0;
1900 while (tok_see() != '}' || depth--)
1901 if (tok_get() == '{')
1902 depth++;
1903 tok_expect('}');
1906 /* compute the size of the initializer expression */
1907 static int initsize(void)
1909 long addr = tok_addr();
1910 int n = 0;
1911 if (tok_jmp('='))
1912 return 0;
1913 if (!tok_jmp(TOK_STR)) {
1914 tok_str(NULL, &n);
1915 tok_jump(addr);
1916 return n;
1918 tok_expect('{');
1919 while (tok_jmp('}')) {
1920 long idx = n;
1921 if (!tok_jmp('[')) {
1922 readexpr();
1923 ts_pop_de(NULL);
1924 o_popnum(&idx);
1925 tok_expect(']');
1926 tok_expect('=');
1928 if (n < idx + 1)
1929 n = idx + 1;
1930 while (tok_see() != '}' && tok_see() != ',')
1931 if (tok_get() == '{')
1932 jumpbrace();
1933 tok_jmp(',');
1935 tok_jump(addr);
1936 return n;
1939 static struct type *innertype(struct type *t)
1941 if (t->flags & T_ARRAY && !t->ptr)
1942 return innertype(&arrays[t->id].type);
1943 return t;
1946 /* read the initializer expression and initialize basic types using set() cb */
1947 static void initexpr(struct type *t, int off, void *obj,
1948 void (*set)(void *obj, int off, struct type *t))
1950 if (tok_jmp('{')) {
1951 set(obj, off, t);
1952 return;
1954 if (!t->ptr && t->flags & T_STRUCT) {
1955 struct structinfo *si = &structs[t->id];
1956 int i;
1957 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1958 struct name *field = &si->fields[i];
1959 if (!tok_jmp('.')) {
1960 tok_expect(TOK_NAME);
1961 field = struct_field(t->id, tok_id());
1962 tok_expect('=');
1964 initexpr(&field->type, off + field->addr, obj, set);
1965 if (tok_jmp(','))
1966 break;
1968 } else if (t->flags & T_ARRAY) {
1969 struct type *t_de = &arrays[t->id].type;
1970 int i;
1971 /* handling extra braces as in: char s[] = {"sth"} */
1972 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1973 set(obj, off, t);
1974 tok_expect('}');
1975 return;
1977 for (i = 0; tok_see() != '}'; i++) {
1978 long idx = i;
1979 struct type *it = t_de;
1980 if (!tok_jmp('[')) {
1981 readexpr();
1982 ts_pop_de(NULL);
1983 o_popnum(&idx);
1984 tok_expect(']');
1985 tok_expect('=');
1987 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1988 !(it->flags & T_ARRAY)))
1989 it = innertype(t_de);
1990 initexpr(it, off + type_totsz(it) * idx, obj, set);
1991 if (tok_jmp(','))
1992 break;
1995 tok_expect('}');