npp: allow using neatcc's preprocessor as a standalone program
[neatcc.git] / ncc.c
blob03b1f8845cefce68d64d02c92c12014740eaf495
1 /*
2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This file is released under GNU GPL version 2.
7 */
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <sys/stat.h>
13 #include <sys/types.h>
14 #include "gen.h"
15 #include "tok.h"
17 #define MAXLOCALS (1 << 10)
18 #define MAXGLOBALS (1 << 10)
19 #define MAXARGS (1 << 5)
21 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
22 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
24 #define T_ARRAY 0x01
25 #define T_STRUCT 0x02
26 #define T_FUNC 0x04
28 #define F_INIT 0x01
29 #define F_STATIC 0x02
30 #define F_EXTERN 0x04
32 struct type {
33 unsigned bt;
34 unsigned flags;
35 int ptr;
36 int id; /* for structs, functions and arrays */
39 /* type stack */
40 static struct type ts[MAXTMP];
41 static int nts;
43 static void ts_push_bt(unsigned bt)
45 ts[nts].ptr = 0;
46 ts[nts].flags = 0;
47 ts[nts++].bt = bt;
50 static void ts_push(struct type *t)
52 memcpy(&ts[nts++], t, sizeof(*t));
53 if (t->flags & (T_FUNC | T_ARRAY) && !t->ptr)
54 o_addr();
57 static void ts_pop(struct type *type)
59 nts--;
60 if (type)
61 *type = ts[nts];
64 void err(char *msg)
66 char err[1 << 7];
67 int len = cpp_loc(err, tok_addr());
68 strcpy(err + len, msg);
69 die(err);
72 struct name {
73 char name[NAMELEN];
74 struct type type;
75 long addr;
76 int unused; /* unreferenced external symbols */
79 static struct name locals[MAXLOCALS];
80 static int nlocals;
81 static struct name globals[MAXGLOBALS];
82 static int nglobals;
84 static void local_add(struct name *name)
86 if (nlocals >= MAXLOCALS)
87 err("nomem: MAXLOCALS reached!\n");
88 memcpy(&locals[nlocals++], name, sizeof(*name));
91 static int global_find(char *name)
93 int i;
94 for (i = 0; i < nglobals; i++)
95 if (!strcmp(name, globals[i].name))
96 return i;
97 return -1;
100 static void global_add(struct name *name)
102 int found = global_find(name->name);
103 int i = found == -1 ? nglobals++ : found;
104 if (nglobals >= MAXGLOBALS)
105 err("nomem: MAXGLOBALS reached!\n");
106 memcpy(&globals[i], name, sizeof(*name));
109 #define MAXENUMS (1 << 10)
111 static struct enumval {
112 char name[NAMELEN];
113 int n;
114 } enums[MAXENUMS];
115 static int nenums;
117 static void enum_add(char *name, int val)
119 struct enumval *ev = &enums[nenums++];
120 if (nenums >= MAXENUMS)
121 err("nomem: MAXENUMS reached!\n");
122 strcpy(ev->name, name);
123 ev->n = val;
126 static int enum_find(int *val, char *name)
128 int i;
129 for (i = nenums - 1; i >= 0; --i)
130 if (!strcmp(name, enums[i].name)) {
131 *val = enums[i].n;
132 return 0;
134 return 1;
137 #define MAXTYPEDEFS (1 << 10)
139 static struct typdefinfo {
140 char name[NAMELEN];
141 struct type type;
142 } typedefs[MAXTYPEDEFS];
143 static int ntypedefs;
145 static void typedef_add(char *name, struct type *type)
147 struct typdefinfo *ti = &typedefs[ntypedefs++];
148 if (ntypedefs >= MAXTYPEDEFS)
149 err("nomem: MAXTYPEDEFS reached!\n");
150 strcpy(ti->name, name);
151 memcpy(&ti->type, type, sizeof(*type));
154 static int typedef_find(char *name)
156 int i;
157 for (i = ntypedefs - 1; i >= 0; --i)
158 if (!strcmp(name, typedefs[i].name))
159 return i;
160 return -1;
163 #define MAXARRAYS (1 << 10)
165 static struct array {
166 struct type type;
167 int n;
168 } arrays[MAXARRAYS];
169 static int narrays;
171 static int array_add(struct type *type, int n)
173 struct array *a = &arrays[narrays++];
174 if (narrays >= MAXARRAYS)
175 err("nomem: MAXARRAYS reached!\n");
176 memcpy(&a->type, type, sizeof(*type));
177 a->n = n;
178 return a - arrays;
181 static void array2ptr(struct type *t)
183 if (!(t->flags & T_ARRAY) || t->ptr)
184 return;
185 memcpy(t, &arrays[t->id].type, sizeof(*t));
186 t->ptr++;
189 #define MAXSTRUCTS (1 << 10)
190 #define MAXFIELDS (1 << 7)
192 static struct structinfo {
193 char name[NAMELEN];
194 struct name fields[MAXFIELDS];
195 int nfields;
196 int isunion;
197 int size;
198 } structs[MAXSTRUCTS];
199 static int nstructs;
201 static int struct_find(char *name, int isunion)
203 int i;
204 for (i = nstructs - 1; i >= 0; --i)
205 if (*structs[i].name && !strcmp(name, structs[i].name) &&
206 structs[i].isunion == isunion)
207 return i;
208 i = nstructs++;
209 if (nstructs >= MAXSTRUCTS)
210 err("nomem: MAXTYPES reached!\n");
211 memset(&structs[i], 0, sizeof(structs[i]));
212 strcpy(structs[i].name, name);
213 structs[i].isunion = isunion;
214 return i;
217 static struct name *struct_field(int id, char *name)
219 struct structinfo *si = &structs[id];
220 int i;
221 for (i = 0; i < si->nfields; i++)
222 if (!strcmp(name, si->fields[i].name))
223 return &si->fields[i];
224 err("field not found\n");
227 #define MAXBREAK (1 << 7)
229 static long breaks[MAXBREAK];
230 static int nbreaks;
231 static long continues[MAXBREAK];
232 static int ncontinues;
234 static void break_fill(long addr, int till)
236 int i;
237 for (i = till; i < nbreaks; i++)
238 o_filljmp2(breaks[i], addr);
239 nbreaks = till;
242 static void continue_fill(long addr, int till)
244 int i;
245 for (i = till; i < ncontinues; i++)
246 o_filljmp2(continues[i], addr);
247 ncontinues = till;
250 static int type_totsz(struct type *t)
252 if (t->ptr)
253 return LONGSZ;
254 if (t->flags & T_ARRAY)
255 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
256 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
259 static unsigned type_szde(struct type *t)
261 struct type de = *t;
262 array2ptr(&de);
263 de.ptr--;
264 return type_totsz(&de);
267 static int tok_jmp(int tok)
269 if (tok_see() != tok)
270 return 1;
271 tok_get();
272 return 0;
275 static void tok_expect(int tok)
277 if (tok_get() != tok)
278 err("syntax error\n");
281 static unsigned bt_op(unsigned bt1, unsigned bt2)
283 unsigned s1 = BT_SZ(bt1);
284 unsigned s2 = BT_SZ(bt2);
285 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
288 static void ts_binop(int op)
290 struct type t1, t2;
291 ts_pop(&t1);
292 ts_pop(&t2);
293 o_bop(op);
294 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
297 static void ts_addop(int op)
299 struct type t1, t2;
300 ts_pop(&t1);
301 ts_pop(&t2);
302 array2ptr(&t1);
303 array2ptr(&t2);
304 if (!t1.ptr && !t2.ptr) {
305 o_bop(op);
306 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
307 return;
309 if (t1.ptr && !t2.ptr)
310 o_tmpswap();
311 if (!t1.ptr && t2.ptr)
312 if (type_szde(&t2) > 1) {
313 o_num(type_szde(&t2), 4);
314 o_bop(O_MUL);
316 if (t1.ptr && !t2.ptr)
317 o_tmpswap();
318 o_bop(op);
319 if (t1.ptr && t2.ptr) {
320 int sz = type_szde(&t1);
321 if (sz > 1) {
322 o_num(sz, 4);
323 o_bop(O_DIV);
325 ts_push_bt(4 | BT_SIGNED);
326 } else {
327 ts_push(t1.ptr ? &t1 : &t2);
331 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
332 #define MIN(a, b) ((a) < (b) ? (a) : (b))
334 static int type_alignment(struct type *t)
336 if (t->flags & T_ARRAY && !t->ptr)
337 return type_alignment(&arrays[t->id].type);
338 if (t->flags & T_STRUCT && !t->ptr)
339 return type_alignment(&structs[t->id].fields[0].type);
340 return MIN(LONGSZ, type_totsz(t));
343 static void structdef(void *data, struct name *name, unsigned flags)
345 struct structinfo *si = data;
346 if (si->isunion) {
347 name->addr = 0;
348 if (si->size < type_totsz(&name->type))
349 si->size = type_totsz(&name->type);
350 } else {
351 struct type *t = &name->type;
352 int alignment = type_alignment(t);
353 if (t->flags & T_ARRAY && !t->ptr)
354 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
355 si->size = ALIGN(si->size, alignment);
356 name->addr = si->size;
357 si->size += type_totsz(&name->type);
359 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
362 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
364 static int struct_create(char *name, int isunion)
366 int id = struct_find(name, isunion);
367 struct structinfo *si = &structs[id];
368 tok_expect('{');
369 while (tok_jmp('}')) {
370 readdefs(structdef, si);
371 tok_expect(';');
373 return id;
376 static void readexpr(void);
378 static void enum_create(void)
380 long n = 0;
381 tok_expect('{');
382 while (tok_jmp('}')) {
383 char name[NAMELEN];
384 tok_expect(TOK_NAME);
385 strcpy(name, tok_id());
386 if (tok_see() == '=') {
387 tok_get();
388 readexpr();
389 ts_pop(NULL);
390 if (o_popnum(&n))
391 err("const expr expected!\n");
393 enum_add(name, n++);
394 tok_jmp(',');
398 static int basetype(struct type *type, unsigned *flags)
400 int sign = 1;
401 int size = 4;
402 int done = 0;
403 int i = 0;
404 int isunion;
405 char name[NAMELEN] = "";
406 *flags = 0;
407 type->flags = 0;
408 type->ptr = 0;
409 while (!done) {
410 switch (tok_see()) {
411 case TOK_STATIC:
412 *flags |= F_STATIC;
413 break;
414 case TOK_EXTERN:
415 *flags |= F_EXTERN;
416 break;
417 case TOK_VOID:
418 sign = 0;
419 size = 0;
420 done = 1;
421 break;
422 case TOK_INT:
423 done = 1;
424 break;
425 case TOK_CHAR:
426 size = 1;
427 done = 1;
428 break;
429 case TOK_SHORT:
430 size = 2;
431 break;
432 case TOK_LONG:
433 size = LONGSZ;
434 break;
435 case TOK_SIGNED:
436 break;
437 case TOK_UNSIGNED:
438 sign = 0;
439 break;
440 case TOK_UNION:
441 case TOK_STRUCT:
442 isunion = tok_get() == TOK_UNION;
443 if (!tok_jmp(TOK_NAME))
444 strcpy(name, tok_id());
445 if (tok_see() == '{')
446 type->id = struct_create(name, isunion);
447 else
448 type->id = struct_find(name, isunion);
449 type->flags |= T_STRUCT;
450 type->bt = LONGSZ;
451 return 0;
452 case TOK_ENUM:
453 tok_get();
454 tok_jmp(TOK_NAME);
455 if (tok_see() == '{')
456 enum_create();
457 type->bt = 4 | BT_SIGNED;
458 return 0;
459 default:
460 if (tok_see() == TOK_NAME) {
461 int id = typedef_find(tok_id());
462 if (id != -1) {
463 tok_get();
464 memcpy(type, &typedefs[id].type,
465 sizeof(*type));
466 return 0;
469 if (!i)
470 return 1;
471 done = 1;
472 continue;
474 i++;
475 tok_get();
477 type->bt = size | (sign ? BT_SIGNED : 0);
478 return 0;
481 static int readname(struct type *main, char *name,
482 struct type *base, unsigned flags);
484 static int readtype(struct type *type)
486 return readname(type, NULL, NULL, 0);
489 static void readptrs(struct type *type)
491 while (!tok_jmp('*')) {
492 type->ptr++;
493 if (!type->bt)
494 type->bt = 1;
498 /* used to differenciate labels from case and cond exprs */
499 static int ncexpr;
500 static int caseexpr;
502 static void readpre(void);
504 static void readprimary(void)
506 int i;
507 if (!tok_jmp(TOK_NUM)) {
508 long n;
509 int bt = tok_num(&n);
510 ts_push_bt(bt);
511 o_num(n, bt);
512 return;
514 if (!tok_jmp(TOK_STR)) {
515 struct type t;
516 char buf[BUFSIZE];
517 int len;
518 t.bt = 1 | BT_SIGNED;
519 t.ptr = 1;
520 t.flags = 0;
521 ts_push(&t);
522 len = tok_str(buf);
523 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
524 o_addr();
525 return;
527 if (!tok_jmp(TOK_NAME)) {
528 struct name unkn = {""};
529 char *name = unkn.name;
530 int n;
531 strcpy(name, tok_id());
532 /* don't search for labels here */
533 if (!ncexpr && !caseexpr && tok_see() == ':')
534 return;
535 for (i = nlocals - 1; i >= 0; --i) {
536 struct type *t = &locals[i].type;
537 if (!strcmp(locals[i].name, name)) {
538 o_local(locals[i].addr, TYPE_BT(t));
539 ts_push(t);
540 return;
543 if ((n = global_find(name)) != -1) {
544 struct name *g = &globals[n];
545 struct type *t = &g->type;
546 if (g->unused) {
547 g->unused = 0;
548 if (t->flags & T_FUNC && !t->ptr)
549 g->addr = out_mkundef(name, 0);
550 else
551 g->addr = out_mkundef(name, type_totsz(t));
553 o_symaddr(g->addr, TYPE_BT(t));
554 ts_push(t);
555 return;
557 if (!enum_find(&n, name)) {
558 ts_push_bt(4 | BT_SIGNED);
559 o_num(n, 4 | BT_SIGNED);
560 return;
562 if (tok_see() != '(')
563 err("unknown symbol\n");
564 unkn.addr = out_mkundef(unkn.name, 0);
565 global_add(&unkn);
566 ts_push_bt(LONGSZ);
567 o_symaddr(unkn.addr, LONGSZ);
568 return;
570 if (!tok_jmp('(')) {
571 struct type t;
572 if (!readtype(&t)) {
573 struct type o;
574 tok_expect(')');
575 readpre();
576 ts_pop(&o);
577 ts_push(&t);
578 if (!t.ptr || !o.ptr)
579 o_cast(TYPE_BT(&t));
580 } else {
581 readexpr();
582 tok_expect(')');
584 return;
588 void arrayderef(struct type *t)
590 int sz = type_totsz(t);
591 if (sz > 1) {
592 o_num(sz, 4);
593 o_bop(O_MUL);
595 o_bop(O_ADD);
596 o_deref(TYPE_BT(t));
599 static void inc_post(int inc_one, int inc_many)
601 struct type *t = &ts[nts - 1];
602 int sz = type_szde(t);
603 o_tmpcopy();
604 o_load();
605 o_tmpswap();
606 if (!t->ptr || sz == 1) {
607 o_uop(inc_one);
608 } else {
609 o_tmpcopy();
610 o_num(sz, 4);
611 o_bop(inc_many);
612 o_assign(TYPE_BT(t));
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_bop(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(LONGSZ);
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_INC, O_ADD);
710 continue;
712 if (!tok_jmp(TOK2("--"))) {
713 inc_post(O_DEC, 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(int inc_one, int inc_many)
731 struct type *t;
732 int sz;
733 readpre();
734 t = &ts[nts - 1];
735 sz = (t->flags & T_ARRAY || t->ptr) ? type_szde(t) : 1;
736 if (sz == 1) {
737 o_uop(inc_one);
738 } else {
739 o_tmpcopy();
740 o_num(sz, 4);
741 o_bop(inc_many);
742 o_assign(TYPE_BT(t));
746 static void readpre(void)
748 if (!tok_jmp('&')) {
749 struct type type;
750 readpre();
751 ts_pop(&type);
752 type.ptr++;
753 ts_push(&type);
754 o_addr();
755 return;
757 if (!tok_jmp('*')) {
758 struct type t;
759 readpre();
760 ts_pop(&t);
761 array2ptr(&t);
762 t.ptr--;
763 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_uop(O_LNOT);
772 ts_push_bt(4 | BT_SIGNED);
773 return;
775 if (!tok_jmp('-')) {
776 readpre();
777 o_uop(O_NEG);
778 return;
780 if (!tok_jmp('~')) {
781 readpre();
782 o_uop(O_NOT);
783 return;
785 if (!tok_jmp(TOK2("++"))) {
786 inc_pre(O_INC, O_ADD);
787 return;
789 if (!tok_jmp(TOK2("--"))) {
790 inc_pre(O_DEC, 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_addop(O_ADD);
843 continue;
845 if (!tok_jmp('-')) {
846 readmul();
847 ts_addop(O_SUB);
848 continue;
850 break;
854 static void shift(int op)
856 struct type t;
857 readadd();
858 ts_pop(NULL);
859 ts_pop(&t);
860 o_bop(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(int op)
882 readshift();
883 ts_pop(NULL);
884 ts_pop(NULL);
885 o_bop(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(int op)
915 readcmp();
916 ts_pop(NULL);
917 ts_pop(NULL);
918 o_bop(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(int op, int ptrop)
1080 struct type *t = &ts[nts - 1];
1081 if (ptrop && (t->flags & T_ARRAY || t->ptr)) {
1082 o_tmpcopy();
1083 readexpr();
1084 ts_addop(op);
1085 o_assign(TYPE_BT(&ts[nts - 1]));
1086 ts_pop(NULL);
1087 } else {
1088 readexpr();
1089 o_bop(op | O_SET);
1090 ts_pop(NULL);
1094 static void doassign(void)
1096 struct type t;
1097 ts_pop(&t);
1098 if (!t.ptr && t.flags & T_STRUCT)
1099 o_memcpy(type_totsz(&t));
1100 else
1101 o_assign(TYPE_BT(&ts[nts - 1]));
1104 static void readexpr(void)
1106 readcexpr();
1107 if (!tok_jmp('=')) {
1108 readexpr();
1109 doassign();
1110 return;
1112 if (!tok_jmp(TOK2("+="))) {
1113 opassign(O_ADD, 1);
1114 return;
1116 if (!tok_jmp(TOK2("-="))) {
1117 opassign(O_SUB, 1);
1118 return;
1120 if (!tok_jmp(TOK2("*="))) {
1121 opassign(O_MUL, 0);
1122 return;
1124 if (!tok_jmp(TOK2("/="))) {
1125 opassign(O_DIV, 0);
1126 return;
1128 if (!tok_jmp(TOK2("%="))) {
1129 opassign(O_MOD, 0);
1130 return;
1132 if (!tok_jmp(TOK3("<<="))) {
1133 opassign(O_SHL, 0);
1134 return;
1136 if (!tok_jmp(TOK3(">>="))) {
1137 opassign(O_SHR, 0);
1138 return;
1140 if (!tok_jmp(TOK3("&="))) {
1141 opassign(O_AND, 0);
1142 return;
1144 if (!tok_jmp(TOK3("|="))) {
1145 opassign(O_OR, 0);
1146 return;
1148 if (!tok_jmp(TOK3("^="))) {
1149 opassign(O_XOR, 0);
1150 return;
1154 static void readestmt(void)
1156 do {
1157 o_tmpdrop(-1);
1158 nts = 0;
1159 readexpr();
1160 } while (!tok_jmp(','));
1163 static void o_localoff(long addr, int off, unsigned bt)
1165 o_local(addr, bt);
1166 if (off) {
1167 o_addr();
1168 o_num(off, 4);
1169 o_bop(O_ADD);
1170 o_deref(bt);
1174 static struct type *innertype(struct type *t)
1176 if (t->flags & T_ARRAY && !t->ptr)
1177 return innertype(&arrays[t->id].type);
1178 return t;
1181 static void initexpr(struct type *t, int off, void *obj,
1182 void (*set)(void *obj, int off, struct type *t))
1184 if (tok_jmp('{')) {
1185 set(obj, off, t);
1186 return;
1188 if (!t->ptr && t->flags & T_STRUCT) {
1189 struct structinfo *si = &structs[t->id];
1190 int i;
1191 for (i = 0; i < si->nfields; i++) {
1192 struct name *field = &si->fields[i];
1193 if (!tok_jmp('.')) {
1194 tok_expect(TOK_NAME);
1195 field = struct_field(t->id, tok_id());
1196 tok_expect('=');
1198 initexpr(&field->type, off + field->addr, obj, set);
1199 if (tok_jmp(',') || tok_see() == '}')
1200 break;
1202 } else if (t->flags & T_ARRAY) {
1203 struct type *t_de = &arrays[t->id].type;
1204 int i;
1205 for (i = 0; ; i++) {
1206 long idx = i;
1207 struct type *it = t_de;
1208 if (!tok_jmp('[')) {
1209 readexpr();
1210 o_popnum(&idx);
1211 ts_pop(NULL);
1212 tok_expect(']');
1213 tok_expect('=');
1215 if (tok_see() != '{')
1216 it = innertype(t_de);
1217 initexpr(it, off + type_totsz(it) * idx, obj, set);
1218 if (tok_jmp(',') || tok_see() == '}')
1219 break;
1222 tok_expect('}');
1225 static void jumpbrace(void)
1227 int depth = 0;
1228 while (tok_see() != '}' || depth--)
1229 if (tok_get() == '{')
1230 depth++;
1231 tok_expect('}');
1234 static int initsize(void)
1236 long addr = tok_addr();
1237 int n = 0;
1238 if (!tok_jmp(TOK_STR)) {
1239 n = tok_str(NULL);
1240 tok_jump(addr);
1241 return n;
1243 o_nogen();
1244 tok_expect('{');
1245 while (tok_jmp('}')) {
1246 long idx = n;
1247 if (!tok_jmp('[')) {
1248 readexpr();
1249 o_popnum(&idx);
1250 ts_pop(NULL);
1251 tok_expect(']');
1252 tok_expect('=');
1254 if (n < idx + 1)
1255 n = idx + 1;
1256 while (tok_see() != '}' && tok_see() != ',')
1257 if (tok_get() == '{')
1258 jumpbrace();
1259 tok_jmp(',');
1261 o_dogen();
1262 tok_jump(addr);
1263 return n;
1266 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1268 static void globalinit(void *obj, int off, struct type *t)
1270 long addr = *(long *) obj;
1271 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1272 struct type *t_de = &arrays[t->id].type;
1273 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1274 char buf[BUFSIZE];
1275 int len;
1276 tok_expect(TOK_STR);
1277 len = tok_str(buf);
1278 out_datcpy(addr, off, buf, len);
1279 return;
1282 readexpr();
1283 o_datset(addr, off, TYPE_BT(t));
1284 ts_pop(NULL);
1287 static void globaldef(void *data, struct name *name, unsigned flags)
1289 struct type *t = &name->type;
1290 char *varname = flags & F_STATIC ? NULL : name->name;
1291 int sz;
1292 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1293 if (~flags & F_EXTERN)
1294 arrays[t->id].n = initsize();
1295 sz = type_totsz(t);
1296 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1297 name->unused = 1;
1298 else if (flags & F_INIT)
1299 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1300 else
1301 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1302 global_add(name);
1303 if (flags & F_INIT)
1304 initexpr(t, 0, &name->addr, globalinit);
1307 static void localinit(void *obj, int off, struct type *t)
1309 long addr = *(long *) obj;
1310 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1311 struct type *t_de = &arrays[t->id].type;
1312 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1313 char buf[BUFSIZE];
1314 int len;
1315 tok_expect(TOK_STR);
1316 len = tok_str(buf);
1317 o_localoff(addr, off, TYPE_BT(t));
1318 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1319 o_memcpy(len);
1320 o_tmpdrop(1);
1321 return;
1324 o_localoff(addr, off, TYPE_BT(t));
1325 ts_push(t);
1326 readexpr();
1327 doassign();
1328 ts_pop(NULL);
1329 o_tmpdrop(1);
1332 static void localdef(void *data, struct name *name, unsigned flags)
1334 struct type *t = &name->type;
1335 if (flags & (F_STATIC | F_EXTERN)) {
1336 globaldef(data, name, flags);
1337 return;
1339 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1340 arrays[t->id].n = initsize();
1341 name->addr = o_mklocal(type_totsz(&name->type));
1342 local_add(name);
1343 if (flags & F_INIT) {
1344 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1345 o_local(name->addr, TYPE_BT(t));
1346 o_memset(0, type_totsz(t));
1347 o_tmpdrop(1);
1349 initexpr(t, 0, &name->addr, localinit);
1353 static void funcdef(char *name, struct type *type, struct name *args,
1354 int nargs, unsigned flags)
1356 struct name global;
1357 int i;
1358 strcpy(global.name, name);
1359 memcpy(&global.type, type, sizeof(*type));
1360 global.addr = o_func_beg(name, F_GLOBAL(flags));
1361 global.unused = 0;
1362 global_add(&global);
1363 ret_bt = TYPE_BT(&funcs[type->id].ret);
1364 for (i = 0; i < nargs; i++) {
1365 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1366 local_add(&args[i]);
1370 static int readargs(struct name *args)
1372 int nargs = 0;
1373 tok_expect('(');
1374 while (tok_see() != ')') {
1375 if (!tok_jmp(TOK3("...")))
1376 break;
1377 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1378 array2ptr(&args[nargs].type);
1379 nargs++;
1380 if (tok_jmp(','))
1381 break;
1383 tok_expect(')');
1384 if (nargs == 1 && !TYPE_BT(&args[0].type))
1385 return 0;
1386 return nargs;
1389 static int readname(struct type *main, char *name,
1390 struct type *base, unsigned flags)
1392 struct type tpool[3];
1393 int npool = 0;
1394 struct type *type = &tpool[npool++];
1395 struct type *func = NULL;
1396 struct type *ret = NULL;
1397 int arsz[10];
1398 int nar = 0;
1399 int i;
1400 memset(tpool, 0, sizeof(tpool));
1401 if (name)
1402 *name = '\0';
1403 if (!base) {
1404 if (basetype(type, &flags))
1405 return 1;
1406 } else {
1407 memcpy(type, base, sizeof(*base));
1409 readptrs(type);
1410 if (!tok_jmp('(')) {
1411 ret = type;
1412 type = &tpool[npool++];
1413 func = type;
1414 readptrs(type);
1416 if (!tok_jmp(TOK_NAME) && name)
1417 strcpy(name, tok_id());
1418 while (!tok_jmp('[')) {
1419 long n = 0;
1420 if (tok_jmp(']')) {
1421 readexpr();
1422 ts_pop(NULL);
1423 if (o_popnum(&n))
1424 err("const expr expected\n");
1425 tok_expect(']');
1427 arsz[nar++] = n;
1429 for (i = nar - 1; i >= 0; i--) {
1430 type->id = array_add(type, arsz[i]);
1431 if (func && i == nar - 1)
1432 func = &arrays[type->id].type;
1433 type->flags = T_ARRAY;
1434 type->bt = LONGSZ;
1435 type->ptr = 0;
1437 if (func)
1438 tok_expect(')');
1439 if (tok_see() == '(') {
1440 struct name args[MAXARGS];
1441 int nargs = readargs(args);
1442 int fdef = !func;
1443 if (!func) {
1444 ret = type;
1445 type = &tpool[npool++];
1446 func = type;
1448 func->flags = T_FUNC;
1449 func->bt = LONGSZ;
1450 func->id = func_create(ret, args, nargs);
1451 if (fdef && tok_see() == '{') {
1452 funcdef(name, func, args, nargs, flags);
1453 return 1;
1456 memcpy(main, type, sizeof(*type));
1457 return 0;
1460 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1461 void *data)
1463 struct type base;
1464 unsigned base_flags;
1465 if (basetype(&base, &base_flags))
1466 return 1;
1467 while (tok_see() != ';' && tok_see() != '{') {
1468 struct name name;
1469 unsigned flags = base_flags;
1470 name.unused = 0;
1471 if (readname(&name.type, name.name, &base, flags))
1472 break;
1473 if (!tok_jmp('='))
1474 flags |= F_INIT;
1475 def(data, &name, flags);
1476 tok_jmp(',');
1478 return 0;
1481 static void typedefdef(void *data, struct name *name, unsigned flags)
1483 typedef_add(name->name, &name->type);
1486 static void readstmt(void);
1488 #define MAXCASES (1 << 7)
1490 static void readswitch(void)
1492 int break_beg = nbreaks;
1493 long val_addr = o_mklocal(LONGSZ);
1494 long matched[MAXCASES];
1495 int nmatched = 0;
1496 struct type t;
1497 long next;
1498 int ref = 1;
1499 int i;
1500 tok_expect('(');
1501 readexpr();
1502 ts_pop(&t);
1503 o_local(val_addr, TYPE_BT(&t));
1504 o_tmpswap();
1505 o_assign(TYPE_BT(&t));
1506 o_tmpdrop(1);
1507 tok_expect(')');
1508 tok_expect('{');
1509 while (tok_jmp('}')) {
1510 int n = 0;
1511 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1512 if (n++ > 0)
1513 matched[nmatched++] = o_jmp(0);
1514 if (!ref++)
1515 o_filljmp(next);
1516 if (!tok_jmp(TOK_CASE)) {
1517 caseexpr = 1;
1518 readexpr();
1519 caseexpr = 0;
1520 o_local(val_addr, TYPE_BT(&t));
1521 o_bop(O_EQ);
1522 next = o_jz(0);
1523 ref = 0;
1524 tok_expect(':');
1525 o_tmpdrop(1);
1526 ts_pop(NULL);
1527 continue;
1529 if (!tok_jmp(TOK_DEFAULT)) {
1530 tok_expect(':');
1531 continue;
1534 for (i = 0; i < nmatched; i++)
1535 o_filljmp(matched[i]);
1536 nmatched = 0;
1537 readstmt();
1539 o_rmlocal(val_addr, LONGSZ);
1540 if (!ref++)
1541 o_filljmp(next);
1542 break_fill(o_mklabel(), break_beg);
1545 #define MAXGOTO (1 << 10)
1547 static struct gotoinfo {
1548 char name[NAMELEN];
1549 long addr;
1550 } gotos[MAXGOTO];
1551 static int ngotos;
1553 static struct labelinfo {
1554 char name[NAMELEN];
1555 long addr;
1556 } labels[MAXGOTO];
1557 static int nlabels;
1559 static void goto_add(char *name)
1561 strcpy(gotos[ngotos].name, name);
1562 gotos[ngotos++].addr = o_jmp(0);
1565 static void label_add(char *name)
1567 strcpy(labels[nlabels].name, name);
1568 labels[nlabels++].addr = o_mklabel();
1571 static void goto_fill(void)
1573 int i, j;
1574 for (i = 0; i < ngotos; i++)
1575 for (j = 0; j < nlabels; j++)
1576 if (!strcmp(gotos[i].name, labels[j].name)) {
1577 o_filljmp2(gotos[i].addr, labels[j].addr);
1578 break;
1582 static void readstmt(void)
1584 o_tmpdrop(-1);
1585 nts = 0;
1586 if (!tok_jmp('{')) {
1587 int _nlocals = nlocals;
1588 int _nglobals = nglobals;
1589 int _nenums = nenums;
1590 int _ntypedefs = ntypedefs;
1591 int _nstructs = nstructs;
1592 int _nfuncs = nfuncs;
1593 int _narrays = narrays;
1594 while (tok_jmp('}'))
1595 readstmt();
1596 nlocals = _nlocals;
1597 nenums = _nenums;
1598 ntypedefs = _ntypedefs;
1599 nstructs = _nstructs;
1600 nfuncs = _nfuncs;
1601 narrays = _narrays;
1602 nglobals = _nglobals;
1603 return;
1605 if (!readdefs(localdef, NULL)) {
1606 tok_expect(';');
1607 return;
1609 if (!tok_jmp(TOK_TYPEDEF)) {
1610 readdefs(typedefdef, NULL);
1611 tok_expect(';');
1612 return;
1614 if (!tok_jmp(TOK_IF)) {
1615 long l1, l2;
1616 tok_expect('(');
1617 readexpr();
1618 tok_expect(')');
1619 l1 = o_jz(0);
1620 readstmt();
1621 if (!tok_jmp(TOK_ELSE)) {
1622 l2 = o_jmp(0);
1623 o_filljmp(l1);
1624 readstmt();
1625 o_filljmp(l2);
1626 } else {
1627 o_filljmp(l1);
1629 return;
1631 if (!tok_jmp(TOK_WHILE)) {
1632 long l1, l2;
1633 int break_beg = nbreaks;
1634 int continue_beg = ncontinues;
1635 l1 = o_mklabel();
1636 tok_expect('(');
1637 readexpr();
1638 tok_expect(')');
1639 l2 = o_jz(0);
1640 readstmt();
1641 o_jmp(l1);
1642 o_filljmp(l2);
1643 break_fill(o_mklabel(), break_beg);
1644 continue_fill(l1, continue_beg);
1645 return;
1647 if (!tok_jmp(TOK_DO)) {
1648 long l1, l2;
1649 int break_beg = nbreaks;
1650 int continue_beg = ncontinues;
1651 l1 = o_mklabel();
1652 readstmt();
1653 tok_expect(TOK_WHILE);
1654 tok_expect('(');
1655 l2 = o_mklabel();
1656 readexpr();
1657 o_jnz(l1);
1658 tok_expect(')');
1659 break_fill(o_mklabel(), break_beg);
1660 continue_fill(l2, continue_beg);
1661 return;
1663 if (!tok_jmp(TOK_FOR)) {
1664 long l_check, l_jump, j_fail, j_pass;
1665 int break_beg = nbreaks;
1666 int continue_beg = ncontinues;
1667 int has_cond = 0;
1668 tok_expect('(');
1669 if (tok_see() != ';')
1670 readestmt();
1671 tok_expect(';');
1672 l_check = o_mklabel();
1673 if (tok_see() != ';') {
1674 readestmt();
1675 j_fail = o_jz(0);
1676 has_cond = 1;
1678 tok_expect(';');
1679 j_pass = o_jmp(0);
1680 l_jump = o_mklabel();
1681 if (tok_see() != ')')
1682 readestmt();
1683 tok_expect(')');
1684 o_jmp(l_check);
1685 o_filljmp(j_pass);
1686 readstmt();
1687 o_jmp(l_jump);
1688 if (has_cond)
1689 o_filljmp(j_fail);
1690 break_fill(o_mklabel(), break_beg);
1691 continue_fill(l_jump, continue_beg);
1692 return;
1694 if (!tok_jmp(TOK_SWITCH)) {
1695 readswitch();
1696 return;
1698 if (!tok_jmp(TOK_RETURN)) {
1699 int ret = tok_see() != ';';
1700 if (ret)
1701 readexpr();
1702 tok_expect(';');
1703 o_ret(ret_bt);
1704 return;
1706 if (!tok_jmp(TOK_BREAK)) {
1707 tok_expect(';');
1708 breaks[nbreaks++] = o_jmp(0);
1709 return;
1711 if (!tok_jmp(TOK_CONTINUE)) {
1712 tok_expect(';');
1713 continues[ncontinues++] = o_jmp(0);
1714 return;
1716 if (!tok_jmp(TOK_GOTO)) {
1717 tok_expect(TOK_NAME);
1718 goto_add(tok_id());
1719 tok_expect(';');
1720 return;
1722 readestmt();
1723 /* labels */
1724 if (!tok_jmp(':')) {
1725 label_add(tok_id());
1726 return;
1728 tok_expect(';');
1731 static void readdecl(void)
1733 if (!tok_jmp(TOK_TYPEDEF)) {
1734 readdefs(typedefdef, NULL);
1735 tok_expect(';');
1736 return;
1738 readdefs(globaldef, NULL);
1739 if (tok_see() == '{') {
1740 readstmt();
1741 goto_fill();
1742 o_func_end();
1743 nlocals = 0;
1744 ngotos = 0;
1745 nlabels = 0;
1746 return;
1748 tok_expect(';');
1751 static void parse(void)
1753 while (tok_see() != TOK_EOF)
1754 readdecl();
1757 int main(int argc, char *argv[])
1759 char obj[128];
1760 int ofd;
1761 int i = 1;
1762 while (i < argc && argv[i][0] == '-') {
1763 if (argv[i][1] == 'I')
1764 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1765 if (argv[i][1] == 'D') {
1766 char *name = argv[i] + 2;
1767 char *def = "";
1768 char *eq = strchr(name, '=');
1769 if (eq) {
1770 *eq = '\0';
1771 def = eq + 1;
1773 cpp_define(name, def);
1775 i++;
1777 if (i == argc)
1778 die("neatcc: no file given\n");
1779 if (cpp_init(argv[i]))
1780 die("neatcc: cannot open input file\n");
1781 parse();
1782 strcpy(obj, argv[i]);
1783 obj[strlen(obj) - 1] = 'o';
1784 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1785 out_write(ofd);
1786 close(ofd);
1787 return 0;