ncc: better char array initialization
[neatcc.git] / ncc.c
blobca65dc5cdeb148cf52dcbc2723003b75fe891cdf
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 static int nogen; /* don't generate code */
20 /* nogen macros */
21 #define o_bop(op) {if (!nogen) o_bop(op);}
22 #define o_uop(op) {if (!nogen) o_uop(op);}
23 #define o_cast(bt) {if (!nogen) o_cast(bt);}
24 #define o_memcpy() {if (!nogen) o_memcpy();}
25 #define o_memset() {if (!nogen) o_memset();}
26 #define o_call(argc, ret) {if (!nogen) o_call(argc, ret);}
27 #define o_ret(ret) {if (!nogen) o_ret(ret);}
28 #define o_assign(bt) {if (!nogen) o_assign(bt);}
29 #define o_deref(bt) {if (!nogen) o_deref(bt);}
30 #define o_load() {if (!nogen) o_load();}
31 #define o_popnum(c) (nogen ? 0 : o_popnum(c))
32 #define o_num(n) {if (!nogen) o_num(n);}
33 #define o_local(addr) {if (!nogen) o_local(addr);}
34 #define o_sym(sym) {if (!nogen) o_sym(sym);}
35 #define o_tmpdrop(n) {if (!nogen) o_tmpdrop(n);}
36 #define o_tmpswap() {if (!nogen) o_tmpswap();}
37 #define o_tmpcopy() {if (!nogen) o_tmpcopy();}
38 #define o_mklabel() (nogen ? 0 : o_mklabel())
39 #define o_jz(addr) (nogen ? 0 : o_jz(addr))
40 #define o_jnz(addr) (nogen ? 0 : o_jnz(addr))
41 #define o_jmp(addr) (nogen ? 0 : o_jmp(addr))
42 #define o_filljmp(addr) {if (!nogen) o_filljmp(addr);}
43 #define o_filljmp2(addr, dst) {if (!nogen) o_filljmp2(addr, dst);}
44 #define o_fork() {if (!nogen) o_fork();}
45 #define o_forkpush() {if (!nogen) o_forkpush();}
46 #define o_forkjoin() {if (!nogen) o_forkjoin();}
48 #define MAXLOCALS (1 << 10)
49 #define MAXGLOBALS (1 << 10)
50 #define MAXARGS (1 << 5)
52 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
53 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
55 #define T_ARRAY 0x01
56 #define T_STRUCT 0x02
57 #define T_FUNC 0x04
59 #define F_INIT 0x01
60 #define F_STATIC 0x02
61 #define F_EXTERN 0x04
63 struct type {
64 unsigned bt;
65 unsigned flags;
66 int ptr;
67 int id; /* for structs, functions and arrays */
68 int addr; /* the address is passed to gen.c; deref for value */
71 /* type stack */
72 static struct type ts[MAXTMP];
73 static int nts;
75 static void ts_push_bt(unsigned bt)
77 ts[nts].ptr = 0;
78 ts[nts].flags = 0;
79 ts[nts].addr = 0;
80 ts[nts++].bt = bt;
83 static void ts_push(struct type *t)
85 struct type *d = &ts[nts++];
86 memcpy(d, t, sizeof(*t));
89 static void ts_push_addr(struct type *t)
91 ts_push(t);
92 ts[nts - 1].addr = 1;
95 static void ts_pop(struct type *type)
97 nts--;
98 if (type)
99 *type = ts[nts];
102 void err(char *msg)
104 die("%s: %s", cpp_loc(tok_addr()), msg);
107 struct name {
108 char name[NAMELEN];
109 char elfname[NAMELEN]; /* local elf name for static variables in function */
110 struct type type;
111 long addr; /* local stack offset, global data addr, struct offset */
114 static struct name locals[MAXLOCALS];
115 static int nlocals;
116 static struct name globals[MAXGLOBALS];
117 static int nglobals;
119 static void local_add(struct name *name)
121 if (nlocals >= MAXLOCALS)
122 err("nomem: MAXLOCALS reached!\n");
123 memcpy(&locals[nlocals++], name, sizeof(*name));
126 static int local_find(char *name)
128 int i;
129 for (i = nlocals - 1; i >= 0; --i)
130 if (!strcmp(locals[i].name, name))
131 return i;
132 return -1;
135 static int global_find(char *name)
137 int i;
138 for (i = nglobals - 1; i >= 0; i--)
139 if (!strcmp(name, globals[i].name))
140 return i;
141 return -1;
144 static void global_add(struct name *name)
146 if (nglobals >= MAXGLOBALS)
147 err("nomem: MAXGLOBALS reached!\n");
148 memcpy(&globals[nglobals++], name, sizeof(*name));
151 #define MAXENUMS (1 << 10)
153 static struct enumval {
154 char name[NAMELEN];
155 int n;
156 } enums[MAXENUMS];
157 static int nenums;
159 static void enum_add(char *name, int val)
161 struct enumval *ev = &enums[nenums++];
162 if (nenums >= MAXENUMS)
163 err("nomem: MAXENUMS reached!\n");
164 strcpy(ev->name, name);
165 ev->n = val;
168 static int enum_find(int *val, char *name)
170 int i;
171 for (i = nenums - 1; i >= 0; --i)
172 if (!strcmp(name, enums[i].name)) {
173 *val = enums[i].n;
174 return 0;
176 return 1;
179 #define MAXTYPEDEFS (1 << 10)
181 static struct typdefinfo {
182 char name[NAMELEN];
183 struct type type;
184 } typedefs[MAXTYPEDEFS];
185 static int ntypedefs;
187 static void typedef_add(char *name, struct type *type)
189 struct typdefinfo *ti = &typedefs[ntypedefs++];
190 if (ntypedefs >= MAXTYPEDEFS)
191 err("nomem: MAXTYPEDEFS reached!\n");
192 strcpy(ti->name, name);
193 memcpy(&ti->type, type, sizeof(*type));
196 static int typedef_find(char *name)
198 int i;
199 for (i = ntypedefs - 1; i >= 0; --i)
200 if (!strcmp(name, typedefs[i].name))
201 return i;
202 return -1;
205 #define MAXARRAYS (1 << 10)
207 static struct array {
208 struct type type;
209 int n;
210 } arrays[MAXARRAYS];
211 static int narrays;
213 static int array_add(struct type *type, int n)
215 struct array *a = &arrays[narrays++];
216 if (narrays >= MAXARRAYS)
217 err("nomem: MAXARRAYS reached!\n");
218 memcpy(&a->type, type, sizeof(*type));
219 a->n = n;
220 return a - arrays;
223 static void array2ptr(struct type *t)
225 if (t->flags & T_ARRAY && !t->ptr) {
226 memcpy(t, &arrays[t->id].type, sizeof(*t));
227 t->ptr++;
231 #define MAXSTRUCTS (1 << 10)
232 #define MAXFIELDS (1 << 7)
234 static struct structinfo {
235 char name[NAMELEN];
236 struct name fields[MAXFIELDS];
237 int nfields;
238 int isunion;
239 int size;
240 } structs[MAXSTRUCTS];
241 static int nstructs;
243 static int struct_find(char *name, int isunion)
245 int i;
246 for (i = nstructs - 1; i >= 0; --i)
247 if (*structs[i].name && !strcmp(name, structs[i].name) &&
248 structs[i].isunion == isunion)
249 return i;
250 i = nstructs++;
251 if (nstructs >= MAXSTRUCTS)
252 err("nomem: MAXTYPES reached!\n");
253 memset(&structs[i], 0, sizeof(structs[i]));
254 strcpy(structs[i].name, name);
255 structs[i].isunion = isunion;
256 return i;
259 static struct name *struct_field(int id, char *name)
261 struct structinfo *si = &structs[id];
262 int i;
263 for (i = 0; i < si->nfields; i++)
264 if (!strcmp(name, si->fields[i].name))
265 return &si->fields[i];
266 err("field not found\n");
269 #define MAXBREAK (1 << 7)
271 static long breaks[MAXBREAK];
272 static int nbreaks;
273 static long continues[MAXBREAK];
274 static int ncontinues;
276 static void break_fill(long addr, int till)
278 int i;
279 for (i = till; i < nbreaks; i++)
280 o_filljmp2(breaks[i], addr);
281 nbreaks = till;
284 static void continue_fill(long addr, int till)
286 int i;
287 for (i = till; i < ncontinues; i++)
288 o_filljmp2(continues[i], addr);
289 ncontinues = till;
292 /* return t's size */
293 static int type_totsz(struct type *t)
295 if (t->ptr)
296 return LONGSZ;
297 if (t->flags & T_ARRAY)
298 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
299 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
302 /* return t's dereferenced size */
303 static unsigned type_szde(struct type *t)
305 struct type de = *t;
306 array2ptr(&de);
307 de.ptr--;
308 return type_totsz(&de);
311 /* dereference stack top if t->addr (ie. address is pushed to gen.c) */
312 static void ts_de(int deref)
314 struct type *t = &ts[nts - 1];
315 array2ptr(t);
316 if (deref && t->addr && (t->ptr || !(t->flags & T_FUNC)))
317 o_deref(TYPE_BT(t));
318 t->addr = 0;
321 /* pop stack pop to *t and dereference if t->addr */
322 static void ts_pop_de(struct type *t)
324 ts_de(1);
325 ts_pop(t);
328 /* pop the top 2 stack values and dereference them if t->addr */
329 static void ts_pop_de2(struct type *t1, struct type *t2)
331 ts_pop_de(t1);
332 o_tmpswap();
333 ts_pop_de(t2);
334 o_tmpswap();
337 static int tok_jmp(int tok)
339 if (tok_see() != tok)
340 return 1;
341 tok_get();
342 return 0;
345 static void tok_expect(int tok)
347 if (tok_get() != tok)
348 err("syntax error\n");
351 static unsigned bt_op(unsigned bt1, unsigned bt2)
353 unsigned s1 = BT_SZ(bt1);
354 unsigned s2 = BT_SZ(bt2);
355 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
358 static void ts_binop(int op)
360 struct type t1, t2;
361 int bt;
362 ts_pop_de2(&t1, &t2);
363 if (op == O_DIV || op == O_MOD)
364 bt = TYPE_BT(&t2);
365 else
366 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
367 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
368 ts_push_bt(bt);
371 static void ts_addop(int op)
373 struct type t1, t2;
374 ts_pop_de2(&t1, &t2);
375 if (!t1.ptr && !t2.ptr) {
376 o_bop(op);
377 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
378 return;
380 if (t1.ptr && !t2.ptr)
381 o_tmpswap();
382 if (!t1.ptr && t2.ptr)
383 if (type_szde(&t2) > 1) {
384 o_num(type_szde(&t2));
385 o_bop(O_MUL);
387 if (t1.ptr && !t2.ptr)
388 o_tmpswap();
389 o_bop(op);
390 if (t1.ptr && t2.ptr) {
391 int sz = type_szde(&t1);
392 if (sz > 1) {
393 o_num(sz);
394 o_bop(O_DIV);
396 ts_push_bt(4 | BT_SIGNED);
397 } else {
398 ts_push(t1.ptr ? &t1 : &t2);
402 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
403 #define MIN(a, b) ((a) < (b) ? (a) : (b))
405 static int type_alignment(struct type *t)
407 if (t->flags & T_ARRAY && !t->ptr)
408 return type_alignment(&arrays[t->id].type);
409 if (t->flags & T_STRUCT && !t->ptr)
410 return type_alignment(&structs[t->id].fields[0].type);
411 return MIN(LONGSZ, type_totsz(t));
414 static void structdef(void *data, struct name *name, unsigned flags)
416 struct structinfo *si = data;
417 if (si->isunion) {
418 name->addr = 0;
419 if (si->size < type_totsz(&name->type))
420 si->size = type_totsz(&name->type);
421 } else {
422 struct type *t = &name->type;
423 int alignment = type_alignment(t);
424 if (t->flags & T_ARRAY && !t->ptr)
425 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
426 si->size = ALIGN(si->size, alignment);
427 name->addr = si->size;
428 si->size += type_totsz(&name->type);
430 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
433 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
435 static int struct_create(char *name, int isunion)
437 int id = struct_find(name, isunion);
438 struct structinfo *si = &structs[id];
439 tok_expect('{');
440 while (tok_jmp('}')) {
441 readdefs(structdef, si);
442 tok_expect(';');
444 return id;
447 static void readexpr(void);
449 static void enum_create(void)
451 long n = 0;
452 tok_expect('{');
453 while (tok_jmp('}')) {
454 char name[NAMELEN];
455 tok_expect(TOK_NAME);
456 strcpy(name, tok_id());
457 if (!tok_jmp('=')) {
458 readexpr();
459 ts_pop_de(NULL);
460 if (o_popnum(&n))
461 err("const expr expected!\n");
463 enum_add(name, n++);
464 tok_jmp(',');
468 static int basetype(struct type *type, unsigned *flags)
470 int sign = 1;
471 int size = 4;
472 int done = 0;
473 int i = 0;
474 int isunion;
475 char name[NAMELEN] = "";
476 *flags = 0;
477 type->flags = 0;
478 type->ptr = 0;
479 type->addr = 0;
480 while (!done) {
481 switch (tok_see()) {
482 case TOK_STATIC:
483 *flags |= F_STATIC;
484 break;
485 case TOK_EXTERN:
486 *flags |= F_EXTERN;
487 break;
488 case TOK_VOID:
489 sign = 0;
490 size = 0;
491 done = 1;
492 break;
493 case TOK_INT:
494 done = 1;
495 break;
496 case TOK_CHAR:
497 size = 1;
498 done = 1;
499 break;
500 case TOK_SHORT:
501 size = 2;
502 break;
503 case TOK_LONG:
504 size = LONGSZ;
505 break;
506 case TOK_SIGNED:
507 break;
508 case TOK_UNSIGNED:
509 sign = 0;
510 break;
511 case TOK_UNION:
512 case TOK_STRUCT:
513 isunion = tok_get() == TOK_UNION;
514 if (!tok_jmp(TOK_NAME))
515 strcpy(name, tok_id());
516 if (tok_see() == '{')
517 type->id = struct_create(name, isunion);
518 else
519 type->id = struct_find(name, isunion);
520 type->flags |= T_STRUCT;
521 type->bt = LONGSZ;
522 return 0;
523 case TOK_ENUM:
524 tok_get();
525 tok_jmp(TOK_NAME);
526 if (tok_see() == '{')
527 enum_create();
528 type->bt = 4 | BT_SIGNED;
529 return 0;
530 default:
531 if (tok_see() == TOK_NAME) {
532 int id = typedef_find(tok_id());
533 if (id != -1) {
534 tok_get();
535 memcpy(type, &typedefs[id].type,
536 sizeof(*type));
537 return 0;
540 if (!i)
541 return 1;
542 done = 1;
543 continue;
545 i++;
546 tok_get();
548 type->bt = size | (sign ? BT_SIGNED : 0);
549 return 0;
552 static int readname(struct type *main, char *name,
553 struct type *base, unsigned flags);
555 static int readtype(struct type *type)
557 return readname(type, NULL, NULL, 0);
560 static void readptrs(struct type *type)
562 while (!tok_jmp('*')) {
563 type->ptr++;
564 if (!type->bt)
565 type->bt = 1;
569 /* used to differenciate labels from case and cond exprs */
570 static int ncexpr;
571 static int caseexpr;
573 static void readpre(void);
575 static char *tmp_str(char *buf, int len)
577 static char name[NAMELEN];
578 static int id;
579 void *dat;
580 sprintf(name, "__neatcc.s%d", id++);
581 dat = o_mkdat(name, len, 0);
582 memcpy(dat, buf, len);
583 return name;
586 static void readprimary(void)
588 if (!tok_jmp(TOK_NUM)) {
589 long n;
590 int bt = tok_num(&n);
591 ts_push_bt(bt);
592 o_num(n);
593 return;
595 if (!tok_jmp(TOK_STR)) {
596 struct type t;
597 char buf[BUFSIZE];
598 int len;
599 t.bt = 1 | BT_SIGNED;
600 t.ptr = 1;
601 t.addr = 0;
602 t.flags = 0;
603 ts_push(&t);
604 len = tok_str(buf);
605 o_sym(tmp_str(buf, len));
606 return;
608 if (!tok_jmp(TOK_NAME)) {
609 struct name unkn = {""};
610 char *name = unkn.name;
611 int n;
612 strcpy(name, tok_id());
613 /* don't search for labels here */
614 if (!ncexpr && !caseexpr && tok_see() == ':')
615 return;
616 if ((n = local_find(name)) != -1) {
617 struct name *l = &locals[n];
618 o_local(l->addr);
619 ts_push_addr(&l->type);
620 return;
622 if ((n = global_find(name)) != -1) {
623 struct name *g = &globals[n];
624 o_sym(*g->elfname ? g->elfname : g->name);
625 ts_push_addr(&g->type);
626 return;
628 if (!enum_find(&n, name)) {
629 ts_push_bt(4 | BT_SIGNED);
630 o_num(n);
631 return;
633 if (tok_see() != '(')
634 err("unknown symbol\n");
635 global_add(&unkn);
636 ts_push_bt(LONGSZ);
637 o_sym(unkn.name);
638 return;
640 if (!tok_jmp('(')) {
641 struct type t;
642 if (!readtype(&t)) {
643 struct type o;
644 tok_expect(')');
645 readpre();
646 ts_pop_de(&o);
647 ts_push(&t);
648 if (!t.ptr || !o.ptr)
649 o_cast(TYPE_BT(&t));
650 } else {
651 readexpr();
652 tok_expect(')');
654 return;
658 static void arrayderef(void)
660 struct type t;
661 int sz;
662 ts_pop_de(NULL);
663 ts_pop(&t);
664 if (!(t.flags & T_ARRAY) && t.addr) {
665 o_tmpswap();
666 o_deref(TYPE_BT(&t));
667 o_tmpswap();
669 array2ptr(&t);
670 t.ptr--;
671 sz = type_totsz(&t);
672 t.addr = 1;
673 if (sz > 1) {
674 o_num(sz);
675 o_bop(O_MUL);
677 o_bop(O_ADD);
678 ts_push(&t);
681 static void inc_post(int op)
683 struct type t = ts[nts - 1];
684 /* pushing the value before inc */
685 o_tmpcopy();
686 ts_de(1);
687 o_load();
688 o_tmpswap();
690 /* increment by 1 or pointer size */
691 o_tmpcopy();
692 ts_push(&t);
693 ts_pop_de(&t);
694 o_num(t.ptr > 0 ? type_szde(&t) : 1);
695 o_bop(op);
697 /* assign back */
698 o_assign(TYPE_BT(&t));
699 o_tmpdrop(1);
702 static void readfield(void)
704 struct name *field;
705 struct type t;
706 tok_expect(TOK_NAME);
707 ts_pop(&t);
708 array2ptr(&t);
709 field = struct_field(t.id, tok_id());
710 if (field->addr) {
711 o_num(field->addr);
712 o_bop(O_ADD);
714 ts_push_addr(&field->type);
717 #define MAXFUNCS (1 << 10)
719 static struct funcinfo {
720 struct type args[MAXFIELDS];
721 struct type ret;
722 int nargs;
723 int varg;
724 } funcs[MAXFUNCS];
725 static int nfuncs;
727 static int func_create(struct type *ret, struct name *args, int nargs)
729 struct funcinfo *fi = &funcs[nfuncs++];
730 int i;
731 if (nfuncs >= MAXFUNCS)
732 err("nomem: MAXFUNCS reached!\n");
733 memcpy(&fi->ret, ret, sizeof(*ret));
734 for (i = 0; i < nargs; i++)
735 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
736 fi->nargs = nargs;
737 return fi - funcs;
740 static void readcall(void)
742 struct type t;
743 struct funcinfo *fi;
744 int argc = 0;
745 ts_pop(&t);
746 if (t.flags & T_FUNC && t.ptr > 0)
747 o_deref(LONGSZ);
748 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
749 if (tok_see() != ')') {
750 do {
751 readexpr();
752 ts_pop_de(NULL);
753 argc++;
754 } while (!tok_jmp(','));
756 tok_expect(')');
757 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
758 if (fi) {
759 if (TYPE_BT(&fi->ret))
760 o_cast(TYPE_BT(&fi->ret));
761 ts_push(&fi->ret);
762 } else {
763 ts_push_bt(4 | BT_SIGNED);
767 static void readpost(void)
769 readprimary();
770 while (1) {
771 if (!tok_jmp('[')) {
772 readexpr();
773 tok_expect(']');
774 arrayderef();
775 continue;
777 if (!tok_jmp('(')) {
778 readcall();
779 continue;
781 if (!tok_jmp(TOK2("++"))) {
782 inc_post(O_ADD);
783 continue;
785 if (!tok_jmp(TOK2("--"))) {
786 inc_post(O_SUB);
787 continue;
789 if (!tok_jmp('.')) {
790 readfield();
791 continue;
793 if (!tok_jmp(TOK2("->"))) {
794 ts_de(1);
795 readfield();
796 continue;
798 break;
802 static void inc_pre(int op)
804 struct type t;
805 readpre();
806 /* copy the destination */
807 o_tmpcopy();
808 ts_push(&ts[nts - 1]);
809 /* increment by 1 or pointer size */
810 ts_pop_de(&t);
811 o_num(t.ptr > 0 ? type_szde(&t) : 1);
812 o_bop(op);
813 /* assign the result */
814 o_assign(TYPE_BT(&t));
815 ts_de(0);
818 static void readpre(void)
820 if (!tok_jmp('&')) {
821 struct type type;
822 readpre();
823 ts_pop(&type);
824 if (!type.addr)
825 err("cannot use the address\n");
826 type.ptr++;
827 type.addr = 0;
828 ts_push(&type);
829 return;
831 if (!tok_jmp('*')) {
832 struct type t;
833 readpre();
834 ts_pop(&t);
835 array2ptr(&t);
836 if (!t.ptr)
837 err("dereferencing non-pointer\n");
838 if (t.addr)
839 o_deref(TYPE_BT(&t));
840 t.ptr--;
841 t.addr = 1;
842 ts_push(&t);
843 return;
845 if (!tok_jmp('!')) {
846 readpre();
847 ts_pop_de(NULL);
848 o_uop(O_LNOT);
849 ts_push_bt(4 | BT_SIGNED);
850 return;
852 if (!tok_jmp('-')) {
853 readpre();
854 ts_de(1);
855 o_uop(O_NEG);
856 return;
858 if (!tok_jmp('~')) {
859 readpre();
860 ts_de(1);
861 o_uop(O_NOT);
862 return;
864 if (!tok_jmp(TOK2("++"))) {
865 inc_pre(O_ADD);
866 return;
868 if (!tok_jmp(TOK2("--"))) {
869 inc_pre(O_SUB);
870 return;
872 if (!tok_jmp(TOK_SIZEOF)) {
873 struct type t;
874 int op = !tok_jmp('(');
875 if (readtype(&t)) {
876 nogen++;
877 if (op)
878 readexpr();
879 else
880 readpre();
881 nogen--;
882 ts_pop(&t);
884 ts_push_bt(4);
885 o_num(type_totsz(&t));
886 if (op)
887 tok_expect(')');
888 return;
890 readpost();
893 static void readmul(void)
895 readpre();
896 while (1) {
897 if (!tok_jmp('*')) {
898 readpre();
899 ts_binop(O_MUL);
900 continue;
902 if (!tok_jmp('/')) {
903 readpre();
904 ts_binop(O_DIV);
905 continue;
907 if (!tok_jmp('%')) {
908 readpre();
909 ts_binop(O_MOD);
910 continue;
912 break;
916 static void readadd(void)
918 readmul();
919 while (1) {
920 if (!tok_jmp('+')) {
921 readmul();
922 ts_addop(O_ADD);
923 continue;
925 if (!tok_jmp('-')) {
926 readmul();
927 ts_addop(O_SUB);
928 continue;
930 break;
934 static void shift(int op)
936 struct type t;
937 readadd();
938 ts_pop_de2(NULL, &t);
939 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
940 ts_push_bt(TYPE_BT(&t));
943 static void readshift(void)
945 readadd();
946 while (1) {
947 if (!tok_jmp(TOK2("<<"))) {
948 shift(O_SHL);
949 continue;
951 if (!tok_jmp(TOK2(">>"))) {
952 shift(O_SHR);
953 continue;
955 break;
959 static void cmp(int op)
961 struct type t1, t2;
962 int bt;
963 readshift();
964 ts_pop_de2(&t1, &t2);
965 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
966 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
967 ts_push_bt(4 | BT_SIGNED);
970 static void readcmp(void)
972 readshift();
973 while (1) {
974 if (!tok_jmp('<')) {
975 cmp(O_LT);
976 continue;
978 if (!tok_jmp('>')) {
979 cmp(O_GT);
980 continue;
982 if (!tok_jmp(TOK2("<="))) {
983 cmp(O_LE);
984 continue;
986 if (!tok_jmp(TOK2(">="))) {
987 cmp(O_GE);
988 continue;
990 break;
994 static void eq(int op)
996 readcmp();
997 ts_pop_de2(NULL, NULL);
998 o_bop(op);
999 ts_push_bt(4 | BT_SIGNED);
1002 static void readeq(void)
1004 readcmp();
1005 while (1) {
1006 if (!tok_jmp(TOK2("=="))) {
1007 eq(O_EQ);
1008 continue;
1010 if (!tok_jmp(TOK2("!="))) {
1011 eq(O_NEQ);
1012 continue;
1014 break;
1018 static void readbitand(void)
1020 readeq();
1021 while (!tok_jmp('&')) {
1022 readeq();
1023 ts_binop(O_AND);
1027 static void readxor(void)
1029 readbitand();
1030 while (!tok_jmp('^')) {
1031 readbitand();
1032 ts_binop(O_XOR);
1036 static void readbitor(void)
1038 readxor();
1039 while (!tok_jmp('|')) {
1040 readxor();
1041 ts_binop(O_OR);
1045 #define MAXCOND (1 << 7)
1047 static void readand(void)
1049 long conds[MAXCOND];
1050 int nconds = 0;
1051 long passed;
1052 int i;
1053 readbitor();
1054 if (tok_see() != TOK2("&&"))
1055 return;
1056 o_fork();
1057 ts_pop_de(NULL);
1058 conds[nconds++] = o_jz(0);
1059 while (!tok_jmp(TOK2("&&"))) {
1060 readbitor();
1061 ts_pop_de(NULL);
1062 conds[nconds++] = o_jz(0);
1064 o_num(1);
1065 o_forkpush();
1066 passed = o_jmp(0);
1067 for (i = 0; i < nconds; i++)
1068 o_filljmp(conds[i]);
1069 o_num(0);
1070 o_forkpush();
1071 o_forkjoin();
1072 o_filljmp(passed);
1073 ts_push_bt(4 | BT_SIGNED);
1076 static void reador(void)
1078 long conds[MAXCOND];
1079 int nconds = 0;
1080 long failed;
1081 int i;
1082 readand();
1083 if (tok_see() != TOK2("||"))
1084 return;
1085 o_fork();
1086 ts_pop_de(NULL);
1087 conds[nconds++] = o_jnz(0);
1088 while (!tok_jmp(TOK2("||"))) {
1089 readand();
1090 ts_pop_de(NULL);
1091 conds[nconds++] = o_jnz(0);
1093 o_num(0);
1094 o_forkpush();
1095 failed = o_jmp(0);
1096 for (i = 0; i < nconds; i++)
1097 o_filljmp(conds[i]);
1098 o_num(1);
1099 o_forkpush();
1100 o_forkjoin();
1101 o_filljmp(failed);
1102 ts_push_bt(4 | BT_SIGNED);
1105 static void readcexpr(void);
1107 static int readcexpr_const(void)
1109 long c;
1110 if (o_popnum(&c))
1111 return -1;
1112 if (!c)
1113 nogen++;
1114 readcexpr();
1115 /* both branches yield the same type; so ignore the first */
1116 ts_pop_de(NULL);
1117 tok_expect(':');
1118 if (c)
1119 nogen++;
1120 else
1121 nogen--;
1122 readcexpr();
1123 /* making sure t->addr == 0 on both branches */
1124 ts_de(1);
1125 if (c)
1126 nogen--;
1127 return 0;
1130 static void readcexpr(void)
1132 long l1, l2;
1133 reador();
1134 if (tok_jmp('?'))
1135 return;
1136 ncexpr++;
1137 ts_pop_de(NULL);
1138 o_fork();
1139 if (readcexpr_const()) {
1140 l1 = o_jz(0);
1141 readcexpr();
1142 /* both branches yield the same type; so ignore the first */
1143 ts_pop_de(NULL);
1144 o_forkpush();
1145 l2 = o_jmp(0);
1147 tok_expect(':');
1148 o_filljmp(l1);
1149 readcexpr();
1150 /* making sure t->addr == 0 on both branches */
1151 ts_de(1);
1152 o_forkpush();
1153 o_forkjoin();
1154 o_filljmp(l2);
1156 ncexpr--;
1159 static void opassign(int op, int ptrop)
1161 struct type t = ts[nts - 1];
1162 o_tmpcopy();
1163 ts_push(&t);
1164 readexpr();
1165 ts_addop(op);
1166 o_assign(TYPE_BT(&ts[nts - 2]));
1167 ts_pop(NULL);
1168 ts_de(0);
1171 static void doassign(void)
1173 struct type t = ts[nts - 1];
1174 if (!t.ptr && t.flags & T_STRUCT) {
1175 ts_pop(NULL);
1176 o_num(type_totsz(&t));
1177 o_memcpy();
1178 } else {
1179 ts_pop_de(NULL);
1180 o_assign(TYPE_BT(&ts[nts - 1]));
1181 ts_de(0);
1185 static void readexpr(void)
1187 readcexpr();
1188 if (!tok_jmp('=')) {
1189 readexpr();
1190 doassign();
1191 return;
1193 if (!tok_jmp(TOK2("+="))) {
1194 opassign(O_ADD, 1);
1195 return;
1197 if (!tok_jmp(TOK2("-="))) {
1198 opassign(O_SUB, 1);
1199 return;
1201 if (!tok_jmp(TOK2("*="))) {
1202 opassign(O_MUL, 0);
1203 return;
1205 if (!tok_jmp(TOK2("/="))) {
1206 opassign(O_DIV, 0);
1207 return;
1209 if (!tok_jmp(TOK2("%="))) {
1210 opassign(O_MOD, 0);
1211 return;
1213 if (!tok_jmp(TOK3("<<="))) {
1214 opassign(O_SHL, 0);
1215 return;
1217 if (!tok_jmp(TOK3(">>="))) {
1218 opassign(O_SHR, 0);
1219 return;
1221 if (!tok_jmp(TOK3("&="))) {
1222 opassign(O_AND, 0);
1223 return;
1225 if (!tok_jmp(TOK3("|="))) {
1226 opassign(O_OR, 0);
1227 return;
1229 if (!tok_jmp(TOK3("^="))) {
1230 opassign(O_XOR, 0);
1231 return;
1235 static void readestmt(void)
1237 do {
1238 o_tmpdrop(-1);
1239 nts = 0;
1240 readexpr();
1241 } while (!tok_jmp(','));
1244 static void o_localoff(long addr, int off)
1246 o_local(addr);
1247 if (off) {
1248 o_num(off);
1249 o_bop(O_ADD);
1253 static struct type *innertype(struct type *t)
1255 if (t->flags & T_ARRAY && !t->ptr)
1256 return innertype(&arrays[t->id].type);
1257 return t;
1260 static void initexpr(struct type *t, int off, void *obj,
1261 void (*set)(void *obj, int off, struct type *t))
1263 if (tok_jmp('{')) {
1264 set(obj, off, t);
1265 return;
1267 if (!t->ptr && t->flags & T_STRUCT) {
1268 struct structinfo *si = &structs[t->id];
1269 int i;
1270 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1271 struct name *field = &si->fields[i];
1272 if (!tok_jmp('.')) {
1273 tok_expect(TOK_NAME);
1274 field = struct_field(t->id, tok_id());
1275 tok_expect('=');
1277 initexpr(&field->type, off + field->addr, obj, set);
1278 if (tok_jmp(','))
1279 break;
1281 } else if (t->flags & T_ARRAY) {
1282 struct type *t_de = &arrays[t->id].type;
1283 int i;
1284 /* handling extra braces as in: char s[] = {"sth"} */
1285 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1286 set(obj, off, t);
1287 tok_expect('}');
1288 return;
1290 for (i = 0; tok_see() != '}'; i++) {
1291 long idx = i;
1292 struct type *it = t_de;
1293 if (!tok_jmp('[')) {
1294 readexpr();
1295 ts_pop_de(NULL);
1296 o_popnum(&idx);
1297 tok_expect(']');
1298 tok_expect('=');
1300 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1301 !(it->flags & T_ARRAY)))
1302 it = innertype(t_de);
1303 initexpr(it, off + type_totsz(it) * idx, obj, set);
1304 if (tok_jmp(','))
1305 break;
1308 tok_expect('}');
1311 static void jumpbrace(void)
1313 int depth = 0;
1314 while (tok_see() != '}' || depth--)
1315 if (tok_get() == '{')
1316 depth++;
1317 tok_expect('}');
1320 static int initsize(void)
1322 long addr = tok_addr();
1323 int n = 0;
1324 if (!tok_jmp(TOK_STR)) {
1325 n = tok_str(NULL);
1326 tok_jump(addr);
1327 return n;
1329 tok_expect('{');
1330 while (tok_jmp('}')) {
1331 long idx = n;
1332 if (!tok_jmp('[')) {
1333 readexpr();
1334 ts_pop_de(NULL);
1335 o_popnum(&idx);
1336 tok_expect(']');
1337 tok_expect('=');
1339 if (n < idx + 1)
1340 n = idx + 1;
1341 while (tok_see() != '}' && tok_see() != ',')
1342 if (tok_get() == '{')
1343 jumpbrace();
1344 tok_jmp(',');
1346 tok_jump(addr);
1347 return n;
1350 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1352 static void globalinit(void *obj, int off, struct type *t)
1354 struct name *name = obj;
1355 char *elfname = *name->elfname ? name->elfname : name->name;
1356 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1357 struct type *t_de = &arrays[t->id].type;
1358 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1359 char buf[BUFSIZE];
1360 int len;
1361 tok_expect(TOK_STR);
1362 len = tok_str(buf);
1363 memcpy((void *) name->addr + off, buf, len);
1364 return;
1367 readexpr();
1368 o_datset(elfname, off, TYPE_BT(t));
1369 ts_pop(NULL);
1372 static void globaldef(void *data, struct name *name, unsigned flags)
1374 struct type *t = &name->type;
1375 char *elfname = *name->elfname ? name->elfname : name->name;
1376 int sz;
1377 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1378 if (~flags & F_EXTERN)
1379 arrays[t->id].n = initsize();
1380 sz = type_totsz(t);
1381 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1382 if (flags & F_INIT)
1383 name->addr = (long) o_mkdat(elfname, sz, F_GLOBAL(flags));
1384 else
1385 o_mkbss(elfname, sz, F_GLOBAL(flags));
1387 global_add(name);
1388 if (flags & F_INIT)
1389 initexpr(t, 0, name, globalinit);
1392 static void localinit(void *obj, int off, struct type *t)
1394 long addr = *(long *) obj;
1395 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1396 struct type *t_de = &arrays[t->id].type;
1397 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1398 char buf[BUFSIZE];
1399 int len;
1400 tok_expect(TOK_STR);
1401 len = tok_str(buf);
1402 o_localoff(addr, off);
1403 o_sym(tmp_str(buf, len));
1404 o_num(len);
1405 o_memcpy();
1406 o_tmpdrop(1);
1407 return;
1410 o_localoff(addr, off);
1411 ts_push(t);
1412 readexpr();
1413 doassign();
1414 ts_pop(NULL);
1415 o_tmpdrop(1);
1418 /* current function name */
1419 static char func_name[NAMELEN];
1421 static void localdef(void *data, struct name *name, unsigned flags)
1423 struct type *t = &name->type;
1424 if ((flags & F_EXTERN) || (t->flags & T_FUNC) && !t->ptr) {
1425 global_add(name);
1426 return;
1428 if (flags & F_STATIC) {
1429 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1430 globaldef(data, name, flags);
1431 return;
1433 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1434 arrays[t->id].n = initsize();
1435 name->addr = o_mklocal(type_totsz(&name->type));
1436 local_add(name);
1437 if (flags & F_INIT) {
1438 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1439 o_local(name->addr);
1440 o_num(0);
1441 o_num(type_totsz(t));
1442 o_memset();
1443 o_tmpdrop(1);
1445 initexpr(t, 0, &name->addr, localinit);
1449 static void funcdef(char *name, struct type *type, struct name *args,
1450 int nargs, int varg, unsigned flags)
1452 struct name global = {""};
1453 int i;
1454 strcpy(global.name, name);
1455 strcpy(func_name, name);
1456 memcpy(&global.type, type, sizeof(*type));
1457 o_func_beg(name, nargs, F_GLOBAL(flags), varg);
1458 global_add(&global);
1459 for (i = 0; i < nargs; i++) {
1460 args[i].addr = o_arg2loc(i);
1461 local_add(&args[i]);
1465 static int readargs(struct name *args, int *varg)
1467 int nargs = 0;
1468 tok_expect('(');
1469 *varg = 0;
1470 while (tok_see() != ')') {
1471 if (!tok_jmp(TOK3("..."))) {
1472 *varg = 1;
1473 break;
1475 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1476 array2ptr(&args[nargs].type);
1477 nargs++;
1478 if (tok_jmp(','))
1479 break;
1481 tok_expect(')');
1482 if (nargs == 1 && !TYPE_BT(&args[0].type))
1483 return 0;
1484 return nargs;
1487 static int readname(struct type *main, char *name,
1488 struct type *base, unsigned flags)
1490 struct type tpool[3];
1491 int npool = 0;
1492 struct type *type = &tpool[npool++];
1493 struct type *func = NULL;
1494 struct type *ret = NULL;
1495 int arsz[10];
1496 int nar = 0;
1497 int i;
1498 memset(tpool, 0, sizeof(tpool));
1499 if (name)
1500 *name = '\0';
1501 if (!base) {
1502 if (basetype(type, &flags))
1503 return 1;
1504 } else {
1505 memcpy(type, base, sizeof(*base));
1507 readptrs(type);
1508 if (!tok_jmp('(')) {
1509 ret = type;
1510 type = &tpool[npool++];
1511 func = type;
1512 readptrs(type);
1514 if (!tok_jmp(TOK_NAME) && name)
1515 strcpy(name, tok_id());
1516 while (!tok_jmp('[')) {
1517 long n = 0;
1518 if (tok_jmp(']')) {
1519 readexpr();
1520 ts_pop_de(NULL);
1521 if (o_popnum(&n))
1522 err("const expr expected\n");
1523 tok_expect(']');
1525 arsz[nar++] = n;
1527 for (i = nar - 1; i >= 0; i--) {
1528 type->id = array_add(type, arsz[i]);
1529 if (func && i == nar - 1)
1530 func = &arrays[type->id].type;
1531 type->flags = T_ARRAY;
1532 type->bt = LONGSZ;
1533 type->ptr = 0;
1535 if (func)
1536 tok_expect(')');
1537 if (tok_see() == '(') {
1538 struct name args[MAXARGS] = {{""}};
1539 int varg = 0;
1540 int nargs = readargs(args, &varg);
1541 int fdef = !func;
1542 if (!func) {
1543 ret = type;
1544 type = &tpool[npool++];
1545 func = type;
1547 func->flags = T_FUNC;
1548 func->bt = LONGSZ;
1549 func->id = func_create(ret, args, nargs);
1550 if (fdef && tok_see() == '{') {
1551 funcdef(name, func, args, nargs, varg, flags);
1552 return 1;
1555 memcpy(main, type, sizeof(*type));
1556 return 0;
1559 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1560 void *data)
1562 struct type base;
1563 unsigned base_flags;
1564 if (basetype(&base, &base_flags))
1565 return 1;
1566 while (tok_see() != ';' && tok_see() != '{') {
1567 struct name name = {{""}};
1568 unsigned flags = base_flags;
1569 if (readname(&name.type, name.name, &base, flags))
1570 break;
1571 if (!tok_jmp('='))
1572 flags |= F_INIT;
1573 def(data, &name, flags);
1574 tok_jmp(',');
1576 return 0;
1579 static void typedefdef(void *data, struct name *name, unsigned flags)
1581 typedef_add(name->name, &name->type);
1584 static void readstmt(void);
1586 #define MAXCASES (1 << 7)
1588 static void readswitch(void)
1590 int break_beg = nbreaks;
1591 long val_addr = o_mklocal(LONGSZ);
1592 struct type t;
1593 int ncases = 0; /* number of case labels */
1594 long last_failed = -1; /* address of last failed jmp */
1595 long last_matched = -1; /* address of last walk through jmp */
1596 long default_addr = -1; /* address of the default label */
1597 tok_expect('(');
1598 readexpr();
1599 ts_pop_de(&t);
1600 o_local(val_addr);
1601 o_tmpswap();
1602 o_assign(TYPE_BT(&t));
1603 ts_de(0);
1604 o_tmpdrop(1);
1605 tok_expect(')');
1606 tok_expect('{');
1607 while (tok_jmp('}')) {
1608 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1609 readstmt();
1610 continue;
1612 if (ncases)
1613 last_matched = o_jmp(0);
1614 if (tok_get() == TOK_CASE) {
1615 if (last_failed >= 0)
1616 o_filljmp(last_failed);
1617 caseexpr = 1;
1618 readexpr();
1619 ts_pop_de(NULL);
1620 caseexpr = 0;
1621 o_local(val_addr);
1622 o_deref(TYPE_BT(&t));
1623 o_bop(O_EQ);
1624 last_failed = o_jz(0);
1625 o_tmpdrop(1);
1626 } else {
1627 if (!ncases)
1628 last_failed = o_jmp(0);
1629 default_addr = o_mklabel();
1631 tok_expect(':');
1632 if (last_matched >= 0)
1633 o_filljmp(last_matched);
1634 ncases++;
1636 o_rmlocal(val_addr, LONGSZ);
1637 if (last_failed >= 0)
1638 o_filljmp2(last_failed,
1639 default_addr >= 0 ? default_addr : o_mklabel());
1640 break_fill(o_mklabel(), break_beg);
1643 #define MAXGOTO (1 << 10)
1645 static struct gotoinfo {
1646 char name[NAMELEN];
1647 long addr;
1648 } gotos[MAXGOTO];
1649 static int ngotos;
1651 static struct labelinfo {
1652 char name[NAMELEN];
1653 long addr;
1654 } labels[MAXGOTO];
1655 static int nlabels;
1657 static void goto_add(char *name)
1659 strcpy(gotos[ngotos].name, name);
1660 gotos[ngotos++].addr = o_jmp(0);
1663 static void label_add(char *name)
1665 strcpy(labels[nlabels].name, name);
1666 labels[nlabels++].addr = o_mklabel();
1669 static void goto_fill(void)
1671 int i, j;
1672 for (i = 0; i < ngotos; i++)
1673 for (j = 0; j < nlabels; j++)
1674 if (!strcmp(gotos[i].name, labels[j].name)) {
1675 o_filljmp2(gotos[i].addr, labels[j].addr);
1676 break;
1680 static void readstmt(void)
1682 o_tmpdrop(-1);
1683 nts = 0;
1684 if (!tok_jmp('{')) {
1685 int _nlocals = nlocals;
1686 int _nglobals = nglobals;
1687 int _nenums = nenums;
1688 int _ntypedefs = ntypedefs;
1689 int _nstructs = nstructs;
1690 int _nfuncs = nfuncs;
1691 int _narrays = narrays;
1692 while (tok_jmp('}'))
1693 readstmt();
1694 nlocals = _nlocals;
1695 nenums = _nenums;
1696 ntypedefs = _ntypedefs;
1697 nstructs = _nstructs;
1698 nfuncs = _nfuncs;
1699 narrays = _narrays;
1700 nglobals = _nglobals;
1701 return;
1703 if (!readdefs(localdef, NULL)) {
1704 tok_expect(';');
1705 return;
1707 if (!tok_jmp(TOK_TYPEDEF)) {
1708 readdefs(typedefdef, NULL);
1709 tok_expect(';');
1710 return;
1712 if (!tok_jmp(TOK_IF)) {
1713 long l1, l2;
1714 tok_expect('(');
1715 readexpr();
1716 tok_expect(')');
1717 ts_pop_de(NULL);
1718 l1 = o_jz(0);
1719 readstmt();
1720 if (!tok_jmp(TOK_ELSE)) {
1721 l2 = o_jmp(0);
1722 o_filljmp(l1);
1723 readstmt();
1724 o_filljmp(l2);
1725 } else {
1726 o_filljmp(l1);
1728 return;
1730 if (!tok_jmp(TOK_WHILE)) {
1731 long l1, l2;
1732 int break_beg = nbreaks;
1733 int continue_beg = ncontinues;
1734 l1 = o_mklabel();
1735 tok_expect('(');
1736 readexpr();
1737 tok_expect(')');
1738 ts_pop_de(NULL);
1739 l2 = o_jz(0);
1740 readstmt();
1741 o_jmp(l1);
1742 o_filljmp(l2);
1743 break_fill(o_mklabel(), break_beg);
1744 continue_fill(l1, continue_beg);
1745 return;
1747 if (!tok_jmp(TOK_DO)) {
1748 long l1, l2;
1749 int break_beg = nbreaks;
1750 int continue_beg = ncontinues;
1751 l1 = o_mklabel();
1752 readstmt();
1753 tok_expect(TOK_WHILE);
1754 tok_expect('(');
1755 l2 = o_mklabel();
1756 readexpr();
1757 ts_pop_de(NULL);
1758 o_jnz(l1);
1759 tok_expect(')');
1760 break_fill(o_mklabel(), break_beg);
1761 continue_fill(l2, continue_beg);
1762 tok_expect(';');
1763 return;
1765 if (!tok_jmp(TOK_FOR)) {
1766 long l_check, l_jump, j_fail, j_pass;
1767 int break_beg = nbreaks;
1768 int continue_beg = ncontinues;
1769 int has_cond = 0;
1770 tok_expect('(');
1771 if (tok_see() != ';')
1772 readestmt();
1773 tok_expect(';');
1774 l_check = o_mklabel();
1775 if (tok_see() != ';') {
1776 readestmt();
1777 ts_pop_de(NULL);
1778 j_fail = o_jz(0);
1779 has_cond = 1;
1781 tok_expect(';');
1782 j_pass = o_jmp(0);
1783 l_jump = o_mklabel();
1784 if (tok_see() != ')')
1785 readestmt();
1786 tok_expect(')');
1787 o_jmp(l_check);
1788 o_filljmp(j_pass);
1789 readstmt();
1790 o_jmp(l_jump);
1791 if (has_cond)
1792 o_filljmp(j_fail);
1793 break_fill(o_mklabel(), break_beg);
1794 continue_fill(l_jump, continue_beg);
1795 return;
1797 if (!tok_jmp(TOK_SWITCH)) {
1798 readswitch();
1799 return;
1801 if (!tok_jmp(TOK_RETURN)) {
1802 int ret = tok_see() != ';';
1803 if (ret) {
1804 readexpr();
1805 ts_pop_de(NULL);
1807 tok_expect(';');
1808 o_ret(ret);
1809 return;
1811 if (!tok_jmp(TOK_BREAK)) {
1812 tok_expect(';');
1813 breaks[nbreaks++] = o_jmp(0);
1814 return;
1816 if (!tok_jmp(TOK_CONTINUE)) {
1817 tok_expect(';');
1818 continues[ncontinues++] = o_jmp(0);
1819 return;
1821 if (!tok_jmp(TOK_GOTO)) {
1822 tok_expect(TOK_NAME);
1823 goto_add(tok_id());
1824 tok_expect(';');
1825 return;
1827 readestmt();
1828 /* labels */
1829 if (!tok_jmp(':')) {
1830 label_add(tok_id());
1831 return;
1833 tok_expect(';');
1836 static void readdecl(void)
1838 if (!tok_jmp(TOK_TYPEDEF)) {
1839 readdefs(typedefdef, NULL);
1840 tok_expect(';');
1841 return;
1843 readdefs(globaldef, NULL);
1844 if (tok_see() == '{') {
1845 readstmt();
1846 goto_fill();
1847 o_func_end();
1848 func_name[0] = '\0';
1849 nlocals = 0;
1850 ngotos = 0;
1851 nlabels = 0;
1852 return;
1854 tok_expect(';');
1857 static void parse(void)
1859 while (tok_see() != TOK_EOF)
1860 readdecl();
1863 static void compat_macros(void)
1865 cpp_define("__STDC__", "");
1866 cpp_define("__arm__", "");
1867 cpp_define("__linux__", "");
1869 /* ignored keywords */
1870 cpp_define("const", "");
1871 cpp_define("register", "");
1872 cpp_define("volatile", "");
1873 cpp_define("inline", "");
1874 cpp_define("restrict", "");
1875 cpp_define("__inline__", "");
1876 cpp_define("__restrict__", "");
1877 cpp_define("__attribute__(x)", "");
1878 cpp_define("__builtin_va_list__", "long");
1881 int main(int argc, char *argv[])
1883 char obj[128] = "";
1884 int ofd;
1885 int i = 1;
1886 compat_macros();
1887 while (i < argc && argv[i][0] == '-') {
1888 if (argv[i][1] == 'I')
1889 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1890 if (argv[i][1] == 'D') {
1891 char *name = argv[i] + 2;
1892 char *def = "";
1893 char *eq = strchr(name, '=');
1894 if (eq) {
1895 *eq = '\0';
1896 def = eq + 1;
1898 cpp_define(name, def);
1900 if (argv[i][1] == 'o')
1901 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1902 i++;
1904 if (i == argc)
1905 die("neatcc: no file given\n");
1906 if (cpp_init(argv[i]))
1907 die("neatcc: cannot open <%s>\n", argv[i]);
1908 parse();
1909 if (!*obj) {
1910 strcpy(obj, argv[i]);
1911 obj[strlen(obj) - 1] = 'o';
1913 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1914 o_write(ofd);
1915 close(ofd);
1916 return 0;