gen: change stack alignment to 4
[neatcc/cc.git] / ncc.c
blobbaca72370b51d38861deb7ce5bc8c94678af4672
1 /*
2 * neatcc - A small and simple C compiler
4 * Copyright (C) 2010 Ali Gholami Rudi
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License, as published by the
8 * Free Software Foundation.
9 */
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include "gen.h"
17 #include "tok.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
22 #define print(s) write(2, (s), strlen(s));
24 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
25 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
27 #define T_ARRAY 0x01
28 #define T_STRUCT 0x02
29 #define T_FUNC 0x04
31 #define F_INIT 0x01
32 #define F_STATIC 0x02
33 #define F_EXTERN 0x04
35 struct type {
36 unsigned bt;
37 unsigned flags;
38 int ptr;
39 int id; /* for structs, functions and arrays */
42 /* type stack */
43 static struct type ts[MAXTMP];
44 static int nts;
46 static void ts_push_bt(unsigned bt)
48 ts[nts].ptr = 0;
49 ts[nts].flags = 0;
50 ts[nts++].bt = bt;
53 static void ts_push(struct type *t)
55 memcpy(&ts[nts++], t, sizeof(*t));
56 if (t->flags & (T_FUNC | T_ARRAY) && !t->ptr)
57 o_addr();
60 static void ts_pop(struct type *type)
62 nts--;
63 if (type)
64 *type = ts[nts];
67 void die(char *msg)
69 print(msg);
70 exit(1);
73 void err(char *msg)
75 char err[1 << 7];
76 int len = cpp_loc(err, tok_addr());
77 strcpy(err + len, msg);
78 die(err);
81 struct name {
82 char name[NAMELEN];
83 struct type type;
84 long addr;
85 int unused; /* unreferenced external symbols */
88 static struct name locals[MAXLOCALS];
89 static int nlocals;
90 static struct name globals[MAXGLOBALS];
91 static int nglobals;
93 static void local_add(struct name *name)
95 if (nlocals >= MAXLOCALS)
96 err("nomem: MAXLOCALS reached!\n");
97 memcpy(&locals[nlocals++], name, sizeof(*name));
100 static int global_find(char *name)
102 int i;
103 for (i = 0; i < nglobals; i++)
104 if (!strcmp(name, globals[i].name))
105 return i;
106 return -1;
109 static void global_add(struct name *name)
111 int found = global_find(name->name);
112 int i = found == -1 ? nglobals++ : found;
113 if (nglobals >= MAXGLOBALS)
114 err("nomem: MAXGLOBALS reached!\n");
115 memcpy(&globals[i], name, sizeof(*name));
118 #define MAXENUMS (1 << 10)
120 static struct enumval {
121 char name[NAMELEN];
122 int n;
123 } enums[MAXENUMS];
124 static int nenums;
126 static void enum_add(char *name, int val)
128 struct enumval *ev = &enums[nenums++];
129 if (nenums >= MAXENUMS)
130 err("nomem: MAXENUMS reached!\n");
131 strcpy(ev->name, name);
132 ev->n = val;
135 static int enum_find(int *val, char *name)
137 int i;
138 for (i = nenums - 1; i >= 0; --i)
139 if (!strcmp(name, enums[i].name)) {
140 *val = enums[i].n;
141 return 0;
143 return 1;
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo {
149 char name[NAMELEN];
150 struct type type;
151 } typedefs[MAXTYPEDEFS];
152 static int ntypedefs;
154 static void typedef_add(char *name, struct type *type)
156 struct typdefinfo *ti = &typedefs[ntypedefs++];
157 if (ntypedefs >= MAXTYPEDEFS)
158 err("nomem: MAXTYPEDEFS reached!\n");
159 strcpy(ti->name, name);
160 memcpy(&ti->type, type, sizeof(*type));
163 static int typedef_find(char *name)
165 int i;
166 for (i = ntypedefs - 1; i >= 0; --i)
167 if (!strcmp(name, typedefs[i].name))
168 return i;
169 return -1;
172 #define MAXARRAYS (1 << 10)
174 static struct array {
175 struct type type;
176 int n;
177 } arrays[MAXARRAYS];
178 static int narrays;
180 static int array_add(struct type *type, int n)
182 struct array *a = &arrays[narrays++];
183 if (narrays >= MAXARRAYS)
184 err("nomem: MAXARRAYS reached!\n");
185 memcpy(&a->type, type, sizeof(*type));
186 a->n = n;
187 return a - arrays;
190 static void array2ptr(struct type *t)
192 if (!(t->flags & T_ARRAY) || t->ptr)
193 return;
194 memcpy(t, &arrays[t->id].type, sizeof(*t));
195 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return LONGSZ;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static int tok_jmp(int tok)
278 if (tok_see() != tok)
279 return 1;
280 tok_get();
281 return 0;
284 static void tok_expect(int tok)
286 if (tok_get() != tok)
287 err("syntax error\n");
290 static unsigned bt_op(unsigned bt1, unsigned bt2)
292 unsigned s1 = BT_SZ(bt1);
293 unsigned s2 = BT_SZ(bt2);
294 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
297 static void ts_binop(int op)
299 struct type t1, t2;
300 ts_pop(&t1);
301 ts_pop(&t2);
302 o_bop(op);
303 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
306 static void ts_addop(int op)
308 struct type t1, t2;
309 ts_pop(&t1);
310 ts_pop(&t2);
311 array2ptr(&t1);
312 array2ptr(&t2);
313 if (!t1.ptr && !t2.ptr) {
314 o_bop(op);
315 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
316 return;
318 if (t1.ptr && !t2.ptr)
319 o_tmpswap();
320 if (!t1.ptr && t2.ptr)
321 if (type_szde(&t2) > 1) {
322 o_num(type_szde(&t2), 4);
323 o_bop(O_MUL);
325 if (t1.ptr && !t2.ptr)
326 o_tmpswap();
327 o_bop(op);
328 if (t1.ptr && t2.ptr) {
329 int sz = type_szde(&t1);
330 if (sz > 1) {
331 o_num(sz, 4);
332 o_bop(O_DIV);
334 ts_push_bt(4 | BT_SIGNED);
335 } else {
336 ts_push(t1.ptr ? &t1 : &t2);
340 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
341 #define MIN(a, b) ((a) < (b) ? (a) : (b))
343 static int type_alignment(struct type *t)
345 if (t->flags & T_ARRAY && !t->ptr)
346 return type_alignment(&arrays[t->id].type);
347 if (t->flags & T_STRUCT && !t->ptr)
348 return type_alignment(&structs[t->id].fields[0].type);
349 return MIN(LONGSZ, type_totsz(t));
352 static void structdef(void *data, struct name *name, unsigned flags)
354 struct structinfo *si = data;
355 if (si->isunion) {
356 name->addr = 0;
357 if (si->size < type_totsz(&name->type))
358 si->size = type_totsz(&name->type);
359 } else {
360 struct type *t = &name->type;
361 int alignment = type_alignment(t);
362 if (t->flags & T_ARRAY && !t->ptr)
363 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
364 si->size = ALIGN(si->size, alignment);
365 name->addr = si->size;
366 si->size += type_totsz(&name->type);
368 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
371 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
373 static int struct_create(char *name, int isunion)
375 int id = struct_find(name, isunion);
376 struct structinfo *si = &structs[id];
377 tok_expect('{');
378 while (tok_jmp('}')) {
379 readdefs(structdef, si);
380 tok_expect(';');
382 return id;
385 static void readexpr(void);
387 static void enum_create(void)
389 long n = 0;
390 tok_expect('{');
391 while (tok_jmp('}')) {
392 char name[NAMELEN];
393 tok_expect(TOK_NAME);
394 strcpy(name, tok_id());
395 if (tok_see() == '=') {
396 tok_get();
397 readexpr();
398 ts_pop(NULL);
399 if (o_popnum(&n))
400 err("const expr expected!\n");
402 enum_add(name, n++);
403 tok_jmp(',');
407 static int basetype(struct type *type, unsigned *flags)
409 int sign = 1;
410 int size = 4;
411 int done = 0;
412 int i = 0;
413 int isunion;
414 char name[NAMELEN] = "";
415 *flags = 0;
416 type->flags = 0;
417 type->ptr = 0;
418 while (!done) {
419 switch (tok_see()) {
420 case TOK_STATIC:
421 *flags |= F_STATIC;
422 break;
423 case TOK_EXTERN:
424 *flags |= F_EXTERN;
425 break;
426 case TOK_VOID:
427 sign = 0;
428 size = 0;
429 done = 1;
430 break;
431 case TOK_INT:
432 done = 1;
433 break;
434 case TOK_CHAR:
435 size = 1;
436 done = 1;
437 break;
438 case TOK_SHORT:
439 size = 2;
440 break;
441 case TOK_LONG:
442 size = LONGSZ;
443 break;
444 case TOK_SIGNED:
445 break;
446 case TOK_UNSIGNED:
447 sign = 0;
448 break;
449 case TOK_UNION:
450 case TOK_STRUCT:
451 isunion = tok_get() == TOK_UNION;
452 if (!tok_jmp(TOK_NAME))
453 strcpy(name, tok_id());
454 if (tok_see() == '{')
455 type->id = struct_create(name, isunion);
456 else
457 type->id = struct_find(name, isunion);
458 type->flags |= T_STRUCT;
459 type->bt = LONGSZ;
460 return 0;
461 case TOK_ENUM:
462 tok_get();
463 tok_jmp(TOK_NAME);
464 if (tok_see() == '{')
465 enum_create();
466 type->bt = 4 | BT_SIGNED;
467 return 0;
468 default:
469 if (tok_see() == TOK_NAME) {
470 int id = typedef_find(tok_id());
471 if (id != -1) {
472 tok_get();
473 memcpy(type, &typedefs[id].type,
474 sizeof(*type));
475 return 0;
478 if (!i)
479 return 1;
480 done = 1;
481 continue;
483 i++;
484 tok_get();
486 type->bt = size | (sign ? BT_SIGNED : 0);
487 return 0;
490 static int readname(struct type *main, char *name,
491 struct type *base, unsigned flags);
493 static int readtype(struct type *type)
495 return readname(type, NULL, NULL, 0);
498 static void readptrs(struct type *type)
500 while (!tok_jmp('*')) {
501 type->ptr++;
502 if (!type->bt)
503 type->bt = 1;
507 /* used to differenciate labels from case and cond exprs */
508 static int ncexpr;
509 static int caseexpr;
511 static void readpre(void);
513 static void readprimary(void)
515 int i;
516 if (!tok_jmp(TOK_NUM)) {
517 long n;
518 int bt = tok_num(&n);
519 ts_push_bt(bt);
520 o_num(n, bt);
521 return;
523 if (!tok_jmp(TOK_STR)) {
524 struct type t;
525 char buf[BUFSIZE];
526 int len;
527 t.bt = 1 | BT_SIGNED;
528 t.ptr = 1;
529 t.flags = 0;
530 ts_push(&t);
531 len = tok_str(buf);
532 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
533 o_addr();
534 return;
536 if (!tok_jmp(TOK_NAME)) {
537 struct name unkn = {0};
538 char *name = unkn.name;
539 int n;
540 strcpy(name, tok_id());
541 /* don't search for labels here */
542 if (!ncexpr && !caseexpr && tok_see() == ':')
543 return;
544 for (i = nlocals - 1; i >= 0; --i) {
545 struct type *t = &locals[i].type;
546 if (!strcmp(locals[i].name, name)) {
547 o_local(locals[i].addr, TYPE_BT(t));
548 ts_push(t);
549 return;
552 if ((n = global_find(name)) != -1) {
553 struct name *g = &globals[n];
554 struct type *t = &g->type;
555 if (g->unused) {
556 g->unused = 0;
557 if (t->flags & T_FUNC && !t->ptr)
558 g->addr = out_mkundef(name, 0);
559 else
560 g->addr = out_mkundef(name, type_totsz(t));
562 o_symaddr(g->addr, TYPE_BT(t));
563 ts_push(t);
564 return;
566 if (!enum_find(&n, name)) {
567 ts_push_bt(4 | BT_SIGNED);
568 o_num(n, 4 | BT_SIGNED);
569 return;
571 if (tok_see() != '(')
572 err("unknown symbol\n");
573 unkn.addr = out_mkundef(unkn.name, 0);
574 global_add(&unkn);
575 ts_push_bt(LONGSZ);
576 o_symaddr(unkn.addr, LONGSZ);
577 return;
579 if (!tok_jmp('(')) {
580 struct type t;
581 if (!readtype(&t)) {
582 struct type o;
583 tok_expect(')');
584 readpre();
585 ts_pop(&o);
586 ts_push(&t);
587 if (!t.ptr || !o.ptr)
588 o_cast(TYPE_BT(&t));
589 } else {
590 readexpr();
591 tok_expect(')');
593 return;
597 void arrayderef(struct type *t)
599 int sz = type_totsz(t);
600 if (sz > 1) {
601 o_num(sz, 4);
602 o_bop(O_MUL);
604 o_bop(O_ADD);
605 o_deref(TYPE_BT(t));
608 static void inc_post(int inc_one, int inc_many)
610 struct type *t = &ts[nts - 1];
611 int sz = type_szde(t);
612 o_tmpcopy();
613 o_load();
614 o_tmpswap();
615 if (!t->ptr || sz == 1) {
616 o_uop(inc_one);
617 } else {
618 o_tmpcopy();
619 o_num(sz, 4);
620 o_bop(inc_many);
621 o_assign(TYPE_BT(t));
623 o_tmpdrop(1);
626 static void readfield(void)
628 struct name *field;
629 struct type t;
630 tok_expect(TOK_NAME);
631 ts_pop(&t);
632 array2ptr(&t);
633 field = struct_field(t.id, tok_id());
634 if (field->addr) {
635 o_num(field->addr, 4);
636 o_bop(O_ADD);
638 o_deref(TYPE_BT(&field->type));
639 ts_push(&field->type);
642 #define MAXFUNCS (1 << 10)
644 static struct funcinfo {
645 struct type args[MAXFIELDS];
646 struct type ret;
647 int nargs;
648 } funcs[MAXFUNCS];
649 static int nfuncs;
650 static unsigned ret_bt;
652 static int func_create(struct type *ret, struct name *args, int nargs)
654 struct funcinfo *fi = &funcs[nfuncs++];
655 int i;
656 if (nfuncs >= MAXFUNCS)
657 err("nomem: MAXFUNCS reached!\n");
658 memcpy(&fi->ret, ret, sizeof(*ret));
659 for (i = 0; i < nargs; i++)
660 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
661 fi->nargs = nargs;
662 return fi - funcs;
665 static void readcall(void)
667 struct type t;
668 unsigned bt[MAXARGS];
669 struct funcinfo *fi;
670 int argc = 0;
671 int i;
672 ts_pop(&t);
673 if (t.flags & T_FUNC && t.ptr > 0)
674 o_deref(LONGSZ);
675 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
676 if (tok_see() != ')') {
677 readexpr();
678 ts_pop(&t);
679 bt[argc++] = TYPE_BT(&t);
681 while (!tok_jmp(',')) {
682 readexpr();
683 ts_pop(&t);
684 bt[argc++] = TYPE_BT(&t);
686 tok_expect(')');
687 if (fi)
688 for (i = 0; i < fi->nargs; i++)
689 bt[i] = TYPE_BT(&fi->args[i]);
690 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
691 if (fi)
692 ts_push(&fi->ret);
693 else
694 ts_push_bt(4 | BT_SIGNED);
697 static void readpost(void)
699 readprimary();
700 while (1) {
701 if (!tok_jmp('[')) {
702 struct type t;
703 ts_pop(&t);
704 readexpr();
705 ts_pop(NULL);
706 tok_expect(']');
707 array2ptr(&t);
708 t.ptr--;
709 arrayderef(&t);
710 ts_push(&t);
711 continue;
713 if (!tok_jmp('(')) {
714 readcall();
715 continue;
717 if (!tok_jmp(TOK2("++"))) {
718 inc_post(O_INC, O_ADD);
719 continue;
721 if (!tok_jmp(TOK2("--"))) {
722 inc_post(O_DEC, O_SUB);
723 continue;
725 if (!tok_jmp('.')) {
726 o_addr();
727 readfield();
728 continue;
730 if (!tok_jmp(TOK2("->"))) {
731 readfield();
732 continue;
734 break;
738 static void inc_pre(int inc_one, int inc_many)
740 struct type *t;
741 int sz;
742 readpre();
743 t = &ts[nts - 1];
744 sz = (t->flags & T_ARRAY || t->ptr) ? type_szde(t) : 1;
745 if (sz == 1) {
746 o_uop(inc_one);
747 } else {
748 o_tmpcopy();
749 o_num(sz, 4);
750 o_bop(inc_many);
751 o_assign(TYPE_BT(t));
755 static void readpre(void)
757 if (!tok_jmp('&')) {
758 struct type type;
759 readpre();
760 ts_pop(&type);
761 if (!(type.flags & T_FUNC) && !type.ptr)
762 type.ptr++;
763 ts_push(&type);
764 o_addr();
765 return;
767 if (!tok_jmp('*')) {
768 struct type t;
769 readpre();
770 ts_pop(&t);
771 array2ptr(&t);
772 if (!(t.flags & T_FUNC) || t.ptr > 0) {
773 t.ptr--;
774 o_deref(TYPE_BT(&t));
776 ts_push(&t);
777 return;
779 if (!tok_jmp('!')) {
780 struct type type;
781 readpre();
782 ts_pop(&type);
783 o_uop(O_LNOT);
784 ts_push_bt(4 | BT_SIGNED);
785 return;
787 if (!tok_jmp('-')) {
788 readpre();
789 o_uop(O_NEG);
790 return;
792 if (!tok_jmp('~')) {
793 readpre();
794 o_uop(O_NOT);
795 return;
797 if (!tok_jmp(TOK2("++"))) {
798 inc_pre(O_INC, O_ADD);
799 return;
801 if (!tok_jmp(TOK2("--"))) {
802 inc_pre(O_DEC, O_SUB);
803 return;
805 if (!tok_jmp(TOK_SIZEOF)) {
806 struct type t;
807 int op = !tok_jmp('(');
808 if (readtype(&t)) {
809 int nogen = !o_nogen();
810 readexpr();
811 if (nogen)
812 o_dogen();
813 ts_pop(&t);
814 o_tmpdrop(1);
816 ts_push_bt(4);
817 o_num(type_totsz(&t), 4);
818 if (op)
819 tok_expect(')');
820 return;
822 readpost();
825 static void readmul(void)
827 readpre();
828 while (1) {
829 if (!tok_jmp('*')) {
830 readpre();
831 ts_binop(O_MUL);
832 continue;
834 if (!tok_jmp('/')) {
835 readpre();
836 ts_binop(O_DIV);
837 continue;
839 if (!tok_jmp('%')) {
840 readpre();
841 ts_binop(O_MOD);
842 continue;
844 break;
848 static void readadd(void)
850 readmul();
851 while (1) {
852 if (!tok_jmp('+')) {
853 readmul();
854 ts_addop(O_ADD);
855 continue;
857 if (!tok_jmp('-')) {
858 readmul();
859 ts_addop(O_SUB);
860 continue;
862 break;
866 static void shift(int op)
868 struct type t;
869 readadd();
870 ts_pop(NULL);
871 ts_pop(&t);
872 o_bop(op);
873 ts_push_bt(TYPE_BT(&t));
876 static void readshift(void)
878 readadd();
879 while (1) {
880 if (!tok_jmp(TOK2("<<"))) {
881 shift(O_SHL);
882 continue;
884 if (!tok_jmp(TOK2(">>"))) {
885 shift(O_SHR);
886 continue;
888 break;
892 static void cmp(int op)
894 readshift();
895 ts_pop(NULL);
896 ts_pop(NULL);
897 o_bop(op);
898 ts_push_bt(4 | BT_SIGNED);
901 static void readcmp(void)
903 readshift();
904 while (1) {
905 if (!tok_jmp('<')) {
906 cmp(O_LT);
907 continue;
909 if (!tok_jmp('>')) {
910 cmp(O_GT);
911 continue;
913 if (!tok_jmp(TOK2("<="))) {
914 cmp(O_LE);
915 continue;
917 if (!tok_jmp(TOK2(">="))) {
918 cmp(O_GE);
919 continue;
921 break;
925 static void eq(int op)
927 readcmp();
928 ts_pop(NULL);
929 ts_pop(NULL);
930 o_bop(op);
931 ts_push_bt(4 | BT_SIGNED);
934 static void readeq(void)
936 readcmp();
937 while (1) {
938 if (!tok_jmp(TOK2("=="))) {
939 eq(O_EQ);
940 continue;
942 if (!tok_jmp(TOK2("!="))) {
943 eq(O_NEQ);
944 continue;
946 break;
950 static void readbitand(void)
952 readeq();
953 while (!tok_jmp('&')) {
954 readeq();
955 ts_binop(O_AND);
959 static void readxor(void)
961 readbitand();
962 while (!tok_jmp('^')) {
963 readbitand();
964 ts_binop(O_XOR);
968 static void readbitor(void)
970 readxor();
971 while (!tok_jmp('|')) {
972 readxor();
973 ts_binop(O_OR);
977 #define MAXCOND (1 << 7)
979 static void readand(void)
981 long conds[MAXCOND];
982 int nconds = 0;
983 long passed;
984 int i;
985 readbitor();
986 if (tok_see() != TOK2("&&"))
987 return;
988 o_fork();
989 conds[nconds++] = o_jz(0);
990 ts_pop(NULL);
991 while (!tok_jmp(TOK2("&&"))) {
992 readbitor();
993 conds[nconds++] = o_jz(0);
994 ts_pop(NULL);
996 o_num(1, 4 | BT_SIGNED);
997 o_forkpush();
998 passed = o_jmp(0);
999 for (i = 0; i < nconds; i++)
1000 o_filljmp(conds[i]);
1001 o_num(0, 4 | BT_SIGNED);
1002 o_forkpush();
1003 o_forkjoin();
1004 o_filljmp(passed);
1005 ts_push_bt(4 | BT_SIGNED);
1008 static void reador(void)
1010 long conds[MAXCOND];
1011 int nconds = 0;
1012 long failed;
1013 int i;
1014 readand();
1015 if (tok_see() != TOK2("||"))
1016 return;
1017 o_fork();
1018 conds[nconds++] = o_jnz(0);
1019 ts_pop(NULL);
1020 while (!tok_jmp(TOK2("||"))) {
1021 readand();
1022 conds[nconds++] = o_jnz(0);
1023 ts_pop(NULL);
1025 o_num(0, 4 | BT_SIGNED);
1026 o_forkpush();
1027 failed = o_jmp(0);
1028 for (i = 0; i < nconds; i++)
1029 o_filljmp(conds[i]);
1030 o_num(1, 4 | BT_SIGNED);
1031 o_forkpush();
1032 o_forkjoin();
1033 o_filljmp(failed);
1034 ts_push_bt(4 | BT_SIGNED);
1037 static int readcexpr_const(void)
1039 long c;
1040 int nogen;
1041 if (o_popnum(&c))
1042 return -1;
1043 if (!c)
1044 nogen = !o_nogen();
1045 reador();
1046 ts_pop(NULL);
1047 tok_expect(':');
1048 if (c) {
1049 nogen = !o_nogen();
1050 } else {
1051 if (nogen)
1052 o_dogen();
1053 o_tmpdrop(1);
1055 reador();
1056 if (c) {
1057 if (nogen)
1058 o_dogen();
1059 o_tmpdrop(1);
1061 return 0;
1064 static void readcexpr(void)
1066 long l1, l2;
1067 reador();
1068 if (tok_jmp('?'))
1069 return;
1070 ncexpr++;
1071 ts_pop(NULL);
1072 o_fork();
1073 if (readcexpr_const()) {
1074 l1 = o_jz(0);
1075 reador();
1076 o_forkpush();
1077 l2 = o_jmp(0);
1078 ts_pop(NULL);
1080 tok_expect(':');
1081 o_filljmp(l1);
1082 reador();
1083 o_forkpush();
1084 o_forkjoin();
1085 o_filljmp(l2);
1087 ncexpr--;
1090 static void opassign(int op, int ptrop)
1092 struct type *t = &ts[nts - 1];
1093 if (ptrop && (t->flags & T_ARRAY || t->ptr)) {
1094 o_tmpcopy();
1095 readexpr();
1096 ts_addop(op);
1097 ts_pop(NULL);
1098 o_assign(TYPE_BT(&ts[nts - 1]));
1099 } else {
1100 readexpr();
1101 o_bop(op | O_SET);
1102 ts_pop(NULL);
1106 static void doassign(void)
1108 struct type t;
1109 ts_pop(&t);
1110 if (!t.ptr && t.flags & T_STRUCT)
1111 o_memcpy(type_totsz(&t));
1112 else
1113 o_assign(TYPE_BT(&ts[nts - 1]));
1116 static void readexpr(void)
1118 readcexpr();
1119 if (!tok_jmp('=')) {
1120 readexpr();
1121 doassign();
1122 return;
1124 if (!tok_jmp(TOK2("+="))) {
1125 opassign(O_ADD, 1);
1126 return;
1128 if (!tok_jmp(TOK2("-="))) {
1129 opassign(O_SUB, 1);
1130 return;
1132 if (!tok_jmp(TOK2("*="))) {
1133 opassign(O_MUL, 0);
1134 return;
1136 if (!tok_jmp(TOK2("/="))) {
1137 opassign(O_DIV, 0);
1138 return;
1140 if (!tok_jmp(TOK2("%="))) {
1141 opassign(O_MOD, 0);
1142 return;
1144 if (!tok_jmp(TOK3("<<="))) {
1145 opassign(O_SHL, 0);
1146 return;
1148 if (!tok_jmp(TOK3(">>="))) {
1149 opassign(O_SHR, 0);
1150 return;
1152 if (!tok_jmp(TOK3("&="))) {
1153 opassign(O_AND, 0);
1154 return;
1156 if (!tok_jmp(TOK3("|="))) {
1157 opassign(O_OR, 0);
1158 return;
1160 if (!tok_jmp(TOK3("^="))) {
1161 opassign(O_XOR, 0);
1162 return;
1166 static void readestmt(void)
1168 do {
1169 o_tmpdrop(-1);
1170 nts = 0;
1171 readexpr();
1172 } while (!tok_jmp(','));
1175 static void o_localoff(long addr, int off, unsigned bt)
1177 o_local(addr, bt);
1178 if (off) {
1179 o_addr();
1180 o_num(off, 4);
1181 o_bop(O_ADD);
1182 o_deref(bt);
1186 static struct type *innertype(struct type *t)
1188 if (t->flags & T_ARRAY && !t->ptr)
1189 return innertype(&arrays[t->id].type);
1190 return t;
1193 static void initexpr(struct type *t, int off, void *obj,
1194 void (*set)(void *obj, int off, struct type *t))
1196 if (tok_jmp('{')) {
1197 set(obj, off, t);
1198 return;
1200 if (!t->ptr && t->flags & T_STRUCT) {
1201 struct structinfo *si = &structs[t->id];
1202 int i;
1203 for (i = 0; i < si->nfields; i++) {
1204 struct name *field = &si->fields[i];
1205 if (!tok_jmp('.')) {
1206 tok_expect(TOK_NAME);
1207 field = struct_field(t->id, tok_id());
1208 tok_expect('=');
1210 initexpr(&field->type, off + field->addr, obj, set);
1211 if (tok_jmp(',') || tok_see() == '}')
1212 break;
1214 } else if (t->flags & T_ARRAY) {
1215 struct type *t_de = &arrays[t->id].type;
1216 int i;
1217 for (i = 0; ; i++) {
1218 long idx = i;
1219 struct type *it = t_de;
1220 if (!tok_jmp('[')) {
1221 readexpr();
1222 o_popnum(&idx);
1223 ts_pop(NULL);
1224 tok_expect(']');
1225 tok_expect('=');
1227 if (tok_see() != '{')
1228 it = innertype(t_de);
1229 initexpr(it, off + type_totsz(it) * idx, obj, set);
1230 if (tok_jmp(',') || tok_see() == '}')
1231 break;
1234 tok_expect('}');
1237 static void jumpbrace(void)
1239 int depth = 0;
1240 while (tok_see() != '}' || depth--)
1241 if (tok_get() == '{')
1242 depth++;
1243 tok_expect('}');
1246 static int initsize(void)
1248 long addr = tok_addr();
1249 int n = 0;
1250 if (!tok_jmp(TOK_STR)) {
1251 n = tok_str(NULL);
1252 tok_jump(addr);
1253 return n;
1255 o_nogen();
1256 tok_expect('{');
1257 while (tok_jmp('}')) {
1258 long idx = n;
1259 if (!tok_jmp('[')) {
1260 readexpr();
1261 o_popnum(&idx);
1262 ts_pop(NULL);
1263 tok_expect(']');
1264 tok_expect('=');
1266 if (n < idx + 1)
1267 n = idx + 1;
1268 while (tok_see() != '}' && tok_see() != ',')
1269 if (tok_get() == '{')
1270 jumpbrace();
1271 tok_jmp(',');
1273 o_dogen();
1274 tok_jump(addr);
1275 return n;
1278 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1280 static void globalinit(void *obj, int off, struct type *t)
1282 long addr = *(long *) obj;
1283 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1284 struct type *t_de = &arrays[t->id].type;
1285 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1286 char buf[BUFSIZE];
1287 int len;
1288 tok_expect(TOK_STR);
1289 len = tok_str(buf);
1290 out_datcpy(addr, off, buf, len);
1291 return;
1294 readexpr();
1295 o_datset(addr, off, TYPE_BT(t));
1296 ts_pop(NULL);
1299 static void globaldef(void *data, struct name *name, unsigned flags)
1301 struct type *t = &name->type;
1302 char *varname = flags & F_STATIC ? NULL : name->name;
1303 int sz;
1304 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1305 arrays[t->id].n = initsize();
1306 sz = type_totsz(t);
1307 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1308 name->unused = 1;
1309 else if (flags & F_INIT)
1310 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1311 else
1312 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1313 global_add(name);
1314 if (flags & F_INIT)
1315 initexpr(t, 0, &name->addr, globalinit);
1318 static void localinit(void *obj, int off, struct type *t)
1320 long addr = *(long *) obj;
1321 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1322 struct type *t_de = &arrays[t->id].type;
1323 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1324 char buf[BUFSIZE];
1325 int len;
1326 tok_expect(TOK_STR);
1327 len = tok_str(buf);
1328 o_localoff(addr, off, TYPE_BT(t));
1329 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1330 o_memcpy(len);
1331 o_tmpdrop(1);
1332 return;
1335 o_localoff(addr, off, TYPE_BT(t));
1336 ts_push(t);
1337 readexpr();
1338 doassign();
1339 ts_pop(NULL);
1340 o_tmpdrop(1);
1343 static void localdef(void *data, struct name *name, unsigned flags)
1345 struct type *t = &name->type;
1346 if (flags & (F_STATIC | F_EXTERN)) {
1347 globaldef(data, name, flags);
1348 return;
1350 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1351 arrays[t->id].n = initsize();
1352 name->addr = o_mklocal(type_totsz(&name->type));
1353 local_add(name);
1354 if (flags & F_INIT) {
1355 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1356 o_local(name->addr, TYPE_BT(t));
1357 o_memset(0, type_totsz(t));
1358 o_tmpdrop(1);
1360 initexpr(t, 0, &name->addr, localinit);
1364 static void funcdef(char *name, struct type *type, struct name *args,
1365 int nargs, unsigned flags)
1367 struct name global;
1368 int i;
1369 strcpy(global.name, name);
1370 memcpy(&global.type, type, sizeof(*type));
1371 global.addr = o_func_beg(name, F_GLOBAL(flags));
1372 global.unused = 0;
1373 global_add(&global);
1374 ret_bt = TYPE_BT(&funcs[type->id].ret);
1375 for (i = 0; i < nargs; i++) {
1376 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1377 local_add(&args[i]);
1381 static int readargs(struct name *args)
1383 int nargs = 0;
1384 tok_expect('(');
1385 while (tok_see() != ')') {
1386 if (!tok_jmp(TOK3("...")))
1387 break;
1388 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1389 array2ptr(&args[nargs].type);
1390 nargs++;
1391 if (tok_jmp(','))
1392 break;
1394 tok_expect(')');
1395 if (nargs == 1 && !TYPE_BT(&args[0].type))
1396 return 0;
1397 return nargs;
1400 static int readname(struct type *main, char *name,
1401 struct type *base, unsigned flags)
1403 struct type tpool[3];
1404 int npool = 0;
1405 struct type *type = &tpool[npool++];
1406 struct type *func = NULL;
1407 struct type *ret = NULL;
1408 int arsz[10];
1409 int nar = 0;
1410 int i;
1411 memset(tpool, 0, sizeof(tpool));
1412 if (name)
1413 *name = '\0';
1414 if (!base) {
1415 if (basetype(type, &flags))
1416 return 1;
1417 } else {
1418 memcpy(type, base, sizeof(*base));
1420 readptrs(type);
1421 if (!tok_jmp('(')) {
1422 ret = type;
1423 type = &tpool[npool++];
1424 func = type;
1425 readptrs(type);
1427 if (!tok_jmp(TOK_NAME) && name)
1428 strcpy(name, tok_id());
1429 while (!tok_jmp('[')) {
1430 long n = 0;
1431 if (tok_jmp(']')) {
1432 readexpr();
1433 ts_pop(NULL);
1434 if (o_popnum(&n))
1435 err("const expr expected\n");
1436 tok_expect(']');
1438 arsz[nar++] = n;
1440 for (i = nar - 1; i >= 0; i--) {
1441 type->id = array_add(type, arsz[i]);
1442 if (func && i == nar - 1)
1443 func = &arrays[type->id].type;
1444 type->flags = T_ARRAY;
1445 type->bt = LONGSZ;
1446 type->ptr = 0;
1448 if (func)
1449 tok_expect(')');
1450 if (tok_see() == '(') {
1451 struct name args[MAXARGS];
1452 int nargs = readargs(args);
1453 int fdef = !func;
1454 if (!func) {
1455 ret = type;
1456 type = &tpool[npool++];
1457 func = type;
1459 func->flags = T_FUNC;
1460 func->bt = LONGSZ;
1461 func->id = func_create(ret, args, nargs);
1462 if (fdef && tok_see() == '{') {
1463 funcdef(name, func, args, nargs, flags);
1464 return 1;
1467 memcpy(main, type, sizeof(*type));
1468 return 0;
1471 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1472 void *data)
1474 struct type base;
1475 unsigned flags;
1476 if (basetype(&base, &flags))
1477 return 1;
1478 while (tok_see() != ';' && tok_see() != '{') {
1479 struct name name;
1480 name.unused = 0;
1481 if (readname(&name.type, name.name, &base, flags))
1482 break;
1483 if (!tok_jmp('='))
1484 flags |= F_INIT;
1485 def(data, &name, flags);
1486 tok_jmp(',');
1488 return 0;
1491 static void typedefdef(void *data, struct name *name, unsigned flags)
1493 typedef_add(name->name, &name->type);
1496 static void readstmt(void);
1498 #define MAXCASES (1 << 7)
1500 static void readswitch(void)
1502 int break_beg = nbreaks;
1503 long val_addr = o_mklocal(LONGSZ);
1504 long matched[MAXCASES];
1505 int nmatched = 0;
1506 struct type t;
1507 long next;
1508 int ref = 1;
1509 int i;
1510 tok_expect('(');
1511 readexpr();
1512 ts_pop(&t);
1513 o_local(val_addr, TYPE_BT(&t));
1514 o_tmpswap();
1515 o_assign(TYPE_BT(&t));
1516 o_tmpdrop(1);
1517 tok_expect(')');
1518 tok_expect('{');
1519 while (tok_jmp('}')) {
1520 int n = 0;
1521 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1522 if (n++ > 0)
1523 matched[nmatched++] = o_jmp(0);
1524 if (!ref++)
1525 o_filljmp(next);
1526 if (!tok_jmp(TOK_CASE)) {
1527 caseexpr = 1;
1528 readexpr();
1529 caseexpr = 0;
1530 o_local(val_addr, TYPE_BT(&t));
1531 o_bop(O_EQ);
1532 next = o_jz(0);
1533 ref = 0;
1534 tok_expect(':');
1535 o_tmpdrop(1);
1536 ts_pop(NULL);
1537 continue;
1539 if (!tok_jmp(TOK_DEFAULT)) {
1540 tok_expect(':');
1541 continue;
1544 for (i = 0; i < nmatched; i++)
1545 o_filljmp(matched[i]);
1546 nmatched = 0;
1547 readstmt();
1549 o_rmlocal(val_addr, LONGSZ);
1550 if (!ref++)
1551 o_filljmp(next);
1552 break_fill(o_mklabel(), break_beg);
1555 #define MAXGOTO (1 << 10)
1557 static struct gotoinfo {
1558 char name[NAMELEN];
1559 long addr;
1560 } gotos[MAXGOTO];
1561 static int ngotos;
1563 static struct labelinfo {
1564 char name[NAMELEN];
1565 long addr;
1566 } labels[MAXGOTO];
1567 static int nlabels;
1569 static void goto_add(char *name)
1571 strcpy(gotos[ngotos].name, name);
1572 gotos[ngotos++].addr = o_jmp(0);
1575 static void label_add(char *name)
1577 strcpy(labels[nlabels].name, name);
1578 labels[nlabels++].addr = o_mklabel();
1581 static void goto_fill(void)
1583 int i, j;
1584 for (i = 0; i < ngotos; i++)
1585 for (j = 0; j < nlabels; j++)
1586 if (!strcmp(gotos[i].name, labels[j].name)) {
1587 o_filljmp2(gotos[i].addr, labels[j].addr);
1588 break;
1592 static void readstmt(void)
1594 o_tmpdrop(-1);
1595 nts = 0;
1596 if (!tok_jmp('{')) {
1597 int _nlocals = nlocals;
1598 int _nglobals = nglobals;
1599 int _nenums = nenums;
1600 int _ntypedefs = ntypedefs;
1601 int _nstructs = nstructs;
1602 int _nfuncs = nfuncs;
1603 int _narrays = narrays;
1604 while (tok_jmp('}'))
1605 readstmt();
1606 nlocals = _nlocals;
1607 nenums = _nenums;
1608 ntypedefs = _ntypedefs;
1609 nstructs = _nstructs;
1610 nfuncs = _nfuncs;
1611 narrays = _narrays;
1612 nglobals = _nglobals;
1613 return;
1615 if (!readdefs(localdef, NULL)) {
1616 tok_expect(';');
1617 return;
1619 if (!tok_jmp(TOK_TYPEDEF)) {
1620 readdefs(typedefdef, NULL);
1621 tok_expect(';');
1622 return;
1624 if (!tok_jmp(TOK_IF)) {
1625 long l1, l2;
1626 tok_expect('(');
1627 readexpr();
1628 tok_expect(')');
1629 l1 = o_jz(0);
1630 readstmt();
1631 if (!tok_jmp(TOK_ELSE)) {
1632 l2 = o_jmp(0);
1633 o_filljmp(l1);
1634 readstmt();
1635 o_filljmp(l2);
1636 } else {
1637 o_filljmp(l1);
1639 return;
1641 if (!tok_jmp(TOK_WHILE)) {
1642 long l1, l2;
1643 int break_beg = nbreaks;
1644 int continue_beg = ncontinues;
1645 l1 = o_mklabel();
1646 tok_expect('(');
1647 readexpr();
1648 tok_expect(')');
1649 l2 = o_jz(0);
1650 readstmt();
1651 o_jmp(l1);
1652 o_filljmp(l2);
1653 break_fill(o_mklabel(), break_beg);
1654 continue_fill(l1, continue_beg);
1655 return;
1657 if (!tok_jmp(TOK_DO)) {
1658 long l1, l2;
1659 int break_beg = nbreaks;
1660 int continue_beg = ncontinues;
1661 l1 = o_mklabel();
1662 readstmt();
1663 tok_expect(TOK_WHILE);
1664 tok_expect('(');
1665 l2 = o_mklabel();
1666 readexpr();
1667 o_jnz(l1);
1668 tok_expect(')');
1669 break_fill(o_mklabel(), break_beg);
1670 continue_fill(l2, continue_beg);
1671 return;
1673 if (!tok_jmp(TOK_FOR)) {
1674 long l_check, l_jump, j_fail, j_pass;
1675 int break_beg = nbreaks;
1676 int continue_beg = ncontinues;
1677 int has_cond = 0;
1678 tok_expect('(');
1679 if (tok_see() != ';')
1680 readestmt();
1681 tok_expect(';');
1682 l_check = o_mklabel();
1683 if (tok_see() != ';') {
1684 readestmt();
1685 j_fail = o_jz(0);
1686 has_cond = 1;
1688 tok_expect(';');
1689 j_pass = o_jmp(0);
1690 l_jump = o_mklabel();
1691 if (tok_see() != ')')
1692 readestmt();
1693 tok_expect(')');
1694 o_jmp(l_check);
1695 o_filljmp(j_pass);
1696 readstmt();
1697 o_jmp(l_jump);
1698 if (has_cond)
1699 o_filljmp(j_fail);
1700 break_fill(o_mklabel(), break_beg);
1701 continue_fill(l_jump, continue_beg);
1702 return;
1704 if (!tok_jmp(TOK_SWITCH)) {
1705 readswitch();
1706 return;
1708 if (!tok_jmp(TOK_RETURN)) {
1709 int ret = tok_see() != ';';
1710 if (ret)
1711 readexpr();
1712 tok_expect(';');
1713 o_ret(ret_bt);
1714 return;
1716 if (!tok_jmp(TOK_BREAK)) {
1717 tok_expect(';');
1718 breaks[nbreaks++] = o_jmp(0);
1719 return;
1721 if (!tok_jmp(TOK_CONTINUE)) {
1722 tok_expect(';');
1723 continues[ncontinues++] = o_jmp(0);
1724 return;
1726 if (!tok_jmp(TOK_GOTO)) {
1727 tok_expect(TOK_NAME);
1728 goto_add(tok_id());
1729 tok_expect(';');
1730 return;
1732 readestmt();
1733 /* labels */
1734 if (!tok_jmp(':')) {
1735 label_add(tok_id());
1736 return;
1738 tok_expect(';');
1741 static void readdecl(void)
1743 if (!tok_jmp(TOK_TYPEDEF)) {
1744 readdefs(typedefdef, NULL);
1745 tok_expect(';');
1746 return;
1748 readdefs(globaldef, NULL);
1749 if (tok_see() == '{') {
1750 readstmt();
1751 goto_fill();
1752 o_func_end();
1753 nlocals = 0;
1754 ngotos = 0;
1755 nlabels = 0;
1756 return;
1758 tok_expect(';');
1761 static void parse(void)
1763 while (tok_see() != TOK_EOF)
1764 readdecl();
1767 int main(int argc, char *argv[])
1769 char obj[128];
1770 int ofd;
1771 int i = 1;
1772 while (i < argc && argv[i][0] == '-') {
1773 if (argv[i][1] == 'I')
1774 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1775 if (argv[i][1] == 'D') {
1776 char *name = argv[i] + 2;
1777 char *def = "";
1778 char *eq = strchr(name, '=');
1779 if (eq) {
1780 *eq = '\0';
1781 def = eq + 1;
1783 cpp_define(name, def);
1785 i++;
1787 if (i == argc)
1788 die("neatcc: no file given\n");
1789 if (cpp_init(argv[i]))
1790 die("neatcc: cannot open input file\n");
1791 parse();
1792 strcpy(obj, argv[i]);
1793 obj[strlen(obj) - 1] = 'o';
1794 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1795 out_write(ofd);
1796 close(ofd);
1797 return 0;