ncc: let shift amount be an unsigned
[neatcc.git] / ncc.c
blob330a474097861801f07857adda344221bce53988
1 /*
2 * neatcc - A small and simple x86_64 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 ? 8 : (t)->bt)
25 #define TYPE_SZ(t) ((t)->ptr ? 8 : (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 8;
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(void (*o_sth)(void))
299 struct type t1, t2;
300 ts_pop(&t1);
301 ts_pop(&t2);
302 o_sth();
303 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
306 static int shifts(int n)
308 int i = -1;
309 while (i++ < 16)
310 if (n == 1 << i)
311 break;
312 return i;
315 static void ts_binop_add(void (*o_sth)(void))
317 struct type t1, t2;
318 ts_pop(&t1);
319 ts_pop(&t2);
320 array2ptr(&t1);
321 array2ptr(&t2);
322 if (!t1.ptr && !t2.ptr) {
323 o_sth();
324 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
325 return;
327 if (t1.ptr && !t2.ptr) {
328 struct type t = t2;
329 t2 = t1;
330 t1 = t;
331 o_tmpswap();
333 if (!t1.ptr && t2.ptr)
334 if (type_szde(&t2) > 1) {
335 o_num(shifts(type_szde(&t2)), 4);
336 o_shl();
338 o_sth();
339 if (t1.ptr && t2.ptr) {
340 o_num(shifts(type_szde(&t1)), 4);
341 o_shr();
342 ts_push_bt(4 | BT_SIGNED);
343 } else {
344 ts_push(&t2);
348 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
349 #define MIN(a, b) ((a) < (b) ? (a) : (b))
351 static void structdef(void *data, struct name *name, unsigned flags)
353 struct structinfo *si = data;
354 if (si->isunion) {
355 name->addr = 0;
356 if (si->size < type_totsz(&name->type))
357 si->size = type_totsz(&name->type);
358 } else {
359 struct type *t = &name->type;
360 int alignment = MIN(8, type_totsz(t));
361 if (t->flags & T_ARRAY && !t->ptr)
362 alignment = MIN(8, type_totsz(&arrays[t->id].type));
363 si->size = ALIGN(si->size, alignment);
364 name->addr = si->size;
365 si->size += type_totsz(&name->type);
367 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
370 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
372 static int struct_create(char *name, int isunion)
374 int id = struct_find(name, isunion);
375 struct structinfo *si = &structs[id];
376 tok_expect('{');
377 while (tok_jmp('}')) {
378 readdefs(structdef, si);
379 tok_expect(';');
381 return id;
384 static void readexpr(void);
386 static void enum_create(void)
388 long n = 0;
389 tok_expect('{');
390 while (tok_jmp('}')) {
391 char name[NAMELEN];
392 tok_expect(TOK_NAME);
393 strcpy(name, tok_id());
394 if (tok_see() == '=') {
395 tok_get();
396 readexpr();
397 ts_pop(NULL);
398 if (o_popnum(&n))
399 err("const expr expected!\n");
401 enum_add(name, n++);
402 tok_jmp(',');
406 static int basetype(struct type *type, unsigned *flags)
408 int sign = 1;
409 int size = 4;
410 int done = 0;
411 int i = 0;
412 int isunion;
413 char name[NAMELEN] = "";
414 *flags = 0;
415 type->flags = 0;
416 type->ptr = 0;
417 while (!done) {
418 switch (tok_see()) {
419 case TOK_STATIC:
420 *flags |= F_STATIC;
421 break;
422 case TOK_EXTERN:
423 *flags |= F_EXTERN;
424 break;
425 case TOK_VOID:
426 sign = 0;
427 size = 0;
428 done = 1;
429 break;
430 case TOK_INT:
431 done = 1;
432 break;
433 case TOK_CHAR:
434 size = 1;
435 done = 1;
436 break;
437 case TOK_SHORT:
438 size = 2;
439 break;
440 case TOK_LONG:
441 size = 8;
442 break;
443 case TOK_SIGNED:
444 break;
445 case TOK_UNSIGNED:
446 sign = 0;
447 break;
448 case TOK_UNION:
449 case TOK_STRUCT:
450 isunion = tok_get() == TOK_UNION;
451 if (!tok_jmp(TOK_NAME))
452 strcpy(name, tok_id());
453 if (tok_see() == '{')
454 type->id = struct_create(name, isunion);
455 else
456 type->id = struct_find(name, isunion);
457 type->flags |= T_STRUCT;
458 type->bt = 8;
459 return 0;
460 case TOK_ENUM:
461 tok_get();
462 tok_jmp(TOK_NAME);
463 if (tok_see() == '{')
464 enum_create();
465 type->bt = 4 | BT_SIGNED;
466 return 0;
467 default:
468 if (tok_see() == TOK_NAME) {
469 int id = typedef_find(tok_id());
470 if (id != -1) {
471 tok_get();
472 memcpy(type, &typedefs[id].type,
473 sizeof(*type));
474 return 0;
477 if (!i)
478 return 1;
479 done = 1;
480 continue;
482 i++;
483 tok_get();
485 type->bt = size | (sign ? BT_SIGNED : 0);
486 return 0;
489 static int readname(struct type *main, char *name,
490 struct type *base, unsigned flags);
492 static int readtype(struct type *type)
494 return readname(type, NULL, NULL, 0);
497 static void readptrs(struct type *type)
499 while (!tok_jmp('*')) {
500 type->ptr++;
501 if (!type->bt)
502 type->bt = 1;
506 static int ncexpr;
508 static void readpre(void);
510 static void readprimary(void)
512 int i;
513 if (!tok_jmp(TOK_NUM)) {
514 ts_push_bt(4 | BT_SIGNED);
515 o_num(tok_num(), 4 | BT_SIGNED);
516 return;
518 if (!tok_jmp(TOK_STR)) {
519 struct type t;
520 char buf[BUFSIZE];
521 int len;
522 t.bt = 1 | BT_SIGNED;
523 t.ptr = 1;
524 t.flags = 0;
525 ts_push(&t);
526 len = tok_str(buf);
527 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
528 o_addr();
529 return;
531 if (!tok_jmp(TOK_NAME)) {
532 struct name unkn;
533 char *name = unkn.name;
534 int n;
535 strcpy(name, tok_id());
536 /* don't search for labels here */
537 if (!ncexpr && tok_see() == ':')
538 return;
539 for (i = nlocals - 1; i >= 0; --i) {
540 struct type *t = &locals[i].type;
541 if (!strcmp(locals[i].name, name)) {
542 o_local(locals[i].addr, TYPE_BT(t));
543 ts_push(t);
544 return;
547 if ((n = global_find(name)) != -1) {
548 struct name *g = &globals[n];
549 struct type *t = &g->type;
550 if (g->unused) {
551 g->unused = 0;
552 if (t->flags & T_FUNC && !t->ptr)
553 g->addr = out_mkundef(name, 0);
554 else
555 g->addr = out_mkundef(name, type_totsz(t));
557 o_symaddr(g->addr, TYPE_BT(t));
558 ts_push(t);
559 return;
561 if (!enum_find(&n, name)) {
562 ts_push_bt(4 | BT_SIGNED);
563 o_num(n, 4 | BT_SIGNED);
564 return;
566 if (tok_see() != '(')
567 err("unknown symbol\n");
568 unkn.addr = out_mkundef(unkn.name, 0);
569 global_add(&unkn);
570 ts_push_bt(8);
571 o_symaddr(unkn.addr, 8);
572 return;
574 if (!tok_jmp('(')) {
575 struct type t;
576 if (!readtype(&t)) {
577 struct type o;
578 tok_expect(')');
579 readpre();
580 ts_pop(&o);
581 ts_push(&t);
582 if (!t.ptr || !o.ptr)
583 o_cast(TYPE_BT(&t));
584 } else {
585 readexpr();
586 tok_expect(')');
588 return;
592 void arrayderef(struct type *t)
594 int sz = type_totsz(t);
595 if (sz > 1) {
596 o_num(sz, 4);
597 o_mul();
599 o_add();
600 o_deref(TYPE_BT(t));
603 static void inc_post(void (*op)(void))
605 unsigned bt = TYPE_BT(&ts[nts - 1]);
606 o_tmpcopy();
607 o_load();
608 o_tmpswap();
609 o_tmpcopy();
610 o_num(1, 4);
611 ts_push_bt(bt);
612 ts_push_bt(bt);
613 ts_binop_add(op);
614 ts_pop(NULL);
615 o_assign(bt);
616 o_tmpdrop(1);
619 static void readfield(void)
621 struct name *field;
622 struct type t;
623 tok_expect(TOK_NAME);
624 ts_pop(&t);
625 array2ptr(&t);
626 field = struct_field(t.id, tok_id());
627 if (field->addr) {
628 o_num(field->addr, 4);
629 o_add();
631 o_deref(TYPE_BT(&field->type));
632 ts_push(&field->type);
635 #define MAXFUNCS (1 << 10)
637 static struct funcinfo {
638 struct type args[MAXFIELDS];
639 struct type ret;
640 int nargs;
641 } funcs[MAXFUNCS];
642 static int nfuncs;
643 static unsigned ret_bt;
645 static int func_create(struct type *ret, struct name *args, int nargs)
647 struct funcinfo *fi = &funcs[nfuncs++];
648 int i;
649 if (nfuncs >= MAXFUNCS)
650 err("nomem: MAXFUNCS reached!\n");
651 memcpy(&fi->ret, ret, sizeof(*ret));
652 for (i = 0; i < nargs; i++)
653 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
654 fi->nargs = nargs;
655 return fi - funcs;
658 static void readcall(void)
660 struct type t;
661 unsigned bt[MAXARGS];
662 struct funcinfo *fi;
663 int argc = 0;
664 int i;
665 if (tok_see() != ')') {
666 readexpr();
667 ts_pop(&t);
668 bt[argc++] = TYPE_BT(&t);
670 while (!tok_jmp(',')) {
671 readexpr();
672 ts_pop(&t);
673 bt[argc++] = TYPE_BT(&t);
675 tok_expect(')');
676 ts_pop(&t);
677 if (t.flags & T_FUNC && t.ptr > 0)
678 o_deref(8);
679 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
680 if (fi)
681 for (i = 0; i < fi->nargs; i++)
682 bt[i] = TYPE_BT(&fi->args[i]);
683 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
684 if (fi)
685 ts_push(&fi->ret);
686 else
687 ts_push_bt(4 | BT_SIGNED);
690 static void readpost(void)
692 readprimary();
693 while (1) {
694 if (!tok_jmp('[')) {
695 struct type t;
696 ts_pop(&t);
697 readexpr();
698 ts_pop(NULL);
699 tok_expect(']');
700 array2ptr(&t);
701 t.ptr--;
702 arrayderef(&t);
703 ts_push(&t);
704 continue;
706 if (!tok_jmp('(')) {
707 readcall();
708 continue;
710 if (!tok_jmp(TOK2("++"))) {
711 inc_post(o_add);
712 continue;
714 if (!tok_jmp(TOK2("--"))) {
715 inc_post(o_sub);
716 continue;
718 if (!tok_jmp('.')) {
719 o_addr();
720 readfield();
721 continue;
723 if (!tok_jmp(TOK2("->"))) {
724 readfield();
725 continue;
727 break;
731 static void inc_pre(void (*op)(void))
733 unsigned bt = TYPE_BT(&ts[nts - 1]);
734 readpre();
735 o_tmpcopy();
736 o_num(1, 4);
737 ts_push_bt(bt);
738 ts_push_bt(bt);
739 ts_binop_add(op);
740 ts_pop(NULL);
741 o_assign(bt);
744 static void readpre(void)
746 if (!tok_jmp('&')) {
747 struct type type;
748 readpre();
749 ts_pop(&type);
750 if (!(type.flags & T_FUNC) && !type.ptr)
751 type.ptr++;
752 ts_push(&type);
753 o_addr();
754 return;
756 if (!tok_jmp('*')) {
757 struct type t;
758 readpre();
759 ts_pop(&t);
760 array2ptr(&t);
761 if (!(t.flags & T_FUNC) || t.ptr > 0) {
762 t.ptr--;
763 o_deref(TYPE_BT(&t));
765 ts_push(&t);
766 return;
768 if (!tok_jmp('!')) {
769 struct type type;
770 readpre();
771 ts_pop(&type);
772 o_lnot();
773 ts_push_bt(4 | BT_SIGNED);
774 return;
776 if (!tok_jmp('-')) {
777 readpre();
778 o_neg();
779 return;
781 if (!tok_jmp('~')) {
782 readpre();
783 o_not();
784 return;
786 if (!tok_jmp(TOK2("++"))) {
787 inc_pre(o_add);
788 return;
790 if (!tok_jmp(TOK2("--"))) {
791 inc_pre(o_sub);
792 return;
794 if (!tok_jmp(TOK_SIZEOF)) {
795 struct type t;
796 int op = !tok_jmp('(');
797 if (readtype(&t)) {
798 int nogen = !o_nogen();
799 readexpr();
800 if (nogen)
801 o_dogen();
802 ts_pop(&t);
803 o_tmpdrop(1);
805 ts_push_bt(4);
806 o_num(type_totsz(&t), 4);
807 if (op)
808 tok_expect(')');
809 return;
811 readpost();
814 static void readmul(void)
816 readpre();
817 while (1) {
818 if (!tok_jmp('*')) {
819 readpre();
820 ts_binop(o_mul);
821 continue;
823 if (!tok_jmp('/')) {
824 readpre();
825 ts_binop(o_div);
826 continue;
828 if (!tok_jmp('%')) {
829 readpre();
830 ts_binop(o_mod);
831 continue;
833 break;
837 static void readadd(void)
839 readmul();
840 while (1) {
841 if (!tok_jmp('+')) {
842 readmul();
843 ts_binop_add(o_add);
844 continue;
846 if (!tok_jmp('-')) {
847 readmul();
848 ts_binop_add(o_sub);
849 continue;
851 break;
855 static void shift(void (*op)(void))
857 struct type t;
858 readadd();
859 ts_pop(NULL);
860 ts_pop(&t);
861 op();
862 ts_push_bt(TYPE_BT(&t));
865 static void readshift(void)
867 readadd();
868 while (1) {
869 if (!tok_jmp(TOK2("<<"))) {
870 shift(o_shl);
871 continue;
873 if (!tok_jmp(TOK2(">>"))) {
874 shift(o_shr);
875 continue;
877 break;
881 static void cmp(void (*op)(void))
883 readshift();
884 ts_pop(NULL);
885 ts_pop(NULL);
886 op();
887 ts_push_bt(4 | BT_SIGNED);
890 static void readcmp(void)
892 readshift();
893 while (1) {
894 if (!tok_jmp('<')) {
895 cmp(o_lt);
896 continue;
898 if (!tok_jmp('>')) {
899 cmp(o_gt);
900 continue;
902 if (!tok_jmp(TOK2("<="))) {
903 cmp(o_le);
904 continue;
906 if (!tok_jmp(TOK2(">="))) {
907 cmp(o_ge);
908 continue;
910 break;
914 static void eq(void (*op)(void))
916 readcmp();
917 ts_pop(NULL);
918 ts_pop(NULL);
919 op();
920 ts_push_bt(4 | BT_SIGNED);
923 static void readeq(void)
925 readcmp();
926 while (1) {
927 if (!tok_jmp(TOK2("=="))) {
928 eq(o_eq);
929 continue;
931 if (!tok_jmp(TOK2("!="))) {
932 eq(o_neq);
933 continue;
935 break;
939 static void readbitand(void)
941 readeq();
942 while (!tok_jmp('&')) {
943 readeq();
944 ts_binop(o_and);
948 static void readxor(void)
950 readbitand();
951 while (!tok_jmp('^')) {
952 readbitand();
953 ts_binop(o_xor);
957 static void readbitor(void)
959 readxor();
960 while (!tok_jmp('|')) {
961 readxor();
962 ts_binop(o_or);
966 #define MAXCOND (1 << 7)
968 static void readand(void)
970 long conds[MAXCOND];
971 int nconds = 0;
972 long passed;
973 int i;
974 readbitor();
975 if (tok_see() != TOK2("&&"))
976 return;
977 conds[nconds++] = o_jz(0);
978 ts_pop(NULL);
979 while (!tok_jmp(TOK2("&&"))) {
980 readbitor();
981 conds[nconds++] = o_jz(0);
982 ts_pop(NULL);
984 o_num(1, 4 | BT_SIGNED);
985 o_tmpfork();
986 passed = o_jmp(0);
987 for (i = 0; i < nconds; i++)
988 o_filljmp(conds[i]);
989 o_num(0, 4 | BT_SIGNED);
990 o_tmpjoin();
991 o_filljmp(passed);
992 ts_push_bt(4 | BT_SIGNED);
995 static void reador(void)
997 long conds[MAXCOND];
998 int nconds = 0;
999 long failed;
1000 int i;
1001 readand();
1002 if (tok_see() != TOK2("||"))
1003 return;
1004 conds[nconds++] = o_jnz(0);
1005 ts_pop(NULL);
1006 while (!tok_jmp(TOK2("||"))) {
1007 readand();
1008 conds[nconds++] = o_jnz(0);
1009 ts_pop(NULL);
1011 o_num(0, 4 | BT_SIGNED);
1012 o_tmpfork();
1013 failed = o_jmp(0);
1014 for (i = 0; i < nconds; i++)
1015 o_filljmp(conds[i]);
1016 o_num(1, 4 | BT_SIGNED);
1017 o_tmpjoin();
1018 o_filljmp(failed);
1019 ts_push_bt(4 | BT_SIGNED);
1022 static void readcexpr(void)
1024 long l1, l2;
1025 long c;
1026 int cexpr, nogen;
1027 reador();
1028 if (tok_jmp('?'))
1029 return;
1030 ncexpr++;
1031 cexpr = !o_popnum(&c);
1032 ts_pop(NULL);
1033 if (cexpr) {
1034 if (!c)
1035 nogen = !o_nogen();
1036 } else {
1037 l1 = o_jz(0);
1039 reador();
1040 if (!cexpr) {
1041 o_tmpfork();
1042 l2 = o_jmp(0);
1044 ts_pop(NULL);
1045 tok_expect(':');
1046 if (cexpr) {
1047 if (c) {
1048 nogen = !o_nogen();
1049 } else {
1050 if (nogen)
1051 o_dogen();
1052 o_tmpdrop(1);
1054 } else {
1055 o_filljmp(l1);
1057 reador();
1058 if (cexpr) {
1059 if (c) {
1060 if (nogen)
1061 o_dogen();
1062 o_tmpdrop(1);
1064 } else {
1065 o_tmpjoin();
1066 o_filljmp(l2);
1068 ncexpr--;
1071 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1073 unsigned bt = TYPE_BT(&ts[nts - 1]);
1074 o_tmpcopy();
1075 readexpr();
1076 bop(op);
1077 ts_pop(NULL);
1078 o_assign(bt);
1081 static void doassign(void)
1083 struct type t;
1084 ts_pop(&t);
1085 if (!t.ptr && t.flags & T_STRUCT)
1086 o_memcpy(type_totsz(&t));
1087 else
1088 o_assign(TYPE_BT(&ts[nts - 1]));
1091 static void readexpr(void)
1093 readcexpr();
1094 if (!tok_jmp('=')) {
1095 readexpr();
1096 doassign();
1097 return;
1099 if (!tok_jmp(TOK2("+="))) {
1100 opassign(ts_binop_add, o_add);
1101 return;
1103 if (!tok_jmp(TOK2("-="))) {
1104 opassign(ts_binop_add, o_sub);
1105 return;
1107 if (!tok_jmp(TOK2("*="))) {
1108 opassign(ts_binop, o_mul);
1109 return;
1111 if (!tok_jmp(TOK2("/="))) {
1112 opassign(ts_binop, o_div);
1113 return;
1115 if (!tok_jmp(TOK2("%="))) {
1116 opassign(ts_binop, o_mod);
1117 return;
1119 if (!tok_jmp(TOK3("<<="))) {
1120 opassign(ts_binop, o_shl);
1121 return;
1123 if (!tok_jmp(TOK3(">>="))) {
1124 opassign(ts_binop, o_shr);
1125 return;
1127 if (!tok_jmp(TOK3("&="))) {
1128 opassign(ts_binop, o_and);
1129 return;
1131 if (!tok_jmp(TOK3("|="))) {
1132 opassign(ts_binop, o_or);
1133 return;
1135 if (!tok_jmp(TOK3("^="))) {
1136 opassign(ts_binop, o_xor);
1137 return;
1141 static void readestmt(void)
1143 do {
1144 o_tmpdrop(-1);
1145 nts = 0;
1146 readexpr();
1147 } while (!tok_jmp(','));
1150 static void o_localoff(long addr, int off, unsigned bt)
1152 o_local(addr, bt);
1153 if (off) {
1154 o_addr();
1155 o_num(off, 4);
1156 o_add();
1157 o_deref(bt);
1161 static struct type *innertype(struct type *t)
1163 if (t->flags & T_ARRAY && !t->ptr)
1164 return innertype(&arrays[t->id].type);
1165 return t;
1168 static void initexpr(struct type *t, int off, void *obj,
1169 void (*set)(void *obj, int off, struct type *t))
1171 if (tok_jmp('{')) {
1172 set(obj, off, t);
1173 return;
1175 if (!t->ptr && t->flags & T_STRUCT) {
1176 struct structinfo *si = &structs[t->id];
1177 int i;
1178 for (i = 0; i < si->nfields; i++) {
1179 struct name *field = &si->fields[i];
1180 if (!tok_jmp('.')) {
1181 tok_expect(TOK_NAME);
1182 field = struct_field(t->id, tok_id());
1183 tok_expect('=');
1185 initexpr(&field->type, off + field->addr, obj, set);
1186 if (tok_jmp(',') || tok_see() == '}')
1187 break;
1189 } else if (t->flags & T_ARRAY) {
1190 struct type *t_de = &arrays[t->id].type;
1191 int i;
1192 for (i = 0; ; i++) {
1193 long idx = i;
1194 struct type *it = t_de;
1195 if (!tok_jmp('[')) {
1196 readexpr();
1197 o_popnum(&idx);
1198 ts_pop(NULL);
1199 tok_expect(']');
1200 tok_expect('=');
1202 if (tok_see() != '{')
1203 it = innertype(t_de);
1204 initexpr(it, off + type_totsz(it) * idx, obj, set);
1205 if (tok_jmp(',') || tok_see() == '}')
1206 break;
1209 tok_expect('}');
1212 static void jumpbrace(void)
1214 int depth = 0;
1215 while (tok_see() != '}' || depth--)
1216 if (tok_get() == '{')
1217 depth++;
1218 tok_expect('}');
1221 static int initsize(void)
1223 long addr = tok_addr();
1224 int n = 0;
1225 if (!tok_jmp(TOK_STR)) {
1226 n = tok_str(NULL);
1227 tok_jump(addr);
1228 return n;
1230 o_nogen();
1231 tok_expect('{');
1232 while (tok_jmp('}')) {
1233 long idx = n;
1234 if (!tok_jmp('[')) {
1235 readexpr();
1236 o_popnum(&idx);
1237 ts_pop(NULL);
1238 tok_expect(']');
1239 tok_expect('=');
1241 if (n < idx + 1)
1242 n = idx + 1;
1243 while (tok_see() != '}' && tok_see() != ',')
1244 if (tok_get() == '{')
1245 jumpbrace();
1246 tok_jmp(',');
1248 o_dogen();
1249 tok_jump(addr);
1250 return n;
1253 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1255 static void globalinit(void *obj, int off, struct type *t)
1257 long addr = *(long *) obj;
1258 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1259 struct type *t_de = &arrays[t->id].type;
1260 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1261 char buf[BUFSIZE];
1262 int len;
1263 tok_expect(TOK_STR);
1264 len = tok_str(buf);
1265 out_datcpy(addr, off, buf, len);
1266 return;
1269 readexpr();
1270 o_datset(addr, off, TYPE_BT(t));
1271 ts_pop(NULL);
1274 static void globaldef(void *data, struct name *name, unsigned flags)
1276 struct type *t = &name->type;
1277 char *varname = flags & F_STATIC ? NULL : name->name;
1278 int sz;
1279 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1280 arrays[t->id].n = initsize();
1281 sz = type_totsz(t);
1282 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1283 name->unused = 1;
1284 else if (flags & F_INIT)
1285 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1286 else
1287 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1288 global_add(name);
1289 if (flags & F_INIT)
1290 initexpr(t, 0, &name->addr, globalinit);
1293 static void localinit(void *obj, int off, struct type *t)
1295 long addr = *(long *) obj;
1296 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1297 struct type *t_de = &arrays[t->id].type;
1298 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1299 char buf[BUFSIZE];
1300 int len;
1301 tok_expect(TOK_STR);
1302 len = tok_str(buf);
1303 o_localoff(addr, off, TYPE_BT(t));
1304 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1305 o_memcpy(len);
1306 o_tmpdrop(1);
1307 return;
1310 o_localoff(addr, off, TYPE_BT(t));
1311 ts_push(t);
1312 readexpr();
1313 doassign();
1314 ts_pop(NULL);
1315 o_tmpdrop(1);
1318 static void localdef(void *data, struct name *name, unsigned flags)
1320 struct type *t = &name->type;
1321 if (flags & (F_STATIC | F_EXTERN)) {
1322 globaldef(data, name, flags);
1323 return;
1325 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1326 arrays[t->id].n = initsize();
1327 name->addr = o_mklocal(type_totsz(&name->type));
1328 local_add(name);
1329 if (flags & F_INIT) {
1330 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1331 o_local(name->addr, TYPE_BT(t));
1332 o_memset(0, type_totsz(t));
1333 o_tmpdrop(1);
1335 initexpr(t, 0, &name->addr, localinit);
1339 static void funcdef(char *name, struct type *type, struct name *args,
1340 int nargs, unsigned flags)
1342 struct name global;
1343 int i;
1344 strcpy(global.name, name);
1345 memcpy(&global.type, type, sizeof(*type));
1346 global.addr = o_func_beg(name, F_GLOBAL(flags));
1347 global.unused = 0;
1348 global_add(&global);
1349 ret_bt = TYPE_BT(&funcs[type->id].ret);
1350 for (i = 0; i < nargs; i++) {
1351 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1352 local_add(&args[i]);
1356 static int readargs(struct name *args)
1358 int nargs = 0;
1359 tok_expect('(');
1360 while (tok_see() != ')') {
1361 if (!tok_jmp(TOK3("...")))
1362 break;
1363 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1364 array2ptr(&args[nargs].type);
1365 nargs++;
1366 if (tok_jmp(','))
1367 break;
1369 tok_expect(')');
1370 if (nargs == 1 && !TYPE_BT(&args[0].type))
1371 return 0;
1372 return nargs;
1375 static int readname(struct type *main, char *name,
1376 struct type *base, unsigned flags)
1378 struct type tpool[3];
1379 int npool = 0;
1380 struct type *type = &tpool[npool++];
1381 struct type *func = NULL;
1382 struct type *ret = NULL;
1383 int arsz[10];
1384 int nar = 0;
1385 int i;
1386 memset(tpool, 0, sizeof(tpool));
1387 if (name)
1388 *name = '\0';
1389 if (!base) {
1390 if (basetype(type, &flags))
1391 return 1;
1392 } else {
1393 memcpy(type, base, sizeof(*base));
1395 readptrs(type);
1396 if (!tok_jmp('(')) {
1397 ret = type;
1398 type = &tpool[npool++];
1399 func = type;
1400 readptrs(type);
1402 if (!tok_jmp(TOK_NAME) && name)
1403 strcpy(name, tok_id());
1404 while (!tok_jmp('[')) {
1405 long n = 0;
1406 if (tok_jmp(']')) {
1407 readexpr();
1408 ts_pop(NULL);
1409 if (o_popnum(&n))
1410 err("const expr expected\n");
1411 tok_expect(']');
1413 arsz[nar++] = n;
1415 for (i = nar - 1; i >= 0; i--) {
1416 type->id = array_add(type, arsz[i]);
1417 if (type->flags & T_FUNC)
1418 func = &arrays[type->id].type;
1419 type->flags = T_ARRAY;
1420 type->bt = 8;
1421 type->ptr = 0;
1423 if (func)
1424 tok_expect(')');
1425 if (tok_see() == '(') {
1426 struct name args[MAXARGS];
1427 int nargs = readargs(args);
1428 int fdef = !func;
1429 if (!func) {
1430 ret = type;
1431 type = &tpool[npool++];
1432 func = type;
1434 func->flags = T_FUNC;
1435 func->bt = 8;
1436 func->id = func_create(ret, args, nargs);
1437 if (fdef && tok_see() == '{') {
1438 funcdef(name, func, args, nargs, flags);
1439 return 1;
1442 memcpy(main, type, sizeof(*type));
1443 return 0;
1446 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1447 void *data)
1449 struct type base;
1450 unsigned flags;
1451 if (basetype(&base, &flags))
1452 return 1;
1453 while (tok_see() != ';' && tok_see() != '{') {
1454 struct name name;
1455 name.unused = 0;
1456 if (readname(&name.type, name.name, &base, flags))
1457 break;
1458 if (!tok_jmp('='))
1459 flags |= F_INIT;
1460 def(data, &name, flags);
1461 tok_jmp(',');
1463 return 0;
1466 static void typedefdef(void *data, struct name *name, unsigned flags)
1468 typedef_add(name->name, &name->type);
1471 static void readstmt(void);
1473 #define MAXCASES (1 << 7)
1475 static void readswitch(void)
1477 int break_beg = nbreaks;
1478 long val_addr = o_mklocal(8);
1479 long matched[MAXCASES];
1480 int nmatched = 0;
1481 struct type t;
1482 long next;
1483 int ref = 1;
1484 int i;
1485 tok_expect('(');
1486 readexpr();
1487 ts_pop(&t);
1488 o_local(val_addr, TYPE_BT(&t));
1489 o_tmpswap();
1490 o_assign(TYPE_BT(&t));
1491 o_tmpdrop(1);
1492 tok_expect(')');
1493 tok_expect('{');
1494 while (tok_jmp('}')) {
1495 int n = 0;
1496 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1497 if (n++ > 0)
1498 matched[nmatched++] = o_jmp(0);
1499 if (!ref++)
1500 o_filljmp(next);
1501 if (!tok_jmp(TOK_CASE)) {
1502 readexpr();
1503 o_local(val_addr, TYPE_BT(&t));
1504 o_eq();
1505 next = o_jz(0);
1506 ref = 0;
1507 tok_expect(':');
1508 o_tmpdrop(1);
1509 ts_pop(NULL);
1510 continue;
1512 if (!tok_jmp(TOK_DEFAULT)) {
1513 tok_expect(':');
1514 continue;
1517 for (i = 0; i < nmatched; i++)
1518 o_filljmp(matched[i]);
1519 nmatched = 0;
1520 readstmt();
1522 o_rmlocal(val_addr, 8);
1523 if (!ref++)
1524 o_filljmp(next);
1525 break_fill(o_mklabel(), break_beg);
1528 #define MAXGOTO (1 << 10)
1530 static struct gotoinfo {
1531 char name[NAMELEN];
1532 long addr;
1533 } gotos[MAXGOTO];
1534 static int ngotos;
1536 static struct labelinfo {
1537 char name[NAMELEN];
1538 long addr;
1539 } labels[MAXGOTO];
1540 static int nlabels;
1542 static void goto_add(char *name)
1544 strcpy(gotos[ngotos].name, name);
1545 gotos[ngotos++].addr = o_jmp(0);
1548 static void label_add(char *name)
1550 strcpy(labels[nlabels].name, name);
1551 labels[nlabels++].addr = o_mklabel();
1554 static void goto_fill(void)
1556 int i, j;
1557 for (i = 0; i < ngotos; i++)
1558 for (j = 0; j < nlabels; j++)
1559 if (!strcmp(gotos[i].name, labels[j].name)) {
1560 o_filljmp2(gotos[i].addr, labels[j].addr);
1561 break;
1565 static void readstmt(void)
1567 o_tmpdrop(-1);
1568 nts = 0;
1569 if (!tok_jmp('{')) {
1570 int _nlocals = nlocals;
1571 int _nglobals = nglobals;
1572 int _nenums = nenums;
1573 int _ntypedefs = ntypedefs;
1574 int _nstructs = nstructs;
1575 int _nfuncs = nfuncs;
1576 int _narrays = narrays;
1577 while (tok_jmp('}'))
1578 readstmt();
1579 nlocals = _nlocals;
1580 nenums = _nenums;
1581 ntypedefs = _ntypedefs;
1582 nstructs = _nstructs;
1583 nfuncs = _nfuncs;
1584 narrays = _narrays;
1585 nglobals = _nglobals;
1586 return;
1588 if (!readdefs(localdef, NULL)) {
1589 tok_expect(';');
1590 return;
1592 if (!tok_jmp(TOK_TYPEDEF)) {
1593 readdefs(typedefdef, NULL);
1594 tok_expect(';');
1595 return;
1597 if (!tok_jmp(TOK_IF)) {
1598 long l1, l2;
1599 tok_expect('(');
1600 readexpr();
1601 tok_expect(')');
1602 l1 = o_jz(0);
1603 readstmt();
1604 if (!tok_jmp(TOK_ELSE)) {
1605 l2 = o_jmp(0);
1606 o_filljmp(l1);
1607 readstmt();
1608 o_filljmp(l2);
1609 } else {
1610 o_filljmp(l1);
1612 return;
1614 if (!tok_jmp(TOK_WHILE)) {
1615 long l1, l2;
1616 int break_beg = nbreaks;
1617 int continue_beg = ncontinues;
1618 l1 = o_mklabel();
1619 tok_expect('(');
1620 readexpr();
1621 tok_expect(')');
1622 l2 = o_jz(0);
1623 readstmt();
1624 o_jmp(l1);
1625 o_filljmp(l2);
1626 break_fill(o_mklabel(), break_beg);
1627 continue_fill(l1, continue_beg);
1628 return;
1630 if (!tok_jmp(TOK_DO)) {
1631 long l1, l2;
1632 int break_beg = nbreaks;
1633 int continue_beg = ncontinues;
1634 l1 = o_mklabel();
1635 readstmt();
1636 tok_expect(TOK_WHILE);
1637 tok_expect('(');
1638 l2 = o_mklabel();
1639 readexpr();
1640 o_jnz(l1);
1641 tok_expect(')');
1642 break_fill(o_mklabel(), break_beg);
1643 continue_fill(l2, continue_beg);
1644 return;
1646 if (!tok_jmp(TOK_FOR)) {
1647 long l_check, l_jump, j_fail, j_pass;
1648 int break_beg = nbreaks;
1649 int continue_beg = ncontinues;
1650 int has_cond = 0;
1651 tok_expect('(');
1652 if (tok_see() != ';')
1653 readestmt();
1654 tok_expect(';');
1655 l_check = o_mklabel();
1656 if (tok_see() != ';') {
1657 readestmt();
1658 j_fail = o_jz(0);
1659 has_cond = 1;
1661 tok_expect(';');
1662 j_pass = o_jmp(0);
1663 l_jump = o_mklabel();
1664 if (tok_see() != ')')
1665 readestmt();
1666 tok_expect(')');
1667 o_jmp(l_check);
1668 o_filljmp(j_pass);
1669 readstmt();
1670 o_jmp(l_jump);
1671 if (has_cond)
1672 o_filljmp(j_fail);
1673 break_fill(o_mklabel(), break_beg);
1674 continue_fill(l_jump, continue_beg);
1675 return;
1677 if (!tok_jmp(TOK_SWITCH)) {
1678 readswitch();
1679 return;
1681 if (!tok_jmp(TOK_RETURN)) {
1682 int ret = tok_see() != ';';
1683 if (ret)
1684 readexpr();
1685 tok_expect(';');
1686 o_ret(ret_bt);
1687 return;
1689 if (!tok_jmp(TOK_BREAK)) {
1690 tok_expect(';');
1691 breaks[nbreaks++] = o_jmp(0);
1692 return;
1694 if (!tok_jmp(TOK_CONTINUE)) {
1695 tok_expect(';');
1696 continues[ncontinues++] = o_jmp(0);
1697 return;
1699 if (!tok_jmp(TOK_GOTO)) {
1700 tok_expect(TOK_NAME);
1701 goto_add(tok_id());
1702 tok_expect(';');
1703 return;
1705 readestmt();
1706 /* labels */
1707 if (!tok_jmp(':')) {
1708 label_add(tok_id());
1709 return;
1711 tok_expect(';');
1714 static void readdecl(void)
1716 if (!tok_jmp(TOK_TYPEDEF)) {
1717 readdefs(typedefdef, NULL);
1718 tok_expect(';');
1719 return;
1721 readdefs(globaldef, NULL);
1722 if (tok_see() == '{') {
1723 readstmt();
1724 goto_fill();
1725 o_func_end();
1726 nlocals = 0;
1727 ngotos = 0;
1728 nlabels = 0;
1729 return;
1731 tok_expect(';');
1734 static void parse(void)
1736 while (tok_see() != TOK_EOF)
1737 readdecl();
1740 int main(int argc, char *argv[])
1742 char obj[128];
1743 int ofd;
1744 int i = 1;
1745 while (i < argc && argv[i][0] == '-') {
1746 if (argv[i][1] == 'I')
1747 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1748 if (argv[i][1] == 'D') {
1749 char *name = argv[i] + 2;
1750 char *def = "";
1751 char *eq = strchr(name, '=');
1752 if (eq) {
1753 *eq = '\0';
1754 def = eq + 1;
1756 cpp_define(name, def);
1758 i++;
1760 if (i == argc)
1761 die("neatcc: no file given\n");
1762 if (cpp_init(argv[i]))
1763 die("neatcc: cannot open input file\n");
1764 parse();
1765 strcpy(obj, argv[i]);
1766 obj[strlen(obj) - 1] = 'o';
1767 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1768 out_write(ofd);
1769 close(ofd);
1770 return 0;