ncc: fix ++s for pointers
[neatcc/cc.git] / ncc.c
blob3745749544b9f491f77a4dbfa4cd99b3586edc92
1 /*
2 * neatcc - A small and simple C compiler
4 * Copyright (C) 2010 Ali Gholami Rudi
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License, as published by the
8 * Free Software Foundation.
9 */
10 #include <fcntl.h>
11 #include <unistd.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/stat.h>
15 #include <sys/types.h>
16 #include "gen.h"
17 #include "tok.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
22 #define print(s) write(2, (s), strlen(s));
24 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
25 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
27 #define T_ARRAY 0x01
28 #define T_STRUCT 0x02
29 #define T_FUNC 0x04
31 #define F_INIT 0x01
32 #define F_STATIC 0x02
33 #define F_EXTERN 0x04
35 struct type {
36 unsigned bt;
37 unsigned flags;
38 int ptr;
39 int id; /* for structs, functions and arrays */
42 /* type stack */
43 static struct type ts[MAXTMP];
44 static int nts;
46 static void ts_push_bt(unsigned bt)
48 ts[nts].ptr = 0;
49 ts[nts].flags = 0;
50 ts[nts++].bt = bt;
53 static void ts_push(struct type *t)
55 memcpy(&ts[nts++], t, sizeof(*t));
56 if (t->flags & (T_FUNC | T_ARRAY) && !t->ptr)
57 o_addr();
60 static void ts_pop(struct type *type)
62 nts--;
63 if (type)
64 *type = ts[nts];
67 void die(char *msg)
69 print(msg);
70 exit(1);
73 void err(char *msg)
75 char err[1 << 7];
76 int len = cpp_loc(err, tok_addr());
77 strcpy(err + len, msg);
78 die(err);
81 struct name {
82 char name[NAMELEN];
83 struct type type;
84 long addr;
85 int unused; /* unreferenced external symbols */
88 static struct name locals[MAXLOCALS];
89 static int nlocals;
90 static struct name globals[MAXGLOBALS];
91 static int nglobals;
93 static void local_add(struct name *name)
95 if (nlocals >= MAXLOCALS)
96 err("nomem: MAXLOCALS reached!\n");
97 memcpy(&locals[nlocals++], name, sizeof(*name));
100 static int global_find(char *name)
102 int i;
103 for (i = 0; i < nglobals; i++)
104 if (!strcmp(name, globals[i].name))
105 return i;
106 return -1;
109 static void global_add(struct name *name)
111 int found = global_find(name->name);
112 int i = found == -1 ? nglobals++ : found;
113 if (nglobals >= MAXGLOBALS)
114 err("nomem: MAXGLOBALS reached!\n");
115 memcpy(&globals[i], name, sizeof(*name));
118 #define MAXENUMS (1 << 10)
120 static struct enumval {
121 char name[NAMELEN];
122 int n;
123 } enums[MAXENUMS];
124 static int nenums;
126 static void enum_add(char *name, int val)
128 struct enumval *ev = &enums[nenums++];
129 if (nenums >= MAXENUMS)
130 err("nomem: MAXENUMS reached!\n");
131 strcpy(ev->name, name);
132 ev->n = val;
135 static int enum_find(int *val, char *name)
137 int i;
138 for (i = nenums - 1; i >= 0; --i)
139 if (!strcmp(name, enums[i].name)) {
140 *val = enums[i].n;
141 return 0;
143 return 1;
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo {
149 char name[NAMELEN];
150 struct type type;
151 } typedefs[MAXTYPEDEFS];
152 static int ntypedefs;
154 static void typedef_add(char *name, struct type *type)
156 struct typdefinfo *ti = &typedefs[ntypedefs++];
157 if (ntypedefs >= MAXTYPEDEFS)
158 err("nomem: MAXTYPEDEFS reached!\n");
159 strcpy(ti->name, name);
160 memcpy(&ti->type, type, sizeof(*type));
163 static int typedef_find(char *name)
165 int i;
166 for (i = ntypedefs - 1; i >= 0; --i)
167 if (!strcmp(name, typedefs[i].name))
168 return i;
169 return -1;
172 #define MAXARRAYS (1 << 10)
174 static struct array {
175 struct type type;
176 int n;
177 } arrays[MAXARRAYS];
178 static int narrays;
180 static int array_add(struct type *type, int n)
182 struct array *a = &arrays[narrays++];
183 if (narrays >= MAXARRAYS)
184 err("nomem: MAXARRAYS reached!\n");
185 memcpy(&a->type, type, sizeof(*type));
186 a->n = n;
187 return a - arrays;
190 static void array2ptr(struct type *t)
192 if (!(t->flags & T_ARRAY) || t->ptr)
193 return;
194 memcpy(t, &arrays[t->id].type, sizeof(*t));
195 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return LONGSZ;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static int tok_jmp(int tok)
278 if (tok_see() != tok)
279 return 1;
280 tok_get();
281 return 0;
284 static void tok_expect(int tok)
286 if (tok_get() != tok)
287 err("syntax error\n");
290 static unsigned bt_op(unsigned bt1, unsigned bt2)
292 unsigned s1 = BT_SZ(bt1);
293 unsigned s2 = BT_SZ(bt2);
294 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
297 static void ts_binop(int op)
299 struct type t1, t2;
300 ts_pop(&t1);
301 ts_pop(&t2);
302 o_bop(op);
303 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
306 static void ts_addop(int op)
308 struct type t1, t2;
309 ts_pop(&t1);
310 ts_pop(&t2);
311 array2ptr(&t1);
312 array2ptr(&t2);
313 if (!t1.ptr && !t2.ptr) {
314 o_bop(op);
315 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
316 return;
318 if (t1.ptr && !t2.ptr) {
319 struct type t = t2;
320 t2 = t1;
321 t1 = t;
322 o_tmpswap();
324 if (!t1.ptr && t2.ptr)
325 if (type_szde(&t2) > 1) {
326 o_num(type_szde(&t2), 4);
327 o_bop(O_MUL);
329 o_bop(op);
330 if (t1.ptr && t2.ptr) {
331 int sz = type_szde(&t1);
332 if (sz > 1) {
333 o_num(sz, 4);
334 o_bop(O_DIV);
336 ts_push_bt(4 | BT_SIGNED);
337 } else {
338 ts_push(&t2);
342 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
343 #define MIN(a, b) ((a) < (b) ? (a) : (b))
345 static int type_alignment(struct type *t)
347 if (t->flags & T_ARRAY && !t->ptr)
348 return type_alignment(&arrays[t->id].type);
349 if (t->flags & T_STRUCT && !t->ptr)
350 return type_alignment(&structs[t->id].fields[0].type);
351 return MIN(LONGSZ, type_totsz(t));
354 static void structdef(void *data, struct name *name, unsigned flags)
356 struct structinfo *si = data;
357 if (si->isunion) {
358 name->addr = 0;
359 if (si->size < type_totsz(&name->type))
360 si->size = type_totsz(&name->type);
361 } else {
362 struct type *t = &name->type;
363 int alignment = type_alignment(t);
364 if (t->flags & T_ARRAY && !t->ptr)
365 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
366 si->size = ALIGN(si->size, alignment);
367 name->addr = si->size;
368 si->size += type_totsz(&name->type);
370 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
373 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
375 static int struct_create(char *name, int isunion)
377 int id = struct_find(name, isunion);
378 struct structinfo *si = &structs[id];
379 tok_expect('{');
380 while (tok_jmp('}')) {
381 readdefs(structdef, si);
382 tok_expect(';');
384 return id;
387 static void readexpr(void);
389 static void enum_create(void)
391 long n = 0;
392 tok_expect('{');
393 while (tok_jmp('}')) {
394 char name[NAMELEN];
395 tok_expect(TOK_NAME);
396 strcpy(name, tok_id());
397 if (tok_see() == '=') {
398 tok_get();
399 readexpr();
400 ts_pop(NULL);
401 if (o_popnum(&n))
402 err("const expr expected!\n");
404 enum_add(name, n++);
405 tok_jmp(',');
409 static int basetype(struct type *type, unsigned *flags)
411 int sign = 1;
412 int size = 4;
413 int done = 0;
414 int i = 0;
415 int isunion;
416 char name[NAMELEN] = "";
417 *flags = 0;
418 type->flags = 0;
419 type->ptr = 0;
420 while (!done) {
421 switch (tok_see()) {
422 case TOK_STATIC:
423 *flags |= F_STATIC;
424 break;
425 case TOK_EXTERN:
426 *flags |= F_EXTERN;
427 break;
428 case TOK_VOID:
429 sign = 0;
430 size = 0;
431 done = 1;
432 break;
433 case TOK_INT:
434 done = 1;
435 break;
436 case TOK_CHAR:
437 size = 1;
438 done = 1;
439 break;
440 case TOK_SHORT:
441 size = 2;
442 break;
443 case TOK_LONG:
444 size = LONGSZ;
445 break;
446 case TOK_SIGNED:
447 break;
448 case TOK_UNSIGNED:
449 sign = 0;
450 break;
451 case TOK_UNION:
452 case TOK_STRUCT:
453 isunion = tok_get() == TOK_UNION;
454 if (!tok_jmp(TOK_NAME))
455 strcpy(name, tok_id());
456 if (tok_see() == '{')
457 type->id = struct_create(name, isunion);
458 else
459 type->id = struct_find(name, isunion);
460 type->flags |= T_STRUCT;
461 type->bt = LONGSZ;
462 return 0;
463 case TOK_ENUM:
464 tok_get();
465 tok_jmp(TOK_NAME);
466 if (tok_see() == '{')
467 enum_create();
468 type->bt = 4 | BT_SIGNED;
469 return 0;
470 default:
471 if (tok_see() == TOK_NAME) {
472 int id = typedef_find(tok_id());
473 if (id != -1) {
474 tok_get();
475 memcpy(type, &typedefs[id].type,
476 sizeof(*type));
477 return 0;
480 if (!i)
481 return 1;
482 done = 1;
483 continue;
485 i++;
486 tok_get();
488 type->bt = size | (sign ? BT_SIGNED : 0);
489 return 0;
492 static int readname(struct type *main, char *name,
493 struct type *base, unsigned flags);
495 static int readtype(struct type *type)
497 return readname(type, NULL, NULL, 0);
500 static void readptrs(struct type *type)
502 while (!tok_jmp('*')) {
503 type->ptr++;
504 if (!type->bt)
505 type->bt = 1;
509 /* used to differenciate labels from case and cond exprs */
510 static int ncexpr;
511 static int caseexpr;
513 static void readpre(void);
515 static void readprimary(void)
517 int i;
518 if (!tok_jmp(TOK_NUM)) {
519 long n;
520 int bt = tok_num(&n);
521 ts_push_bt(bt);
522 o_num(n, bt);
523 return;
525 if (!tok_jmp(TOK_STR)) {
526 struct type t;
527 char buf[BUFSIZE];
528 int len;
529 t.bt = 1 | BT_SIGNED;
530 t.ptr = 1;
531 t.flags = 0;
532 ts_push(&t);
533 len = tok_str(buf);
534 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
535 o_addr();
536 return;
538 if (!tok_jmp(TOK_NAME)) {
539 struct name unkn = {0};
540 char *name = unkn.name;
541 int n;
542 strcpy(name, tok_id());
543 /* don't search for labels here */
544 if (!ncexpr && !caseexpr && tok_see() == ':')
545 return;
546 for (i = nlocals - 1; i >= 0; --i) {
547 struct type *t = &locals[i].type;
548 if (!strcmp(locals[i].name, name)) {
549 o_local(locals[i].addr, TYPE_BT(t));
550 ts_push(t);
551 return;
554 if ((n = global_find(name)) != -1) {
555 struct name *g = &globals[n];
556 struct type *t = &g->type;
557 if (g->unused) {
558 g->unused = 0;
559 if (t->flags & T_FUNC && !t->ptr)
560 g->addr = out_mkundef(name, 0);
561 else
562 g->addr = out_mkundef(name, type_totsz(t));
564 o_symaddr(g->addr, TYPE_BT(t));
565 ts_push(t);
566 return;
568 if (!enum_find(&n, name)) {
569 ts_push_bt(4 | BT_SIGNED);
570 o_num(n, 4 | BT_SIGNED);
571 return;
573 if (tok_see() != '(')
574 err("unknown symbol\n");
575 unkn.addr = out_mkundef(unkn.name, 0);
576 global_add(&unkn);
577 ts_push_bt(LONGSZ);
578 o_symaddr(unkn.addr, LONGSZ);
579 return;
581 if (!tok_jmp('(')) {
582 struct type t;
583 if (!readtype(&t)) {
584 struct type o;
585 tok_expect(')');
586 readpre();
587 ts_pop(&o);
588 ts_push(&t);
589 if (!t.ptr || !o.ptr)
590 o_cast(TYPE_BT(&t));
591 } else {
592 readexpr();
593 tok_expect(')');
595 return;
599 void arrayderef(struct type *t)
601 int sz = type_totsz(t);
602 if (sz > 1) {
603 o_num(sz, 4);
604 o_bop(O_MUL);
606 o_bop(O_ADD);
607 o_deref(TYPE_BT(t));
610 static void inc_post(int inc_one, int inc_many)
612 struct type *t = &ts[nts - 1];
613 int sz = type_szde(t);
614 o_tmpcopy();
615 o_load();
616 o_tmpswap();
617 if (!t->ptr || sz == 1) {
618 o_uop(inc_one);
619 } else {
620 o_tmpcopy();
621 o_num(sz, 4);
622 o_bop(inc_many);
623 o_assign(TYPE_BT(t));
625 o_tmpdrop(1);
628 static void readfield(void)
630 struct name *field;
631 struct type t;
632 tok_expect(TOK_NAME);
633 ts_pop(&t);
634 array2ptr(&t);
635 field = struct_field(t.id, tok_id());
636 if (field->addr) {
637 o_num(field->addr, 4);
638 o_bop(O_ADD);
640 o_deref(TYPE_BT(&field->type));
641 ts_push(&field->type);
644 #define MAXFUNCS (1 << 10)
646 static struct funcinfo {
647 struct type args[MAXFIELDS];
648 struct type ret;
649 int nargs;
650 } funcs[MAXFUNCS];
651 static int nfuncs;
652 static unsigned ret_bt;
654 static int func_create(struct type *ret, struct name *args, int nargs)
656 struct funcinfo *fi = &funcs[nfuncs++];
657 int i;
658 if (nfuncs >= MAXFUNCS)
659 err("nomem: MAXFUNCS reached!\n");
660 memcpy(&fi->ret, ret, sizeof(*ret));
661 for (i = 0; i < nargs; i++)
662 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
663 fi->nargs = nargs;
664 return fi - funcs;
667 static void readcall(void)
669 struct type t;
670 unsigned bt[MAXARGS];
671 struct funcinfo *fi;
672 int argc = 0;
673 int i;
674 ts_pop(&t);
675 if (t.flags & T_FUNC && t.ptr > 0)
676 o_deref(LONGSZ);
677 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
678 if (tok_see() != ')') {
679 readexpr();
680 ts_pop(&t);
681 bt[argc++] = TYPE_BT(&t);
683 while (!tok_jmp(',')) {
684 readexpr();
685 ts_pop(&t);
686 bt[argc++] = TYPE_BT(&t);
688 tok_expect(')');
689 if (fi)
690 for (i = 0; i < fi->nargs; i++)
691 bt[i] = TYPE_BT(&fi->args[i]);
692 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
693 if (fi)
694 ts_push(&fi->ret);
695 else
696 ts_push_bt(4 | BT_SIGNED);
699 static void readpost(void)
701 readprimary();
702 while (1) {
703 if (!tok_jmp('[')) {
704 struct type t;
705 ts_pop(&t);
706 readexpr();
707 ts_pop(NULL);
708 tok_expect(']');
709 array2ptr(&t);
710 t.ptr--;
711 arrayderef(&t);
712 ts_push(&t);
713 continue;
715 if (!tok_jmp('(')) {
716 readcall();
717 continue;
719 if (!tok_jmp(TOK2("++"))) {
720 inc_post(O_INC, O_ADD);
721 continue;
723 if (!tok_jmp(TOK2("--"))) {
724 inc_post(O_DEC, O_SUB);
725 continue;
727 if (!tok_jmp('.')) {
728 o_addr();
729 readfield();
730 continue;
732 if (!tok_jmp(TOK2("->"))) {
733 readfield();
734 continue;
736 break;
740 static void inc_pre(int inc_one, int inc_many)
742 struct type *t;
743 int sz;
744 readpre();
745 t = &ts[nts - 1];
746 sz = (t->flags & T_ARRAY || t->ptr) ? type_szde(t) : 1;
747 if (sz == 1) {
748 o_uop(inc_one);
749 } else {
750 o_tmpcopy();
751 o_num(sz, 4);
752 o_bop(inc_many);
753 o_assign(TYPE_BT(t));
757 static void readpre(void)
759 if (!tok_jmp('&')) {
760 struct type type;
761 readpre();
762 ts_pop(&type);
763 if (!(type.flags & T_FUNC) && !type.ptr)
764 type.ptr++;
765 ts_push(&type);
766 o_addr();
767 return;
769 if (!tok_jmp('*')) {
770 struct type t;
771 readpre();
772 ts_pop(&t);
773 array2ptr(&t);
774 if (!(t.flags & T_FUNC) || t.ptr > 0) {
775 t.ptr--;
776 o_deref(TYPE_BT(&t));
778 ts_push(&t);
779 return;
781 if (!tok_jmp('!')) {
782 struct type type;
783 readpre();
784 ts_pop(&type);
785 o_uop(O_LNOT);
786 ts_push_bt(4 | BT_SIGNED);
787 return;
789 if (!tok_jmp('-')) {
790 readpre();
791 o_uop(O_NEG);
792 return;
794 if (!tok_jmp('~')) {
795 readpre();
796 o_uop(O_NOT);
797 return;
799 if (!tok_jmp(TOK2("++"))) {
800 inc_pre(O_INC, O_ADD);
801 return;
803 if (!tok_jmp(TOK2("--"))) {
804 inc_pre(O_DEC, O_SUB);
805 return;
807 if (!tok_jmp(TOK_SIZEOF)) {
808 struct type t;
809 int op = !tok_jmp('(');
810 if (readtype(&t)) {
811 int nogen = !o_nogen();
812 readexpr();
813 if (nogen)
814 o_dogen();
815 ts_pop(&t);
816 o_tmpdrop(1);
818 ts_push_bt(4);
819 o_num(type_totsz(&t), 4);
820 if (op)
821 tok_expect(')');
822 return;
824 readpost();
827 static void readmul(void)
829 readpre();
830 while (1) {
831 if (!tok_jmp('*')) {
832 readpre();
833 ts_binop(O_MUL);
834 continue;
836 if (!tok_jmp('/')) {
837 readpre();
838 ts_binop(O_DIV);
839 continue;
841 if (!tok_jmp('%')) {
842 readpre();
843 ts_binop(O_MOD);
844 continue;
846 break;
850 static void readadd(void)
852 readmul();
853 while (1) {
854 if (!tok_jmp('+')) {
855 readmul();
856 ts_addop(O_ADD);
857 continue;
859 if (!tok_jmp('-')) {
860 readmul();
861 ts_addop(O_SUB);
862 continue;
864 break;
868 static void shift(int op)
870 struct type t;
871 readadd();
872 ts_pop(NULL);
873 ts_pop(&t);
874 o_bop(op);
875 ts_push_bt(TYPE_BT(&t));
878 static void readshift(void)
880 readadd();
881 while (1) {
882 if (!tok_jmp(TOK2("<<"))) {
883 shift(O_SHL);
884 continue;
886 if (!tok_jmp(TOK2(">>"))) {
887 shift(O_SHR);
888 continue;
890 break;
894 static void cmp(int op)
896 readshift();
897 ts_pop(NULL);
898 ts_pop(NULL);
899 o_bop(op);
900 ts_push_bt(4 | BT_SIGNED);
903 static void readcmp(void)
905 readshift();
906 while (1) {
907 if (!tok_jmp('<')) {
908 cmp(O_LT);
909 continue;
911 if (!tok_jmp('>')) {
912 cmp(O_GT);
913 continue;
915 if (!tok_jmp(TOK2("<="))) {
916 cmp(O_LE);
917 continue;
919 if (!tok_jmp(TOK2(">="))) {
920 cmp(O_GE);
921 continue;
923 break;
927 static void eq(int op)
929 readcmp();
930 ts_pop(NULL);
931 ts_pop(NULL);
932 o_bop(op);
933 ts_push_bt(4 | BT_SIGNED);
936 static void readeq(void)
938 readcmp();
939 while (1) {
940 if (!tok_jmp(TOK2("=="))) {
941 eq(O_EQ);
942 continue;
944 if (!tok_jmp(TOK2("!="))) {
945 eq(O_NEQ);
946 continue;
948 break;
952 static void readbitand(void)
954 readeq();
955 while (!tok_jmp('&')) {
956 readeq();
957 ts_binop(O_AND);
961 static void readxor(void)
963 readbitand();
964 while (!tok_jmp('^')) {
965 readbitand();
966 ts_binop(O_XOR);
970 static void readbitor(void)
972 readxor();
973 while (!tok_jmp('|')) {
974 readxor();
975 ts_binop(O_OR);
979 #define MAXCOND (1 << 7)
981 static void readand(void)
983 long conds[MAXCOND];
984 int nconds = 0;
985 long passed;
986 int i;
987 readbitor();
988 if (tok_see() != TOK2("&&"))
989 return;
990 o_fork();
991 conds[nconds++] = o_jz(0);
992 ts_pop(NULL);
993 while (!tok_jmp(TOK2("&&"))) {
994 readbitor();
995 conds[nconds++] = o_jz(0);
996 ts_pop(NULL);
998 o_num(1, 4 | BT_SIGNED);
999 o_forkpush();
1000 passed = o_jmp(0);
1001 for (i = 0; i < nconds; i++)
1002 o_filljmp(conds[i]);
1003 o_num(0, 4 | BT_SIGNED);
1004 o_forkpush();
1005 o_forkjoin();
1006 o_filljmp(passed);
1007 ts_push_bt(4 | BT_SIGNED);
1010 static void reador(void)
1012 long conds[MAXCOND];
1013 int nconds = 0;
1014 long failed;
1015 int i;
1016 readand();
1017 if (tok_see() != TOK2("||"))
1018 return;
1019 o_fork();
1020 conds[nconds++] = o_jnz(0);
1021 ts_pop(NULL);
1022 while (!tok_jmp(TOK2("||"))) {
1023 readand();
1024 conds[nconds++] = o_jnz(0);
1025 ts_pop(NULL);
1027 o_num(0, 4 | BT_SIGNED);
1028 o_forkpush();
1029 failed = o_jmp(0);
1030 for (i = 0; i < nconds; i++)
1031 o_filljmp(conds[i]);
1032 o_num(1, 4 | BT_SIGNED);
1033 o_forkpush();
1034 o_forkjoin();
1035 o_filljmp(failed);
1036 ts_push_bt(4 | BT_SIGNED);
1039 static int readcexpr_const(void)
1041 long c;
1042 int nogen;
1043 if (o_popnum(&c))
1044 return -1;
1045 if (!c)
1046 nogen = !o_nogen();
1047 reador();
1048 ts_pop(NULL);
1049 tok_expect(':');
1050 if (c) {
1051 nogen = !o_nogen();
1052 } else {
1053 if (nogen)
1054 o_dogen();
1055 o_tmpdrop(1);
1057 reador();
1058 if (c) {
1059 if (nogen)
1060 o_dogen();
1061 o_tmpdrop(1);
1063 return 0;
1066 static void readcexpr(void)
1068 long l1, l2;
1069 reador();
1070 if (tok_jmp('?'))
1071 return;
1072 ncexpr++;
1073 ts_pop(NULL);
1074 o_fork();
1075 if (readcexpr_const()) {
1076 l1 = o_jz(0);
1077 reador();
1078 o_forkpush();
1079 l2 = o_jmp(0);
1080 ts_pop(NULL);
1082 tok_expect(':');
1083 o_filljmp(l1);
1084 reador();
1085 o_forkpush();
1086 o_forkjoin();
1087 o_filljmp(l2);
1089 ncexpr--;
1092 static void opassign(int op, int ptrop)
1094 struct type *t = &ts[nts - 1];
1095 if (ptrop && (t->flags & T_ARRAY || t->ptr)) {
1096 o_tmpcopy();
1097 readexpr();
1098 ts_addop(op);
1099 ts_pop(NULL);
1100 o_assign(TYPE_BT(&ts[nts - 1]));
1101 } else {
1102 readexpr();
1103 o_bop(op | O_SET);
1104 ts_pop(NULL);
1108 static void doassign(void)
1110 struct type t;
1111 ts_pop(&t);
1112 if (!t.ptr && t.flags & T_STRUCT)
1113 o_memcpy(type_totsz(&t));
1114 else
1115 o_assign(TYPE_BT(&ts[nts - 1]));
1118 static void readexpr(void)
1120 readcexpr();
1121 if (!tok_jmp('=')) {
1122 readexpr();
1123 doassign();
1124 return;
1126 if (!tok_jmp(TOK2("+="))) {
1127 opassign(O_ADD, 1);
1128 return;
1130 if (!tok_jmp(TOK2("-="))) {
1131 opassign(O_SUB, 1);
1132 return;
1134 if (!tok_jmp(TOK2("*="))) {
1135 opassign(O_MUL, 0);
1136 return;
1138 if (!tok_jmp(TOK2("/="))) {
1139 opassign(O_DIV, 0);
1140 return;
1142 if (!tok_jmp(TOK2("%="))) {
1143 opassign(O_MOD, 0);
1144 return;
1146 if (!tok_jmp(TOK3("<<="))) {
1147 opassign(O_SHL, 0);
1148 return;
1150 if (!tok_jmp(TOK3(">>="))) {
1151 opassign(O_SHR, 0);
1152 return;
1154 if (!tok_jmp(TOK3("&="))) {
1155 opassign(O_AND, 0);
1156 return;
1158 if (!tok_jmp(TOK3("|="))) {
1159 opassign(O_OR, 0);
1160 return;
1162 if (!tok_jmp(TOK3("^="))) {
1163 opassign(O_XOR, 0);
1164 return;
1168 static void readestmt(void)
1170 do {
1171 o_tmpdrop(-1);
1172 nts = 0;
1173 readexpr();
1174 } while (!tok_jmp(','));
1177 static void o_localoff(long addr, int off, unsigned bt)
1179 o_local(addr, bt);
1180 if (off) {
1181 o_addr();
1182 o_num(off, 4);
1183 o_bop(O_ADD);
1184 o_deref(bt);
1188 static struct type *innertype(struct type *t)
1190 if (t->flags & T_ARRAY && !t->ptr)
1191 return innertype(&arrays[t->id].type);
1192 return t;
1195 static void initexpr(struct type *t, int off, void *obj,
1196 void (*set)(void *obj, int off, struct type *t))
1198 if (tok_jmp('{')) {
1199 set(obj, off, t);
1200 return;
1202 if (!t->ptr && t->flags & T_STRUCT) {
1203 struct structinfo *si = &structs[t->id];
1204 int i;
1205 for (i = 0; i < si->nfields; i++) {
1206 struct name *field = &si->fields[i];
1207 if (!tok_jmp('.')) {
1208 tok_expect(TOK_NAME);
1209 field = struct_field(t->id, tok_id());
1210 tok_expect('=');
1212 initexpr(&field->type, off + field->addr, obj, set);
1213 if (tok_jmp(',') || tok_see() == '}')
1214 break;
1216 } else if (t->flags & T_ARRAY) {
1217 struct type *t_de = &arrays[t->id].type;
1218 int i;
1219 for (i = 0; ; i++) {
1220 long idx = i;
1221 struct type *it = t_de;
1222 if (!tok_jmp('[')) {
1223 readexpr();
1224 o_popnum(&idx);
1225 ts_pop(NULL);
1226 tok_expect(']');
1227 tok_expect('=');
1229 if (tok_see() != '{')
1230 it = innertype(t_de);
1231 initexpr(it, off + type_totsz(it) * idx, obj, set);
1232 if (tok_jmp(',') || tok_see() == '}')
1233 break;
1236 tok_expect('}');
1239 static void jumpbrace(void)
1241 int depth = 0;
1242 while (tok_see() != '}' || depth--)
1243 if (tok_get() == '{')
1244 depth++;
1245 tok_expect('}');
1248 static int initsize(void)
1250 long addr = tok_addr();
1251 int n = 0;
1252 if (!tok_jmp(TOK_STR)) {
1253 n = tok_str(NULL);
1254 tok_jump(addr);
1255 return n;
1257 o_nogen();
1258 tok_expect('{');
1259 while (tok_jmp('}')) {
1260 long idx = n;
1261 if (!tok_jmp('[')) {
1262 readexpr();
1263 o_popnum(&idx);
1264 ts_pop(NULL);
1265 tok_expect(']');
1266 tok_expect('=');
1268 if (n < idx + 1)
1269 n = idx + 1;
1270 while (tok_see() != '}' && tok_see() != ',')
1271 if (tok_get() == '{')
1272 jumpbrace();
1273 tok_jmp(',');
1275 o_dogen();
1276 tok_jump(addr);
1277 return n;
1280 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1282 static void globalinit(void *obj, int off, struct type *t)
1284 long addr = *(long *) obj;
1285 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1286 struct type *t_de = &arrays[t->id].type;
1287 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1288 char buf[BUFSIZE];
1289 int len;
1290 tok_expect(TOK_STR);
1291 len = tok_str(buf);
1292 out_datcpy(addr, off, buf, len);
1293 return;
1296 readexpr();
1297 o_datset(addr, off, TYPE_BT(t));
1298 ts_pop(NULL);
1301 static void globaldef(void *data, struct name *name, unsigned flags)
1303 struct type *t = &name->type;
1304 char *varname = flags & F_STATIC ? NULL : name->name;
1305 int sz;
1306 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1307 arrays[t->id].n = initsize();
1308 sz = type_totsz(t);
1309 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1310 name->unused = 1;
1311 else if (flags & F_INIT)
1312 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1313 else
1314 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1315 global_add(name);
1316 if (flags & F_INIT)
1317 initexpr(t, 0, &name->addr, globalinit);
1320 static void localinit(void *obj, int off, struct type *t)
1322 long addr = *(long *) obj;
1323 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1324 struct type *t_de = &arrays[t->id].type;
1325 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1326 char buf[BUFSIZE];
1327 int len;
1328 tok_expect(TOK_STR);
1329 len = tok_str(buf);
1330 o_localoff(addr, off, TYPE_BT(t));
1331 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1332 o_memcpy(len);
1333 o_tmpdrop(1);
1334 return;
1337 o_localoff(addr, off, TYPE_BT(t));
1338 ts_push(t);
1339 readexpr();
1340 doassign();
1341 ts_pop(NULL);
1342 o_tmpdrop(1);
1345 static void localdef(void *data, struct name *name, unsigned flags)
1347 struct type *t = &name->type;
1348 if (flags & (F_STATIC | F_EXTERN)) {
1349 globaldef(data, name, flags);
1350 return;
1352 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1353 arrays[t->id].n = initsize();
1354 name->addr = o_mklocal(type_totsz(&name->type));
1355 local_add(name);
1356 if (flags & F_INIT) {
1357 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1358 o_local(name->addr, TYPE_BT(t));
1359 o_memset(0, type_totsz(t));
1360 o_tmpdrop(1);
1362 initexpr(t, 0, &name->addr, localinit);
1366 static void funcdef(char *name, struct type *type, struct name *args,
1367 int nargs, unsigned flags)
1369 struct name global;
1370 int i;
1371 strcpy(global.name, name);
1372 memcpy(&global.type, type, sizeof(*type));
1373 global.addr = o_func_beg(name, F_GLOBAL(flags));
1374 global.unused = 0;
1375 global_add(&global);
1376 ret_bt = TYPE_BT(&funcs[type->id].ret);
1377 for (i = 0; i < nargs; i++) {
1378 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1379 local_add(&args[i]);
1383 static int readargs(struct name *args)
1385 int nargs = 0;
1386 tok_expect('(');
1387 while (tok_see() != ')') {
1388 if (!tok_jmp(TOK3("...")))
1389 break;
1390 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1391 array2ptr(&args[nargs].type);
1392 nargs++;
1393 if (tok_jmp(','))
1394 break;
1396 tok_expect(')');
1397 if (nargs == 1 && !TYPE_BT(&args[0].type))
1398 return 0;
1399 return nargs;
1402 static int readname(struct type *main, char *name,
1403 struct type *base, unsigned flags)
1405 struct type tpool[3];
1406 int npool = 0;
1407 struct type *type = &tpool[npool++];
1408 struct type *func = NULL;
1409 struct type *ret = NULL;
1410 int arsz[10];
1411 int nar = 0;
1412 int i;
1413 memset(tpool, 0, sizeof(tpool));
1414 if (name)
1415 *name = '\0';
1416 if (!base) {
1417 if (basetype(type, &flags))
1418 return 1;
1419 } else {
1420 memcpy(type, base, sizeof(*base));
1422 readptrs(type);
1423 if (!tok_jmp('(')) {
1424 ret = type;
1425 type = &tpool[npool++];
1426 func = type;
1427 readptrs(type);
1429 if (!tok_jmp(TOK_NAME) && name)
1430 strcpy(name, tok_id());
1431 while (!tok_jmp('[')) {
1432 long n = 0;
1433 if (tok_jmp(']')) {
1434 readexpr();
1435 ts_pop(NULL);
1436 if (o_popnum(&n))
1437 err("const expr expected\n");
1438 tok_expect(']');
1440 arsz[nar++] = n;
1442 for (i = nar - 1; i >= 0; i--) {
1443 type->id = array_add(type, arsz[i]);
1444 if (func && i == nar - 1)
1445 func = &arrays[type->id].type;
1446 type->flags = T_ARRAY;
1447 type->bt = LONGSZ;
1448 type->ptr = 0;
1450 if (func)
1451 tok_expect(')');
1452 if (tok_see() == '(') {
1453 struct name args[MAXARGS];
1454 int nargs = readargs(args);
1455 int fdef = !func;
1456 if (!func) {
1457 ret = type;
1458 type = &tpool[npool++];
1459 func = type;
1461 func->flags = T_FUNC;
1462 func->bt = LONGSZ;
1463 func->id = func_create(ret, args, nargs);
1464 if (fdef && tok_see() == '{') {
1465 funcdef(name, func, args, nargs, flags);
1466 return 1;
1469 memcpy(main, type, sizeof(*type));
1470 return 0;
1473 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1474 void *data)
1476 struct type base;
1477 unsigned flags;
1478 if (basetype(&base, &flags))
1479 return 1;
1480 while (tok_see() != ';' && tok_see() != '{') {
1481 struct name name;
1482 name.unused = 0;
1483 if (readname(&name.type, name.name, &base, flags))
1484 break;
1485 if (!tok_jmp('='))
1486 flags |= F_INIT;
1487 def(data, &name, flags);
1488 tok_jmp(',');
1490 return 0;
1493 static void typedefdef(void *data, struct name *name, unsigned flags)
1495 typedef_add(name->name, &name->type);
1498 static void readstmt(void);
1500 #define MAXCASES (1 << 7)
1502 static void readswitch(void)
1504 int break_beg = nbreaks;
1505 long val_addr = o_mklocal(LONGSZ);
1506 long matched[MAXCASES];
1507 int nmatched = 0;
1508 struct type t;
1509 long next;
1510 int ref = 1;
1511 int i;
1512 tok_expect('(');
1513 readexpr();
1514 ts_pop(&t);
1515 o_local(val_addr, TYPE_BT(&t));
1516 o_tmpswap();
1517 o_assign(TYPE_BT(&t));
1518 o_tmpdrop(1);
1519 tok_expect(')');
1520 tok_expect('{');
1521 while (tok_jmp('}')) {
1522 int n = 0;
1523 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1524 if (n++ > 0)
1525 matched[nmatched++] = o_jmp(0);
1526 if (!ref++)
1527 o_filljmp(next);
1528 if (!tok_jmp(TOK_CASE)) {
1529 caseexpr = 1;
1530 readexpr();
1531 caseexpr = 0;
1532 o_local(val_addr, TYPE_BT(&t));
1533 o_bop(O_EQ);
1534 next = o_jz(0);
1535 ref = 0;
1536 tok_expect(':');
1537 o_tmpdrop(1);
1538 ts_pop(NULL);
1539 continue;
1541 if (!tok_jmp(TOK_DEFAULT)) {
1542 tok_expect(':');
1543 continue;
1546 for (i = 0; i < nmatched; i++)
1547 o_filljmp(matched[i]);
1548 nmatched = 0;
1549 readstmt();
1551 o_rmlocal(val_addr, LONGSZ);
1552 if (!ref++)
1553 o_filljmp(next);
1554 break_fill(o_mklabel(), break_beg);
1557 #define MAXGOTO (1 << 10)
1559 static struct gotoinfo {
1560 char name[NAMELEN];
1561 long addr;
1562 } gotos[MAXGOTO];
1563 static int ngotos;
1565 static struct labelinfo {
1566 char name[NAMELEN];
1567 long addr;
1568 } labels[MAXGOTO];
1569 static int nlabels;
1571 static void goto_add(char *name)
1573 strcpy(gotos[ngotos].name, name);
1574 gotos[ngotos++].addr = o_jmp(0);
1577 static void label_add(char *name)
1579 strcpy(labels[nlabels].name, name);
1580 labels[nlabels++].addr = o_mklabel();
1583 static void goto_fill(void)
1585 int i, j;
1586 for (i = 0; i < ngotos; i++)
1587 for (j = 0; j < nlabels; j++)
1588 if (!strcmp(gotos[i].name, labels[j].name)) {
1589 o_filljmp2(gotos[i].addr, labels[j].addr);
1590 break;
1594 static void readstmt(void)
1596 o_tmpdrop(-1);
1597 nts = 0;
1598 if (!tok_jmp('{')) {
1599 int _nlocals = nlocals;
1600 int _nglobals = nglobals;
1601 int _nenums = nenums;
1602 int _ntypedefs = ntypedefs;
1603 int _nstructs = nstructs;
1604 int _nfuncs = nfuncs;
1605 int _narrays = narrays;
1606 while (tok_jmp('}'))
1607 readstmt();
1608 nlocals = _nlocals;
1609 nenums = _nenums;
1610 ntypedefs = _ntypedefs;
1611 nstructs = _nstructs;
1612 nfuncs = _nfuncs;
1613 narrays = _narrays;
1614 nglobals = _nglobals;
1615 return;
1617 if (!readdefs(localdef, NULL)) {
1618 tok_expect(';');
1619 return;
1621 if (!tok_jmp(TOK_TYPEDEF)) {
1622 readdefs(typedefdef, NULL);
1623 tok_expect(';');
1624 return;
1626 if (!tok_jmp(TOK_IF)) {
1627 long l1, l2;
1628 tok_expect('(');
1629 readexpr();
1630 tok_expect(')');
1631 l1 = o_jz(0);
1632 readstmt();
1633 if (!tok_jmp(TOK_ELSE)) {
1634 l2 = o_jmp(0);
1635 o_filljmp(l1);
1636 readstmt();
1637 o_filljmp(l2);
1638 } else {
1639 o_filljmp(l1);
1641 return;
1643 if (!tok_jmp(TOK_WHILE)) {
1644 long l1, l2;
1645 int break_beg = nbreaks;
1646 int continue_beg = ncontinues;
1647 l1 = o_mklabel();
1648 tok_expect('(');
1649 readexpr();
1650 tok_expect(')');
1651 l2 = o_jz(0);
1652 readstmt();
1653 o_jmp(l1);
1654 o_filljmp(l2);
1655 break_fill(o_mklabel(), break_beg);
1656 continue_fill(l1, continue_beg);
1657 return;
1659 if (!tok_jmp(TOK_DO)) {
1660 long l1, l2;
1661 int break_beg = nbreaks;
1662 int continue_beg = ncontinues;
1663 l1 = o_mklabel();
1664 readstmt();
1665 tok_expect(TOK_WHILE);
1666 tok_expect('(');
1667 l2 = o_mklabel();
1668 readexpr();
1669 o_jnz(l1);
1670 tok_expect(')');
1671 break_fill(o_mklabel(), break_beg);
1672 continue_fill(l2, continue_beg);
1673 return;
1675 if (!tok_jmp(TOK_FOR)) {
1676 long l_check, l_jump, j_fail, j_pass;
1677 int break_beg = nbreaks;
1678 int continue_beg = ncontinues;
1679 int has_cond = 0;
1680 tok_expect('(');
1681 if (tok_see() != ';')
1682 readestmt();
1683 tok_expect(';');
1684 l_check = o_mklabel();
1685 if (tok_see() != ';') {
1686 readestmt();
1687 j_fail = o_jz(0);
1688 has_cond = 1;
1690 tok_expect(';');
1691 j_pass = o_jmp(0);
1692 l_jump = o_mklabel();
1693 if (tok_see() != ')')
1694 readestmt();
1695 tok_expect(')');
1696 o_jmp(l_check);
1697 o_filljmp(j_pass);
1698 readstmt();
1699 o_jmp(l_jump);
1700 if (has_cond)
1701 o_filljmp(j_fail);
1702 break_fill(o_mklabel(), break_beg);
1703 continue_fill(l_jump, continue_beg);
1704 return;
1706 if (!tok_jmp(TOK_SWITCH)) {
1707 readswitch();
1708 return;
1710 if (!tok_jmp(TOK_RETURN)) {
1711 int ret = tok_see() != ';';
1712 if (ret)
1713 readexpr();
1714 tok_expect(';');
1715 o_ret(ret_bt);
1716 return;
1718 if (!tok_jmp(TOK_BREAK)) {
1719 tok_expect(';');
1720 breaks[nbreaks++] = o_jmp(0);
1721 return;
1723 if (!tok_jmp(TOK_CONTINUE)) {
1724 tok_expect(';');
1725 continues[ncontinues++] = o_jmp(0);
1726 return;
1728 if (!tok_jmp(TOK_GOTO)) {
1729 tok_expect(TOK_NAME);
1730 goto_add(tok_id());
1731 tok_expect(';');
1732 return;
1734 readestmt();
1735 /* labels */
1736 if (!tok_jmp(':')) {
1737 label_add(tok_id());
1738 return;
1740 tok_expect(';');
1743 static void readdecl(void)
1745 if (!tok_jmp(TOK_TYPEDEF)) {
1746 readdefs(typedefdef, NULL);
1747 tok_expect(';');
1748 return;
1750 readdefs(globaldef, NULL);
1751 if (tok_see() == '{') {
1752 readstmt();
1753 goto_fill();
1754 o_func_end();
1755 nlocals = 0;
1756 ngotos = 0;
1757 nlabels = 0;
1758 return;
1760 tok_expect(';');
1763 static void parse(void)
1765 while (tok_see() != TOK_EOF)
1766 readdecl();
1769 int main(int argc, char *argv[])
1771 char obj[128];
1772 int ofd;
1773 int i = 1;
1774 while (i < argc && argv[i][0] == '-') {
1775 if (argv[i][1] == 'I')
1776 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1777 if (argv[i][1] == 'D') {
1778 char *name = argv[i] + 2;
1779 char *def = "";
1780 char *eq = strchr(name, '=');
1781 if (eq) {
1782 *eq = '\0';
1783 def = eq + 1;
1785 cpp_define(name, def);
1787 i++;
1789 if (i == argc)
1790 die("neatcc: no file given\n");
1791 if (cpp_init(argv[i]))
1792 die("neatcc: cannot open input file\n");
1793 parse();
1794 strcpy(obj, argv[i]);
1795 obj[strlen(obj) - 1] = 'o';
1796 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1797 out_write(ofd);
1798 close(ofd);
1799 return 0;