README: ignored keywords are now built into ncc.c
[neatcc.git] / ncc.c
blob60729295fbe231314503ec43a6e321b0ec4d93b9
1 /*
2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This program 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 <stdio.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include "gen.h"
16 #include "tok.h"
17 #include "out.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
23 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
24 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
26 #define T_ARRAY 0x01
27 #define T_STRUCT 0x02
28 #define T_FUNC 0x04
30 #define F_INIT 0x01
31 #define F_STATIC 0x02
32 #define F_EXTERN 0x04
34 struct type {
35 unsigned bt;
36 unsigned flags;
37 int ptr;
38 int id; /* for structs, functions and arrays */
39 int addr; /* the address is passed to gen.c; deref for value */
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].addr = 0;
51 ts[nts++].bt = bt;
54 static void ts_push(struct type *t)
56 struct type *d = &ts[nts++];
57 memcpy(d, t, sizeof(*t));
60 static void ts_push_addr(struct type *t)
62 ts_push(t);
63 ts[nts - 1].addr = 1;
66 static void ts_pop(struct type *type)
68 nts--;
69 if (type)
70 *type = ts[nts];
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 char elfname[NAMELEN]; /* local elf name for static variables in function */
84 struct type type;
85 long addr; /* local stack offset, global data addr, struct offset */
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 memcpy(t, &arrays[t->id].type, sizeof(*t));
194 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return LONGSZ;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static void ts_de(int deref)
278 struct type *t = &ts[nts - 1];
279 if (deref && t->addr && (!(t->flags & T_ARRAY) || (t->ptr)))
280 o_deref(TYPE_BT(t));
281 t->addr = 0;
284 static void ts_pop_de(struct type *t)
286 struct type de;
287 if (!t)
288 t = &de;
289 ts_pop(t);
290 array2ptr(t);
291 if (t->addr && (t->ptr || !(t->flags & T_FUNC)))
292 o_deref(TYPE_BT(t));
293 t->addr = 0;
296 static void ts_pop_de2(struct type *t1, struct type *t2)
298 ts_pop_de(t1);
299 o_tmpswap();
300 ts_pop_de(t2);
301 o_tmpswap();
304 static int tok_jmp(int tok)
306 if (tok_see() != tok)
307 return 1;
308 tok_get();
309 return 0;
312 static void tok_expect(int tok)
314 if (tok_get() != tok)
315 err("syntax error\n");
318 static unsigned bt_op(unsigned bt1, unsigned bt2)
320 unsigned s1 = BT_SZ(bt1);
321 unsigned s2 = BT_SZ(bt2);
322 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
325 static void ts_binop(int op)
327 struct type t1, t2;
328 int bt;
329 ts_pop_de2(&t1, &t2);
330 if (op == O_DIV || op == O_MOD)
331 bt = TYPE_BT(&t2);
332 else
333 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
334 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
335 ts_push_bt(bt);
338 static void ts_addop(int op)
340 struct type t1, t2;
341 ts_pop_de2(&t1, &t2);
342 if (!t1.ptr && !t2.ptr) {
343 o_bop(op);
344 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
345 return;
347 if (t1.ptr && !t2.ptr)
348 o_tmpswap();
349 if (!t1.ptr && t2.ptr)
350 if (type_szde(&t2) > 1) {
351 o_num(type_szde(&t2));
352 o_bop(O_MUL);
354 if (t1.ptr && !t2.ptr)
355 o_tmpswap();
356 o_bop(op);
357 if (t1.ptr && t2.ptr) {
358 int sz = type_szde(&t1);
359 if (sz > 1) {
360 o_num(sz);
361 o_bop(O_DIV);
363 ts_push_bt(4 | BT_SIGNED);
364 } else {
365 ts_push(t1.ptr ? &t1 : &t2);
369 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
370 #define MIN(a, b) ((a) < (b) ? (a) : (b))
372 static int type_alignment(struct type *t)
374 if (t->flags & T_ARRAY && !t->ptr)
375 return type_alignment(&arrays[t->id].type);
376 if (t->flags & T_STRUCT && !t->ptr)
377 return type_alignment(&structs[t->id].fields[0].type);
378 return MIN(LONGSZ, type_totsz(t));
381 static void structdef(void *data, struct name *name, unsigned flags)
383 struct structinfo *si = data;
384 if (si->isunion) {
385 name->addr = 0;
386 if (si->size < type_totsz(&name->type))
387 si->size = type_totsz(&name->type);
388 } else {
389 struct type *t = &name->type;
390 int alignment = type_alignment(t);
391 if (t->flags & T_ARRAY && !t->ptr)
392 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
393 si->size = ALIGN(si->size, alignment);
394 name->addr = si->size;
395 si->size += type_totsz(&name->type);
397 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
400 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
402 static int struct_create(char *name, int isunion)
404 int id = struct_find(name, isunion);
405 struct structinfo *si = &structs[id];
406 tok_expect('{');
407 while (tok_jmp('}')) {
408 readdefs(structdef, si);
409 tok_expect(';');
411 return id;
414 static void readexpr(void);
416 static void enum_create(void)
418 long n = 0;
419 tok_expect('{');
420 while (tok_jmp('}')) {
421 char name[NAMELEN];
422 tok_expect(TOK_NAME);
423 strcpy(name, tok_id());
424 if (!tok_jmp('=')) {
425 readexpr();
426 ts_pop(NULL);
427 if (o_popnum(&n))
428 err("const expr expected!\n");
430 enum_add(name, n++);
431 tok_jmp(',');
435 static int basetype(struct type *type, unsigned *flags)
437 int sign = 1;
438 int size = 4;
439 int done = 0;
440 int i = 0;
441 int isunion;
442 char name[NAMELEN] = "";
443 *flags = 0;
444 type->flags = 0;
445 type->ptr = 0;
446 type->addr = 0;
447 while (!done) {
448 switch (tok_see()) {
449 case TOK_STATIC:
450 *flags |= F_STATIC;
451 break;
452 case TOK_EXTERN:
453 *flags |= F_EXTERN;
454 break;
455 case TOK_VOID:
456 sign = 0;
457 size = 0;
458 done = 1;
459 break;
460 case TOK_INT:
461 done = 1;
462 break;
463 case TOK_CHAR:
464 size = 1;
465 done = 1;
466 break;
467 case TOK_SHORT:
468 size = 2;
469 break;
470 case TOK_LONG:
471 size = LONGSZ;
472 break;
473 case TOK_SIGNED:
474 break;
475 case TOK_UNSIGNED:
476 sign = 0;
477 break;
478 case TOK_UNION:
479 case TOK_STRUCT:
480 isunion = tok_get() == TOK_UNION;
481 if (!tok_jmp(TOK_NAME))
482 strcpy(name, tok_id());
483 if (tok_see() == '{')
484 type->id = struct_create(name, isunion);
485 else
486 type->id = struct_find(name, isunion);
487 type->flags |= T_STRUCT;
488 type->bt = LONGSZ;
489 return 0;
490 case TOK_ENUM:
491 tok_get();
492 tok_jmp(TOK_NAME);
493 if (tok_see() == '{')
494 enum_create();
495 type->bt = 4 | BT_SIGNED;
496 return 0;
497 default:
498 if (tok_see() == TOK_NAME) {
499 int id = typedef_find(tok_id());
500 if (id != -1) {
501 tok_get();
502 memcpy(type, &typedefs[id].type,
503 sizeof(*type));
504 return 0;
507 if (!i)
508 return 1;
509 done = 1;
510 continue;
512 i++;
513 tok_get();
515 type->bt = size | (sign ? BT_SIGNED : 0);
516 return 0;
519 static int readname(struct type *main, char *name,
520 struct type *base, unsigned flags);
522 static int readtype(struct type *type)
524 return readname(type, NULL, NULL, 0);
527 static void readptrs(struct type *type)
529 while (!tok_jmp('*')) {
530 type->ptr++;
531 if (!type->bt)
532 type->bt = 1;
536 /* used to differenciate labels from case and cond exprs */
537 static int ncexpr;
538 static int caseexpr;
540 static void readpre(void);
542 static char *tmp_str(char *buf, int len)
544 static char name[NAMELEN];
545 static int id;
546 void *dat;
547 sprintf(name, "__neatcc.s%d", id++);
548 dat = o_mkdat(name, len, 0);
549 memcpy(dat, buf, len);
550 return name;
553 static void readprimary(void)
555 int i;
556 if (!tok_jmp(TOK_NUM)) {
557 long n;
558 int bt = tok_num(&n);
559 ts_push_bt(bt);
560 o_num(n);
561 return;
563 if (!tok_jmp(TOK_STR)) {
564 struct type t;
565 char buf[BUFSIZE];
566 int len;
567 t.bt = 1 | BT_SIGNED;
568 t.ptr = 1;
569 t.addr = 0;
570 t.flags = 0;
571 ts_push(&t);
572 len = tok_str(buf);
573 o_sym(tmp_str(buf, len));
574 return;
576 if (!tok_jmp(TOK_NAME)) {
577 struct name unkn = {""};
578 char *name = unkn.name;
579 int n;
580 strcpy(name, tok_id());
581 /* don't search for labels here */
582 if (!ncexpr && !caseexpr && tok_see() == ':')
583 return;
584 for (i = nlocals - 1; i >= 0; --i) {
585 struct type *t = &locals[i].type;
586 if (!strcmp(locals[i].name, name)) {
587 o_local(locals[i].addr);
588 ts_push_addr(t);
589 return;
592 if ((n = global_find(name)) != -1) {
593 struct name *g = &globals[n];
594 struct type *t = &g->type;
595 char *elfname = *g->elfname ? g->elfname : g->name;
596 o_sym(elfname);
597 ts_push_addr(t);
598 return;
600 if (!enum_find(&n, name)) {
601 ts_push_bt(4 | BT_SIGNED);
602 o_num(n);
603 return;
605 if (tok_see() != '(')
606 err("unknown symbol\n");
607 global_add(&unkn);
608 ts_push_bt(LONGSZ);
609 o_sym(unkn.name);
610 return;
612 if (!tok_jmp('(')) {
613 struct type t;
614 if (!readtype(&t)) {
615 struct type o;
616 tok_expect(')');
617 readpre();
618 ts_pop_de(&o);
619 ts_push(&t);
620 if (!t.ptr || !o.ptr)
621 o_cast(TYPE_BT(&t));
622 } else {
623 readexpr();
624 tok_expect(')');
626 return;
630 static void arrayderef(void)
632 struct type t;
633 int sz;
634 ts_pop_de(NULL);
635 ts_pop(&t);
636 if (!(t.flags & T_ARRAY) && t.addr) {
637 o_tmpswap();
638 o_deref(TYPE_BT(&t));
639 o_tmpswap();
641 array2ptr(&t);
642 t.ptr--;
643 sz = type_totsz(&t);
644 t.addr = 1;
645 if (sz > 1) {
646 o_num(sz);
647 o_bop(O_MUL);
649 o_bop(O_ADD);
650 ts_push(&t);
653 static void inc_post(int op)
655 struct type t = ts[nts - 1];
656 /* pushing the value before inc */
657 o_tmpcopy();
658 ts_de(1);
659 o_load();
660 o_tmpswap();
662 /* increment by 1 or pointer size */
663 o_tmpcopy();
664 ts_push(&t);
665 ts_pop_de(&t);
666 o_num(t.ptr > 0 ? type_szde(&t) : 1);
667 o_bop(op);
669 /* assign back */
670 o_assign(TYPE_BT(&t));
671 o_tmpdrop(1);
674 static void readfield(void)
676 struct name *field;
677 struct type t;
678 tok_expect(TOK_NAME);
679 ts_pop(&t);
680 array2ptr(&t);
681 field = struct_field(t.id, tok_id());
682 if (field->addr) {
683 o_num(field->addr);
684 o_bop(O_ADD);
686 ts_push_addr(&field->type);
689 #define MAXFUNCS (1 << 10)
691 static struct funcinfo {
692 struct type args[MAXFIELDS];
693 struct type ret;
694 int nargs;
695 int varg;
696 } funcs[MAXFUNCS];
697 static int nfuncs;
699 static int func_create(struct type *ret, struct name *args, int nargs)
701 struct funcinfo *fi = &funcs[nfuncs++];
702 int i;
703 if (nfuncs >= MAXFUNCS)
704 err("nomem: MAXFUNCS reached!\n");
705 memcpy(&fi->ret, ret, sizeof(*ret));
706 for (i = 0; i < nargs; i++)
707 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
708 fi->nargs = nargs;
709 return fi - funcs;
712 static void readcall(void)
714 struct type t;
715 struct funcinfo *fi;
716 int argc = 0;
717 ts_pop(&t);
718 if (t.flags & T_FUNC && t.ptr > 0)
719 o_deref(LONGSZ);
720 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
721 if (tok_see() != ')') {
722 do {
723 readexpr();
724 ts_pop_de(NULL);
725 argc++;
726 } while (!tok_jmp(','));
728 tok_expect(')');
729 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
730 if (fi) {
731 if (TYPE_BT(&fi->ret))
732 o_cast(TYPE_BT(&fi->ret));
733 ts_push(&fi->ret);
734 } else {
735 ts_push_bt(4 | BT_SIGNED);
739 static void readpost(void)
741 readprimary();
742 while (1) {
743 if (!tok_jmp('[')) {
744 readexpr();
745 tok_expect(']');
746 arrayderef();
747 continue;
749 if (!tok_jmp('(')) {
750 readcall();
751 continue;
753 if (!tok_jmp(TOK2("++"))) {
754 inc_post(O_ADD);
755 continue;
757 if (!tok_jmp(TOK2("--"))) {
758 inc_post(O_SUB);
759 continue;
761 if (!tok_jmp('.')) {
762 readfield();
763 continue;
765 if (!tok_jmp(TOK2("->"))) {
766 ts_de(1);
767 readfield();
768 continue;
770 break;
774 static void inc_pre(int op)
776 struct type t;
777 readpre();
778 /* copy the destination */
779 o_tmpcopy();
780 ts_push(&ts[nts - 1]);
781 /* increment by 1 or pointer size */
782 ts_pop_de(&t);
783 o_num(t.ptr > 0 ? type_szde(&t) : 1);
784 o_bop(op);
785 /* assign the result */
786 o_assign(TYPE_BT(&t));
787 ts_de(0);
790 static void readpre(void)
792 if (!tok_jmp('&')) {
793 struct type type;
794 readpre();
795 ts_pop(&type);
796 if (!type.addr)
797 die("cannot use the address\n");
798 type.ptr++;
799 type.addr = 0;
800 ts_push(&type);
801 return;
803 if (!tok_jmp('*')) {
804 struct type t;
805 readpre();
806 ts_pop(&t);
807 array2ptr(&t);
808 if (!t.ptr)
809 err("dereferencing non-pointer\n");
810 if (t.addr)
811 o_deref(TYPE_BT(&t));
812 t.ptr--;
813 t.addr = 1;
814 ts_push(&t);
815 return;
817 if (!tok_jmp('!')) {
818 readpre();
819 ts_pop_de(NULL);
820 o_uop(O_LNOT);
821 ts_push_bt(4 | BT_SIGNED);
822 return;
824 if (!tok_jmp('-')) {
825 readpre();
826 ts_de(1);
827 o_uop(O_NEG);
828 return;
830 if (!tok_jmp('~')) {
831 readpre();
832 ts_de(1);
833 o_uop(O_NOT);
834 return;
836 if (!tok_jmp(TOK2("++"))) {
837 inc_pre(O_ADD);
838 return;
840 if (!tok_jmp(TOK2("--"))) {
841 inc_pre(O_SUB);
842 return;
844 if (!tok_jmp(TOK_SIZEOF)) {
845 struct type t;
846 int op = !tok_jmp('(');
847 if (readtype(&t)) {
848 o_nogen();
849 readexpr();
850 o_dogen();
851 ts_pop(&t);
852 o_tmpdrop(1);
854 ts_push_bt(4);
855 o_num(type_totsz(&t));
856 if (op)
857 tok_expect(')');
858 return;
860 readpost();
863 static void readmul(void)
865 readpre();
866 while (1) {
867 if (!tok_jmp('*')) {
868 readpre();
869 ts_binop(O_MUL);
870 continue;
872 if (!tok_jmp('/')) {
873 readpre();
874 ts_binop(O_DIV);
875 continue;
877 if (!tok_jmp('%')) {
878 readpre();
879 ts_binop(O_MOD);
880 continue;
882 break;
886 static void readadd(void)
888 readmul();
889 while (1) {
890 if (!tok_jmp('+')) {
891 readmul();
892 ts_addop(O_ADD);
893 continue;
895 if (!tok_jmp('-')) {
896 readmul();
897 ts_addop(O_SUB);
898 continue;
900 break;
904 static void shift(int op)
906 struct type t;
907 readadd();
908 ts_pop_de2(NULL, &t);
909 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
910 ts_push_bt(TYPE_BT(&t));
913 static void readshift(void)
915 readadd();
916 while (1) {
917 if (!tok_jmp(TOK2("<<"))) {
918 shift(O_SHL);
919 continue;
921 if (!tok_jmp(TOK2(">>"))) {
922 shift(O_SHR);
923 continue;
925 break;
929 static void cmp(int op)
931 struct type t1, t2;
932 int bt;
933 readshift();
934 ts_pop_de2(&t1, &t2);
935 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
936 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
937 ts_push_bt(4 | BT_SIGNED);
940 static void readcmp(void)
942 readshift();
943 while (1) {
944 if (!tok_jmp('<')) {
945 cmp(O_LT);
946 continue;
948 if (!tok_jmp('>')) {
949 cmp(O_GT);
950 continue;
952 if (!tok_jmp(TOK2("<="))) {
953 cmp(O_LE);
954 continue;
956 if (!tok_jmp(TOK2(">="))) {
957 cmp(O_GE);
958 continue;
960 break;
964 static void eq(int op)
966 readcmp();
967 ts_pop_de2(NULL, NULL);
968 o_bop(op);
969 ts_push_bt(4 | BT_SIGNED);
972 static void readeq(void)
974 readcmp();
975 while (1) {
976 if (!tok_jmp(TOK2("=="))) {
977 eq(O_EQ);
978 continue;
980 if (!tok_jmp(TOK2("!="))) {
981 eq(O_NEQ);
982 continue;
984 break;
988 static void readbitand(void)
990 readeq();
991 while (!tok_jmp('&')) {
992 readeq();
993 ts_binop(O_AND);
997 static void readxor(void)
999 readbitand();
1000 while (!tok_jmp('^')) {
1001 readbitand();
1002 ts_binop(O_XOR);
1006 static void readbitor(void)
1008 readxor();
1009 while (!tok_jmp('|')) {
1010 readxor();
1011 ts_binop(O_OR);
1015 #define MAXCOND (1 << 7)
1017 static void readand(void)
1019 long conds[MAXCOND];
1020 int nconds = 0;
1021 long passed;
1022 int i;
1023 readbitor();
1024 if (tok_see() != TOK2("&&"))
1025 return;
1026 o_fork();
1027 ts_pop_de(NULL);
1028 conds[nconds++] = o_jz(0);
1029 while (!tok_jmp(TOK2("&&"))) {
1030 readbitor();
1031 ts_pop_de(NULL);
1032 conds[nconds++] = o_jz(0);
1034 o_num(1);
1035 o_forkpush();
1036 passed = o_jmp(0);
1037 for (i = 0; i < nconds; i++)
1038 o_filljmp(conds[i]);
1039 o_num(0);
1040 o_forkpush();
1041 o_forkjoin();
1042 o_filljmp(passed);
1043 ts_push_bt(4 | BT_SIGNED);
1046 static void reador(void)
1048 long conds[MAXCOND];
1049 int nconds = 0;
1050 long failed;
1051 int i;
1052 readand();
1053 if (tok_see() != TOK2("||"))
1054 return;
1055 o_fork();
1056 ts_pop_de(NULL);
1057 conds[nconds++] = o_jnz(0);
1058 while (!tok_jmp(TOK2("||"))) {
1059 readand();
1060 ts_pop_de(NULL);
1061 conds[nconds++] = o_jnz(0);
1063 o_num(0);
1064 o_forkpush();
1065 failed = o_jmp(0);
1066 for (i = 0; i < nconds; i++)
1067 o_filljmp(conds[i]);
1068 o_num(1);
1069 o_forkpush();
1070 o_forkjoin();
1071 o_filljmp(failed);
1072 ts_push_bt(4 | BT_SIGNED);
1075 static int readcexpr_const(void)
1077 long c;
1078 if (o_popnum(&c))
1079 return -1;
1080 if (!c)
1081 o_nogen();
1082 reador();
1083 ts_pop(NULL);
1084 tok_expect(':');
1085 if (c) {
1086 o_nogen();
1087 } else {
1088 o_dogen();
1089 o_tmpdrop(1);
1091 reador();
1092 if (c) {
1093 o_dogen();
1094 o_tmpdrop(1);
1096 return 0;
1099 static void readcexpr(void)
1101 long l1, l2;
1102 reador();
1103 if (tok_jmp('?'))
1104 return;
1105 ncexpr++;
1106 ts_pop_de(NULL);
1107 o_fork();
1108 if (readcexpr_const()) {
1109 l1 = o_jz(0);
1110 reador();
1111 ts_de(1);
1112 o_forkpush();
1113 l2 = o_jmp(0);
1114 ts_pop(NULL);
1116 tok_expect(':');
1117 o_filljmp(l1);
1118 reador();
1119 ts_de(1);
1120 o_forkpush();
1121 o_forkjoin();
1122 o_filljmp(l2);
1124 ncexpr--;
1127 static void opassign(int op, int ptrop)
1129 struct type t = ts[nts - 1];
1130 o_tmpcopy();
1131 ts_push(&t);
1132 readexpr();
1133 ts_addop(op);
1134 o_assign(TYPE_BT(&ts[nts - 1]));
1135 ts_pop(NULL);
1136 ts_de(0);
1139 static void doassign(void)
1141 struct type t = ts[nts - 1];
1142 if (!t.ptr && t.flags & T_STRUCT) {
1143 ts_pop(NULL);
1144 o_num(type_totsz(&t));
1145 o_memcpy();
1146 } else {
1147 ts_pop_de(NULL);
1148 o_assign(TYPE_BT(&ts[nts - 1]));
1149 ts_de(0);
1153 static void readexpr(void)
1155 readcexpr();
1156 if (!tok_jmp('=')) {
1157 readexpr();
1158 doassign();
1159 return;
1161 if (!tok_jmp(TOK2("+="))) {
1162 opassign(O_ADD, 1);
1163 return;
1165 if (!tok_jmp(TOK2("-="))) {
1166 opassign(O_SUB, 1);
1167 return;
1169 if (!tok_jmp(TOK2("*="))) {
1170 opassign(O_MUL, 0);
1171 return;
1173 if (!tok_jmp(TOK2("/="))) {
1174 opassign(O_DIV, 0);
1175 return;
1177 if (!tok_jmp(TOK2("%="))) {
1178 opassign(O_MOD, 0);
1179 return;
1181 if (!tok_jmp(TOK3("<<="))) {
1182 opassign(O_SHL, 0);
1183 return;
1185 if (!tok_jmp(TOK3(">>="))) {
1186 opassign(O_SHR, 0);
1187 return;
1189 if (!tok_jmp(TOK3("&="))) {
1190 opassign(O_AND, 0);
1191 return;
1193 if (!tok_jmp(TOK3("|="))) {
1194 opassign(O_OR, 0);
1195 return;
1197 if (!tok_jmp(TOK3("^="))) {
1198 opassign(O_XOR, 0);
1199 return;
1203 static void readestmt(void)
1205 do {
1206 o_tmpdrop(-1);
1207 nts = 0;
1208 readexpr();
1209 } while (!tok_jmp(','));
1212 static void o_localoff(long addr, int off)
1214 o_local(addr);
1215 if (off) {
1216 o_num(off);
1217 o_bop(O_ADD);
1221 static struct type *innertype(struct type *t)
1223 if (t->flags & T_ARRAY && !t->ptr)
1224 return innertype(&arrays[t->id].type);
1225 return t;
1228 static void initexpr(struct type *t, int off, void *obj,
1229 void (*set)(void *obj, int off, struct type *t))
1231 if (tok_jmp('{')) {
1232 set(obj, off, t);
1233 return;
1235 if (!t->ptr && t->flags & T_STRUCT) {
1236 struct structinfo *si = &structs[t->id];
1237 int i;
1238 for (i = 0; i < si->nfields; i++) {
1239 struct name *field = &si->fields[i];
1240 if (!tok_jmp('.')) {
1241 tok_expect(TOK_NAME);
1242 field = struct_field(t->id, tok_id());
1243 tok_expect('=');
1245 initexpr(&field->type, off + field->addr, obj, set);
1246 if (tok_jmp(',') || tok_see() == '}')
1247 break;
1249 } else if (t->flags & T_ARRAY) {
1250 struct type *t_de = &arrays[t->id].type;
1251 int i;
1252 for (i = 0; ; i++) {
1253 long idx = i;
1254 struct type *it = t_de;
1255 if (!tok_jmp('[')) {
1256 readexpr();
1257 o_popnum(&idx);
1258 ts_pop(NULL);
1259 tok_expect(']');
1260 tok_expect('=');
1262 if (tok_see() != '{')
1263 it = innertype(t_de);
1264 initexpr(it, off + type_totsz(it) * idx, obj, set);
1265 if (tok_jmp(',') || tok_see() == '}')
1266 break;
1269 tok_expect('}');
1272 static void jumpbrace(void)
1274 int depth = 0;
1275 while (tok_see() != '}' || depth--)
1276 if (tok_get() == '{')
1277 depth++;
1278 tok_expect('}');
1281 static int initsize(void)
1283 long addr = tok_addr();
1284 int n = 0;
1285 if (!tok_jmp(TOK_STR)) {
1286 n = tok_str(NULL);
1287 tok_jump(addr);
1288 return n;
1290 o_nogen();
1291 tok_expect('{');
1292 while (tok_jmp('}')) {
1293 long idx = n;
1294 if (!tok_jmp('[')) {
1295 readexpr();
1296 o_popnum(&idx);
1297 ts_pop(NULL);
1298 tok_expect(']');
1299 tok_expect('=');
1301 if (n < idx + 1)
1302 n = idx + 1;
1303 while (tok_see() != '}' && tok_see() != ',')
1304 if (tok_get() == '{')
1305 jumpbrace();
1306 tok_jmp(',');
1308 o_dogen();
1309 tok_jump(addr);
1310 return n;
1313 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1315 static void globalinit(void *obj, int off, struct type *t)
1317 struct name *name = obj;
1318 char *elfname = *name->elfname ? name->elfname : name->name;
1319 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1320 struct type *t_de = &arrays[t->id].type;
1321 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1322 char buf[BUFSIZE];
1323 int len;
1324 tok_expect(TOK_STR);
1325 len = tok_str(buf);
1326 memcpy((void *) name->addr + off, buf, len);
1327 return;
1330 readexpr();
1331 o_datset(elfname, off, TYPE_BT(t));
1332 ts_pop(NULL);
1335 static void globaldef(void *data, struct name *name, unsigned flags)
1337 struct type *t = &name->type;
1338 char *elfname = *name->elfname ? name->elfname : name->name;
1339 int sz;
1340 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1341 if (~flags & F_EXTERN)
1342 arrays[t->id].n = initsize();
1343 sz = type_totsz(t);
1344 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1345 if (flags & F_INIT)
1346 name->addr = (long) o_mkdat(elfname, sz, F_GLOBAL(flags));
1347 else
1348 o_mkbss(elfname, sz, F_GLOBAL(flags));
1350 global_add(name);
1351 if (flags & F_INIT)
1352 initexpr(t, 0, name, globalinit);
1355 static void localinit(void *obj, int off, struct type *t)
1357 long addr = *(long *) obj;
1358 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1359 struct type *t_de = &arrays[t->id].type;
1360 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1361 char buf[BUFSIZE];
1362 int len;
1363 tok_expect(TOK_STR);
1364 len = tok_str(buf);
1365 o_localoff(addr, off);
1366 o_sym(tmp_str(buf, len));
1367 o_num(len);
1368 o_memcpy();
1369 o_tmpdrop(1);
1370 return;
1373 o_localoff(addr, off);
1374 ts_push(t);
1375 readexpr();
1376 doassign();
1377 ts_pop(NULL);
1378 o_tmpdrop(1);
1381 /* current function name */
1382 static char func_name[NAMELEN];
1384 static void localdef(void *data, struct name *name, unsigned flags)
1386 struct type *t = &name->type;
1387 if ((flags & F_EXTERN) || (t->flags & T_FUNC) && !t->ptr) {
1388 global_add(name);
1389 return;
1391 if (flags & F_STATIC) {
1392 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1393 globaldef(data, name, flags);
1394 return;
1396 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1397 arrays[t->id].n = initsize();
1398 name->addr = o_mklocal(type_totsz(&name->type));
1399 local_add(name);
1400 if (flags & F_INIT) {
1401 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1402 o_local(name->addr);
1403 o_num(0);
1404 o_num(type_totsz(t));
1405 o_memset();
1406 o_tmpdrop(1);
1408 initexpr(t, 0, &name->addr, localinit);
1412 static void funcdef(char *name, struct type *type, struct name *args,
1413 int nargs, int varg, unsigned flags)
1415 struct name global = {""};
1416 int i;
1417 strcpy(global.name, name);
1418 strcpy(func_name, name);
1419 memcpy(&global.type, type, sizeof(*type));
1420 o_func_beg(name, nargs, F_GLOBAL(flags), varg);
1421 global_add(&global);
1422 for (i = 0; i < nargs; i++) {
1423 args[i].addr = o_arg2loc(i);
1424 local_add(&args[i]);
1428 static int readargs(struct name *args, int *varg)
1430 int nargs = 0;
1431 tok_expect('(');
1432 *varg = 0;
1433 while (tok_see() != ')') {
1434 if (!tok_jmp(TOK3("..."))) {
1435 *varg = 1;
1436 break;
1438 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1439 array2ptr(&args[nargs].type);
1440 nargs++;
1441 if (tok_jmp(','))
1442 break;
1444 tok_expect(')');
1445 if (nargs == 1 && !TYPE_BT(&args[0].type))
1446 return 0;
1447 return nargs;
1450 static int readname(struct type *main, char *name,
1451 struct type *base, unsigned flags)
1453 struct type tpool[3];
1454 int npool = 0;
1455 struct type *type = &tpool[npool++];
1456 struct type *func = NULL;
1457 struct type *ret = NULL;
1458 int arsz[10];
1459 int nar = 0;
1460 int i;
1461 memset(tpool, 0, sizeof(tpool));
1462 if (name)
1463 *name = '\0';
1464 if (!base) {
1465 if (basetype(type, &flags))
1466 return 1;
1467 } else {
1468 memcpy(type, base, sizeof(*base));
1470 readptrs(type);
1471 if (!tok_jmp('(')) {
1472 ret = type;
1473 type = &tpool[npool++];
1474 func = type;
1475 readptrs(type);
1477 if (!tok_jmp(TOK_NAME) && name)
1478 strcpy(name, tok_id());
1479 while (!tok_jmp('[')) {
1480 long n = 0;
1481 if (tok_jmp(']')) {
1482 readexpr();
1483 ts_pop(NULL);
1484 if (o_popnum(&n))
1485 err("const expr expected\n");
1486 tok_expect(']');
1488 arsz[nar++] = n;
1490 for (i = nar - 1; i >= 0; i--) {
1491 type->id = array_add(type, arsz[i]);
1492 if (func && i == nar - 1)
1493 func = &arrays[type->id].type;
1494 type->flags = T_ARRAY;
1495 type->bt = LONGSZ;
1496 type->ptr = 0;
1498 if (func)
1499 tok_expect(')');
1500 if (tok_see() == '(') {
1501 struct name args[MAXARGS] = {{""}};
1502 int varg = 0;
1503 int nargs = readargs(args, &varg);
1504 int fdef = !func;
1505 if (!func) {
1506 ret = type;
1507 type = &tpool[npool++];
1508 func = type;
1510 func->flags = T_FUNC;
1511 func->bt = LONGSZ;
1512 func->id = func_create(ret, args, nargs);
1513 if (fdef && tok_see() == '{') {
1514 funcdef(name, func, args, nargs, varg, flags);
1515 return 1;
1518 memcpy(main, type, sizeof(*type));
1519 return 0;
1522 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1523 void *data)
1525 struct type base;
1526 unsigned base_flags;
1527 if (basetype(&base, &base_flags))
1528 return 1;
1529 while (tok_see() != ';' && tok_see() != '{') {
1530 struct name name = {{""}};
1531 unsigned flags = base_flags;
1532 if (readname(&name.type, name.name, &base, flags))
1533 break;
1534 if (!tok_jmp('='))
1535 flags |= F_INIT;
1536 def(data, &name, flags);
1537 tok_jmp(',');
1539 return 0;
1542 static void typedefdef(void *data, struct name *name, unsigned flags)
1544 typedef_add(name->name, &name->type);
1547 static void readstmt(void);
1549 #define MAXCASES (1 << 7)
1551 static void readswitch(void)
1553 int break_beg = nbreaks;
1554 long val_addr = o_mklocal(LONGSZ);
1555 long matched[MAXCASES];
1556 int nmatched = 0;
1557 struct type t;
1558 long next;
1559 int ref = 1;
1560 int i;
1561 tok_expect('(');
1562 readexpr();
1563 ts_pop_de(&t);
1564 o_local(val_addr);
1565 o_tmpswap();
1566 o_assign(TYPE_BT(&t));
1567 ts_de(0);
1568 o_tmpdrop(1);
1569 tok_expect(')');
1570 tok_expect('{');
1571 while (tok_jmp('}')) {
1572 int n = 0;
1573 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1574 if (n++ > 0)
1575 matched[nmatched++] = o_jmp(0);
1576 if (!ref++)
1577 o_filljmp(next);
1578 if (!tok_jmp(TOK_CASE)) {
1579 caseexpr = 1;
1580 readexpr();
1581 ts_pop_de(NULL);
1582 caseexpr = 0;
1583 o_local(val_addr);
1584 o_deref(TYPE_BT(&t));
1585 o_bop(O_EQ);
1586 next = o_jz(0);
1587 ref = 0;
1588 tok_expect(':');
1589 o_tmpdrop(1);
1590 continue;
1592 if (!tok_jmp(TOK_DEFAULT)) {
1593 tok_expect(':');
1594 continue;
1597 for (i = 0; i < nmatched; i++)
1598 o_filljmp(matched[i]);
1599 nmatched = 0;
1600 readstmt();
1602 o_rmlocal(val_addr, LONGSZ);
1603 if (!ref++)
1604 o_filljmp(next);
1605 break_fill(o_mklabel(), break_beg);
1608 #define MAXGOTO (1 << 10)
1610 static struct gotoinfo {
1611 char name[NAMELEN];
1612 long addr;
1613 } gotos[MAXGOTO];
1614 static int ngotos;
1616 static struct labelinfo {
1617 char name[NAMELEN];
1618 long addr;
1619 } labels[MAXGOTO];
1620 static int nlabels;
1622 static void goto_add(char *name)
1624 strcpy(gotos[ngotos].name, name);
1625 gotos[ngotos++].addr = o_jmp(0);
1628 static void label_add(char *name)
1630 strcpy(labels[nlabels].name, name);
1631 labels[nlabels++].addr = o_mklabel();
1634 static void goto_fill(void)
1636 int i, j;
1637 for (i = 0; i < ngotos; i++)
1638 for (j = 0; j < nlabels; j++)
1639 if (!strcmp(gotos[i].name, labels[j].name)) {
1640 o_filljmp2(gotos[i].addr, labels[j].addr);
1641 break;
1645 static void readstmt(void)
1647 o_tmpdrop(-1);
1648 nts = 0;
1649 if (!tok_jmp('{')) {
1650 int _nlocals = nlocals;
1651 int _nglobals = nglobals;
1652 int _nenums = nenums;
1653 int _ntypedefs = ntypedefs;
1654 int _nstructs = nstructs;
1655 int _nfuncs = nfuncs;
1656 int _narrays = narrays;
1657 while (tok_jmp('}'))
1658 readstmt();
1659 nlocals = _nlocals;
1660 nenums = _nenums;
1661 ntypedefs = _ntypedefs;
1662 nstructs = _nstructs;
1663 nfuncs = _nfuncs;
1664 narrays = _narrays;
1665 nglobals = _nglobals;
1666 return;
1668 if (!readdefs(localdef, NULL)) {
1669 tok_expect(';');
1670 return;
1672 if (!tok_jmp(TOK_TYPEDEF)) {
1673 readdefs(typedefdef, NULL);
1674 tok_expect(';');
1675 return;
1677 if (!tok_jmp(TOK_IF)) {
1678 long l1, l2;
1679 tok_expect('(');
1680 readexpr();
1681 tok_expect(')');
1682 ts_pop_de(NULL);
1683 l1 = o_jz(0);
1684 readstmt();
1685 if (!tok_jmp(TOK_ELSE)) {
1686 l2 = o_jmp(0);
1687 o_filljmp(l1);
1688 readstmt();
1689 o_filljmp(l2);
1690 } else {
1691 o_filljmp(l1);
1693 return;
1695 if (!tok_jmp(TOK_WHILE)) {
1696 long l1, l2;
1697 int break_beg = nbreaks;
1698 int continue_beg = ncontinues;
1699 l1 = o_mklabel();
1700 tok_expect('(');
1701 readexpr();
1702 tok_expect(')');
1703 ts_pop_de(NULL);
1704 l2 = o_jz(0);
1705 readstmt();
1706 o_jmp(l1);
1707 o_filljmp(l2);
1708 break_fill(o_mklabel(), break_beg);
1709 continue_fill(l1, continue_beg);
1710 return;
1712 if (!tok_jmp(TOK_DO)) {
1713 long l1, l2;
1714 int break_beg = nbreaks;
1715 int continue_beg = ncontinues;
1716 l1 = o_mklabel();
1717 readstmt();
1718 tok_expect(TOK_WHILE);
1719 tok_expect('(');
1720 l2 = o_mklabel();
1721 readexpr();
1722 ts_pop_de(NULL);
1723 o_jnz(l1);
1724 tok_expect(')');
1725 break_fill(o_mklabel(), break_beg);
1726 continue_fill(l2, continue_beg);
1727 return;
1729 if (!tok_jmp(TOK_FOR)) {
1730 long l_check, l_jump, j_fail, j_pass;
1731 int break_beg = nbreaks;
1732 int continue_beg = ncontinues;
1733 int has_cond = 0;
1734 tok_expect('(');
1735 if (tok_see() != ';')
1736 readestmt();
1737 tok_expect(';');
1738 l_check = o_mklabel();
1739 if (tok_see() != ';') {
1740 readestmt();
1741 ts_pop_de(NULL);
1742 j_fail = o_jz(0);
1743 has_cond = 1;
1745 tok_expect(';');
1746 j_pass = o_jmp(0);
1747 l_jump = o_mklabel();
1748 if (tok_see() != ')')
1749 readestmt();
1750 tok_expect(')');
1751 o_jmp(l_check);
1752 o_filljmp(j_pass);
1753 readstmt();
1754 o_jmp(l_jump);
1755 if (has_cond)
1756 o_filljmp(j_fail);
1757 break_fill(o_mklabel(), break_beg);
1758 continue_fill(l_jump, continue_beg);
1759 return;
1761 if (!tok_jmp(TOK_SWITCH)) {
1762 readswitch();
1763 return;
1765 if (!tok_jmp(TOK_RETURN)) {
1766 int ret = tok_see() != ';';
1767 if (ret) {
1768 readexpr();
1769 ts_pop_de(NULL);
1771 tok_expect(';');
1772 o_ret(ret);
1773 return;
1775 if (!tok_jmp(TOK_BREAK)) {
1776 tok_expect(';');
1777 breaks[nbreaks++] = o_jmp(0);
1778 return;
1780 if (!tok_jmp(TOK_CONTINUE)) {
1781 tok_expect(';');
1782 continues[ncontinues++] = o_jmp(0);
1783 return;
1785 if (!tok_jmp(TOK_GOTO)) {
1786 tok_expect(TOK_NAME);
1787 goto_add(tok_id());
1788 tok_expect(';');
1789 return;
1791 readestmt();
1792 /* labels */
1793 if (!tok_jmp(':')) {
1794 label_add(tok_id());
1795 return;
1797 tok_expect(';');
1800 static void readdecl(void)
1802 if (!tok_jmp(TOK_TYPEDEF)) {
1803 readdefs(typedefdef, NULL);
1804 tok_expect(';');
1805 return;
1807 readdefs(globaldef, NULL);
1808 if (tok_see() == '{') {
1809 readstmt();
1810 goto_fill();
1811 o_func_end();
1812 func_name[0] = '\0';
1813 nlocals = 0;
1814 ngotos = 0;
1815 nlabels = 0;
1816 return;
1818 tok_expect(';');
1821 static void parse(void)
1823 while (tok_see() != TOK_EOF)
1824 readdecl();
1827 static void compat_macros(void)
1829 cpp_define("__STDC__", "");
1830 cpp_define("__arm__", "");
1831 cpp_define("__linux__", "");
1833 /* ignored keywords */
1834 cpp_define("const", "");
1835 cpp_define("register", "");
1836 cpp_define("volatile", "");
1837 cpp_define("inline", "");
1838 cpp_define("restrict", "");
1839 cpp_define("__inline__", "");
1840 cpp_define("__restrict__", "");
1841 cpp_define("__attribute__(x)", "");
1842 cpp_define("__builtin_va_list__", "long");
1845 int main(int argc, char *argv[])
1847 char obj[128];
1848 int ofd;
1849 int i = 1;
1850 compat_macros();
1851 while (i < argc && argv[i][0] == '-') {
1852 if (argv[i][1] == 'I')
1853 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1854 if (argv[i][1] == 'D') {
1855 char *name = argv[i] + 2;
1856 char *def = "";
1857 char *eq = strchr(name, '=');
1858 if (eq) {
1859 *eq = '\0';
1860 def = eq + 1;
1862 cpp_define(name, def);
1864 if (argv[i][1] == 'o')
1865 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1866 i++;
1868 if (i == argc)
1869 die("neatcc: no file given\n");
1870 if (cpp_init(argv[i]))
1871 die("neatcc: cannot open input file\n");
1872 parse();
1873 if (!*obj) {
1874 strcpy(obj, argv[i]);
1875 obj[strlen(obj) - 1] = 'o';
1877 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1878 o_write(ofd);
1879 close(ofd);
1880 return 0;