x64: use push instruction for saving registers
[neatcc.git] / ncc.c
blobb0d1c5f77945ae1dffe56a63d53e72e2dc98e6d5
1 /*
2 * THE NEATCC C COMPILER
4 * Copyright (C) 2010-2016 Ali Gholami Rudi
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19 * neatcc parser
21 * The parser reads tokens from the tokenizer (tok_*) and calls the
22 * appropriate code generation functions (o_*). The generator
23 * maintains a stack of values pushed via, for instance, o_num()
24 * and generates the necessary code for the accesses to the items
25 * in this stack, like o_bop() for performing a binary operations
26 * on the top two items of the stack. The parser maintains the
27 * types of values pushed to the generator stack in its type stack
28 * (ts_*). For instance, for binary operations two types are
29 * popped first and the resulting type is pushed to the type stack
30 * (ts_binop()).
33 #include <ctype.h>
34 #include <fcntl.h>
35 #include <unistd.h>
36 #include <stdarg.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <stdio.h>
40 #include <sys/stat.h>
41 #include <sys/types.h>
42 #include "ncc.h"
44 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
45 #define MIN(a, b) ((a) < (b) ? (a) : (b))
46 #define MAX(a, b) ((a) < (b) ? (b) : (a))
48 #define TYPE_BT(t) ((t)->ptr ? ULNG : (t)->bt)
49 #define TYPE_SZ(t) ((t)->ptr ? ULNG : (t)->bt & T_MSIZE)
50 #define TYPE_VOID(t) (!(t)->bt && !(t)->flags && !(t)->ptr)
52 /* type->flag values */
53 #define T_ARRAY 0x01
54 #define T_STRUCT 0x02
55 #define T_FUNC 0x04
57 /* variable definition flags */
58 #define F_STATIC 0x01
59 #define F_EXTERN 0x02
61 struct type {
62 unsigned bt;
63 unsigned flags;
64 int ptr;
65 int id; /* for structs, functions and arrays */
66 int addr; /* the address is passed to gen.c; deref for value */
69 /* type stack */
70 static struct type ts[NTMPS];
71 static int nts;
73 static void ts_push_bt(unsigned bt)
75 ts[nts].ptr = 0;
76 ts[nts].flags = 0;
77 ts[nts].addr = 0;
78 ts[nts++].bt = bt;
79 #ifdef NCCWORDCAST
80 o_cast(bt); /* casting to architecture word */
81 #endif
84 static void ts_push(struct type *t)
86 struct type *d = &ts[nts++];
87 memcpy(d, t, sizeof(*t));
90 static void ts_push_addr(struct type *t)
92 ts_push(t);
93 ts[nts - 1].addr = 1;
96 static void ts_pop(struct type *type)
98 nts--;
99 if (type)
100 *type = ts[nts];
103 void err(char *fmt, ...)
105 va_list ap;
106 char msg[512];
107 va_start(ap, fmt);
108 vsprintf(msg, fmt, ap);
109 va_end(ap);
110 die("%s: %s", cpp_loc(tok_addr()), msg);
113 void *mextend(void *old, long oldsz, long newsz, long memsz)
115 void *new = malloc(newsz * memsz);
116 memcpy(new, old, oldsz * memsz);
117 memset(new + oldsz * memsz, 0, (newsz - oldsz) * memsz);
118 free(old);
119 return new;
122 struct name {
123 char name[NAMELEN];
124 char elfname[NAMELEN]; /* local elf name for function static variables */
125 struct type type;
126 long addr; /* local stack offset, global data addr, struct offset */
129 static struct name *locals;
130 static int locals_n, locals_sz;
131 static struct name *globals;
132 static int globals_n, globals_sz;
134 static void local_add(struct name *name)
136 if (locals_n >= locals_sz) {
137 locals_sz = MAX(128, locals_sz * 2);
138 locals = mextend(locals, locals_n, locals_sz, sizeof(locals[0]));
140 memcpy(&locals[locals_n++], name, sizeof(*name));
143 static int local_find(char *name)
145 int i;
146 for (i = locals_n - 1; i >= 0; --i)
147 if (!strcmp(locals[i].name, name))
148 return i;
149 return -1;
152 static int global_find(char *name)
154 int i;
155 for (i = globals_n - 1; i >= 0; i--)
156 if (!strcmp(name, globals[i].name))
157 return i;
158 return -1;
161 static void global_add(struct name *name)
163 if (globals_n >= globals_sz) {
164 globals_sz = MAX(128, globals_sz * 2);
165 globals = mextend(globals, globals_n, globals_sz, sizeof(globals[0]));
167 memcpy(&globals[globals_n++], name, sizeof(*name));
170 #define LABEL() (++label)
172 static int label; /* last used label id */
173 static int l_break; /* current break label */
174 static int l_cont; /* current continue label */
176 static struct enumval {
177 char name[NAMELEN];
178 int n;
179 } *enums;
180 static int enums_n, enums_sz;
182 static void enum_add(char *name, int val)
184 struct enumval *ev;
185 if (enums_n >= enums_sz) {
186 enums_sz = MAX(128, enums_sz * 2);
187 enums = mextend(enums, enums_n, enums_sz, sizeof(enums[0]));
189 ev = &enums[enums_n++];
190 strcpy(ev->name, name);
191 ev->n = val;
194 static int enum_find(int *val, char *name)
196 int i;
197 for (i = enums_n - 1; i >= 0; --i)
198 if (!strcmp(name, enums[i].name)) {
199 *val = enums[i].n;
200 return 0;
202 return 1;
205 static struct typdefinfo {
206 char name[NAMELEN];
207 struct type type;
208 } *typedefs;
209 static int typedefs_n, typedefs_sz;
211 static void typedef_add(char *name, struct type *type)
213 struct typdefinfo *ti;
214 if (typedefs_n >= typedefs_sz) {
215 typedefs_sz = MAX(128, typedefs_sz * 2);
216 typedefs = mextend(typedefs, typedefs_n, typedefs_sz,
217 sizeof(typedefs[0]));
219 ti = &typedefs[typedefs_n++];
220 strcpy(ti->name, name);
221 memcpy(&ti->type, type, sizeof(*type));
224 static int typedef_find(char *name)
226 int i;
227 for (i = typedefs_n - 1; i >= 0; --i)
228 if (!strcmp(name, typedefs[i].name))
229 return i;
230 return -1;
233 static struct array {
234 struct type type;
235 int n;
236 } *arrays;
237 static int arrays_n, arrays_sz;
239 static int array_add(struct type *type, int n)
241 struct array *a;
242 if (arrays_n >= arrays_sz) {
243 arrays_sz = MAX(128, arrays_sz * 2);
244 arrays = mextend(arrays, arrays_n, arrays_sz, sizeof(arrays[0]));
246 a = &arrays[arrays_n++];
247 memcpy(&a->type, type, sizeof(*type));
248 a->n = n;
249 return a - arrays;
252 static void array2ptr(struct type *t)
254 if (t->flags & T_ARRAY && !t->ptr) {
255 memcpy(t, &arrays[t->id].type, sizeof(*t));
256 t->ptr++;
260 static struct structinfo {
261 char name[NAMELEN];
262 struct name fields[NFIELDS];
263 int nfields;
264 int isunion;
265 int size;
266 } *structs;
267 static int structs_n, structs_sz;
269 static int struct_find(char *name, int isunion)
271 int i;
272 for (i = structs_n - 1; i >= 0; --i)
273 if (*structs[i].name && !strcmp(name, structs[i].name) &&
274 structs[i].isunion == isunion)
275 return i;
276 if (structs_n >= structs_sz) {
277 structs_sz = MAX(128, structs_sz * 2);
278 structs = mextend(structs, structs_n, structs_sz, sizeof(structs[0]));
280 i = structs_n++;
281 memset(&structs[i], 0, sizeof(structs[i]));
282 strcpy(structs[i].name, name);
283 structs[i].isunion = isunion;
284 return i;
287 static struct name *struct_field(int id, char *name)
289 struct structinfo *si = &structs[id];
290 int i;
291 for (i = 0; i < si->nfields; i++)
292 if (!strcmp(name, si->fields[i].name))
293 return &si->fields[i];
294 err("unknown field <%s>\n", name);
295 return NULL;
298 /* return t's size */
299 static int type_totsz(struct type *t)
301 if (t->ptr)
302 return ULNG;
303 if (t->flags & T_ARRAY)
304 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
305 return t->flags & T_STRUCT ? structs[t->id].size : T_SZ(t->bt);
308 /* return t's dereferenced size */
309 static unsigned type_szde(struct type *t)
311 struct type de = *t;
312 array2ptr(&de);
313 de.ptr--;
314 return type_totsz(&de);
317 /* dereference stack top if t->addr (ie. address is pushed to gen.c) */
318 static void ts_de(int deref)
320 struct type *t = &ts[nts - 1];
321 array2ptr(t);
322 if (deref && t->addr && (t->ptr || !(t->flags & T_FUNC)))
323 o_deref(TYPE_BT(t));
324 t->addr = 0;
327 /* pop stack pop to *t and dereference if t->addr */
328 static void ts_pop_de(struct type *t)
330 ts_de(1);
331 ts_pop(t);
334 /* pop the top 2 stack values and dereference them if t->addr */
335 static void ts_pop_de2(struct type *t1, struct type *t2)
337 ts_pop_de(t1);
338 o_tmpswap();
339 ts_pop_de(t2);
340 o_tmpswap();
343 /* the previous identifier; to handle labels */
344 static char tok_previden[NAMELEN];
346 static char *tok_iden(void)
348 snprintf(tok_previden, sizeof(tok_previden), "%s", tok_get());
349 return tok_previden;
352 static int tok_jmp(char *tok)
354 if (strcmp(tok, tok_see()))
355 return 1;
356 tok_get();
357 return 0;
360 static int tok_comes(char *tok)
362 return !strcmp(tok, tok_see());
365 static void tok_req(char *tok)
367 char *got = tok_get();
368 if (strcmp(tok, got))
369 err("syntax error (expected <%s> but got <%s>)\n", tok, got);
372 static int tok_grp(void)
374 int c = (unsigned char) tok_see()[0];
375 if (c == '"')
376 return '"';
377 if (c == '\'' || isdigit(c))
378 return '0';
379 if (c == '_' || isalpha(c))
380 return 'a';
381 return 0;
384 /* the result of a binary operation on variables of type bt1 and bt2 */
385 static unsigned bt_op(unsigned bt1, unsigned bt2)
387 int sz = MAX(T_SZ(bt1), T_SZ(bt2));
388 return ((bt1 | bt2) & T_MSIGN) | MAX(sz, UINT);
391 /* the result of a unary operation on variables of bt */
392 static unsigned bt_uop(unsigned bt)
394 return bt_op(bt, UINT);
397 /* push the result of a binary operation on the type stack */
398 static void ts_binop(int op)
400 struct type t1, t2;
401 unsigned bt1, bt2, bt;
402 ts_pop_de2(&t1, &t2);
403 bt1 = TYPE_BT(&t1);
404 bt2 = TYPE_BT(&t2);
405 bt = bt_op(bt1, bt2);
406 if (op == O_DIV || op == O_MOD)
407 bt = T_MK(bt2 & T_MSIGN, bt);
408 o_bop(O_MK(op, bt));
409 ts_push_bt(bt);
412 /* push the result of an additive binary operation on the type stack */
413 static void ts_addop(int op)
415 struct type t1, t2;
416 ts_pop_de2(&t1, &t2);
417 if (!t1.ptr && !t2.ptr) {
418 o_bop(op);
419 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
420 return;
422 if (t1.ptr && !t2.ptr)
423 o_tmpswap();
424 if (!t1.ptr && t2.ptr)
425 if (type_szde(&t2) > 1) {
426 o_num(type_szde(&t2));
427 o_bop(O_MUL);
429 if (t1.ptr && !t2.ptr)
430 o_tmpswap();
431 o_bop(op);
432 if (t1.ptr && t2.ptr) {
433 int sz = type_szde(&t1);
434 if (sz > 1) {
435 o_num(sz);
436 o_bop(O_DIV);
438 ts_push_bt(SLNG);
439 } else {
440 ts_push(t1.ptr ? &t1 : &t2);
444 /* function prototypes for parsing function and variable declarations */
445 static int readname(struct type *main, char *name, struct type *base);
446 static int readtype(struct type *type);
447 static int readdefs(void (*def)(long data, struct name *name, unsigned flags),
448 long data);
449 static int readdefs_int(void (*def)(long data, struct name *name, unsigned flags),
450 long data);
452 /* function prototypes for parsing initializer expressions */
453 static int initsize(void);
454 static void initexpr(struct type *t, int off, void *obj,
455 void (*set)(void *obj, int off, struct type *t));
457 static int type_alignment(struct type *t)
459 if (t->flags & T_ARRAY && !t->ptr)
460 return type_alignment(&arrays[t->id].type);
461 if (t->flags & T_STRUCT && !t->ptr)
462 return type_alignment(&structs[t->id].fields[0].type);
463 return MIN(ULNG, type_totsz(t));
466 static void structdef(long data, struct name *name, unsigned flags)
468 struct structinfo *si = &structs[data];
469 if (si->isunion) {
470 name->addr = 0;
471 if (si->size < type_totsz(&name->type))
472 si->size = type_totsz(&name->type);
473 } else {
474 struct type *t = &name->type;
475 int alignment = type_alignment(t);
476 if (t->flags & T_ARRAY && !t->ptr)
477 alignment = MIN(ULNG, type_totsz(&arrays[t->id].type));
478 si->size = ALIGN(si->size, alignment);
479 name->addr = si->size;
480 si->size += type_totsz(&name->type);
482 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
485 static int struct_create(char *name, int isunion)
487 int id = struct_find(name, isunion);
488 tok_req("{");
489 while (tok_jmp("}")) {
490 readdefs(structdef, id);
491 tok_req(";");
493 return id;
496 static void readexpr(void);
498 static void enum_create(void)
500 long n = 0;
501 tok_req("{");
502 while (tok_jmp("}")) {
503 char name[NAMELEN];
504 strcpy(name, tok_get());
505 if (!tok_jmp("=")) {
506 readexpr();
507 ts_pop_de(NULL);
508 if (o_popnum(&n))
509 err("const expr expected!\n");
511 enum_add(name, n++);
512 tok_jmp(",");
516 /* used to differentiate labels from case and cond exprs */
517 static int ncexpr;
518 static int caseexpr;
520 static void readpre(void);
522 static char *tmp_str(char *buf, int len)
524 static char name[NAMELEN];
525 static int id;
526 sprintf(name, "__neatcc.s%d", id++);
527 buf[len] = '\0';
528 o_dscpy(o_dsnew(name, len + 1, 0), buf, len + 1);
529 return name;
532 static void readprimary(void)
534 if (tok_grp() == '0') {
535 long n;
536 int bt = tok_num(tok_get(), &n);
537 o_num(n);
538 ts_push_bt(bt);
539 return;
541 if (tok_grp() == '"') {
542 struct type t = {}; /* char type inside the arrays */
543 struct type a = {}; /* the char array type */
544 char *buf = tok_get() + 1;
545 int len = tok_len() - 2;
546 t.bt = 1 | T_MSIGN;
547 a.id = array_add(&t, len + 1);
548 a.flags = T_ARRAY;
549 o_sym(tmp_str(buf, len));
550 ts_push(&a);
551 return;
553 if (tok_grp() == 'a') {
554 struct name unkn = {""};
555 char *name = unkn.name;
556 int n;
557 strcpy(name, tok_iden());
558 /* don't search for labels here */
559 if (!ncexpr && !caseexpr && tok_comes(":"))
560 return;
561 if ((n = local_find(name)) != -1) {
562 struct name *l = &locals[n];
563 o_local(l->addr);
564 ts_push_addr(&l->type);
565 return;
567 if ((n = global_find(name)) != -1) {
568 struct name *g = &globals[n];
569 o_sym(*g->elfname ? g->elfname : g->name);
570 ts_push_addr(&g->type);
571 return;
573 if (!enum_find(&n, name)) {
574 o_num(n);
575 ts_push_bt(SINT);
576 return;
578 if (!tok_comes("("))
579 err("unknown symbol <%s>\n", name);
580 global_add(&unkn);
581 o_sym(unkn.name);
582 ts_push_bt(ULNG);
583 return;
585 if (!tok_jmp("(")) {
586 struct type t;
587 if (!readtype(&t)) {
588 struct type o;
589 tok_req(")");
590 readpre();
591 ts_pop_de(&o);
592 ts_push(&t);
593 if (!t.ptr || !o.ptr)
594 o_cast(TYPE_BT(&t));
595 } else {
596 readexpr();
597 while (tok_jmp(")")) {
598 tok_req(",");
599 ts_pop(NULL);
600 o_tmpdrop(1);
601 readexpr();
604 return;
608 static void arrayderef(void)
610 struct type t;
611 int sz;
612 ts_pop_de(NULL);
613 ts_pop(&t);
614 if (!(t.flags & T_ARRAY && !t.ptr) && t.addr) {
615 o_tmpswap();
616 o_deref(TYPE_BT(&t));
617 o_tmpswap();
619 array2ptr(&t);
620 t.ptr--;
621 sz = type_totsz(&t);
622 t.addr = 1;
623 if (sz > 1) {
624 o_num(sz);
625 o_bop(O_MUL);
627 o_bop(O_ADD);
628 ts_push(&t);
631 static void inc_post(int op)
633 struct type t = ts[nts - 1];
634 /* pushing the value before inc */
635 o_tmpcopy();
636 ts_de(1);
637 o_tmpswap();
639 /* increment by 1 or pointer size */
640 o_tmpcopy();
641 ts_push(&t);
642 ts_pop_de(&t);
643 o_num(t.ptr > 0 ? type_szde(&t) : 1);
644 o_bop(op);
646 /* assign back */
647 o_assign(TYPE_BT(&t));
648 o_tmpdrop(1);
651 static void readfield(void)
653 struct name *field;
654 struct type t;
655 ts_pop(&t);
656 array2ptr(&t);
657 field = struct_field(t.id, tok_get());
658 if (field->addr) {
659 o_num(field->addr);
660 o_bop(O_ADD);
662 ts_push_addr(&field->type);
665 static struct funcinfo {
666 struct type args[NARGS];
667 struct type ret;
668 int nargs;
669 int varg;
670 /* function and argument names; useful only when defining */
671 char argnames[NARGS][NAMELEN];
672 char name[NAMELEN];
673 } *funcs;
674 static int funcs_n, funcs_sz;
676 static int func_create(struct type *ret, char *name, char argnames[][NAMELEN],
677 struct type *args, int nargs, int varg)
679 struct funcinfo *fi;
680 int i;
681 if (funcs_n >= funcs_sz) {
682 funcs_sz = MAX(128, funcs_sz * 2);
683 funcs = mextend(funcs, funcs_n, funcs_sz, sizeof(funcs[0]));
685 fi = &funcs[funcs_n++];
686 memcpy(&fi->ret, ret, sizeof(*ret));
687 for (i = 0; i < nargs; i++)
688 memcpy(&fi->args[i], &args[i], sizeof(*ret));
689 fi->nargs = nargs;
690 fi->varg = varg;
691 strcpy(fi->name, name ? name : "");
692 for (i = 0; i < nargs; i++)
693 strcpy(fi->argnames[i], argnames[i]);
694 return fi - funcs;
697 static void readcall(void)
699 struct type t;
700 struct funcinfo *fi;
701 int argc = 0;
702 ts_pop(&t);
703 if (t.flags & T_FUNC && t.ptr > 0)
704 o_deref(ULNG);
705 if (!tok_comes(")")) {
706 do {
707 readexpr();
708 ts_pop_de(NULL);
709 argc++;
710 } while (!tok_jmp(","));
712 tok_req(")");
713 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
714 o_call(argc, fi ? TYPE_BT(&fi->ret) : SINT);
715 if (fi) {
716 if (TYPE_BT(&fi->ret))
717 o_cast(TYPE_BT(&fi->ret));
718 ts_push(&fi->ret);
719 } else {
720 ts_push_bt(SINT);
724 static void readpost(void)
726 readprimary();
727 while (1) {
728 if (!tok_jmp("[")) {
729 readexpr();
730 tok_req("]");
731 arrayderef();
732 continue;
734 if (!tok_jmp("(")) {
735 readcall();
736 continue;
738 if (!tok_jmp("++")) {
739 inc_post(O_ADD);
740 continue;
742 if (!tok_jmp("--")) {
743 inc_post(O_SUB);
744 continue;
746 if (!tok_jmp(".")) {
747 readfield();
748 continue;
750 if (!tok_jmp("->")) {
751 ts_de(1);
752 readfield();
753 continue;
755 break;
759 static void inc_pre(int op)
761 struct type t;
762 readpre();
763 /* copy the destination */
764 o_tmpcopy();
765 ts_push(&ts[nts - 1]);
766 /* increment by 1 or pointer size */
767 ts_pop_de(&t);
768 o_num(t.ptr > 0 ? type_szde(&t) : 1);
769 o_bop(op);
770 /* assign the result */
771 o_assign(TYPE_BT(&t));
772 ts_de(0);
775 static void readpre(void)
777 struct type t;
778 if (!tok_jmp("&")) {
779 readpre();
780 ts_pop(&t);
781 if (!t.addr)
782 err("cannot use the address\n");
783 t.ptr++;
784 t.addr = 0;
785 ts_push(&t);
786 return;
788 if (!tok_jmp("*")) {
789 readpre();
790 ts_pop(&t);
791 array2ptr(&t);
792 if (!t.ptr)
793 err("dereferencing non-pointer\n");
794 if (t.addr)
795 o_deref(TYPE_BT(&t));
796 t.ptr--;
797 t.addr = 1;
798 ts_push(&t);
799 return;
801 if (!tok_jmp("!")) {
802 readpre();
803 ts_pop_de(NULL);
804 o_uop(O_LNOT);
805 ts_push_bt(SINT);
806 return;
808 if (!tok_jmp("+")) {
809 readpre();
810 ts_de(1);
811 ts_pop(&t);
812 ts_push_bt(bt_uop(TYPE_BT(&t)));
813 return;
815 if (!tok_jmp("-")) {
816 readpre();
817 ts_de(1);
818 ts_pop(&t);
819 o_uop(O_NEG);
820 ts_push_bt(bt_uop(TYPE_BT(&t)));
821 return;
823 if (!tok_jmp("~")) {
824 readpre();
825 ts_de(1);
826 ts_pop(&t);
827 o_uop(O_NOT);
828 ts_push_bt(bt_uop(TYPE_BT(&t)));
829 return;
831 if (!tok_jmp("++")) {
832 inc_pre(O_ADD);
833 return;
835 if (!tok_jmp("--")) {
836 inc_pre(O_SUB);
837 return;
839 if (!tok_jmp("sizeof")) {
840 struct type t;
841 int op = !tok_jmp("(");
842 if (readtype(&t)) {
843 long m = o_mark();
844 if (op)
845 readexpr();
846 else
847 readpre();
848 o_back(m);
849 ts_pop(&t);
850 o_tmpdrop(1);
852 o_num(type_totsz(&t));
853 ts_push_bt(ULNG);
854 if (op)
855 tok_req(")");
856 return;
858 readpost();
861 static void readmul(void)
863 readpre();
864 while (1) {
865 if (!tok_jmp("*")) {
866 readpre();
867 ts_binop(O_MUL);
868 continue;
870 if (!tok_jmp("/")) {
871 readpre();
872 ts_binop(O_DIV);
873 continue;
875 if (!tok_jmp("%")) {
876 readpre();
877 ts_binop(O_MOD);
878 continue;
880 break;
884 static void readadd(void)
886 readmul();
887 while (1) {
888 if (!tok_jmp("+")) {
889 readmul();
890 ts_addop(O_ADD);
891 continue;
893 if (!tok_jmp("-")) {
894 readmul();
895 ts_addop(O_SUB);
896 continue;
898 break;
902 static void shift(int op)
904 struct type t;
905 readadd();
906 ts_pop_de2(NULL, &t);
907 o_bop(O_MK(op, TYPE_BT(&t)));
908 ts_push_bt(bt_uop(TYPE_BT(&t)));
911 static void readshift(void)
913 readadd();
914 while (1) {
915 if (!tok_jmp("<<")) {
916 shift(O_SHL);
917 continue;
919 if (!tok_jmp(">>")) {
920 shift(O_SHR);
921 continue;
923 break;
927 static void cmp(int op)
929 struct type t1, t2;
930 int bt;
931 readshift();
932 ts_pop_de2(&t1, &t2);
933 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
934 o_bop(O_MK(op, bt));
935 ts_push_bt(SINT);
938 static void readcmp(void)
940 readshift();
941 while (1) {
942 if (!tok_jmp("<")) {
943 cmp(O_LT);
944 continue;
946 if (!tok_jmp(">")) {
947 cmp(O_GT);
948 continue;
950 if (!tok_jmp("<=")) {
951 cmp(O_LE);
952 continue;
954 if (!tok_jmp(">=")) {
955 cmp(O_GE);
956 continue;
958 break;
962 static void eq(int op)
964 readcmp();
965 ts_pop_de2(NULL, NULL);
966 o_bop(op);
967 ts_push_bt(SINT);
970 static void readeq(void)
972 readcmp();
973 while (1) {
974 if (!tok_jmp("==")) {
975 eq(O_EQ);
976 continue;
978 if (!tok_jmp("!=")) {
979 eq(O_NE);
980 continue;
982 break;
986 static void readbitand(void)
988 readeq();
989 while (!tok_jmp("&")) {
990 readeq();
991 ts_binop(O_AND);
995 static void readxor(void)
997 readbitand();
998 while (!tok_jmp("^")) {
999 readbitand();
1000 ts_binop(O_XOR);
1004 static void readbitor(void)
1006 readxor();
1007 while (!tok_jmp("|")) {
1008 readxor();
1009 ts_binop(O_OR);
1013 static void savelocal(long val, int bt)
1015 o_local(val);
1016 o_tmpswap();
1017 o_assign(bt);
1018 o_tmpdrop(1);
1021 static void loadlocal(long val, int bt)
1023 o_local(val);
1024 o_deref(bt);
1025 o_rmlocal(val, bt);
1028 static void readand(void)
1030 int l_out, l_fail;
1031 long val;
1032 readbitor();
1033 if (!tok_comes("&&"))
1034 return;
1035 val = o_mklocal(UINT);
1036 l_out = LABEL();
1037 l_fail = LABEL();
1038 ts_pop_de(NULL);
1039 o_jz(l_fail);
1040 while (!tok_jmp("&&")) {
1041 readbitor();
1042 ts_pop_de(NULL);
1043 o_jz(l_fail);
1045 o_num(1);
1046 savelocal(val, UINT);
1047 o_jmp(l_out);
1048 o_label(l_fail);
1049 o_num(0);
1050 savelocal(val, UINT);
1051 o_label(l_out);
1052 loadlocal(val, SINT);
1053 ts_push_bt(SINT);
1056 static void reador(void)
1058 int l_pass, l_end;
1059 long val;
1060 readand();
1061 if (!tok_comes("||"))
1062 return;
1063 val = o_mklocal(UINT);
1064 l_pass = LABEL();
1065 l_end = LABEL();
1066 ts_pop_de(NULL);
1067 o_uop(O_LNOT);
1068 o_jz(l_pass);
1069 while (!tok_jmp("||")) {
1070 readand();
1071 ts_pop_de(NULL);
1072 o_uop(O_LNOT);
1073 o_jz(l_pass);
1075 o_num(0);
1076 savelocal(val, SINT);
1077 o_jmp(l_end);
1078 o_label(l_pass);
1079 o_num(1);
1080 savelocal(val, SINT);
1081 o_label(l_end);
1082 loadlocal(val, SINT);
1083 ts_push_bt(SINT);
1086 static void readcexpr(void);
1088 static int readcexpr_const(void)
1090 long c, m = 0;
1091 if (o_popnum(&c))
1092 return -1;
1093 if (!c)
1094 m = o_mark();
1095 readcexpr();
1096 /* both branches yield the same type; so ignore the first */
1097 ts_pop_de(NULL);
1098 tok_req(":");
1099 if (!c) {
1100 o_back(m);
1101 o_tmpdrop(1);
1103 if (c)
1104 m = o_mark();
1105 readcexpr();
1106 /* making sure t->addr == 0 on both branches */
1107 ts_de(1);
1108 if (c) {
1109 o_back(m);
1110 o_tmpdrop(1);
1112 return 0;
1115 static void readcexpr(void)
1117 reador();
1118 if (tok_jmp("?"))
1119 return;
1120 ncexpr++;
1121 ts_pop_de(NULL);
1122 if (readcexpr_const()) {
1123 long val = 0;
1124 int l_fail = LABEL();
1125 int l_end = LABEL();
1126 struct type ret;
1127 o_jz(l_fail);
1128 readcexpr();
1129 /* both branches yield the same type; so ignore the first */
1130 ts_pop_de(&ret);
1131 if (!TYPE_VOID(&ret)) {
1132 val = o_mklocal(ULNG);
1133 savelocal(val, ULNG);
1135 o_jmp(l_end);
1137 tok_req(":");
1138 o_label(l_fail);
1139 readcexpr();
1140 /* making sure t->addr == 0 on both branches */
1141 ts_de(1);
1142 if (!TYPE_VOID(&ret)) {
1143 savelocal(val, ULNG);
1145 o_label(l_end);
1146 if (!TYPE_VOID(&ret)) {
1147 loadlocal(val, ULNG);
1150 ncexpr--;
1153 static void opassign(int op, int ptrop)
1155 struct type t = ts[nts - 1];
1156 o_tmpcopy();
1157 ts_push(&t);
1158 readexpr();
1159 if (op == O_ADD || op == O_SUB)
1160 ts_addop(op);
1161 else
1162 ts_binop(op);
1163 o_assign(TYPE_BT(&ts[nts - 2]));
1164 ts_pop(NULL);
1165 ts_de(0);
1168 static void doassign(void)
1170 struct type t = ts[nts - 1];
1171 if (!t.ptr && t.flags & T_STRUCT) {
1172 ts_pop(NULL);
1173 o_num(type_totsz(&t));
1174 o_memcpy();
1175 } else {
1176 ts_pop_de(NULL);
1177 o_assign(TYPE_BT(&ts[nts - 1]));
1178 ts_de(0);
1182 static void readexpr(void)
1184 readcexpr();
1185 if (!tok_jmp("=")) {
1186 readexpr();
1187 doassign();
1188 return;
1190 if (!tok_jmp("+=")) {
1191 opassign(O_ADD, 1);
1192 return;
1194 if (!tok_jmp("-=")) {
1195 opassign(O_SUB, 1);
1196 return;
1198 if (!tok_jmp("*=")) {
1199 opassign(O_MUL, 0);
1200 return;
1202 if (!tok_jmp("/=")) {
1203 opassign(O_DIV, 0);
1204 return;
1206 if (!tok_jmp("%=")) {
1207 opassign(O_MOD, 0);
1208 return;
1210 if (!tok_jmp("<<=")) {
1211 opassign(O_SHL, 0);
1212 return;
1214 if (!tok_jmp(">>=")) {
1215 opassign(O_SHR, 0);
1216 return;
1218 if (!tok_jmp("&=")) {
1219 opassign(O_AND, 0);
1220 return;
1222 if (!tok_jmp("|=")) {
1223 opassign(O_OR, 0);
1224 return;
1226 if (!tok_jmp("^=")) {
1227 opassign(O_XOR, 0);
1228 return;
1232 static void readestmt(void)
1234 do {
1235 o_tmpdrop(-1);
1236 nts = 0;
1237 readexpr();
1238 } while (!tok_jmp(","));
1241 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1243 static void globalinit(void *obj, int off, struct type *t)
1245 struct name *name = obj;
1246 char *elfname = *name->elfname ? name->elfname : name->name;
1247 if (t->flags & T_ARRAY && tok_grp() == '"') {
1248 struct type *t_de = &arrays[t->id].type;
1249 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1250 char *buf = tok_get() + 1;
1251 int len = tok_len() - 2;
1252 buf[len] = '\0';
1253 o_dscpy(name->addr + off, buf, len + 1);
1254 return;
1257 readexpr();
1258 o_dsset(elfname, off, TYPE_BT(t));
1259 ts_pop(NULL);
1262 static void readfunc(struct name *name, int flags);
1264 static void globaldef(long data, struct name *name, unsigned flags)
1266 struct type *t = &name->type;
1267 char *elfname = *name->elfname ? name->elfname : name->name;
1268 int sz;
1269 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1270 if (~flags & F_EXTERN)
1271 arrays[t->id].n = initsize();
1272 sz = type_totsz(t);
1273 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1274 if (tok_comes("="))
1275 name->addr = o_dsnew(elfname, sz, F_GLOBAL(flags));
1276 else
1277 o_bsnew(elfname, sz, F_GLOBAL(flags));
1279 global_add(name);
1280 if (!tok_jmp("="))
1281 initexpr(t, 0, name, globalinit);
1282 if (tok_comes("{") && name->type.flags & T_FUNC)
1283 readfunc(name, flags);
1286 /* generate the address of local + off */
1287 static void o_localoff(long addr, int off)
1289 o_local(addr);
1290 if (off) {
1291 o_num(off);
1292 o_bop(O_ADD);
1296 static void localinit(void *obj, int off, struct type *t)
1298 long addr = *(long *) obj;
1299 if (t->flags & T_ARRAY && tok_grp() == '"') {
1300 struct type *t_de = &arrays[t->id].type;
1301 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1302 char *buf = tok_get() + 1;
1303 int len = tok_len() - 2;
1304 o_localoff(addr, off);
1305 o_sym(tmp_str(buf, len));
1306 o_num(len + 1);
1307 o_memcpy();
1308 o_tmpdrop(1);
1309 return;
1312 o_localoff(addr, off);
1313 ts_push(t);
1314 readexpr();
1315 doassign();
1316 ts_pop(NULL);
1317 o_tmpdrop(1);
1320 /* current function name */
1321 static char func_name[NAMELEN];
1323 static void localdef(long data, struct name *name, unsigned flags)
1325 struct type *t = &name->type;
1326 if ((flags & F_EXTERN) || ((t->flags & T_FUNC) && !t->ptr)) {
1327 global_add(name);
1328 return;
1330 if (flags & F_STATIC) {
1331 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1332 globaldef(data, name, flags);
1333 return;
1335 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1336 arrays[t->id].n = initsize();
1337 name->addr = o_mklocal(type_totsz(&name->type));
1338 local_add(name);
1339 if (!tok_jmp("=")) {
1340 /* this is not necessary for "struct x = y" */
1341 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1342 o_local(name->addr);
1343 o_num(0);
1344 o_num(type_totsz(t));
1345 o_memset();
1346 o_tmpdrop(1);
1348 initexpr(t, 0, &name->addr, localinit);
1352 static void typedefdef(long data, struct name *name, unsigned flags)
1354 typedef_add(name->name, &name->type);
1357 static void readstmt(void);
1359 static void readswitch(void)
1361 int o_break = l_break;
1362 long val_addr = o_mklocal(ULNG);
1363 struct type t;
1364 int ncases = 0; /* number of case labels */
1365 int l_failed = LABEL(); /* address of last failed jmp */
1366 int l_matched = LABEL(); /* address of last walk through jmp */
1367 int l_default = 0; /* default case label */
1368 l_break = LABEL();
1369 tok_req("(");
1370 readexpr();
1371 ts_pop_de(&t);
1372 o_local(val_addr);
1373 o_tmpswap();
1374 o_assign(TYPE_BT(&t));
1375 ts_de(0);
1376 o_tmpdrop(1);
1377 tok_req(")");
1378 tok_req("{");
1379 while (tok_jmp("}")) {
1380 if (!tok_comes("case") && !tok_comes("default")) {
1381 readstmt();
1382 continue;
1384 if (ncases)
1385 o_jmp(l_matched);
1386 if (!strcmp("case", tok_get())) {
1387 o_label(l_failed);
1388 l_failed = LABEL();
1389 caseexpr = 1;
1390 readexpr();
1391 ts_pop_de(NULL);
1392 caseexpr = 0;
1393 o_local(val_addr);
1394 o_deref(TYPE_BT(&t));
1395 o_bop(O_EQ);
1396 o_jz(l_failed);
1397 o_tmpdrop(1);
1398 } else {
1399 if (!ncases)
1400 o_jmp(l_failed);
1401 l_default = LABEL();
1402 o_label(l_default);
1404 tok_req(":");
1405 o_label(l_matched);
1406 l_matched = LABEL();
1407 ncases++;
1409 o_rmlocal(val_addr, ULNG);
1410 o_jmp(l_break);
1411 o_label(l_failed);
1412 if (l_default)
1413 o_jmp(l_default);
1414 o_label(l_break);
1415 l_break = o_break;
1418 static char (*label_name)[NAMELEN];
1419 static int *label_ids;
1420 static int label_n, label_sz;
1422 static int label_id(char *name)
1424 int i;
1425 if (label_n >= label_sz) {
1426 label_sz = MAX(128, label_sz * 2);
1427 label_name = mextend(label_name, label_n, label_sz,
1428 sizeof(label_name[0]));
1429 label_ids = mextend(label_ids, label_n, label_sz,
1430 sizeof(label_ids[0]));
1432 for (i = label_n - 1; i >= 0; --i)
1433 if (!strcmp(label_name[i], name))
1434 return label_ids[i];
1435 strcpy(label_name[label_n], name);
1436 label_ids[label_n] = LABEL();
1437 return label_ids[label_n++];
1440 static void readstmt(void)
1442 o_tmpdrop(-1);
1443 nts = 0;
1444 if (!tok_jmp("{")) {
1445 int _nlocals = locals_n;
1446 int _nglobals = globals_n;
1447 int _nenums = enums_n;
1448 int _ntypedefs = typedefs_n;
1449 int _nstructs = structs_n;
1450 int _nfuncs = funcs_n;
1451 int _narrays = arrays_n;
1452 while (tok_jmp("}"))
1453 readstmt();
1454 locals_n = _nlocals;
1455 enums_n = _nenums;
1456 typedefs_n = _ntypedefs;
1457 structs_n = _nstructs;
1458 funcs_n = _nfuncs;
1459 arrays_n = _narrays;
1460 globals_n = _nglobals;
1461 return;
1463 if (!readdefs(localdef, 0)) {
1464 tok_req(";");
1465 return;
1467 if (!tok_jmp("typedef")) {
1468 readdefs(typedefdef, 0);
1469 tok_req(";");
1470 return;
1472 if (!tok_jmp("if")) {
1473 int l_fail = LABEL();
1474 int l_end = LABEL();
1475 tok_req("(");
1476 readestmt();
1477 tok_req(")");
1478 ts_pop_de(NULL);
1479 o_jz(l_fail);
1480 readstmt();
1481 if (!tok_jmp("else")) {
1482 o_jmp(l_end);
1483 o_label(l_fail);
1484 readstmt();
1485 o_label(l_end);
1486 } else {
1487 o_label(l_fail);
1489 return;
1491 if (!tok_jmp("while")) {
1492 int o_break = l_break;
1493 int o_cont = l_cont;
1494 l_break = LABEL();
1495 l_cont = LABEL();
1496 o_label(l_cont);
1497 tok_req("(");
1498 readestmt();
1499 tok_req(")");
1500 ts_pop_de(NULL);
1501 o_jz(l_break);
1502 readstmt();
1503 o_jmp(l_cont);
1504 o_label(l_break);
1505 l_break = o_break;
1506 l_cont = o_cont;
1507 return;
1509 if (!tok_jmp("do")) {
1510 int o_break = l_break;
1511 int o_cont = l_cont;
1512 int l_beg = LABEL();
1513 l_break = LABEL();
1514 l_cont = LABEL();
1515 o_label(l_beg);
1516 readstmt();
1517 tok_req("while");
1518 tok_req("(");
1519 o_label(l_cont);
1520 readexpr();
1521 ts_pop_de(NULL);
1522 o_uop(O_LNOT);
1523 o_jz(l_beg);
1524 tok_req(")");
1525 o_label(l_break);
1526 tok_req(";");
1527 l_break = o_break;
1528 l_cont = o_cont;
1529 return;
1531 if (!tok_jmp("for")) {
1532 int o_break = l_break;
1533 int o_cont = l_cont;
1534 int l_check = LABEL(); /* for condition label */
1535 int l_body = LABEL(); /* for block label */
1536 l_cont = LABEL();
1537 l_break = LABEL();
1538 tok_req("(");
1539 if (!tok_comes(";"))
1540 readestmt();
1541 tok_req(";");
1542 o_label(l_check);
1543 if (!tok_comes(";")) {
1544 readestmt();
1545 ts_pop_de(NULL);
1546 o_jz(l_break);
1548 tok_req(";");
1549 o_jmp(l_body);
1550 o_label(l_cont);
1551 if (!tok_comes(")"))
1552 readestmt();
1553 tok_req(")");
1554 o_jmp(l_check);
1555 o_label(l_body);
1556 readstmt();
1557 o_jmp(l_cont);
1558 o_label(l_break);
1559 l_break = o_break;
1560 l_cont = o_cont;
1561 return;
1563 if (!tok_jmp("switch")) {
1564 readswitch();
1565 return;
1567 if (!tok_jmp("return")) {
1568 int ret = !tok_comes(";");
1569 if (ret) {
1570 readexpr();
1571 ts_pop_de(NULL);
1573 tok_req(";");
1574 o_ret(ret);
1575 return;
1577 if (!tok_jmp("break")) {
1578 tok_req(";");
1579 o_jmp(l_break);
1580 return;
1582 if (!tok_jmp("continue")) {
1583 tok_req(";");
1584 o_jmp(l_cont);
1585 return;
1587 if (!tok_jmp("goto")) {
1588 o_jmp(label_id(tok_get()));
1589 tok_req(";");
1590 return;
1592 readestmt();
1593 /* labels */
1594 if (!tok_jmp(":")) {
1595 o_label(label_id(tok_previden));
1596 return;
1598 tok_req(";");
1601 static void readfunc(struct name *name, int flags)
1603 struct funcinfo *fi = &funcs[name->type.id];
1604 int i;
1605 strcpy(func_name, fi->name);
1606 o_func_beg(func_name, fi->nargs, F_GLOBAL(flags), fi->varg);
1607 for (i = 0; i < fi->nargs; i++) {
1608 struct name arg = {"", "", fi->args[i], o_arg2loc(i)};
1609 strcpy(arg.name, fi->argnames[i]);
1610 local_add(&arg);
1612 label = 0;
1613 label_n = 0;
1614 readstmt();
1615 o_func_end();
1616 func_name[0] = '\0';
1617 locals_n = 0;
1620 static void readdecl(void)
1622 if (!tok_jmp("typedef")) {
1623 readdefs(typedefdef, 0);
1624 tok_req(";");
1625 return;
1627 readdefs_int(globaldef, 0);
1628 tok_jmp(";");
1631 static void parse(void)
1633 while (tok_jmp(""))
1634 readdecl();
1637 static void compat_macros(void)
1639 cpp_define("__STDC__", "");
1640 cpp_define("__linux__", "");
1641 cpp_define(I_ARCH, "");
1643 /* ignored keywords */
1644 cpp_define("const", "");
1645 cpp_define("register", "");
1646 cpp_define("volatile", "");
1647 cpp_define("inline", "");
1648 cpp_define("restrict", "");
1649 cpp_define("__inline__", "");
1650 cpp_define("__restrict__", "");
1651 cpp_define("__attribute__(x)", "");
1652 cpp_define("__builtin_va_list__", "long");
1655 static int ncc_opt = 2;
1657 /* return one if the given optimization level is enabled */
1658 int opt(int level)
1660 return level <= ncc_opt;
1663 int main(int argc, char *argv[])
1665 char obj[128] = "";
1666 int ofd;
1667 int i;
1668 compat_macros();
1669 for (i = 1; i < argc && argv[i][0] == '-'; i++) {
1670 if (argv[i][1] == 'I')
1671 cpp_path(argv[i][2] ? argv[i] + 2 : argv[++i]);
1672 if (argv[i][1] == 'O')
1673 ncc_opt = argv[i][2] ? atoi(argv[i] + 2) : 2;
1674 if (argv[i][1] == 'D') {
1675 char *name = argv[i] + 2;
1676 char *def = "";
1677 char *eq = strchr(name, '=');
1678 if (eq) {
1679 *eq = '\0';
1680 def = eq + 1;
1682 cpp_define(name, def);
1684 if (argv[i][1] == 'o')
1685 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1686 if (argv[i][1] == 'h') {
1687 printf("neatcc: [options] source\n");
1688 printf("\n");
1689 printf("Options:\n");
1690 printf(" -I dir \tspecify a header directory\n");
1691 printf(" -o out \tspecify output file name\n");
1692 printf(" -Dname=val \tdefine macro\n");
1693 printf(" -On \toptimize (-O0 to disable)\n");
1694 return 0;
1697 if (i == argc)
1698 die("neatcc: no file given\n");
1699 if (cpp_init(argv[i]))
1700 die("neatcc: cannot open <%s>\n", argv[i]);
1701 out_init(0);
1702 parse();
1703 if (!*obj) {
1704 strcpy(obj, argv[i]);
1705 obj[strlen(obj) - 1] = 'o';
1707 free(locals);
1708 free(globals);
1709 free(label_name);
1710 free(label_ids);
1711 free(funcs);
1712 free(typedefs);
1713 free(structs);
1714 free(arrays);
1715 tok_done();
1716 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1717 o_write(ofd);
1718 close(ofd);
1719 return 0;
1723 /* parsing function and variable declarations */
1725 /* read the base type of a variable */
1726 static int basetype(struct type *type, unsigned *flags)
1728 int sign = 1;
1729 int size = UINT;
1730 int done = 0;
1731 int i = 0;
1732 int isunion;
1733 char name[NAMELEN] = "";
1734 *flags = 0;
1735 type->flags = 0;
1736 type->ptr = 0;
1737 type->addr = 0;
1738 while (!done) {
1739 if (!tok_jmp("static")) {
1740 *flags |= F_STATIC;
1741 } else if (!tok_jmp("extern")) {
1742 *flags |= F_EXTERN;
1743 } else if (!tok_jmp("void")) {
1744 sign = 0;
1745 size = 0;
1746 done = 1;
1747 } else if (!tok_jmp("int")) {
1748 done = 1;
1749 } else if (!tok_jmp("char")) {
1750 size = UCHR;
1751 done = 1;
1752 } else if (!tok_jmp("short")) {
1753 size = USHT;
1754 } else if (!tok_jmp("long")) {
1755 size = ULNG;
1756 } else if (!tok_jmp("signed")) {
1757 sign = 1;
1758 } else if (!tok_jmp("unsigned")) {
1759 sign = 0;
1760 } else if (tok_comes("union") || tok_comes("struct")) {
1761 isunion = !strcmp("union", tok_get());
1762 if (tok_grp() == 'a')
1763 strcpy(name, tok_get());
1764 if (tok_comes("{"))
1765 type->id = struct_create(name, isunion);
1766 else
1767 type->id = struct_find(name, isunion);
1768 type->flags |= T_STRUCT;
1769 type->bt = ULNG;
1770 return 0;
1771 } else if (!tok_jmp("enum")) {
1772 if (tok_grp() == 'a')
1773 tok_get();
1774 if (tok_comes("{"))
1775 enum_create();
1776 type->bt = SINT;
1777 return 0;
1778 } else {
1779 if (tok_grp() == 'a') {
1780 int id = typedef_find(tok_see());
1781 if (id != -1) {
1782 tok_get();
1783 memcpy(type, &typedefs[id].type,
1784 sizeof(*type));
1785 return 0;
1788 if (!i)
1789 return 1;
1790 done = 1;
1791 continue;
1793 i++;
1795 type->bt = size | (sign ? T_MSIGN : 0);
1796 return 0;
1799 static void readptrs(struct type *type)
1801 while (!tok_jmp("*")) {
1802 type->ptr++;
1803 if (!type->bt)
1804 type->bt = 1;
1808 /* read function arguments */
1809 static int readargs(struct type *args, char argnames[][NAMELEN], int *varg)
1811 int nargs = 0;
1812 tok_req("(");
1813 *varg = 0;
1814 while (!tok_comes(")")) {
1815 if (!tok_jmp("...")) {
1816 *varg = 1;
1817 break;
1819 if (readname(&args[nargs], argnames[nargs], NULL)) {
1820 /* argument has no type, assume int */
1821 memset(&args[nargs], 0, sizeof(struct type));
1822 args[nargs].bt = SINT;
1823 strcpy(argnames[nargs], tok_get());
1825 /* argument arrays are pointers */
1826 array2ptr(&args[nargs]);
1827 nargs++;
1828 if (tok_jmp(","))
1829 break;
1831 tok_req(")");
1832 /* void argument */
1833 if (nargs == 1 && !TYPE_BT(&args[0]))
1834 return 0;
1835 return nargs;
1838 /* read K&R function arguments */
1839 static void krdef(long data, struct name *name, unsigned flags)
1841 struct funcinfo *fi = &funcs[data];
1842 int i;
1843 for (i = 0; i < fi->nargs; i++)
1844 if (!strcmp(fi->argnames[i], name->name))
1845 memcpy(&fi->args[i], &name->type, sizeof(name->type));
1849 * readarrays() parses array specifiers when reading a definition in
1850 * readname(). The "type" parameter contains the type contained in the
1851 * inner array; for instance, type in "int *a[10][20]" would be an int
1852 * pointer. When returning, the "type" parameter is changed to point
1853 * to the final array. The function returns a pointer to the type in
1854 * the inner array; this is useful when the type is not complete yet,
1855 * like when creating an array of function pointers as in
1856 * "int (*f[10])(int)". If there is no array brackets, NULL is returned.
1858 static struct type *readarrays(struct type *type)
1860 long arsz[16];
1861 struct type *inner = NULL;
1862 int nar = 0;
1863 int i;
1864 while (!tok_jmp("[")) {
1865 long n = 0;
1866 if (tok_jmp("]")) {
1867 readexpr();
1868 ts_pop_de(NULL);
1869 if (o_popnum(&n))
1870 err("const expr expected\n");
1871 tok_req("]");
1873 arsz[nar++] = n;
1875 for (i = nar - 1; i >= 0; i--) {
1876 type->id = array_add(type, arsz[i]);
1877 if (!inner)
1878 inner = &arrays[type->id].type;
1879 type->flags = T_ARRAY;
1880 type->bt = ULNG;
1881 type->ptr = 0;
1883 return inner;
1886 static struct type *innertype(struct type *t)
1888 while (t->flags & T_ARRAY && !t->ptr)
1889 t = &arrays[t->id].type;
1890 return t;
1893 static void innertype_modify(struct type *t, struct type *s)
1895 struct type *inner = innertype(t);
1896 int ptr = inner->ptr;
1897 memcpy(inner, s, sizeof(*inner));
1898 inner->ptr = ptr;
1902 * readname() reads a variable definition; the name is copied into
1903 * "name" and the type is copied into "main" argument. The "base"
1904 * argument, if not NULL, indicates the base type of the variable.
1905 * For instance, the base type of "a" and "b" in "int *a, b[10]" is
1906 * "int". If NULL, basetype() is called directly to read the base
1907 * type of the variable. readname() returns zero, only if the
1908 * variable can be read.
1910 static int readname(struct type *main, char *name, struct type *base)
1912 struct type type; /* the main type */
1913 struct type btype; /* type before parenthesis; e.g. "int *" in "int *(*p)[10] */
1914 int paren;
1915 unsigned flags;
1916 if (name)
1917 *name = '\0';
1918 if (!base) {
1919 if (basetype(&type, &flags))
1920 return 1;
1921 } else {
1922 type = *base;
1924 readptrs(&type);
1925 paren = !tok_jmp("(");
1926 if (paren) {
1927 btype = type;
1928 readptrs(&type);
1930 if (tok_grp() == 'a' && name)
1931 strcpy(name, tok_get());
1932 readarrays(&type);
1933 if (paren)
1934 tok_req(")");
1935 if (tok_comes("(")) {
1936 struct type args[NARGS];
1937 char argnames[NARGS][NAMELEN];
1938 int varg = 0;
1939 int nargs = readargs(args, argnames, &varg);
1940 struct type rtype = type; /* return type */
1941 struct type ftype = {0}; /* function type */
1942 if (paren)
1943 rtype = btype;
1944 ftype.flags = T_FUNC;
1945 ftype.bt = ULNG;
1946 ftype.id = func_create(&rtype, name, argnames, args, nargs, varg);
1947 if (paren)
1948 innertype_modify(&type, &ftype);
1949 else
1950 type = ftype;
1951 if (!tok_comes(";"))
1952 while (!tok_comes("{") && !readdefs(krdef, type.id))
1953 tok_req(";");
1954 } else {
1955 if (paren && readarrays(&btype))
1956 innertype_modify(&type, &btype);
1958 *main = type;
1959 return 0;
1962 static int readtype(struct type *type)
1964 return readname(type, NULL, NULL);
1968 * readdefs() reads a variable definition statement. The definition
1969 * can appear in different contexts: global variables, function
1970 * local variables, struct fields, and typedefs. For each defined
1971 * variable, def() callback is called with the appropriate name
1972 * struct and flags; the callback should finish parsing the definition
1973 * by possibly reading the initializer expression and saving the name
1974 * struct.
1976 static int readdefs(void (*def)(long data, struct name *name, unsigned flags),
1977 long data)
1979 struct type base;
1980 unsigned base_flags;
1981 if (basetype(&base, &base_flags))
1982 return 1;
1983 if (tok_comes(";") || tok_comes("{"))
1984 return 0;
1985 do {
1986 struct name name = {{""}};
1987 if (readname(&name.type, name.name, &base))
1988 break;
1989 def(data, &name, base_flags);
1990 } while (!tok_jmp(","));
1991 return 0;
1994 /* just like readdefs, but default to int type; for handling K&R functions */
1995 static int readdefs_int(void (*def)(long data, struct name *name, unsigned flags),
1996 long data)
1998 struct type base;
1999 unsigned flags = 0;
2000 if (basetype(&base, &flags)) {
2001 if (tok_grp() != 'a')
2002 return 1;
2003 memset(&base, 0, sizeof(base));
2004 base.bt = SINT;
2006 if (!tok_comes(";")) {
2007 do {
2008 struct name name = {{""}};
2009 if (readname(&name.type, name.name, &base))
2010 break;
2011 def(data, &name, flags);
2012 } while (!tok_jmp(","));
2014 return 0;
2018 /* parsing initializer expressions */
2020 static void jumpbrace(void)
2022 int depth = 0;
2023 while (!tok_comes("}") || depth--)
2024 if (!strcmp("{", tok_get()))
2025 depth++;
2026 tok_req("}");
2029 /* compute the size of the initializer expression */
2030 static int initsize(void)
2032 long addr = tok_addr();
2033 int n = 0;
2034 if (tok_jmp("="))
2035 return 0;
2036 if (tok_grp() == '"') {
2037 tok_get();
2038 n = tok_len() - 2 + 1;
2039 tok_jump(addr);
2040 return n;
2042 tok_req("{");
2043 while (tok_jmp("}")) {
2044 long idx = n;
2045 if (!tok_jmp("[")) {
2046 readexpr();
2047 ts_pop_de(NULL);
2048 o_popnum(&idx);
2049 tok_req("]");
2050 tok_req("=");
2052 if (n < idx + 1)
2053 n = idx + 1;
2054 while (!tok_comes("}") && !tok_comes(","))
2055 if (!strcmp("{", tok_get()))
2056 jumpbrace();
2057 tok_jmp(",");
2059 tok_jump(addr);
2060 return n;
2063 /* read the initializer expression and initialize basic types using set() cb */
2064 static void initexpr(struct type *t, int off, void *obj,
2065 void (*set)(void *obj, int off, struct type *t))
2067 if (tok_jmp("{")) {
2068 set(obj, off, t);
2069 return;
2071 if (!t->ptr && t->flags & T_STRUCT) {
2072 struct structinfo *si = &structs[t->id];
2073 int i;
2074 for (i = 0; i < si->nfields && !tok_comes("}"); i++) {
2075 struct name *field = &si->fields[i];
2076 if (!tok_jmp(".")) {
2077 field = struct_field(t->id, tok_get());
2078 tok_req("=");
2080 initexpr(&field->type, off + field->addr, obj, set);
2081 if (tok_jmp(","))
2082 break;
2084 } else if (t->flags & T_ARRAY) {
2085 struct type t_de = arrays[t->id].type;
2086 int i;
2087 /* handling extra braces as in: char s[] = {"sth"} */
2088 if (TYPE_SZ(&t_de) == 1 && tok_grp() == '"') {
2089 set(obj, off, t);
2090 tok_req("}");
2091 return;
2093 for (i = 0; !tok_comes("}"); i++) {
2094 long idx = i;
2095 struct type it = t_de;
2096 if (!tok_jmp("[")) {
2097 readexpr();
2098 ts_pop_de(NULL);
2099 o_popnum(&idx);
2100 tok_req("]");
2101 tok_req("=");
2103 if (!tok_comes("{") && (tok_grp() != '"' ||
2104 !(it.flags & T_ARRAY)))
2105 it = *innertype(&t_de);
2106 initexpr(&it, off + type_totsz(&it) * idx, obj, set);
2107 if (tok_jmp(","))
2108 break;
2111 tok_req("}");