ncc: make sure t->addr == 0 before calling o_popnum()
[neatcc.git] / ncc.c
blob33e6bfffdaf87ecf98010d00e08863ec7f66f7d3
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 char err[1 << 7];
105 int len = cpp_loc(err, tok_addr());
106 strcpy(err + len, msg);
107 die(err);
110 struct name {
111 char name[NAMELEN];
112 char elfname[NAMELEN]; /* local elf name for static variables in function */
113 struct type type;
114 long addr; /* local stack offset, global data addr, struct offset */
117 static struct name locals[MAXLOCALS];
118 static int nlocals;
119 static struct name globals[MAXGLOBALS];
120 static int nglobals;
122 static void local_add(struct name *name)
124 if (nlocals >= MAXLOCALS)
125 err("nomem: MAXLOCALS reached!\n");
126 memcpy(&locals[nlocals++], name, sizeof(*name));
129 static int global_find(char *name)
131 int i;
132 for (i = 0; i < nglobals; i++)
133 if (!strcmp(name, globals[i].name))
134 return i;
135 return -1;
138 static void global_add(struct name *name)
140 int found = global_find(name->name);
141 int i = found == -1 ? nglobals++ : found;
142 if (nglobals >= MAXGLOBALS)
143 err("nomem: MAXGLOBALS reached!\n");
144 memcpy(&globals[i], name, sizeof(*name));
147 #define MAXENUMS (1 << 10)
149 static struct enumval {
150 char name[NAMELEN];
151 int n;
152 } enums[MAXENUMS];
153 static int nenums;
155 static void enum_add(char *name, int val)
157 struct enumval *ev = &enums[nenums++];
158 if (nenums >= MAXENUMS)
159 err("nomem: MAXENUMS reached!\n");
160 strcpy(ev->name, name);
161 ev->n = val;
164 static int enum_find(int *val, char *name)
166 int i;
167 for (i = nenums - 1; i >= 0; --i)
168 if (!strcmp(name, enums[i].name)) {
169 *val = enums[i].n;
170 return 0;
172 return 1;
175 #define MAXTYPEDEFS (1 << 10)
177 static struct typdefinfo {
178 char name[NAMELEN];
179 struct type type;
180 } typedefs[MAXTYPEDEFS];
181 static int ntypedefs;
183 static void typedef_add(char *name, struct type *type)
185 struct typdefinfo *ti = &typedefs[ntypedefs++];
186 if (ntypedefs >= MAXTYPEDEFS)
187 err("nomem: MAXTYPEDEFS reached!\n");
188 strcpy(ti->name, name);
189 memcpy(&ti->type, type, sizeof(*type));
192 static int typedef_find(char *name)
194 int i;
195 for (i = ntypedefs - 1; i >= 0; --i)
196 if (!strcmp(name, typedefs[i].name))
197 return i;
198 return -1;
201 #define MAXARRAYS (1 << 10)
203 static struct array {
204 struct type type;
205 int n;
206 } arrays[MAXARRAYS];
207 static int narrays;
209 static int array_add(struct type *type, int n)
211 struct array *a = &arrays[narrays++];
212 if (narrays >= MAXARRAYS)
213 err("nomem: MAXARRAYS reached!\n");
214 memcpy(&a->type, type, sizeof(*type));
215 a->n = n;
216 return a - arrays;
219 static void array2ptr(struct type *t)
221 if (t->flags & T_ARRAY && !t->ptr) {
222 memcpy(t, &arrays[t->id].type, sizeof(*t));
223 t->ptr++;
227 #define MAXSTRUCTS (1 << 10)
228 #define MAXFIELDS (1 << 7)
230 static struct structinfo {
231 char name[NAMELEN];
232 struct name fields[MAXFIELDS];
233 int nfields;
234 int isunion;
235 int size;
236 } structs[MAXSTRUCTS];
237 static int nstructs;
239 static int struct_find(char *name, int isunion)
241 int i;
242 for (i = nstructs - 1; i >= 0; --i)
243 if (*structs[i].name && !strcmp(name, structs[i].name) &&
244 structs[i].isunion == isunion)
245 return i;
246 i = nstructs++;
247 if (nstructs >= MAXSTRUCTS)
248 err("nomem: MAXTYPES reached!\n");
249 memset(&structs[i], 0, sizeof(structs[i]));
250 strcpy(structs[i].name, name);
251 structs[i].isunion = isunion;
252 return i;
255 static struct name *struct_field(int id, char *name)
257 struct structinfo *si = &structs[id];
258 int i;
259 for (i = 0; i < si->nfields; i++)
260 if (!strcmp(name, si->fields[i].name))
261 return &si->fields[i];
262 err("field not found\n");
265 #define MAXBREAK (1 << 7)
267 static long breaks[MAXBREAK];
268 static int nbreaks;
269 static long continues[MAXBREAK];
270 static int ncontinues;
272 static void break_fill(long addr, int till)
274 int i;
275 for (i = till; i < nbreaks; i++)
276 o_filljmp2(breaks[i], addr);
277 nbreaks = till;
280 static void continue_fill(long addr, int till)
282 int i;
283 for (i = till; i < ncontinues; i++)
284 o_filljmp2(continues[i], addr);
285 ncontinues = till;
288 static int type_totsz(struct type *t)
290 if (t->ptr)
291 return LONGSZ;
292 if (t->flags & T_ARRAY)
293 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
294 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
297 static unsigned type_szde(struct type *t)
299 struct type de = *t;
300 array2ptr(&de);
301 de.ptr--;
302 return type_totsz(&de);
305 static void ts_de(int deref)
307 struct type *t = &ts[nts - 1];
308 if (deref && t->addr && (!(t->flags & T_ARRAY) || (t->ptr)))
309 o_deref(TYPE_BT(t));
310 t->addr = 0;
313 static void ts_pop_de(struct type *t)
315 struct type de;
316 if (!t)
317 t = &de;
318 ts_pop(t);
319 array2ptr(t);
320 if (t->addr && (t->ptr || !(t->flags & T_FUNC)))
321 o_deref(TYPE_BT(t));
322 t->addr = 0;
325 static void ts_pop_de2(struct type *t1, struct type *t2)
327 ts_pop_de(t1);
328 o_tmpswap();
329 ts_pop_de(t2);
330 o_tmpswap();
333 static int tok_jmp(int tok)
335 if (tok_see() != tok)
336 return 1;
337 tok_get();
338 return 0;
341 static void tok_expect(int tok)
343 if (tok_get() != tok)
344 err("syntax error\n");
347 static unsigned bt_op(unsigned bt1, unsigned bt2)
349 unsigned s1 = BT_SZ(bt1);
350 unsigned s2 = BT_SZ(bt2);
351 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
354 static void ts_binop(int op)
356 struct type t1, t2;
357 int bt;
358 ts_pop_de2(&t1, &t2);
359 if (op == O_DIV || op == O_MOD)
360 bt = TYPE_BT(&t2);
361 else
362 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
363 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
364 ts_push_bt(bt);
367 static void ts_addop(int op)
369 struct type t1, t2;
370 ts_pop_de2(&t1, &t2);
371 if (!t1.ptr && !t2.ptr) {
372 o_bop(op);
373 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
374 return;
376 if (t1.ptr && !t2.ptr)
377 o_tmpswap();
378 if (!t1.ptr && t2.ptr)
379 if (type_szde(&t2) > 1) {
380 o_num(type_szde(&t2));
381 o_bop(O_MUL);
383 if (t1.ptr && !t2.ptr)
384 o_tmpswap();
385 o_bop(op);
386 if (t1.ptr && t2.ptr) {
387 int sz = type_szde(&t1);
388 if (sz > 1) {
389 o_num(sz);
390 o_bop(O_DIV);
392 ts_push_bt(4 | BT_SIGNED);
393 } else {
394 ts_push(t1.ptr ? &t1 : &t2);
398 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
399 #define MIN(a, b) ((a) < (b) ? (a) : (b))
401 static int type_alignment(struct type *t)
403 if (t->flags & T_ARRAY && !t->ptr)
404 return type_alignment(&arrays[t->id].type);
405 if (t->flags & T_STRUCT && !t->ptr)
406 return type_alignment(&structs[t->id].fields[0].type);
407 return MIN(LONGSZ, type_totsz(t));
410 static void structdef(void *data, struct name *name, unsigned flags)
412 struct structinfo *si = data;
413 if (si->isunion) {
414 name->addr = 0;
415 if (si->size < type_totsz(&name->type))
416 si->size = type_totsz(&name->type);
417 } else {
418 struct type *t = &name->type;
419 int alignment = type_alignment(t);
420 if (t->flags & T_ARRAY && !t->ptr)
421 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
422 si->size = ALIGN(si->size, alignment);
423 name->addr = si->size;
424 si->size += type_totsz(&name->type);
426 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
429 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
431 static int struct_create(char *name, int isunion)
433 int id = struct_find(name, isunion);
434 struct structinfo *si = &structs[id];
435 tok_expect('{');
436 while (tok_jmp('}')) {
437 readdefs(structdef, si);
438 tok_expect(';');
440 return id;
443 static void readexpr(void);
445 static void enum_create(void)
447 long n = 0;
448 tok_expect('{');
449 while (tok_jmp('}')) {
450 char name[NAMELEN];
451 tok_expect(TOK_NAME);
452 strcpy(name, tok_id());
453 if (!tok_jmp('=')) {
454 readexpr();
455 ts_pop_de(NULL);
456 if (o_popnum(&n))
457 err("const expr expected!\n");
459 enum_add(name, n++);
460 tok_jmp(',');
464 static int basetype(struct type *type, unsigned *flags)
466 int sign = 1;
467 int size = 4;
468 int done = 0;
469 int i = 0;
470 int isunion;
471 char name[NAMELEN] = "";
472 *flags = 0;
473 type->flags = 0;
474 type->ptr = 0;
475 type->addr = 0;
476 while (!done) {
477 switch (tok_see()) {
478 case TOK_STATIC:
479 *flags |= F_STATIC;
480 break;
481 case TOK_EXTERN:
482 *flags |= F_EXTERN;
483 break;
484 case TOK_VOID:
485 sign = 0;
486 size = 0;
487 done = 1;
488 break;
489 case TOK_INT:
490 done = 1;
491 break;
492 case TOK_CHAR:
493 size = 1;
494 done = 1;
495 break;
496 case TOK_SHORT:
497 size = 2;
498 break;
499 case TOK_LONG:
500 size = LONGSZ;
501 break;
502 case TOK_SIGNED:
503 break;
504 case TOK_UNSIGNED:
505 sign = 0;
506 break;
507 case TOK_UNION:
508 case TOK_STRUCT:
509 isunion = tok_get() == TOK_UNION;
510 if (!tok_jmp(TOK_NAME))
511 strcpy(name, tok_id());
512 if (tok_see() == '{')
513 type->id = struct_create(name, isunion);
514 else
515 type->id = struct_find(name, isunion);
516 type->flags |= T_STRUCT;
517 type->bt = LONGSZ;
518 return 0;
519 case TOK_ENUM:
520 tok_get();
521 tok_jmp(TOK_NAME);
522 if (tok_see() == '{')
523 enum_create();
524 type->bt = 4 | BT_SIGNED;
525 return 0;
526 default:
527 if (tok_see() == TOK_NAME) {
528 int id = typedef_find(tok_id());
529 if (id != -1) {
530 tok_get();
531 memcpy(type, &typedefs[id].type,
532 sizeof(*type));
533 return 0;
536 if (!i)
537 return 1;
538 done = 1;
539 continue;
541 i++;
542 tok_get();
544 type->bt = size | (sign ? BT_SIGNED : 0);
545 return 0;
548 static int readname(struct type *main, char *name,
549 struct type *base, unsigned flags);
551 static int readtype(struct type *type)
553 return readname(type, NULL, NULL, 0);
556 static void readptrs(struct type *type)
558 while (!tok_jmp('*')) {
559 type->ptr++;
560 if (!type->bt)
561 type->bt = 1;
565 /* used to differenciate labels from case and cond exprs */
566 static int ncexpr;
567 static int caseexpr;
569 static void readpre(void);
571 static char *tmp_str(char *buf, int len)
573 static char name[NAMELEN];
574 static int id;
575 void *dat;
576 sprintf(name, "__neatcc.s%d", id++);
577 dat = o_mkdat(name, len, 0);
578 memcpy(dat, buf, len);
579 return name;
582 static void readprimary(void)
584 int i;
585 if (!tok_jmp(TOK_NUM)) {
586 long n;
587 int bt = tok_num(&n);
588 ts_push_bt(bt);
589 o_num(n);
590 return;
592 if (!tok_jmp(TOK_STR)) {
593 struct type t;
594 char buf[BUFSIZE];
595 int len;
596 t.bt = 1 | BT_SIGNED;
597 t.ptr = 1;
598 t.addr = 0;
599 t.flags = 0;
600 ts_push(&t);
601 len = tok_str(buf);
602 o_sym(tmp_str(buf, len));
603 return;
605 if (!tok_jmp(TOK_NAME)) {
606 struct name unkn = {""};
607 char *name = unkn.name;
608 int n;
609 strcpy(name, tok_id());
610 /* don't search for labels here */
611 if (!ncexpr && !caseexpr && tok_see() == ':')
612 return;
613 for (i = nlocals - 1; i >= 0; --i) {
614 struct type *t = &locals[i].type;
615 if (!strcmp(locals[i].name, name)) {
616 o_local(locals[i].addr);
617 ts_push_addr(t);
618 return;
621 if ((n = global_find(name)) != -1) {
622 struct name *g = &globals[n];
623 struct type *t = &g->type;
624 char *elfname = *g->elfname ? g->elfname : g->name;
625 o_sym(elfname);
626 ts_push_addr(t);
627 return;
629 if (!enum_find(&n, name)) {
630 ts_push_bt(4 | BT_SIGNED);
631 o_num(n);
632 return;
634 if (tok_see() != '(')
635 err("unknown symbol\n");
636 global_add(&unkn);
637 ts_push_bt(LONGSZ);
638 o_sym(unkn.name);
639 return;
641 if (!tok_jmp('(')) {
642 struct type t;
643 if (!readtype(&t)) {
644 struct type o;
645 tok_expect(')');
646 readpre();
647 ts_pop_de(&o);
648 ts_push(&t);
649 if (!t.ptr || !o.ptr)
650 o_cast(TYPE_BT(&t));
651 } else {
652 readexpr();
653 tok_expect(')');
655 return;
659 static void arrayderef(void)
661 struct type t;
662 int sz;
663 ts_pop_de(NULL);
664 ts_pop(&t);
665 if (!(t.flags & T_ARRAY) && t.addr) {
666 o_tmpswap();
667 o_deref(TYPE_BT(&t));
668 o_tmpswap();
670 array2ptr(&t);
671 t.ptr--;
672 sz = type_totsz(&t);
673 t.addr = 1;
674 if (sz > 1) {
675 o_num(sz);
676 o_bop(O_MUL);
678 o_bop(O_ADD);
679 ts_push(&t);
682 static void inc_post(int op)
684 struct type t = ts[nts - 1];
685 /* pushing the value before inc */
686 o_tmpcopy();
687 ts_de(1);
688 o_load();
689 o_tmpswap();
691 /* increment by 1 or pointer size */
692 o_tmpcopy();
693 ts_push(&t);
694 ts_pop_de(&t);
695 o_num(t.ptr > 0 ? type_szde(&t) : 1);
696 o_bop(op);
698 /* assign back */
699 o_assign(TYPE_BT(&t));
700 o_tmpdrop(1);
703 static void readfield(void)
705 struct name *field;
706 struct type t;
707 tok_expect(TOK_NAME);
708 ts_pop(&t);
709 array2ptr(&t);
710 field = struct_field(t.id, tok_id());
711 if (field->addr) {
712 o_num(field->addr);
713 o_bop(O_ADD);
715 ts_push_addr(&field->type);
718 #define MAXFUNCS (1 << 10)
720 static struct funcinfo {
721 struct type args[MAXFIELDS];
722 struct type ret;
723 int nargs;
724 int varg;
725 } funcs[MAXFUNCS];
726 static int nfuncs;
728 static int func_create(struct type *ret, struct name *args, int nargs)
730 struct funcinfo *fi = &funcs[nfuncs++];
731 int i;
732 if (nfuncs >= MAXFUNCS)
733 err("nomem: MAXFUNCS reached!\n");
734 memcpy(&fi->ret, ret, sizeof(*ret));
735 for (i = 0; i < nargs; i++)
736 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
737 fi->nargs = nargs;
738 return fi - funcs;
741 static void readcall(void)
743 struct type t;
744 struct funcinfo *fi;
745 int argc = 0;
746 ts_pop(&t);
747 if (t.flags & T_FUNC && t.ptr > 0)
748 o_deref(LONGSZ);
749 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
750 if (tok_see() != ')') {
751 do {
752 readexpr();
753 ts_pop_de(NULL);
754 argc++;
755 } while (!tok_jmp(','));
757 tok_expect(')');
758 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
759 if (fi) {
760 if (TYPE_BT(&fi->ret))
761 o_cast(TYPE_BT(&fi->ret));
762 ts_push(&fi->ret);
763 } else {
764 ts_push_bt(4 | BT_SIGNED);
768 static void readpost(void)
770 readprimary();
771 while (1) {
772 if (!tok_jmp('[')) {
773 readexpr();
774 tok_expect(']');
775 arrayderef();
776 continue;
778 if (!tok_jmp('(')) {
779 readcall();
780 continue;
782 if (!tok_jmp(TOK2("++"))) {
783 inc_post(O_ADD);
784 continue;
786 if (!tok_jmp(TOK2("--"))) {
787 inc_post(O_SUB);
788 continue;
790 if (!tok_jmp('.')) {
791 readfield();
792 continue;
794 if (!tok_jmp(TOK2("->"))) {
795 ts_de(1);
796 readfield();
797 continue;
799 break;
803 static void inc_pre(int op)
805 struct type t;
806 readpre();
807 /* copy the destination */
808 o_tmpcopy();
809 ts_push(&ts[nts - 1]);
810 /* increment by 1 or pointer size */
811 ts_pop_de(&t);
812 o_num(t.ptr > 0 ? type_szde(&t) : 1);
813 o_bop(op);
814 /* assign the result */
815 o_assign(TYPE_BT(&t));
816 ts_de(0);
819 static void readpre(void)
821 if (!tok_jmp('&')) {
822 struct type type;
823 readpre();
824 ts_pop(&type);
825 if (!type.addr)
826 die("cannot use the address\n");
827 type.ptr++;
828 type.addr = 0;
829 ts_push(&type);
830 return;
832 if (!tok_jmp('*')) {
833 struct type t;
834 readpre();
835 ts_pop(&t);
836 array2ptr(&t);
837 if (!t.ptr)
838 err("dereferencing non-pointer\n");
839 if (t.addr)
840 o_deref(TYPE_BT(&t));
841 t.ptr--;
842 t.addr = 1;
843 ts_push(&t);
844 return;
846 if (!tok_jmp('!')) {
847 readpre();
848 ts_pop_de(NULL);
849 o_uop(O_LNOT);
850 ts_push_bt(4 | BT_SIGNED);
851 return;
853 if (!tok_jmp('-')) {
854 readpre();
855 ts_de(1);
856 o_uop(O_NEG);
857 return;
859 if (!tok_jmp('~')) {
860 readpre();
861 ts_de(1);
862 o_uop(O_NOT);
863 return;
865 if (!tok_jmp(TOK2("++"))) {
866 inc_pre(O_ADD);
867 return;
869 if (!tok_jmp(TOK2("--"))) {
870 inc_pre(O_SUB);
871 return;
873 if (!tok_jmp(TOK_SIZEOF)) {
874 struct type t;
875 int op = !tok_jmp('(');
876 if (readtype(&t)) {
877 nogen++;
878 readexpr();
879 nogen--;
880 ts_pop(&t);
882 ts_push_bt(4);
883 o_num(type_totsz(&t));
884 if (op)
885 tok_expect(')');
886 return;
888 readpost();
891 static void readmul(void)
893 readpre();
894 while (1) {
895 if (!tok_jmp('*')) {
896 readpre();
897 ts_binop(O_MUL);
898 continue;
900 if (!tok_jmp('/')) {
901 readpre();
902 ts_binop(O_DIV);
903 continue;
905 if (!tok_jmp('%')) {
906 readpre();
907 ts_binop(O_MOD);
908 continue;
910 break;
914 static void readadd(void)
916 readmul();
917 while (1) {
918 if (!tok_jmp('+')) {
919 readmul();
920 ts_addop(O_ADD);
921 continue;
923 if (!tok_jmp('-')) {
924 readmul();
925 ts_addop(O_SUB);
926 continue;
928 break;
932 static void shift(int op)
934 struct type t;
935 readadd();
936 ts_pop_de2(NULL, &t);
937 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
938 ts_push_bt(TYPE_BT(&t));
941 static void readshift(void)
943 readadd();
944 while (1) {
945 if (!tok_jmp(TOK2("<<"))) {
946 shift(O_SHL);
947 continue;
949 if (!tok_jmp(TOK2(">>"))) {
950 shift(O_SHR);
951 continue;
953 break;
957 static void cmp(int op)
959 struct type t1, t2;
960 int bt;
961 readshift();
962 ts_pop_de2(&t1, &t2);
963 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
964 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
965 ts_push_bt(4 | BT_SIGNED);
968 static void readcmp(void)
970 readshift();
971 while (1) {
972 if (!tok_jmp('<')) {
973 cmp(O_LT);
974 continue;
976 if (!tok_jmp('>')) {
977 cmp(O_GT);
978 continue;
980 if (!tok_jmp(TOK2("<="))) {
981 cmp(O_LE);
982 continue;
984 if (!tok_jmp(TOK2(">="))) {
985 cmp(O_GE);
986 continue;
988 break;
992 static void eq(int op)
994 readcmp();
995 ts_pop_de2(NULL, NULL);
996 o_bop(op);
997 ts_push_bt(4 | BT_SIGNED);
1000 static void readeq(void)
1002 readcmp();
1003 while (1) {
1004 if (!tok_jmp(TOK2("=="))) {
1005 eq(O_EQ);
1006 continue;
1008 if (!tok_jmp(TOK2("!="))) {
1009 eq(O_NEQ);
1010 continue;
1012 break;
1016 static void readbitand(void)
1018 readeq();
1019 while (!tok_jmp('&')) {
1020 readeq();
1021 ts_binop(O_AND);
1025 static void readxor(void)
1027 readbitand();
1028 while (!tok_jmp('^')) {
1029 readbitand();
1030 ts_binop(O_XOR);
1034 static void readbitor(void)
1036 readxor();
1037 while (!tok_jmp('|')) {
1038 readxor();
1039 ts_binop(O_OR);
1043 #define MAXCOND (1 << 7)
1045 static void readand(void)
1047 long conds[MAXCOND];
1048 int nconds = 0;
1049 long passed;
1050 int i;
1051 readbitor();
1052 if (tok_see() != TOK2("&&"))
1053 return;
1054 o_fork();
1055 ts_pop_de(NULL);
1056 conds[nconds++] = o_jz(0);
1057 while (!tok_jmp(TOK2("&&"))) {
1058 readbitor();
1059 ts_pop_de(NULL);
1060 conds[nconds++] = o_jz(0);
1062 o_num(1);
1063 o_forkpush();
1064 passed = o_jmp(0);
1065 for (i = 0; i < nconds; i++)
1066 o_filljmp(conds[i]);
1067 o_num(0);
1068 o_forkpush();
1069 o_forkjoin();
1070 o_filljmp(passed);
1071 ts_push_bt(4 | BT_SIGNED);
1074 static void reador(void)
1076 long conds[MAXCOND];
1077 int nconds = 0;
1078 long failed;
1079 int i;
1080 readand();
1081 if (tok_see() != TOK2("||"))
1082 return;
1083 o_fork();
1084 ts_pop_de(NULL);
1085 conds[nconds++] = o_jnz(0);
1086 while (!tok_jmp(TOK2("||"))) {
1087 readand();
1088 ts_pop_de(NULL);
1089 conds[nconds++] = o_jnz(0);
1091 o_num(0);
1092 o_forkpush();
1093 failed = o_jmp(0);
1094 for (i = 0; i < nconds; i++)
1095 o_filljmp(conds[i]);
1096 o_num(1);
1097 o_forkpush();
1098 o_forkjoin();
1099 o_filljmp(failed);
1100 ts_push_bt(4 | BT_SIGNED);
1103 static int readcexpr_const(void)
1105 long c;
1106 if (o_popnum(&c))
1107 return -1;
1108 if (!c)
1109 nogen++;
1110 reador();
1111 /* both branches yield the same type; so ignore the first */
1112 ts_pop_de(NULL);
1113 tok_expect(':');
1114 if (c)
1115 nogen++;
1116 else
1117 nogen--;
1118 reador();
1119 /* making sure t->addr == 0 on both branches */
1120 ts_de(1);
1121 if (c)
1122 nogen--;
1123 return 0;
1126 static void readcexpr(void)
1128 long l1, l2;
1129 reador();
1130 if (tok_jmp('?'))
1131 return;
1132 ncexpr++;
1133 ts_pop_de(NULL);
1134 o_fork();
1135 if (readcexpr_const()) {
1136 l1 = o_jz(0);
1137 reador();
1138 /* both branches yield the same type; so ignore the first */
1139 ts_pop_de(NULL);
1140 o_forkpush();
1141 l2 = o_jmp(0);
1143 tok_expect(':');
1144 o_filljmp(l1);
1145 reador();
1146 /* making sure t->addr == 0 on both branches */
1147 ts_de(1);
1148 o_forkpush();
1149 o_forkjoin();
1150 o_filljmp(l2);
1152 ncexpr--;
1155 static void opassign(int op, int ptrop)
1157 struct type t = ts[nts - 1];
1158 o_tmpcopy();
1159 ts_push(&t);
1160 readexpr();
1161 ts_addop(op);
1162 o_assign(TYPE_BT(&ts[nts - 2]));
1163 ts_pop(NULL);
1164 ts_de(0);
1167 static void doassign(void)
1169 struct type t = ts[nts - 1];
1170 if (!t.ptr && t.flags & T_STRUCT) {
1171 ts_pop(NULL);
1172 o_num(type_totsz(&t));
1173 o_memcpy();
1174 } else {
1175 ts_pop_de(NULL);
1176 o_assign(TYPE_BT(&ts[nts - 1]));
1177 ts_de(0);
1181 static void readexpr(void)
1183 readcexpr();
1184 if (!tok_jmp('=')) {
1185 readexpr();
1186 doassign();
1187 return;
1189 if (!tok_jmp(TOK2("+="))) {
1190 opassign(O_ADD, 1);
1191 return;
1193 if (!tok_jmp(TOK2("-="))) {
1194 opassign(O_SUB, 1);
1195 return;
1197 if (!tok_jmp(TOK2("*="))) {
1198 opassign(O_MUL, 0);
1199 return;
1201 if (!tok_jmp(TOK2("/="))) {
1202 opassign(O_DIV, 0);
1203 return;
1205 if (!tok_jmp(TOK2("%="))) {
1206 opassign(O_MOD, 0);
1207 return;
1209 if (!tok_jmp(TOK3("<<="))) {
1210 opassign(O_SHL, 0);
1211 return;
1213 if (!tok_jmp(TOK3(">>="))) {
1214 opassign(O_SHR, 0);
1215 return;
1217 if (!tok_jmp(TOK3("&="))) {
1218 opassign(O_AND, 0);
1219 return;
1221 if (!tok_jmp(TOK3("|="))) {
1222 opassign(O_OR, 0);
1223 return;
1225 if (!tok_jmp(TOK3("^="))) {
1226 opassign(O_XOR, 0);
1227 return;
1231 static void readestmt(void)
1233 do {
1234 o_tmpdrop(-1);
1235 nts = 0;
1236 readexpr();
1237 } while (!tok_jmp(','));
1240 static void o_localoff(long addr, int off)
1242 o_local(addr);
1243 if (off) {
1244 o_num(off);
1245 o_bop(O_ADD);
1249 static struct type *innertype(struct type *t)
1251 if (t->flags & T_ARRAY && !t->ptr)
1252 return innertype(&arrays[t->id].type);
1253 return t;
1256 static void initexpr(struct type *t, int off, void *obj,
1257 void (*set)(void *obj, int off, struct type *t))
1259 if (tok_jmp('{')) {
1260 set(obj, off, t);
1261 return;
1263 if (!t->ptr && t->flags & T_STRUCT) {
1264 struct structinfo *si = &structs[t->id];
1265 int i;
1266 for (i = 0; i < si->nfields; i++) {
1267 struct name *field = &si->fields[i];
1268 if (!tok_jmp('.')) {
1269 tok_expect(TOK_NAME);
1270 field = struct_field(t->id, tok_id());
1271 tok_expect('=');
1273 initexpr(&field->type, off + field->addr, obj, set);
1274 if (tok_jmp(',') || tok_see() == '}')
1275 break;
1277 } else if (t->flags & T_ARRAY) {
1278 struct type *t_de = &arrays[t->id].type;
1279 int i;
1280 for (i = 0; ; i++) {
1281 long idx = i;
1282 struct type *it = t_de;
1283 if (!tok_jmp('[')) {
1284 readexpr();
1285 ts_pop_de(NULL);
1286 o_popnum(&idx);
1287 tok_expect(']');
1288 tok_expect('=');
1290 if (tok_see() != '{')
1291 it = innertype(t_de);
1292 initexpr(it, off + type_totsz(it) * idx, obj, set);
1293 if (tok_jmp(',') || tok_see() == '}')
1294 break;
1297 tok_expect('}');
1300 static void jumpbrace(void)
1302 int depth = 0;
1303 while (tok_see() != '}' || depth--)
1304 if (tok_get() == '{')
1305 depth++;
1306 tok_expect('}');
1309 static int initsize(void)
1311 long addr = tok_addr();
1312 int n = 0;
1313 if (!tok_jmp(TOK_STR)) {
1314 n = tok_str(NULL);
1315 tok_jump(addr);
1316 return n;
1318 tok_expect('{');
1319 while (tok_jmp('}')) {
1320 long idx = n;
1321 if (!tok_jmp('[')) {
1322 readexpr();
1323 ts_pop_de(NULL);
1324 o_popnum(&idx);
1325 tok_expect(']');
1326 tok_expect('=');
1328 if (n < idx + 1)
1329 n = idx + 1;
1330 while (tok_see() != '}' && tok_see() != ',')
1331 if (tok_get() == '{')
1332 jumpbrace();
1333 tok_jmp(',');
1335 tok_jump(addr);
1336 return n;
1339 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1341 static void globalinit(void *obj, int off, struct type *t)
1343 struct name *name = obj;
1344 char *elfname = *name->elfname ? name->elfname : name->name;
1345 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1346 struct type *t_de = &arrays[t->id].type;
1347 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1348 char buf[BUFSIZE];
1349 int len;
1350 tok_expect(TOK_STR);
1351 len = tok_str(buf);
1352 memcpy((void *) name->addr + off, buf, len);
1353 return;
1356 readexpr();
1357 o_datset(elfname, off, TYPE_BT(t));
1358 ts_pop(NULL);
1361 static void globaldef(void *data, struct name *name, unsigned flags)
1363 struct type *t = &name->type;
1364 char *elfname = *name->elfname ? name->elfname : name->name;
1365 int sz;
1366 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1367 if (~flags & F_EXTERN)
1368 arrays[t->id].n = initsize();
1369 sz = type_totsz(t);
1370 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1371 if (flags & F_INIT)
1372 name->addr = (long) o_mkdat(elfname, sz, F_GLOBAL(flags));
1373 else
1374 o_mkbss(elfname, sz, F_GLOBAL(flags));
1376 global_add(name);
1377 if (flags & F_INIT)
1378 initexpr(t, 0, name, globalinit);
1381 static void localinit(void *obj, int off, struct type *t)
1383 long addr = *(long *) obj;
1384 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1385 struct type *t_de = &arrays[t->id].type;
1386 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1387 char buf[BUFSIZE];
1388 int len;
1389 tok_expect(TOK_STR);
1390 len = tok_str(buf);
1391 o_localoff(addr, off);
1392 o_sym(tmp_str(buf, len));
1393 o_num(len);
1394 o_memcpy();
1395 o_tmpdrop(1);
1396 return;
1399 o_localoff(addr, off);
1400 ts_push(t);
1401 readexpr();
1402 doassign();
1403 ts_pop(NULL);
1404 o_tmpdrop(1);
1407 /* current function name */
1408 static char func_name[NAMELEN];
1410 static void localdef(void *data, struct name *name, unsigned flags)
1412 struct type *t = &name->type;
1413 if ((flags & F_EXTERN) || (t->flags & T_FUNC) && !t->ptr) {
1414 global_add(name);
1415 return;
1417 if (flags & F_STATIC) {
1418 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1419 globaldef(data, name, flags);
1420 return;
1422 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1423 arrays[t->id].n = initsize();
1424 name->addr = o_mklocal(type_totsz(&name->type));
1425 local_add(name);
1426 if (flags & F_INIT) {
1427 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1428 o_local(name->addr);
1429 o_num(0);
1430 o_num(type_totsz(t));
1431 o_memset();
1432 o_tmpdrop(1);
1434 initexpr(t, 0, &name->addr, localinit);
1438 static void funcdef(char *name, struct type *type, struct name *args,
1439 int nargs, int varg, unsigned flags)
1441 struct name global = {""};
1442 int i;
1443 strcpy(global.name, name);
1444 strcpy(func_name, name);
1445 memcpy(&global.type, type, sizeof(*type));
1446 o_func_beg(name, nargs, F_GLOBAL(flags), varg);
1447 global_add(&global);
1448 for (i = 0; i < nargs; i++) {
1449 args[i].addr = o_arg2loc(i);
1450 local_add(&args[i]);
1454 static int readargs(struct name *args, int *varg)
1456 int nargs = 0;
1457 tok_expect('(');
1458 *varg = 0;
1459 while (tok_see() != ')') {
1460 if (!tok_jmp(TOK3("..."))) {
1461 *varg = 1;
1462 break;
1464 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1465 array2ptr(&args[nargs].type);
1466 nargs++;
1467 if (tok_jmp(','))
1468 break;
1470 tok_expect(')');
1471 if (nargs == 1 && !TYPE_BT(&args[0].type))
1472 return 0;
1473 return nargs;
1476 static int readname(struct type *main, char *name,
1477 struct type *base, unsigned flags)
1479 struct type tpool[3];
1480 int npool = 0;
1481 struct type *type = &tpool[npool++];
1482 struct type *func = NULL;
1483 struct type *ret = NULL;
1484 int arsz[10];
1485 int nar = 0;
1486 int i;
1487 memset(tpool, 0, sizeof(tpool));
1488 if (name)
1489 *name = '\0';
1490 if (!base) {
1491 if (basetype(type, &flags))
1492 return 1;
1493 } else {
1494 memcpy(type, base, sizeof(*base));
1496 readptrs(type);
1497 if (!tok_jmp('(')) {
1498 ret = type;
1499 type = &tpool[npool++];
1500 func = type;
1501 readptrs(type);
1503 if (!tok_jmp(TOK_NAME) && name)
1504 strcpy(name, tok_id());
1505 while (!tok_jmp('[')) {
1506 long n = 0;
1507 if (tok_jmp(']')) {
1508 readexpr();
1509 ts_pop_de(NULL);
1510 if (o_popnum(&n))
1511 err("const expr expected\n");
1512 tok_expect(']');
1514 arsz[nar++] = n;
1516 for (i = nar - 1; i >= 0; i--) {
1517 type->id = array_add(type, arsz[i]);
1518 if (func && i == nar - 1)
1519 func = &arrays[type->id].type;
1520 type->flags = T_ARRAY;
1521 type->bt = LONGSZ;
1522 type->ptr = 0;
1524 if (func)
1525 tok_expect(')');
1526 if (tok_see() == '(') {
1527 struct name args[MAXARGS] = {{""}};
1528 int varg = 0;
1529 int nargs = readargs(args, &varg);
1530 int fdef = !func;
1531 if (!func) {
1532 ret = type;
1533 type = &tpool[npool++];
1534 func = type;
1536 func->flags = T_FUNC;
1537 func->bt = LONGSZ;
1538 func->id = func_create(ret, args, nargs);
1539 if (fdef && tok_see() == '{') {
1540 funcdef(name, func, args, nargs, varg, flags);
1541 return 1;
1544 memcpy(main, type, sizeof(*type));
1545 return 0;
1548 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1549 void *data)
1551 struct type base;
1552 unsigned base_flags;
1553 if (basetype(&base, &base_flags))
1554 return 1;
1555 while (tok_see() != ';' && tok_see() != '{') {
1556 struct name name = {{""}};
1557 unsigned flags = base_flags;
1558 if (readname(&name.type, name.name, &base, flags))
1559 break;
1560 if (!tok_jmp('='))
1561 flags |= F_INIT;
1562 def(data, &name, flags);
1563 tok_jmp(',');
1565 return 0;
1568 static void typedefdef(void *data, struct name *name, unsigned flags)
1570 typedef_add(name->name, &name->type);
1573 static void readstmt(void);
1575 #define MAXCASES (1 << 7)
1577 static void readswitch(void)
1579 int break_beg = nbreaks;
1580 long val_addr = o_mklocal(LONGSZ);
1581 struct type t;
1582 int ncases = 0; /* number of case labels */
1583 long last_failed = -1; /* address of last failed jmp */
1584 long last_matched = -1; /* address of last walk through jmp */
1585 long default_addr = -1; /* address of the default label */
1586 tok_expect('(');
1587 readexpr();
1588 ts_pop_de(&t);
1589 o_local(val_addr);
1590 o_tmpswap();
1591 o_assign(TYPE_BT(&t));
1592 ts_de(0);
1593 o_tmpdrop(1);
1594 tok_expect(')');
1595 tok_expect('{');
1596 while (tok_jmp('}')) {
1597 if (tok_see() != TOK_CASE && tok_see() != TOK_DEFAULT) {
1598 readstmt();
1599 continue;
1601 if (ncases)
1602 last_matched = o_jmp(0);
1603 if (tok_get() == TOK_CASE) {
1604 if (last_failed >= 0)
1605 o_filljmp(last_failed);
1606 caseexpr = 1;
1607 readexpr();
1608 ts_pop_de(NULL);
1609 caseexpr = 0;
1610 o_local(val_addr);
1611 o_deref(TYPE_BT(&t));
1612 o_bop(O_EQ);
1613 last_failed = o_jz(0);
1614 o_tmpdrop(1);
1615 } else {
1616 default_addr = o_mklabel();
1618 tok_expect(':');
1619 if (last_matched >= 0)
1620 o_filljmp(last_matched);
1621 ncases++;
1623 o_rmlocal(val_addr, LONGSZ);
1624 if (last_failed >= 0)
1625 o_filljmp2(last_failed,
1626 default_addr >= 0 ? default_addr : o_mklabel());
1627 break_fill(o_mklabel(), break_beg);
1630 #define MAXGOTO (1 << 10)
1632 static struct gotoinfo {
1633 char name[NAMELEN];
1634 long addr;
1635 } gotos[MAXGOTO];
1636 static int ngotos;
1638 static struct labelinfo {
1639 char name[NAMELEN];
1640 long addr;
1641 } labels[MAXGOTO];
1642 static int nlabels;
1644 static void goto_add(char *name)
1646 strcpy(gotos[ngotos].name, name);
1647 gotos[ngotos++].addr = o_jmp(0);
1650 static void label_add(char *name)
1652 strcpy(labels[nlabels].name, name);
1653 labels[nlabels++].addr = o_mklabel();
1656 static void goto_fill(void)
1658 int i, j;
1659 for (i = 0; i < ngotos; i++)
1660 for (j = 0; j < nlabels; j++)
1661 if (!strcmp(gotos[i].name, labels[j].name)) {
1662 o_filljmp2(gotos[i].addr, labels[j].addr);
1663 break;
1667 static void readstmt(void)
1669 o_tmpdrop(-1);
1670 nts = 0;
1671 if (!tok_jmp('{')) {
1672 int _nlocals = nlocals;
1673 int _nglobals = nglobals;
1674 int _nenums = nenums;
1675 int _ntypedefs = ntypedefs;
1676 int _nstructs = nstructs;
1677 int _nfuncs = nfuncs;
1678 int _narrays = narrays;
1679 while (tok_jmp('}'))
1680 readstmt();
1681 nlocals = _nlocals;
1682 nenums = _nenums;
1683 ntypedefs = _ntypedefs;
1684 nstructs = _nstructs;
1685 nfuncs = _nfuncs;
1686 narrays = _narrays;
1687 nglobals = _nglobals;
1688 return;
1690 if (!readdefs(localdef, NULL)) {
1691 tok_expect(';');
1692 return;
1694 if (!tok_jmp(TOK_TYPEDEF)) {
1695 readdefs(typedefdef, NULL);
1696 tok_expect(';');
1697 return;
1699 if (!tok_jmp(TOK_IF)) {
1700 long l1, l2;
1701 tok_expect('(');
1702 readexpr();
1703 tok_expect(')');
1704 ts_pop_de(NULL);
1705 l1 = o_jz(0);
1706 readstmt();
1707 if (!tok_jmp(TOK_ELSE)) {
1708 l2 = o_jmp(0);
1709 o_filljmp(l1);
1710 readstmt();
1711 o_filljmp(l2);
1712 } else {
1713 o_filljmp(l1);
1715 return;
1717 if (!tok_jmp(TOK_WHILE)) {
1718 long l1, l2;
1719 int break_beg = nbreaks;
1720 int continue_beg = ncontinues;
1721 l1 = o_mklabel();
1722 tok_expect('(');
1723 readexpr();
1724 tok_expect(')');
1725 ts_pop_de(NULL);
1726 l2 = o_jz(0);
1727 readstmt();
1728 o_jmp(l1);
1729 o_filljmp(l2);
1730 break_fill(o_mklabel(), break_beg);
1731 continue_fill(l1, continue_beg);
1732 return;
1734 if (!tok_jmp(TOK_DO)) {
1735 long l1, l2;
1736 int break_beg = nbreaks;
1737 int continue_beg = ncontinues;
1738 l1 = o_mklabel();
1739 readstmt();
1740 tok_expect(TOK_WHILE);
1741 tok_expect('(');
1742 l2 = o_mklabel();
1743 readexpr();
1744 ts_pop_de(NULL);
1745 o_jnz(l1);
1746 tok_expect(')');
1747 break_fill(o_mklabel(), break_beg);
1748 continue_fill(l2, continue_beg);
1749 tok_expect(';');
1750 return;
1752 if (!tok_jmp(TOK_FOR)) {
1753 long l_check, l_jump, j_fail, j_pass;
1754 int break_beg = nbreaks;
1755 int continue_beg = ncontinues;
1756 int has_cond = 0;
1757 tok_expect('(');
1758 if (tok_see() != ';')
1759 readestmt();
1760 tok_expect(';');
1761 l_check = o_mklabel();
1762 if (tok_see() != ';') {
1763 readestmt();
1764 ts_pop_de(NULL);
1765 j_fail = o_jz(0);
1766 has_cond = 1;
1768 tok_expect(';');
1769 j_pass = o_jmp(0);
1770 l_jump = o_mklabel();
1771 if (tok_see() != ')')
1772 readestmt();
1773 tok_expect(')');
1774 o_jmp(l_check);
1775 o_filljmp(j_pass);
1776 readstmt();
1777 o_jmp(l_jump);
1778 if (has_cond)
1779 o_filljmp(j_fail);
1780 break_fill(o_mklabel(), break_beg);
1781 continue_fill(l_jump, continue_beg);
1782 return;
1784 if (!tok_jmp(TOK_SWITCH)) {
1785 readswitch();
1786 return;
1788 if (!tok_jmp(TOK_RETURN)) {
1789 int ret = tok_see() != ';';
1790 if (ret) {
1791 readexpr();
1792 ts_pop_de(NULL);
1794 tok_expect(';');
1795 o_ret(ret);
1796 return;
1798 if (!tok_jmp(TOK_BREAK)) {
1799 tok_expect(';');
1800 breaks[nbreaks++] = o_jmp(0);
1801 return;
1803 if (!tok_jmp(TOK_CONTINUE)) {
1804 tok_expect(';');
1805 continues[ncontinues++] = o_jmp(0);
1806 return;
1808 if (!tok_jmp(TOK_GOTO)) {
1809 tok_expect(TOK_NAME);
1810 goto_add(tok_id());
1811 tok_expect(';');
1812 return;
1814 readestmt();
1815 /* labels */
1816 if (!tok_jmp(':')) {
1817 label_add(tok_id());
1818 return;
1820 tok_expect(';');
1823 static void readdecl(void)
1825 if (!tok_jmp(TOK_TYPEDEF)) {
1826 readdefs(typedefdef, NULL);
1827 tok_expect(';');
1828 return;
1830 readdefs(globaldef, NULL);
1831 if (tok_see() == '{') {
1832 readstmt();
1833 goto_fill();
1834 o_func_end();
1835 func_name[0] = '\0';
1836 nlocals = 0;
1837 ngotos = 0;
1838 nlabels = 0;
1839 return;
1841 tok_expect(';');
1844 static void parse(void)
1846 while (tok_see() != TOK_EOF)
1847 readdecl();
1850 static void compat_macros(void)
1852 cpp_define("__STDC__", "");
1853 cpp_define("__arm__", "");
1854 cpp_define("__linux__", "");
1856 /* ignored keywords */
1857 cpp_define("const", "");
1858 cpp_define("register", "");
1859 cpp_define("volatile", "");
1860 cpp_define("inline", "");
1861 cpp_define("restrict", "");
1862 cpp_define("__inline__", "");
1863 cpp_define("__restrict__", "");
1864 cpp_define("__attribute__(x)", "");
1865 cpp_define("__builtin_va_list__", "long");
1868 int main(int argc, char *argv[])
1870 char obj[128] = "";
1871 int ofd;
1872 int i = 1;
1873 compat_macros();
1874 while (i < argc && argv[i][0] == '-') {
1875 if (argv[i][1] == 'I')
1876 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1877 if (argv[i][1] == 'D') {
1878 char *name = argv[i] + 2;
1879 char *def = "";
1880 char *eq = strchr(name, '=');
1881 if (eq) {
1882 *eq = '\0';
1883 def = eq + 1;
1885 cpp_define(name, def);
1887 if (argv[i][1] == 'o')
1888 strcpy(obj, argv[i][2] ? argv[i] + 2 : argv[++i]);
1889 i++;
1891 if (i == argc)
1892 die("neatcc: no file given\n");
1893 if (cpp_init(argv[i]))
1894 die("neatcc: cannot open input file\n");
1895 parse();
1896 if (!*obj) {
1897 strcpy(obj, argv[i]);
1898 obj[strlen(obj) - 1] = 'o';
1900 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1901 o_write(ofd);
1902 close(ofd);
1903 return 0;