ncc: support (expr, expr) expression
[neatcc.git] / ncc.c
blob2714efc60350d25862e2ea7e4d2f93cbd43500be
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 while (tok_jmp(')')) {
653 tok_expect(',');
654 ts_pop(NULL);
655 o_tmpdrop(1);
656 readexpr();
659 return;
663 static void arrayderef(void)
665 struct type t;
666 int sz;
667 ts_pop_de(NULL);
668 ts_pop(&t);
669 if (!(t.flags & T_ARRAY) && t.addr) {
670 o_tmpswap();
671 o_deref(TYPE_BT(&t));
672 o_tmpswap();
674 array2ptr(&t);
675 t.ptr--;
676 sz = type_totsz(&t);
677 t.addr = 1;
678 if (sz > 1) {
679 o_num(sz);
680 o_bop(O_MUL);
682 o_bop(O_ADD);
683 ts_push(&t);
686 static void inc_post(int op)
688 struct type t = ts[nts - 1];
689 /* pushing the value before inc */
690 o_tmpcopy();
691 ts_de(1);
692 o_load();
693 o_tmpswap();
695 /* increment by 1 or pointer size */
696 o_tmpcopy();
697 ts_push(&t);
698 ts_pop_de(&t);
699 o_num(t.ptr > 0 ? type_szde(&t) : 1);
700 o_bop(op);
702 /* assign back */
703 o_assign(TYPE_BT(&t));
704 o_tmpdrop(1);
707 static void readfield(void)
709 struct name *field;
710 struct type t;
711 tok_expect(TOK_NAME);
712 ts_pop(&t);
713 array2ptr(&t);
714 field = struct_field(t.id, tok_id());
715 if (field->addr) {
716 o_num(field->addr);
717 o_bop(O_ADD);
719 ts_push_addr(&field->type);
722 #define MAXFUNCS (1 << 10)
724 static struct funcinfo {
725 struct type args[MAXFIELDS];
726 struct type ret;
727 int nargs;
728 int varg;
729 } funcs[MAXFUNCS];
730 static int nfuncs;
732 static int func_create(struct type *ret, struct name *args, int nargs)
734 struct funcinfo *fi = &funcs[nfuncs++];
735 int i;
736 if (nfuncs >= MAXFUNCS)
737 err("nomem: MAXFUNCS reached!\n");
738 memcpy(&fi->ret, ret, sizeof(*ret));
739 for (i = 0; i < nargs; i++)
740 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
741 fi->nargs = nargs;
742 return fi - funcs;
745 static void readcall(void)
747 struct type t;
748 struct funcinfo *fi;
749 int argc = 0;
750 ts_pop(&t);
751 if (t.flags & T_FUNC && t.ptr > 0)
752 o_deref(LONGSZ);
753 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
754 if (tok_see() != ')') {
755 do {
756 readexpr();
757 ts_pop_de(NULL);
758 argc++;
759 } while (!tok_jmp(','));
761 tok_expect(')');
762 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
763 if (fi) {
764 if (TYPE_BT(&fi->ret))
765 o_cast(TYPE_BT(&fi->ret));
766 ts_push(&fi->ret);
767 } else {
768 ts_push_bt(4 | BT_SIGNED);
772 static void readpost(void)
774 readprimary();
775 while (1) {
776 if (!tok_jmp('[')) {
777 readexpr();
778 tok_expect(']');
779 arrayderef();
780 continue;
782 if (!tok_jmp('(')) {
783 readcall();
784 continue;
786 if (!tok_jmp(TOK2("++"))) {
787 inc_post(O_ADD);
788 continue;
790 if (!tok_jmp(TOK2("--"))) {
791 inc_post(O_SUB);
792 continue;
794 if (!tok_jmp('.')) {
795 readfield();
796 continue;
798 if (!tok_jmp(TOK2("->"))) {
799 ts_de(1);
800 readfield();
801 continue;
803 break;
807 static void inc_pre(int op)
809 struct type t;
810 readpre();
811 /* copy the destination */
812 o_tmpcopy();
813 ts_push(&ts[nts - 1]);
814 /* increment by 1 or pointer size */
815 ts_pop_de(&t);
816 o_num(t.ptr > 0 ? type_szde(&t) : 1);
817 o_bop(op);
818 /* assign the result */
819 o_assign(TYPE_BT(&t));
820 ts_de(0);
823 static void readpre(void)
825 if (!tok_jmp('&')) {
826 struct type type;
827 readpre();
828 ts_pop(&type);
829 if (!type.addr)
830 err("cannot use the address\n");
831 type.ptr++;
832 type.addr = 0;
833 ts_push(&type);
834 return;
836 if (!tok_jmp('*')) {
837 struct type t;
838 readpre();
839 ts_pop(&t);
840 array2ptr(&t);
841 if (!t.ptr)
842 err("dereferencing non-pointer\n");
843 if (t.addr)
844 o_deref(TYPE_BT(&t));
845 t.ptr--;
846 t.addr = 1;
847 ts_push(&t);
848 return;
850 if (!tok_jmp('!')) {
851 readpre();
852 ts_pop_de(NULL);
853 o_uop(O_LNOT);
854 ts_push_bt(4 | BT_SIGNED);
855 return;
857 if (!tok_jmp('-')) {
858 readpre();
859 ts_de(1);
860 o_uop(O_NEG);
861 return;
863 if (!tok_jmp('~')) {
864 readpre();
865 ts_de(1);
866 o_uop(O_NOT);
867 return;
869 if (!tok_jmp(TOK2("++"))) {
870 inc_pre(O_ADD);
871 return;
873 if (!tok_jmp(TOK2("--"))) {
874 inc_pre(O_SUB);
875 return;
877 if (!tok_jmp(TOK_SIZEOF)) {
878 struct type t;
879 int op = !tok_jmp('(');
880 if (readtype(&t)) {
881 nogen++;
882 if (op)
883 readexpr();
884 else
885 readpre();
886 nogen--;
887 ts_pop(&t);
889 ts_push_bt(4);
890 o_num(type_totsz(&t));
891 if (op)
892 tok_expect(')');
893 return;
895 readpost();
898 static void readmul(void)
900 readpre();
901 while (1) {
902 if (!tok_jmp('*')) {
903 readpre();
904 ts_binop(O_MUL);
905 continue;
907 if (!tok_jmp('/')) {
908 readpre();
909 ts_binop(O_DIV);
910 continue;
912 if (!tok_jmp('%')) {
913 readpre();
914 ts_binop(O_MOD);
915 continue;
917 break;
921 static void readadd(void)
923 readmul();
924 while (1) {
925 if (!tok_jmp('+')) {
926 readmul();
927 ts_addop(O_ADD);
928 continue;
930 if (!tok_jmp('-')) {
931 readmul();
932 ts_addop(O_SUB);
933 continue;
935 break;
939 static void shift(int op)
941 struct type t;
942 readadd();
943 ts_pop_de2(NULL, &t);
944 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
945 ts_push_bt(TYPE_BT(&t));
948 static void readshift(void)
950 readadd();
951 while (1) {
952 if (!tok_jmp(TOK2("<<"))) {
953 shift(O_SHL);
954 continue;
956 if (!tok_jmp(TOK2(">>"))) {
957 shift(O_SHR);
958 continue;
960 break;
964 static void cmp(int op)
966 struct type t1, t2;
967 int bt;
968 readshift();
969 ts_pop_de2(&t1, &t2);
970 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
971 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
972 ts_push_bt(4 | BT_SIGNED);
975 static void readcmp(void)
977 readshift();
978 while (1) {
979 if (!tok_jmp('<')) {
980 cmp(O_LT);
981 continue;
983 if (!tok_jmp('>')) {
984 cmp(O_GT);
985 continue;
987 if (!tok_jmp(TOK2("<="))) {
988 cmp(O_LE);
989 continue;
991 if (!tok_jmp(TOK2(">="))) {
992 cmp(O_GE);
993 continue;
995 break;
999 static void eq(int op)
1001 readcmp();
1002 ts_pop_de2(NULL, NULL);
1003 o_bop(op);
1004 ts_push_bt(4 | BT_SIGNED);
1007 static void readeq(void)
1009 readcmp();
1010 while (1) {
1011 if (!tok_jmp(TOK2("=="))) {
1012 eq(O_EQ);
1013 continue;
1015 if (!tok_jmp(TOK2("!="))) {
1016 eq(O_NEQ);
1017 continue;
1019 break;
1023 static void readbitand(void)
1025 readeq();
1026 while (!tok_jmp('&')) {
1027 readeq();
1028 ts_binop(O_AND);
1032 static void readxor(void)
1034 readbitand();
1035 while (!tok_jmp('^')) {
1036 readbitand();
1037 ts_binop(O_XOR);
1041 static void readbitor(void)
1043 readxor();
1044 while (!tok_jmp('|')) {
1045 readxor();
1046 ts_binop(O_OR);
1050 #define MAXCOND (1 << 7)
1052 static void readand(void)
1054 long conds[MAXCOND];
1055 int nconds = 0;
1056 long passed;
1057 int i;
1058 readbitor();
1059 if (tok_see() != TOK2("&&"))
1060 return;
1061 o_fork();
1062 ts_pop_de(NULL);
1063 conds[nconds++] = o_jz(0);
1064 while (!tok_jmp(TOK2("&&"))) {
1065 readbitor();
1066 ts_pop_de(NULL);
1067 conds[nconds++] = o_jz(0);
1069 o_num(1);
1070 o_forkpush();
1071 passed = o_jmp(0);
1072 for (i = 0; i < nconds; i++)
1073 o_filljmp(conds[i]);
1074 o_num(0);
1075 o_forkpush();
1076 o_forkjoin();
1077 o_filljmp(passed);
1078 ts_push_bt(4 | BT_SIGNED);
1081 static void reador(void)
1083 long conds[MAXCOND];
1084 int nconds = 0;
1085 long failed;
1086 int i;
1087 readand();
1088 if (tok_see() != TOK2("||"))
1089 return;
1090 o_fork();
1091 ts_pop_de(NULL);
1092 conds[nconds++] = o_jnz(0);
1093 while (!tok_jmp(TOK2("||"))) {
1094 readand();
1095 ts_pop_de(NULL);
1096 conds[nconds++] = o_jnz(0);
1098 o_num(0);
1099 o_forkpush();
1100 failed = o_jmp(0);
1101 for (i = 0; i < nconds; i++)
1102 o_filljmp(conds[i]);
1103 o_num(1);
1104 o_forkpush();
1105 o_forkjoin();
1106 o_filljmp(failed);
1107 ts_push_bt(4 | BT_SIGNED);
1110 static void readcexpr(void);
1112 static int readcexpr_const(void)
1114 long c;
1115 if (o_popnum(&c))
1116 return -1;
1117 if (!c)
1118 nogen++;
1119 readcexpr();
1120 /* both branches yield the same type; so ignore the first */
1121 ts_pop_de(NULL);
1122 tok_expect(':');
1123 if (c)
1124 nogen++;
1125 else
1126 nogen--;
1127 readcexpr();
1128 /* making sure t->addr == 0 on both branches */
1129 ts_de(1);
1130 if (c)
1131 nogen--;
1132 return 0;
1135 static void readcexpr(void)
1137 long l1, l2;
1138 reador();
1139 if (tok_jmp('?'))
1140 return;
1141 ncexpr++;
1142 ts_pop_de(NULL);
1143 o_fork();
1144 if (readcexpr_const()) {
1145 l1 = o_jz(0);
1146 readcexpr();
1147 /* both branches yield the same type; so ignore the first */
1148 ts_pop_de(NULL);
1149 o_forkpush();
1150 l2 = o_jmp(0);
1152 tok_expect(':');
1153 o_filljmp(l1);
1154 readcexpr();
1155 /* making sure t->addr == 0 on both branches */
1156 ts_de(1);
1157 o_forkpush();
1158 o_forkjoin();
1159 o_filljmp(l2);
1161 ncexpr--;
1164 static void opassign(int op, int ptrop)
1166 struct type t = ts[nts - 1];
1167 o_tmpcopy();
1168 ts_push(&t);
1169 readexpr();
1170 ts_addop(op);
1171 o_assign(TYPE_BT(&ts[nts - 2]));
1172 ts_pop(NULL);
1173 ts_de(0);
1176 static void doassign(void)
1178 struct type t = ts[nts - 1];
1179 if (!t.ptr && t.flags & T_STRUCT) {
1180 ts_pop(NULL);
1181 o_num(type_totsz(&t));
1182 o_memcpy();
1183 } else {
1184 ts_pop_de(NULL);
1185 o_assign(TYPE_BT(&ts[nts - 1]));
1186 ts_de(0);
1190 static void readexpr(void)
1192 readcexpr();
1193 if (!tok_jmp('=')) {
1194 readexpr();
1195 doassign();
1196 return;
1198 if (!tok_jmp(TOK2("+="))) {
1199 opassign(O_ADD, 1);
1200 return;
1202 if (!tok_jmp(TOK2("-="))) {
1203 opassign(O_SUB, 1);
1204 return;
1206 if (!tok_jmp(TOK2("*="))) {
1207 opassign(O_MUL, 0);
1208 return;
1210 if (!tok_jmp(TOK2("/="))) {
1211 opassign(O_DIV, 0);
1212 return;
1214 if (!tok_jmp(TOK2("%="))) {
1215 opassign(O_MOD, 0);
1216 return;
1218 if (!tok_jmp(TOK3("<<="))) {
1219 opassign(O_SHL, 0);
1220 return;
1222 if (!tok_jmp(TOK3(">>="))) {
1223 opassign(O_SHR, 0);
1224 return;
1226 if (!tok_jmp(TOK3("&="))) {
1227 opassign(O_AND, 0);
1228 return;
1230 if (!tok_jmp(TOK3("|="))) {
1231 opassign(O_OR, 0);
1232 return;
1234 if (!tok_jmp(TOK3("^="))) {
1235 opassign(O_XOR, 0);
1236 return;
1240 static void readestmt(void)
1242 do {
1243 o_tmpdrop(-1);
1244 nts = 0;
1245 readexpr();
1246 } while (!tok_jmp(','));
1249 static void o_localoff(long addr, int off)
1251 o_local(addr);
1252 if (off) {
1253 o_num(off);
1254 o_bop(O_ADD);
1258 static struct type *innertype(struct type *t)
1260 if (t->flags & T_ARRAY && !t->ptr)
1261 return innertype(&arrays[t->id].type);
1262 return t;
1265 static void initexpr(struct type *t, int off, void *obj,
1266 void (*set)(void *obj, int off, struct type *t))
1268 if (tok_jmp('{')) {
1269 set(obj, off, t);
1270 return;
1272 if (!t->ptr && t->flags & T_STRUCT) {
1273 struct structinfo *si = &structs[t->id];
1274 int i;
1275 for (i = 0; i < si->nfields && tok_see() != '}'; i++) {
1276 struct name *field = &si->fields[i];
1277 if (!tok_jmp('.')) {
1278 tok_expect(TOK_NAME);
1279 field = struct_field(t->id, tok_id());
1280 tok_expect('=');
1282 initexpr(&field->type, off + field->addr, obj, set);
1283 if (tok_jmp(','))
1284 break;
1286 } else if (t->flags & T_ARRAY) {
1287 struct type *t_de = &arrays[t->id].type;
1288 int i;
1289 /* handling extra braces as in: char s[] = {"sth"} */
1290 if (TYPE_SZ(t_de) == 1 && tok_see() == TOK_STR) {
1291 set(obj, off, t);
1292 tok_expect('}');
1293 return;
1295 for (i = 0; tok_see() != '}'; i++) {
1296 long idx = i;
1297 struct type *it = t_de;
1298 if (!tok_jmp('[')) {
1299 readexpr();
1300 ts_pop_de(NULL);
1301 o_popnum(&idx);
1302 tok_expect(']');
1303 tok_expect('=');
1305 if (tok_see() != '{' && (tok_see() != TOK_STR ||
1306 !(it->flags & T_ARRAY)))
1307 it = innertype(t_de);
1308 initexpr(it, off + type_totsz(it) * idx, obj, set);
1309 if (tok_jmp(','))
1310 break;
1313 tok_expect('}');
1316 static void jumpbrace(void)
1318 int depth = 0;
1319 while (tok_see() != '}' || depth--)
1320 if (tok_get() == '{')
1321 depth++;
1322 tok_expect('}');
1325 static int initsize(void)
1327 long addr = tok_addr();
1328 int n = 0;
1329 if (!tok_jmp(TOK_STR)) {
1330 n = tok_str(NULL);
1331 tok_jump(addr);
1332 return n;
1334 tok_expect('{');
1335 while (tok_jmp('}')) {
1336 long idx = n;
1337 if (!tok_jmp('[')) {
1338 readexpr();
1339 ts_pop_de(NULL);
1340 o_popnum(&idx);
1341 tok_expect(']');
1342 tok_expect('=');
1344 if (n < idx + 1)
1345 n = idx + 1;
1346 while (tok_see() != '}' && tok_see() != ',')
1347 if (tok_get() == '{')
1348 jumpbrace();
1349 tok_jmp(',');
1351 tok_jump(addr);
1352 return n;
1355 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1357 static void globalinit(void *obj, int off, struct type *t)
1359 struct name *name = obj;
1360 char *elfname = *name->elfname ? name->elfname : name->name;
1361 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1362 struct type *t_de = &arrays[t->id].type;
1363 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1364 char buf[BUFSIZE];
1365 int len;
1366 tok_expect(TOK_STR);
1367 len = tok_str(buf);
1368 memcpy((void *) name->addr + off, buf, len);
1369 return;
1372 readexpr();
1373 o_datset(elfname, off, TYPE_BT(t));
1374 ts_pop(NULL);
1377 static void globaldef(void *data, struct name *name, unsigned flags)
1379 struct type *t = &name->type;
1380 char *elfname = *name->elfname ? name->elfname : name->name;
1381 int sz;
1382 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1383 if (~flags & F_EXTERN)
1384 arrays[t->id].n = initsize();
1385 sz = type_totsz(t);
1386 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1387 if (flags & F_INIT)
1388 name->addr = (long) o_mkdat(elfname, sz, F_GLOBAL(flags));
1389 else
1390 o_mkbss(elfname, sz, F_GLOBAL(flags));
1392 global_add(name);
1393 if (flags & F_INIT)
1394 initexpr(t, 0, name, globalinit);
1397 static void localinit(void *obj, int off, struct type *t)
1399 long addr = *(long *) obj;
1400 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1401 struct type *t_de = &arrays[t->id].type;
1402 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1403 char buf[BUFSIZE];
1404 int len;
1405 tok_expect(TOK_STR);
1406 len = tok_str(buf);
1407 o_localoff(addr, off);
1408 o_sym(tmp_str(buf, len));
1409 o_num(len);
1410 o_memcpy();
1411 o_tmpdrop(1);
1412 return;
1415 o_localoff(addr, off);
1416 ts_push(t);
1417 readexpr();
1418 doassign();
1419 ts_pop(NULL);
1420 o_tmpdrop(1);
1423 /* current function name */
1424 static char func_name[NAMELEN];
1426 static void localdef(void *data, struct name *name, unsigned flags)
1428 struct type *t = &name->type;
1429 if ((flags & F_EXTERN) || (t->flags & T_FUNC) && !t->ptr) {
1430 global_add(name);
1431 return;
1433 if (flags & F_STATIC) {
1434 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1435 globaldef(data, name, flags);
1436 return;
1438 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1439 arrays[t->id].n = initsize();
1440 name->addr = o_mklocal(type_totsz(&name->type));
1441 local_add(name);
1442 if (flags & F_INIT) {
1443 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1444 o_local(name->addr);
1445 o_num(0);
1446 o_num(type_totsz(t));
1447 o_memset();
1448 o_tmpdrop(1);
1450 initexpr(t, 0, &name->addr, localinit);
1454 static void funcdef(char *name, struct type *type, struct name *args,
1455 int nargs, int varg, unsigned flags)
1457 struct name global = {""};
1458 int i;
1459 strcpy(global.name, name);
1460 strcpy(func_name, name);
1461 memcpy(&global.type, type, sizeof(*type));
1462 o_func_beg(name, nargs, F_GLOBAL(flags), varg);
1463 global_add(&global);
1464 for (i = 0; i < nargs; i++) {
1465 args[i].addr = o_arg2loc(i);
1466 local_add(&args[i]);
1470 static int readargs(struct name *args, int *varg)
1472 int nargs = 0;
1473 tok_expect('(');
1474 *varg = 0;
1475 while (tok_see() != ')') {
1476 if (!tok_jmp(TOK3("..."))) {
1477 *varg = 1;
1478 break;
1480 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1481 array2ptr(&args[nargs].type);
1482 nargs++;
1483 if (tok_jmp(','))
1484 break;
1486 tok_expect(')');
1487 if (nargs == 1 && !TYPE_BT(&args[0].type))
1488 return 0;
1489 return nargs;
1492 static int readname(struct type *main, char *name,
1493 struct type *base, unsigned flags)
1495 struct type tpool[3];
1496 int npool = 0;
1497 struct type *type = &tpool[npool++];
1498 struct type *func = NULL;
1499 struct type *ret = NULL;
1500 int arsz[10];
1501 int nar = 0;
1502 int i;
1503 memset(tpool, 0, sizeof(tpool));
1504 if (name)
1505 *name = '\0';
1506 if (!base) {
1507 if (basetype(type, &flags))
1508 return 1;
1509 } else {
1510 memcpy(type, base, sizeof(*base));
1512 readptrs(type);
1513 if (!tok_jmp('(')) {
1514 ret = type;
1515 type = &tpool[npool++];
1516 func = type;
1517 readptrs(type);
1519 if (!tok_jmp(TOK_NAME) && name)
1520 strcpy(name, tok_id());
1521 while (!tok_jmp('[')) {
1522 long n = 0;
1523 if (tok_jmp(']')) {
1524 readexpr();
1525 ts_pop_de(NULL);
1526 if (o_popnum(&n))
1527 err("const expr expected\n");
1528 tok_expect(']');
1530 arsz[nar++] = n;
1532 for (i = nar - 1; i >= 0; i--) {
1533 type->id = array_add(type, arsz[i]);
1534 if (func && i == nar - 1)
1535 func = &arrays[type->id].type;
1536 type->flags = T_ARRAY;
1537 type->bt = LONGSZ;
1538 type->ptr = 0;
1540 if (func)
1541 tok_expect(')');
1542 if (tok_see() == '(') {
1543 struct name args[MAXARGS] = {{""}};
1544 int varg = 0;
1545 int nargs = readargs(args, &varg);
1546 int fdef = !func;
1547 if (!func) {
1548 ret = type;
1549 type = &tpool[npool++];
1550 func = type;
1552 func->flags = T_FUNC;
1553 func->bt = LONGSZ;
1554 func->id = func_create(ret, args, nargs);
1555 if (fdef && tok_see() == '{') {
1556 funcdef(name, func, args, nargs, varg, flags);
1557 return 1;
1560 memcpy(main, type, sizeof(*type));
1561 return 0;
1564 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1565 void *data)
1567 struct type base;
1568 unsigned base_flags;
1569 if (basetype(&base, &base_flags))
1570 return 1;
1571 while (tok_see() != ';' && tok_see() != '{') {
1572 struct name name = {{""}};
1573 unsigned flags = base_flags;
1574 if (readname(&name.type, name.name, &base, flags))
1575 break;
1576 if (!tok_jmp('='))
1577 flags |= F_INIT;
1578 def(data, &name, flags);
1579 tok_jmp(',');
1581 return 0;
1584 static void typedefdef(void *data, struct name *name, unsigned flags)
1586 typedef_add(name->name, &name->type);
1589 static void readstmt(void);
1591 #define MAXCASES (1 << 7)
1593 static void readswitch(void)
1595 int break_beg = nbreaks;
1596 long val_addr = o_mklocal(LONGSZ);
1597 struct type t;
1598 int ncases = 0; /* number of case labels */
1599 long last_failed = -1; /* address of last failed jmp */
1600 long last_matched = -1; /* address of last walk through jmp */
1601 long default_addr = -1; /* address of the default label */
1602 tok_expect('(');
1603 readexpr();
1604 ts_pop_de(&t);
1605 o_local(val_addr);
1606 o_tmpswap();
1607 o_assign(TYPE_BT(&t));
1608 ts_de(0);
1609 o_tmpdrop(1);
1610 tok_expect(')');
1611 tok_expect('{');
1612 while (tok_jmp('}')) {
1613 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1614 readstmt();
1615 continue;
1617 if (ncases)
1618 last_matched = o_jmp(0);
1619 if (tok_get() == TOK_CASE) {
1620 if (last_failed >= 0)
1621 o_filljmp(last_failed);
1622 caseexpr = 1;
1623 readexpr();
1624 ts_pop_de(NULL);
1625 caseexpr = 0;
1626 o_local(val_addr);
1627 o_deref(TYPE_BT(&t));
1628 o_bop(O_EQ);
1629 last_failed = o_jz(0);
1630 o_tmpdrop(1);
1631 } else {
1632 if (!ncases)
1633 last_failed = o_jmp(0);
1634 default_addr = o_mklabel();
1636 tok_expect(':');
1637 if (last_matched >= 0)
1638 o_filljmp(last_matched);
1639 ncases++;
1641 o_rmlocal(val_addr, LONGSZ);
1642 if (last_failed >= 0)
1643 o_filljmp2(last_failed,
1644 default_addr >= 0 ? default_addr : o_mklabel());
1645 break_fill(o_mklabel(), break_beg);
1648 #define MAXGOTO (1 << 10)
1650 static struct gotoinfo {
1651 char name[NAMELEN];
1652 long addr;
1653 } gotos[MAXGOTO];
1654 static int ngotos;
1656 static struct labelinfo {
1657 char name[NAMELEN];
1658 long addr;
1659 } labels[MAXGOTO];
1660 static int nlabels;
1662 static void goto_add(char *name)
1664 strcpy(gotos[ngotos].name, name);
1665 gotos[ngotos++].addr = o_jmp(0);
1668 static void label_add(char *name)
1670 strcpy(labels[nlabels].name, name);
1671 labels[nlabels++].addr = o_mklabel();
1674 static void goto_fill(void)
1676 int i, j;
1677 for (i = 0; i < ngotos; i++)
1678 for (j = 0; j < nlabels; j++)
1679 if (!strcmp(gotos[i].name, labels[j].name)) {
1680 o_filljmp2(gotos[i].addr, labels[j].addr);
1681 break;
1685 static void readstmt(void)
1687 o_tmpdrop(-1);
1688 nts = 0;
1689 if (!tok_jmp('{')) {
1690 int _nlocals = nlocals;
1691 int _nglobals = nglobals;
1692 int _nenums = nenums;
1693 int _ntypedefs = ntypedefs;
1694 int _nstructs = nstructs;
1695 int _nfuncs = nfuncs;
1696 int _narrays = narrays;
1697 while (tok_jmp('}'))
1698 readstmt();
1699 nlocals = _nlocals;
1700 nenums = _nenums;
1701 ntypedefs = _ntypedefs;
1702 nstructs = _nstructs;
1703 nfuncs = _nfuncs;
1704 narrays = _narrays;
1705 nglobals = _nglobals;
1706 return;
1708 if (!readdefs(localdef, NULL)) {
1709 tok_expect(';');
1710 return;
1712 if (!tok_jmp(TOK_TYPEDEF)) {
1713 readdefs(typedefdef, NULL);
1714 tok_expect(';');
1715 return;
1717 if (!tok_jmp(TOK_IF)) {
1718 long l1, l2;
1719 tok_expect('(');
1720 readexpr();
1721 tok_expect(')');
1722 ts_pop_de(NULL);
1723 l1 = o_jz(0);
1724 readstmt();
1725 if (!tok_jmp(TOK_ELSE)) {
1726 l2 = o_jmp(0);
1727 o_filljmp(l1);
1728 readstmt();
1729 o_filljmp(l2);
1730 } else {
1731 o_filljmp(l1);
1733 return;
1735 if (!tok_jmp(TOK_WHILE)) {
1736 long l1, l2;
1737 int break_beg = nbreaks;
1738 int continue_beg = ncontinues;
1739 l1 = o_mklabel();
1740 tok_expect('(');
1741 readexpr();
1742 tok_expect(')');
1743 ts_pop_de(NULL);
1744 l2 = o_jz(0);
1745 readstmt();
1746 o_jmp(l1);
1747 o_filljmp(l2);
1748 break_fill(o_mklabel(), break_beg);
1749 continue_fill(l1, continue_beg);
1750 return;
1752 if (!tok_jmp(TOK_DO)) {
1753 long l1, l2;
1754 int break_beg = nbreaks;
1755 int continue_beg = ncontinues;
1756 l1 = o_mklabel();
1757 readstmt();
1758 tok_expect(TOK_WHILE);
1759 tok_expect('(');
1760 l2 = o_mklabel();
1761 readexpr();
1762 ts_pop_de(NULL);
1763 o_jnz(l1);
1764 tok_expect(')');
1765 break_fill(o_mklabel(), break_beg);
1766 continue_fill(l2, continue_beg);
1767 tok_expect(';');
1768 return;
1770 if (!tok_jmp(TOK_FOR)) {
1771 long l_check, l_jump, j_fail, j_pass;
1772 int break_beg = nbreaks;
1773 int continue_beg = ncontinues;
1774 int has_cond = 0;
1775 tok_expect('(');
1776 if (tok_see() != ';')
1777 readestmt();
1778 tok_expect(';');
1779 l_check = o_mklabel();
1780 if (tok_see() != ';') {
1781 readestmt();
1782 ts_pop_de(NULL);
1783 j_fail = o_jz(0);
1784 has_cond = 1;
1786 tok_expect(';');
1787 j_pass = o_jmp(0);
1788 l_jump = o_mklabel();
1789 if (tok_see() != ')')
1790 readestmt();
1791 tok_expect(')');
1792 o_jmp(l_check);
1793 o_filljmp(j_pass);
1794 readstmt();
1795 o_jmp(l_jump);
1796 if (has_cond)
1797 o_filljmp(j_fail);
1798 break_fill(o_mklabel(), break_beg);
1799 continue_fill(l_jump, continue_beg);
1800 return;
1802 if (!tok_jmp(TOK_SWITCH)) {
1803 readswitch();
1804 return;
1806 if (!tok_jmp(TOK_RETURN)) {
1807 int ret = tok_see() != ';';
1808 if (ret) {
1809 readexpr();
1810 ts_pop_de(NULL);
1812 tok_expect(';');
1813 o_ret(ret);
1814 return;
1816 if (!tok_jmp(TOK_BREAK)) {
1817 tok_expect(';');
1818 breaks[nbreaks++] = o_jmp(0);
1819 return;
1821 if (!tok_jmp(TOK_CONTINUE)) {
1822 tok_expect(';');
1823 continues[ncontinues++] = o_jmp(0);
1824 return;
1826 if (!tok_jmp(TOK_GOTO)) {
1827 tok_expect(TOK_NAME);
1828 goto_add(tok_id());
1829 tok_expect(';');
1830 return;
1832 readestmt();
1833 /* labels */
1834 if (!tok_jmp(':')) {
1835 label_add(tok_id());
1836 return;
1838 tok_expect(';');
1841 static void readdecl(void)
1843 if (!tok_jmp(TOK_TYPEDEF)) {
1844 readdefs(typedefdef, NULL);
1845 tok_expect(';');
1846 return;
1848 readdefs(globaldef, NULL);
1849 if (tok_see() == '{') {
1850 readstmt();
1851 goto_fill();
1852 o_func_end();
1853 func_name[0] = '\0';
1854 nlocals = 0;
1855 ngotos = 0;
1856 nlabels = 0;
1857 return;
1859 tok_expect(';');
1862 static void parse(void)
1864 while (tok_see() != TOK_EOF)
1865 readdecl();
1868 static void compat_macros(void)
1870 cpp_define("__STDC__", "");
1871 cpp_define("__linux__", "");
1872 #ifdef NEATCC_ARM
1873 cpp_define("__arm__", "");
1874 #else
1875 cpp_define("__i386__", "");
1876 #endif
1878 /* ignored keywords */
1879 cpp_define("const", "");
1880 cpp_define("register", "");
1881 cpp_define("volatile", "");
1882 cpp_define("inline", "");
1883 cpp_define("restrict", "");
1884 cpp_define("__inline__", "");
1885 cpp_define("__restrict__", "");
1886 cpp_define("__attribute__(x)", "");
1887 cpp_define("__builtin_va_list__", "long");
1890 int main(int argc, char *argv[])
1892 char obj[128] = "";
1893 int ofd;
1894 int i = 1;
1895 compat_macros();
1896 while (i < argc && argv[i][0] == '-') {
1897 if (argv[i][1] == 'I')
1898 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1899 if (argv[i][1] == 'D') {
1900 char *name = argv[i] + 2;
1901 char *def = "";
1902 char *eq = strchr(name, '=');
1903 if (eq) {
1904 *eq = '\0';
1905 def = eq + 1;
1907 cpp_define(name, def);
1909 if (argv[i][1] == 'o')
1910 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1911 i++;
1913 if (i == argc)
1914 die("neatcc: no file given\n");
1915 if (cpp_init(argv[i]))
1916 die("neatcc: cannot open <%s>\n", argv[i]);
1917 parse();
1918 if (!*obj) {
1919 strcpy(obj, argv[i]);
1920 obj[strlen(obj) - 1] = 'o';
1922 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1923 o_write(ofd);
1924 close(ofd);
1925 return 0;