cpp: save macro names in a hash table
[neatcc.git] / ncc.c
blob42305dabcb7c102e8736071d7d50a7a5ef7db31a
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 void ts_binop_add(void (*o_sth)(void))
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_sth();
315 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
316 return;
318 if (t1.ptr && !t2.ptr) {
319 struct type t = t2;
320 t2 = t1;
321 t1 = t;
322 o_tmpswap();
324 if (!t1.ptr && t2.ptr)
325 if (type_szde(&t2) > 1) {
326 o_num(type_szde(&t2), 4);
327 o_mul();
329 o_sth();
330 if (t1.ptr && t2.ptr) {
331 int sz = type_szde(&t1);
332 if (sz > 1) {
333 o_num(sz, 4);
334 o_div();
336 ts_push_bt(4 | BT_SIGNED);
337 } else {
338 ts_push(&t2);
342 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
343 #define MIN(a, b) ((a) < (b) ? (a) : (b))
345 static void structdef(void *data, struct name *name, unsigned flags)
347 struct structinfo *si = data;
348 if (si->isunion) {
349 name->addr = 0;
350 if (si->size < type_totsz(&name->type))
351 si->size = type_totsz(&name->type);
352 } else {
353 struct type *t = &name->type;
354 int alignment = MIN(8, type_totsz(t));
355 if (t->flags & T_ARRAY && !t->ptr)
356 alignment = MIN(8, type_totsz(&arrays[t->id].type));
357 si->size = ALIGN(si->size, alignment);
358 name->addr = si->size;
359 si->size += type_totsz(&name->type);
361 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
364 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
366 static int struct_create(char *name, int isunion)
368 int id = struct_find(name, isunion);
369 struct structinfo *si = &structs[id];
370 tok_expect('{');
371 while (tok_jmp('}')) {
372 readdefs(structdef, si);
373 tok_expect(';');
375 return id;
378 static void readexpr(void);
380 static void enum_create(void)
382 long n = 0;
383 tok_expect('{');
384 while (tok_jmp('}')) {
385 char name[NAMELEN];
386 tok_expect(TOK_NAME);
387 strcpy(name, tok_id());
388 if (tok_see() == '=') {
389 tok_get();
390 readexpr();
391 ts_pop(NULL);
392 if (o_popnum(&n))
393 err("const expr expected!\n");
395 enum_add(name, n++);
396 tok_jmp(',');
400 static int basetype(struct type *type, unsigned *flags)
402 int sign = 1;
403 int size = 4;
404 int done = 0;
405 int i = 0;
406 int isunion;
407 char name[NAMELEN] = "";
408 *flags = 0;
409 type->flags = 0;
410 type->ptr = 0;
411 while (!done) {
412 switch (tok_see()) {
413 case TOK_STATIC:
414 *flags |= F_STATIC;
415 break;
416 case TOK_EXTERN:
417 *flags |= F_EXTERN;
418 break;
419 case TOK_VOID:
420 sign = 0;
421 size = 0;
422 done = 1;
423 break;
424 case TOK_INT:
425 done = 1;
426 break;
427 case TOK_CHAR:
428 size = 1;
429 done = 1;
430 break;
431 case TOK_SHORT:
432 size = 2;
433 break;
434 case TOK_LONG:
435 size = 8;
436 break;
437 case TOK_SIGNED:
438 break;
439 case TOK_UNSIGNED:
440 sign = 0;
441 break;
442 case TOK_UNION:
443 case TOK_STRUCT:
444 isunion = tok_get() == TOK_UNION;
445 if (!tok_jmp(TOK_NAME))
446 strcpy(name, tok_id());
447 if (tok_see() == '{')
448 type->id = struct_create(name, isunion);
449 else
450 type->id = struct_find(name, isunion);
451 type->flags |= T_STRUCT;
452 type->bt = 8;
453 return 0;
454 case TOK_ENUM:
455 tok_get();
456 tok_jmp(TOK_NAME);
457 if (tok_see() == '{')
458 enum_create();
459 type->bt = 4 | BT_SIGNED;
460 return 0;
461 default:
462 if (tok_see() == TOK_NAME) {
463 int id = typedef_find(tok_id());
464 if (id != -1) {
465 tok_get();
466 memcpy(type, &typedefs[id].type,
467 sizeof(*type));
468 return 0;
471 if (!i)
472 return 1;
473 done = 1;
474 continue;
476 i++;
477 tok_get();
479 type->bt = size | (sign ? BT_SIGNED : 0);
480 return 0;
483 static int readname(struct type *main, char *name,
484 struct type *base, unsigned flags);
486 static int readtype(struct type *type)
488 return readname(type, NULL, NULL, 0);
491 static void readptrs(struct type *type)
493 while (!tok_jmp('*')) {
494 type->ptr++;
495 if (!type->bt)
496 type->bt = 1;
500 /* used to differenciate labels from case and cond exprs */
501 static int ncexpr;
502 static int caseexpr;
504 static void readpre(void);
506 static void readprimary(void)
508 int i;
509 if (!tok_jmp(TOK_NUM)) {
510 long n;
511 int bt = tok_num(&n);
512 ts_push_bt(bt);
513 o_num(n, bt);
514 return;
516 if (!tok_jmp(TOK_STR)) {
517 struct type t;
518 char buf[BUFSIZE];
519 int len;
520 t.bt = 1 | BT_SIGNED;
521 t.ptr = 1;
522 t.flags = 0;
523 ts_push(&t);
524 len = tok_str(buf);
525 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
526 o_addr();
527 return;
529 if (!tok_jmp(TOK_NAME)) {
530 struct name unkn = {0};
531 char *name = unkn.name;
532 int n;
533 strcpy(name, tok_id());
534 /* don't search for labels here */
535 if (!ncexpr && !caseexpr && tok_see() == ':')
536 return;
537 for (i = nlocals - 1; i >= 0; --i) {
538 struct type *t = &locals[i].type;
539 if (!strcmp(locals[i].name, name)) {
540 o_local(locals[i].addr, TYPE_BT(t));
541 ts_push(t);
542 return;
545 if ((n = global_find(name)) != -1) {
546 struct name *g = &globals[n];
547 struct type *t = &g->type;
548 if (g->unused) {
549 g->unused = 0;
550 if (t->flags & T_FUNC && !t->ptr)
551 g->addr = out_mkundef(name, 0);
552 else
553 g->addr = out_mkundef(name, type_totsz(t));
555 o_symaddr(g->addr, TYPE_BT(t));
556 ts_push(t);
557 return;
559 if (!enum_find(&n, name)) {
560 ts_push_bt(4 | BT_SIGNED);
561 o_num(n, 4 | BT_SIGNED);
562 return;
564 if (tok_see() != '(')
565 err("unknown symbol\n");
566 unkn.addr = out_mkundef(unkn.name, 0);
567 global_add(&unkn);
568 ts_push_bt(8);
569 o_symaddr(unkn.addr, 8);
570 return;
572 if (!tok_jmp('(')) {
573 struct type t;
574 if (!readtype(&t)) {
575 struct type o;
576 tok_expect(')');
577 readpre();
578 ts_pop(&o);
579 ts_push(&t);
580 if (!t.ptr || !o.ptr)
581 o_cast(TYPE_BT(&t));
582 } else {
583 readexpr();
584 tok_expect(')');
586 return;
590 void arrayderef(struct type *t)
592 int sz = type_totsz(t);
593 if (sz > 1) {
594 o_num(sz, 4);
595 o_mul();
597 o_add();
598 o_deref(TYPE_BT(t));
601 static void inc_post(void (*op)(void))
603 unsigned bt = TYPE_BT(&ts[nts - 1]);
604 o_tmpcopy();
605 o_load();
606 o_tmpswap();
607 o_tmpcopy();
608 o_num(1, 4);
609 ts_push_bt(bt);
610 ts_push_bt(bt);
611 ts_binop_add(op);
612 ts_pop(NULL);
613 o_assign(bt);
614 o_tmpdrop(1);
617 static void readfield(void)
619 struct name *field;
620 struct type t;
621 tok_expect(TOK_NAME);
622 ts_pop(&t);
623 array2ptr(&t);
624 field = struct_field(t.id, tok_id());
625 if (field->addr) {
626 o_num(field->addr, 4);
627 o_add();
629 o_deref(TYPE_BT(&field->type));
630 ts_push(&field->type);
633 #define MAXFUNCS (1 << 10)
635 static struct funcinfo {
636 struct type args[MAXFIELDS];
637 struct type ret;
638 int nargs;
639 } funcs[MAXFUNCS];
640 static int nfuncs;
641 static unsigned ret_bt;
643 static int func_create(struct type *ret, struct name *args, int nargs)
645 struct funcinfo *fi = &funcs[nfuncs++];
646 int i;
647 if (nfuncs >= MAXFUNCS)
648 err("nomem: MAXFUNCS reached!\n");
649 memcpy(&fi->ret, ret, sizeof(*ret));
650 for (i = 0; i < nargs; i++)
651 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
652 fi->nargs = nargs;
653 return fi - funcs;
656 static void readcall(void)
658 struct type t;
659 unsigned bt[MAXARGS];
660 struct funcinfo *fi;
661 int argc = 0;
662 int i;
663 ts_pop(&t);
664 if (t.flags & T_FUNC && t.ptr > 0)
665 o_deref(8);
666 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
667 if (tok_see() != ')') {
668 readexpr();
669 ts_pop(&t);
670 bt[argc++] = TYPE_BT(&t);
672 while (!tok_jmp(',')) {
673 readexpr();
674 ts_pop(&t);
675 bt[argc++] = TYPE_BT(&t);
677 tok_expect(')');
678 if (fi)
679 for (i = 0; i < fi->nargs; i++)
680 bt[i] = TYPE_BT(&fi->args[i]);
681 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
682 if (fi)
683 ts_push(&fi->ret);
684 else
685 ts_push_bt(4 | BT_SIGNED);
688 static void readpost(void)
690 readprimary();
691 while (1) {
692 if (!tok_jmp('[')) {
693 struct type t;
694 ts_pop(&t);
695 readexpr();
696 ts_pop(NULL);
697 tok_expect(']');
698 array2ptr(&t);
699 t.ptr--;
700 arrayderef(&t);
701 ts_push(&t);
702 continue;
704 if (!tok_jmp('(')) {
705 readcall();
706 continue;
708 if (!tok_jmp(TOK2("++"))) {
709 inc_post(o_add);
710 continue;
712 if (!tok_jmp(TOK2("--"))) {
713 inc_post(o_sub);
714 continue;
716 if (!tok_jmp('.')) {
717 o_addr();
718 readfield();
719 continue;
721 if (!tok_jmp(TOK2("->"))) {
722 readfield();
723 continue;
725 break;
729 static void inc_pre(void (*op)(void))
731 unsigned bt;
732 readpre();
733 bt = TYPE_BT(&ts[nts - 1]);
734 o_tmpcopy();
735 o_num(1, 4);
736 ts_push_bt(bt);
737 ts_push_bt(bt);
738 ts_binop_add(op);
739 ts_pop(NULL);
740 o_assign(bt);
743 static void readpre(void)
745 if (!tok_jmp('&')) {
746 struct type type;
747 readpre();
748 ts_pop(&type);
749 if (!(type.flags & T_FUNC) && !type.ptr)
750 type.ptr++;
751 ts_push(&type);
752 o_addr();
753 return;
755 if (!tok_jmp('*')) {
756 struct type t;
757 readpre();
758 ts_pop(&t);
759 array2ptr(&t);
760 if (!(t.flags & T_FUNC) || t.ptr > 0) {
761 t.ptr--;
762 o_deref(TYPE_BT(&t));
764 ts_push(&t);
765 return;
767 if (!tok_jmp('!')) {
768 struct type type;
769 readpre();
770 ts_pop(&type);
771 o_lnot();
772 ts_push_bt(4 | BT_SIGNED);
773 return;
775 if (!tok_jmp('-')) {
776 readpre();
777 o_neg();
778 return;
780 if (!tok_jmp('~')) {
781 readpre();
782 o_not();
783 return;
785 if (!tok_jmp(TOK2("++"))) {
786 inc_pre(o_add);
787 return;
789 if (!tok_jmp(TOK2("--"))) {
790 inc_pre(o_sub);
791 return;
793 if (!tok_jmp(TOK_SIZEOF)) {
794 struct type t;
795 int op = !tok_jmp('(');
796 if (readtype(&t)) {
797 int nogen = !o_nogen();
798 readexpr();
799 if (nogen)
800 o_dogen();
801 ts_pop(&t);
802 o_tmpdrop(1);
804 ts_push_bt(4);
805 o_num(type_totsz(&t), 4);
806 if (op)
807 tok_expect(')');
808 return;
810 readpost();
813 static void readmul(void)
815 readpre();
816 while (1) {
817 if (!tok_jmp('*')) {
818 readpre();
819 ts_binop(o_mul);
820 continue;
822 if (!tok_jmp('/')) {
823 readpre();
824 ts_binop(o_div);
825 continue;
827 if (!tok_jmp('%')) {
828 readpre();
829 ts_binop(o_mod);
830 continue;
832 break;
836 static void readadd(void)
838 readmul();
839 while (1) {
840 if (!tok_jmp('+')) {
841 readmul();
842 ts_binop_add(o_add);
843 continue;
845 if (!tok_jmp('-')) {
846 readmul();
847 ts_binop_add(o_sub);
848 continue;
850 break;
854 static void shift(void (*op)(void))
856 struct type t;
857 readadd();
858 ts_pop(NULL);
859 ts_pop(&t);
860 op();
861 ts_push_bt(TYPE_BT(&t));
864 static void readshift(void)
866 readadd();
867 while (1) {
868 if (!tok_jmp(TOK2("<<"))) {
869 shift(o_shl);
870 continue;
872 if (!tok_jmp(TOK2(">>"))) {
873 shift(o_shr);
874 continue;
876 break;
880 static void cmp(void (*op)(void))
882 readshift();
883 ts_pop(NULL);
884 ts_pop(NULL);
885 op();
886 ts_push_bt(4 | BT_SIGNED);
889 static void readcmp(void)
891 readshift();
892 while (1) {
893 if (!tok_jmp('<')) {
894 cmp(o_lt);
895 continue;
897 if (!tok_jmp('>')) {
898 cmp(o_gt);
899 continue;
901 if (!tok_jmp(TOK2("<="))) {
902 cmp(o_le);
903 continue;
905 if (!tok_jmp(TOK2(">="))) {
906 cmp(o_ge);
907 continue;
909 break;
913 static void eq(void (*op)(void))
915 readcmp();
916 ts_pop(NULL);
917 ts_pop(NULL);
918 op();
919 ts_push_bt(4 | BT_SIGNED);
922 static void readeq(void)
924 readcmp();
925 while (1) {
926 if (!tok_jmp(TOK2("=="))) {
927 eq(o_eq);
928 continue;
930 if (!tok_jmp(TOK2("!="))) {
931 eq(o_neq);
932 continue;
934 break;
938 static void readbitand(void)
940 readeq();
941 while (!tok_jmp('&')) {
942 readeq();
943 ts_binop(o_and);
947 static void readxor(void)
949 readbitand();
950 while (!tok_jmp('^')) {
951 readbitand();
952 ts_binop(o_xor);
956 static void readbitor(void)
958 readxor();
959 while (!tok_jmp('|')) {
960 readxor();
961 ts_binop(o_or);
965 #define MAXCOND (1 << 7)
967 static void readand(void)
969 long conds[MAXCOND];
970 int nconds = 0;
971 long passed;
972 int i;
973 readbitor();
974 if (tok_see() != TOK2("&&"))
975 return;
976 o_fork();
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_forkpush();
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_forkpush();
991 o_forkjoin();
992 o_filljmp(passed);
993 ts_push_bt(4 | BT_SIGNED);
996 static void reador(void)
998 long conds[MAXCOND];
999 int nconds = 0;
1000 long failed;
1001 int i;
1002 readand();
1003 if (tok_see() != TOK2("||"))
1004 return;
1005 o_fork();
1006 conds[nconds++] = o_jnz(0);
1007 ts_pop(NULL);
1008 while (!tok_jmp(TOK2("||"))) {
1009 readand();
1010 conds[nconds++] = o_jnz(0);
1011 ts_pop(NULL);
1013 o_num(0, 4 | BT_SIGNED);
1014 o_forkpush();
1015 failed = o_jmp(0);
1016 for (i = 0; i < nconds; i++)
1017 o_filljmp(conds[i]);
1018 o_num(1, 4 | BT_SIGNED);
1019 o_forkpush();
1020 o_forkjoin();
1021 o_filljmp(failed);
1022 ts_push_bt(4 | BT_SIGNED);
1025 static int readcexpr_const(void)
1027 long c;
1028 int nogen;
1029 if (o_popnum(&c))
1030 return -1;
1031 if (!c)
1032 nogen = !o_nogen();
1033 reador();
1034 ts_pop(NULL);
1035 tok_expect(':');
1036 if (c) {
1037 nogen = !o_nogen();
1038 } else {
1039 if (nogen)
1040 o_dogen();
1041 o_tmpdrop(1);
1043 reador();
1044 if (c) {
1045 if (nogen)
1046 o_dogen();
1047 o_tmpdrop(1);
1049 return 0;
1052 static void readcexpr(void)
1054 long l1, l2;
1055 reador();
1056 if (tok_jmp('?'))
1057 return;
1058 ncexpr++;
1059 ts_pop(NULL);
1060 o_fork();
1061 if (readcexpr_const()) {
1062 l1 = o_jz(0);
1063 reador();
1064 o_forkpush();
1065 l2 = o_jmp(0);
1066 ts_pop(NULL);
1068 tok_expect(':');
1069 o_filljmp(l1);
1070 reador();
1071 o_forkpush();
1072 o_forkjoin();
1073 o_filljmp(l2);
1075 ncexpr--;
1078 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1080 unsigned bt = TYPE_BT(&ts[nts - 1]);
1081 o_tmpcopy();
1082 readexpr();
1083 bop(op);
1084 ts_pop(NULL);
1085 o_assign(bt);
1088 static void doassign(void)
1090 struct type t;
1091 ts_pop(&t);
1092 if (!t.ptr && t.flags & T_STRUCT)
1093 o_memcpy(type_totsz(&t));
1094 else
1095 o_assign(TYPE_BT(&ts[nts - 1]));
1098 static void readexpr(void)
1100 readcexpr();
1101 if (!tok_jmp('=')) {
1102 readexpr();
1103 doassign();
1104 return;
1106 if (!tok_jmp(TOK2("+="))) {
1107 opassign(ts_binop_add, o_add);
1108 return;
1110 if (!tok_jmp(TOK2("-="))) {
1111 opassign(ts_binop_add, o_sub);
1112 return;
1114 if (!tok_jmp(TOK2("*="))) {
1115 opassign(ts_binop, o_mul);
1116 return;
1118 if (!tok_jmp(TOK2("/="))) {
1119 opassign(ts_binop, o_div);
1120 return;
1122 if (!tok_jmp(TOK2("%="))) {
1123 opassign(ts_binop, o_mod);
1124 return;
1126 if (!tok_jmp(TOK3("<<="))) {
1127 opassign(ts_binop, o_shl);
1128 return;
1130 if (!tok_jmp(TOK3(">>="))) {
1131 opassign(ts_binop, o_shr);
1132 return;
1134 if (!tok_jmp(TOK3("&="))) {
1135 opassign(ts_binop, o_and);
1136 return;
1138 if (!tok_jmp(TOK3("|="))) {
1139 opassign(ts_binop, o_or);
1140 return;
1142 if (!tok_jmp(TOK3("^="))) {
1143 opassign(ts_binop, o_xor);
1144 return;
1148 static void readestmt(void)
1150 do {
1151 o_tmpdrop(-1);
1152 nts = 0;
1153 readexpr();
1154 } while (!tok_jmp(','));
1157 static void o_localoff(long addr, int off, unsigned bt)
1159 o_local(addr, bt);
1160 if (off) {
1161 o_addr();
1162 o_num(off, 4);
1163 o_add();
1164 o_deref(bt);
1168 static struct type *innertype(struct type *t)
1170 if (t->flags & T_ARRAY && !t->ptr)
1171 return innertype(&arrays[t->id].type);
1172 return t;
1175 static void initexpr(struct type *t, int off, void *obj,
1176 void (*set)(void *obj, int off, struct type *t))
1178 if (tok_jmp('{')) {
1179 set(obj, off, t);
1180 return;
1182 if (!t->ptr && t->flags & T_STRUCT) {
1183 struct structinfo *si = &structs[t->id];
1184 int i;
1185 for (i = 0; i < si->nfields; i++) {
1186 struct name *field = &si->fields[i];
1187 if (!tok_jmp('.')) {
1188 tok_expect(TOK_NAME);
1189 field = struct_field(t->id, tok_id());
1190 tok_expect('=');
1192 initexpr(&field->type, off + field->addr, obj, set);
1193 if (tok_jmp(',') || tok_see() == '}')
1194 break;
1196 } else if (t->flags & T_ARRAY) {
1197 struct type *t_de = &arrays[t->id].type;
1198 int i;
1199 for (i = 0; ; i++) {
1200 long idx = i;
1201 struct type *it = t_de;
1202 if (!tok_jmp('[')) {
1203 readexpr();
1204 o_popnum(&idx);
1205 ts_pop(NULL);
1206 tok_expect(']');
1207 tok_expect('=');
1209 if (tok_see() != '{')
1210 it = innertype(t_de);
1211 initexpr(it, off + type_totsz(it) * idx, obj, set);
1212 if (tok_jmp(',') || tok_see() == '}')
1213 break;
1216 tok_expect('}');
1219 static void jumpbrace(void)
1221 int depth = 0;
1222 while (tok_see() != '}' || depth--)
1223 if (tok_get() == '{')
1224 depth++;
1225 tok_expect('}');
1228 static int initsize(void)
1230 long addr = tok_addr();
1231 int n = 0;
1232 if (!tok_jmp(TOK_STR)) {
1233 n = tok_str(NULL);
1234 tok_jump(addr);
1235 return n;
1237 o_nogen();
1238 tok_expect('{');
1239 while (tok_jmp('}')) {
1240 long idx = n;
1241 if (!tok_jmp('[')) {
1242 readexpr();
1243 o_popnum(&idx);
1244 ts_pop(NULL);
1245 tok_expect(']');
1246 tok_expect('=');
1248 if (n < idx + 1)
1249 n = idx + 1;
1250 while (tok_see() != '}' && tok_see() != ',')
1251 if (tok_get() == '{')
1252 jumpbrace();
1253 tok_jmp(',');
1255 o_dogen();
1256 tok_jump(addr);
1257 return n;
1260 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1262 static void globalinit(void *obj, int off, struct type *t)
1264 long addr = *(long *) obj;
1265 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1266 struct type *t_de = &arrays[t->id].type;
1267 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1268 char buf[BUFSIZE];
1269 int len;
1270 tok_expect(TOK_STR);
1271 len = tok_str(buf);
1272 out_datcpy(addr, off, buf, len);
1273 return;
1276 readexpr();
1277 o_datset(addr, off, TYPE_BT(t));
1278 ts_pop(NULL);
1281 static void globaldef(void *data, struct name *name, unsigned flags)
1283 struct type *t = &name->type;
1284 char *varname = flags & F_STATIC ? NULL : name->name;
1285 int sz;
1286 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1287 arrays[t->id].n = initsize();
1288 sz = type_totsz(t);
1289 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1290 name->unused = 1;
1291 else if (flags & F_INIT)
1292 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1293 else
1294 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1295 global_add(name);
1296 if (flags & F_INIT)
1297 initexpr(t, 0, &name->addr, globalinit);
1300 static void localinit(void *obj, int off, struct type *t)
1302 long addr = *(long *) obj;
1303 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1304 struct type *t_de = &arrays[t->id].type;
1305 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1306 char buf[BUFSIZE];
1307 int len;
1308 tok_expect(TOK_STR);
1309 len = tok_str(buf);
1310 o_localoff(addr, off, TYPE_BT(t));
1311 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1312 o_memcpy(len);
1313 o_tmpdrop(1);
1314 return;
1317 o_localoff(addr, off, TYPE_BT(t));
1318 ts_push(t);
1319 readexpr();
1320 doassign();
1321 ts_pop(NULL);
1322 o_tmpdrop(1);
1325 static void localdef(void *data, struct name *name, unsigned flags)
1327 struct type *t = &name->type;
1328 if (flags & (F_STATIC | F_EXTERN)) {
1329 globaldef(data, name, flags);
1330 return;
1332 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1333 arrays[t->id].n = initsize();
1334 name->addr = o_mklocal(type_totsz(&name->type));
1335 local_add(name);
1336 if (flags & F_INIT) {
1337 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1338 o_local(name->addr, TYPE_BT(t));
1339 o_memset(0, type_totsz(t));
1340 o_tmpdrop(1);
1342 initexpr(t, 0, &name->addr, localinit);
1346 static void funcdef(char *name, struct type *type, struct name *args,
1347 int nargs, unsigned flags)
1349 struct name global;
1350 int i;
1351 strcpy(global.name, name);
1352 memcpy(&global.type, type, sizeof(*type));
1353 global.addr = o_func_beg(name, F_GLOBAL(flags));
1354 global.unused = 0;
1355 global_add(&global);
1356 ret_bt = TYPE_BT(&funcs[type->id].ret);
1357 for (i = 0; i < nargs; i++) {
1358 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1359 local_add(&args[i]);
1363 static int readargs(struct name *args)
1365 int nargs = 0;
1366 tok_expect('(');
1367 while (tok_see() != ')') {
1368 if (!tok_jmp(TOK3("...")))
1369 break;
1370 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1371 array2ptr(&args[nargs].type);
1372 nargs++;
1373 if (tok_jmp(','))
1374 break;
1376 tok_expect(')');
1377 if (nargs == 1 && !TYPE_BT(&args[0].type))
1378 return 0;
1379 return nargs;
1382 static int readname(struct type *main, char *name,
1383 struct type *base, unsigned flags)
1385 struct type tpool[3];
1386 int npool = 0;
1387 struct type *type = &tpool[npool++];
1388 struct type *func = NULL;
1389 struct type *ret = NULL;
1390 int arsz[10];
1391 int nar = 0;
1392 int i;
1393 memset(tpool, 0, sizeof(tpool));
1394 if (name)
1395 *name = '\0';
1396 if (!base) {
1397 if (basetype(type, &flags))
1398 return 1;
1399 } else {
1400 memcpy(type, base, sizeof(*base));
1402 readptrs(type);
1403 if (!tok_jmp('(')) {
1404 ret = type;
1405 type = &tpool[npool++];
1406 func = type;
1407 readptrs(type);
1409 if (!tok_jmp(TOK_NAME) && name)
1410 strcpy(name, tok_id());
1411 while (!tok_jmp('[')) {
1412 long n = 0;
1413 if (tok_jmp(']')) {
1414 readexpr();
1415 ts_pop(NULL);
1416 if (o_popnum(&n))
1417 err("const expr expected\n");
1418 tok_expect(']');
1420 arsz[nar++] = n;
1422 for (i = nar - 1; i >= 0; i--) {
1423 type->id = array_add(type, arsz[i]);
1424 if (type->flags & T_FUNC)
1425 func = &arrays[type->id].type;
1426 type->flags = T_ARRAY;
1427 type->bt = 8;
1428 type->ptr = 0;
1430 if (func)
1431 tok_expect(')');
1432 if (tok_see() == '(') {
1433 struct name args[MAXARGS];
1434 int nargs = readargs(args);
1435 int fdef = !func;
1436 if (!func) {
1437 ret = type;
1438 type = &tpool[npool++];
1439 func = type;
1441 func->flags = T_FUNC;
1442 func->bt = 8;
1443 func->id = func_create(ret, args, nargs);
1444 if (fdef && tok_see() == '{') {
1445 funcdef(name, func, args, nargs, flags);
1446 return 1;
1449 memcpy(main, type, sizeof(*type));
1450 return 0;
1453 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1454 void *data)
1456 struct type base;
1457 unsigned flags;
1458 if (basetype(&base, &flags))
1459 return 1;
1460 while (tok_see() != ';' && tok_see() != '{') {
1461 struct name name;
1462 name.unused = 0;
1463 if (readname(&name.type, name.name, &base, flags))
1464 break;
1465 if (!tok_jmp('='))
1466 flags |= F_INIT;
1467 def(data, &name, flags);
1468 tok_jmp(',');
1470 return 0;
1473 static void typedefdef(void *data, struct name *name, unsigned flags)
1475 typedef_add(name->name, &name->type);
1478 static void readstmt(void);
1480 #define MAXCASES (1 << 7)
1482 static void readswitch(void)
1484 int break_beg = nbreaks;
1485 long val_addr = o_mklocal(8);
1486 long matched[MAXCASES];
1487 int nmatched = 0;
1488 struct type t;
1489 long next;
1490 int ref = 1;
1491 int i;
1492 tok_expect('(');
1493 readexpr();
1494 ts_pop(&t);
1495 o_local(val_addr, TYPE_BT(&t));
1496 o_tmpswap();
1497 o_assign(TYPE_BT(&t));
1498 o_tmpdrop(1);
1499 tok_expect(')');
1500 tok_expect('{');
1501 while (tok_jmp('}')) {
1502 int n = 0;
1503 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1504 if (n++ > 0)
1505 matched[nmatched++] = o_jmp(0);
1506 if (!ref++)
1507 o_filljmp(next);
1508 if (!tok_jmp(TOK_CASE)) {
1509 caseexpr = 1;
1510 readexpr();
1511 caseexpr = 0;
1512 o_local(val_addr, TYPE_BT(&t));
1513 o_eq();
1514 next = o_jz(0);
1515 ref = 0;
1516 tok_expect(':');
1517 o_tmpdrop(1);
1518 ts_pop(NULL);
1519 continue;
1521 if (!tok_jmp(TOK_DEFAULT)) {
1522 tok_expect(':');
1523 continue;
1526 for (i = 0; i < nmatched; i++)
1527 o_filljmp(matched[i]);
1528 nmatched = 0;
1529 readstmt();
1531 o_rmlocal(val_addr, 8);
1532 if (!ref++)
1533 o_filljmp(next);
1534 break_fill(o_mklabel(), break_beg);
1537 #define MAXGOTO (1 << 10)
1539 static struct gotoinfo {
1540 char name[NAMELEN];
1541 long addr;
1542 } gotos[MAXGOTO];
1543 static int ngotos;
1545 static struct labelinfo {
1546 char name[NAMELEN];
1547 long addr;
1548 } labels[MAXGOTO];
1549 static int nlabels;
1551 static void goto_add(char *name)
1553 strcpy(gotos[ngotos].name, name);
1554 gotos[ngotos++].addr = o_jmp(0);
1557 static void label_add(char *name)
1559 strcpy(labels[nlabels].name, name);
1560 labels[nlabels++].addr = o_mklabel();
1563 static void goto_fill(void)
1565 int i, j;
1566 for (i = 0; i < ngotos; i++)
1567 for (j = 0; j < nlabels; j++)
1568 if (!strcmp(gotos[i].name, labels[j].name)) {
1569 o_filljmp2(gotos[i].addr, labels[j].addr);
1570 break;
1574 static void readstmt(void)
1576 o_tmpdrop(-1);
1577 nts = 0;
1578 if (!tok_jmp('{')) {
1579 int _nlocals = nlocals;
1580 int _nglobals = nglobals;
1581 int _nenums = nenums;
1582 int _ntypedefs = ntypedefs;
1583 int _nstructs = nstructs;
1584 int _nfuncs = nfuncs;
1585 int _narrays = narrays;
1586 while (tok_jmp('}'))
1587 readstmt();
1588 nlocals = _nlocals;
1589 nenums = _nenums;
1590 ntypedefs = _ntypedefs;
1591 nstructs = _nstructs;
1592 nfuncs = _nfuncs;
1593 narrays = _narrays;
1594 nglobals = _nglobals;
1595 return;
1597 if (!readdefs(localdef, NULL)) {
1598 tok_expect(';');
1599 return;
1601 if (!tok_jmp(TOK_TYPEDEF)) {
1602 readdefs(typedefdef, NULL);
1603 tok_expect(';');
1604 return;
1606 if (!tok_jmp(TOK_IF)) {
1607 long l1, l2;
1608 tok_expect('(');
1609 readexpr();
1610 tok_expect(')');
1611 l1 = o_jz(0);
1612 readstmt();
1613 if (!tok_jmp(TOK_ELSE)) {
1614 l2 = o_jmp(0);
1615 o_filljmp(l1);
1616 readstmt();
1617 o_filljmp(l2);
1618 } else {
1619 o_filljmp(l1);
1621 return;
1623 if (!tok_jmp(TOK_WHILE)) {
1624 long l1, l2;
1625 int break_beg = nbreaks;
1626 int continue_beg = ncontinues;
1627 l1 = o_mklabel();
1628 tok_expect('(');
1629 readexpr();
1630 tok_expect(')');
1631 l2 = o_jz(0);
1632 readstmt();
1633 o_jmp(l1);
1634 o_filljmp(l2);
1635 break_fill(o_mklabel(), break_beg);
1636 continue_fill(l1, continue_beg);
1637 return;
1639 if (!tok_jmp(TOK_DO)) {
1640 long l1, l2;
1641 int break_beg = nbreaks;
1642 int continue_beg = ncontinues;
1643 l1 = o_mklabel();
1644 readstmt();
1645 tok_expect(TOK_WHILE);
1646 tok_expect('(');
1647 l2 = o_mklabel();
1648 readexpr();
1649 o_jnz(l1);
1650 tok_expect(')');
1651 break_fill(o_mklabel(), break_beg);
1652 continue_fill(l2, continue_beg);
1653 return;
1655 if (!tok_jmp(TOK_FOR)) {
1656 long l_check, l_jump, j_fail, j_pass;
1657 int break_beg = nbreaks;
1658 int continue_beg = ncontinues;
1659 int has_cond = 0;
1660 tok_expect('(');
1661 if (tok_see() != ';')
1662 readestmt();
1663 tok_expect(';');
1664 l_check = o_mklabel();
1665 if (tok_see() != ';') {
1666 readestmt();
1667 j_fail = o_jz(0);
1668 has_cond = 1;
1670 tok_expect(';');
1671 j_pass = o_jmp(0);
1672 l_jump = o_mklabel();
1673 if (tok_see() != ')')
1674 readestmt();
1675 tok_expect(')');
1676 o_jmp(l_check);
1677 o_filljmp(j_pass);
1678 readstmt();
1679 o_jmp(l_jump);
1680 if (has_cond)
1681 o_filljmp(j_fail);
1682 break_fill(o_mklabel(), break_beg);
1683 continue_fill(l_jump, continue_beg);
1684 return;
1686 if (!tok_jmp(TOK_SWITCH)) {
1687 readswitch();
1688 return;
1690 if (!tok_jmp(TOK_RETURN)) {
1691 int ret = tok_see() != ';';
1692 if (ret)
1693 readexpr();
1694 tok_expect(';');
1695 o_ret(ret_bt);
1696 return;
1698 if (!tok_jmp(TOK_BREAK)) {
1699 tok_expect(';');
1700 breaks[nbreaks++] = o_jmp(0);
1701 return;
1703 if (!tok_jmp(TOK_CONTINUE)) {
1704 tok_expect(';');
1705 continues[ncontinues++] = o_jmp(0);
1706 return;
1708 if (!tok_jmp(TOK_GOTO)) {
1709 tok_expect(TOK_NAME);
1710 goto_add(tok_id());
1711 tok_expect(';');
1712 return;
1714 readestmt();
1715 /* labels */
1716 if (!tok_jmp(':')) {
1717 label_add(tok_id());
1718 return;
1720 tok_expect(';');
1723 static void readdecl(void)
1725 if (!tok_jmp(TOK_TYPEDEF)) {
1726 readdefs(typedefdef, NULL);
1727 tok_expect(';');
1728 return;
1730 readdefs(globaldef, NULL);
1731 if (tok_see() == '{') {
1732 readstmt();
1733 goto_fill();
1734 o_func_end();
1735 nlocals = 0;
1736 ngotos = 0;
1737 nlabels = 0;
1738 return;
1740 tok_expect(';');
1743 static void parse(void)
1745 while (tok_see() != TOK_EOF)
1746 readdecl();
1749 int main(int argc, char *argv[])
1751 char obj[128];
1752 int ofd;
1753 int i = 1;
1754 while (i < argc && argv[i][0] == '-') {
1755 if (argv[i][1] == 'I')
1756 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1757 if (argv[i][1] == 'D') {
1758 char *name = argv[i] + 2;
1759 char *def = "";
1760 char *eq = strchr(name, '=');
1761 if (eq) {
1762 *eq = '\0';
1763 def = eq + 1;
1765 cpp_define(name, def);
1767 i++;
1769 if (i == argc)
1770 die("neatcc: no file given\n");
1771 if (cpp_init(argv[i]))
1772 die("neatcc: cannot open input file\n");
1773 parse();
1774 strcpy(obj, argv[i]);
1775 obj[strlen(obj) - 1] = 'o';
1776 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1777 out_write(ofd);
1778 close(ofd);
1779 return 0;