allow extern array declarations without size
[neatcc/cc.git] / ncc.c
blobc8879e3ff81f9a0f99d9912b34bbcef1fa51d561
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 o_tmpswap();
320 if (!t1.ptr && t2.ptr)
321 if (type_szde(&t2) > 1) {
322 o_num(type_szde(&t2), 4);
323 o_bop(O_MUL);
325 if (t1.ptr && !t2.ptr)
326 o_tmpswap();
327 o_bop(op);
328 if (t1.ptr && t2.ptr) {
329 int sz = type_szde(&t1);
330 if (sz > 1) {
331 o_num(sz, 4);
332 o_bop(O_DIV);
334 ts_push_bt(4 | BT_SIGNED);
335 } else {
336 ts_push(t1.ptr ? &t1 : &t2);
340 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
341 #define MIN(a, b) ((a) < (b) ? (a) : (b))
343 static int type_alignment(struct type *t)
345 if (t->flags & T_ARRAY && !t->ptr)
346 return type_alignment(&arrays[t->id].type);
347 if (t->flags & T_STRUCT && !t->ptr)
348 return type_alignment(&structs[t->id].fields[0].type);
349 return MIN(LONGSZ, type_totsz(t));
352 static void structdef(void *data, struct name *name, unsigned flags)
354 struct structinfo *si = data;
355 if (si->isunion) {
356 name->addr = 0;
357 if (si->size < type_totsz(&name->type))
358 si->size = type_totsz(&name->type);
359 } else {
360 struct type *t = &name->type;
361 int alignment = type_alignment(t);
362 if (t->flags & T_ARRAY && !t->ptr)
363 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
364 si->size = ALIGN(si->size, alignment);
365 name->addr = si->size;
366 si->size += type_totsz(&name->type);
368 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
371 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
373 static int struct_create(char *name, int isunion)
375 int id = struct_find(name, isunion);
376 struct structinfo *si = &structs[id];
377 tok_expect('{');
378 while (tok_jmp('}')) {
379 readdefs(structdef, si);
380 tok_expect(';');
382 return id;
385 static void readexpr(void);
387 static void enum_create(void)
389 long n = 0;
390 tok_expect('{');
391 while (tok_jmp('}')) {
392 char name[NAMELEN];
393 tok_expect(TOK_NAME);
394 strcpy(name, tok_id());
395 if (tok_see() == '=') {
396 tok_get();
397 readexpr();
398 ts_pop(NULL);
399 if (o_popnum(&n))
400 err("const expr expected!\n");
402 enum_add(name, n++);
403 tok_jmp(',');
407 static int basetype(struct type *type, unsigned *flags)
409 int sign = 1;
410 int size = 4;
411 int done = 0;
412 int i = 0;
413 int isunion;
414 char name[NAMELEN] = "";
415 *flags = 0;
416 type->flags = 0;
417 type->ptr = 0;
418 while (!done) {
419 switch (tok_see()) {
420 case TOK_STATIC:
421 *flags |= F_STATIC;
422 break;
423 case TOK_EXTERN:
424 *flags |= F_EXTERN;
425 break;
426 case TOK_VOID:
427 sign = 0;
428 size = 0;
429 done = 1;
430 break;
431 case TOK_INT:
432 done = 1;
433 break;
434 case TOK_CHAR:
435 size = 1;
436 done = 1;
437 break;
438 case TOK_SHORT:
439 size = 2;
440 break;
441 case TOK_LONG:
442 size = LONGSZ;
443 break;
444 case TOK_SIGNED:
445 break;
446 case TOK_UNSIGNED:
447 sign = 0;
448 break;
449 case TOK_UNION:
450 case TOK_STRUCT:
451 isunion = tok_get() == TOK_UNION;
452 if (!tok_jmp(TOK_NAME))
453 strcpy(name, tok_id());
454 if (tok_see() == '{')
455 type->id = struct_create(name, isunion);
456 else
457 type->id = struct_find(name, isunion);
458 type->flags |= T_STRUCT;
459 type->bt = LONGSZ;
460 return 0;
461 case TOK_ENUM:
462 tok_get();
463 tok_jmp(TOK_NAME);
464 if (tok_see() == '{')
465 enum_create();
466 type->bt = 4 | BT_SIGNED;
467 return 0;
468 default:
469 if (tok_see() == TOK_NAME) {
470 int id = typedef_find(tok_id());
471 if (id != -1) {
472 tok_get();
473 memcpy(type, &typedefs[id].type,
474 sizeof(*type));
475 return 0;
478 if (!i)
479 return 1;
480 done = 1;
481 continue;
483 i++;
484 tok_get();
486 type->bt = size | (sign ? BT_SIGNED : 0);
487 return 0;
490 static int readname(struct type *main, char *name,
491 struct type *base, unsigned flags);
493 static int readtype(struct type *type)
495 return readname(type, NULL, NULL, 0);
498 static void readptrs(struct type *type)
500 while (!tok_jmp('*')) {
501 type->ptr++;
502 if (!type->bt)
503 type->bt = 1;
507 /* used to differenciate labels from case and cond exprs */
508 static int ncexpr;
509 static int caseexpr;
511 static void readpre(void);
513 static void readprimary(void)
515 int i;
516 if (!tok_jmp(TOK_NUM)) {
517 long n;
518 int bt = tok_num(&n);
519 ts_push_bt(bt);
520 o_num(n, bt);
521 return;
523 if (!tok_jmp(TOK_STR)) {
524 struct type t;
525 char buf[BUFSIZE];
526 int len;
527 t.bt = 1 | BT_SIGNED;
528 t.ptr = 1;
529 t.flags = 0;
530 ts_push(&t);
531 len = tok_str(buf);
532 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
533 o_addr();
534 return;
536 if (!tok_jmp(TOK_NAME)) {
537 struct name unkn = {0};
538 char *name = unkn.name;
539 int n;
540 strcpy(name, tok_id());
541 /* don't search for labels here */
542 if (!ncexpr && !caseexpr && tok_see() == ':')
543 return;
544 for (i = nlocals - 1; i >= 0; --i) {
545 struct type *t = &locals[i].type;
546 if (!strcmp(locals[i].name, name)) {
547 o_local(locals[i].addr, TYPE_BT(t));
548 ts_push(t);
549 return;
552 if ((n = global_find(name)) != -1) {
553 struct name *g = &globals[n];
554 struct type *t = &g->type;
555 if (g->unused) {
556 g->unused = 0;
557 if (t->flags & T_FUNC && !t->ptr)
558 g->addr = out_mkundef(name, 0);
559 else
560 g->addr = out_mkundef(name, type_totsz(t));
562 o_symaddr(g->addr, TYPE_BT(t));
563 ts_push(t);
564 return;
566 if (!enum_find(&n, name)) {
567 ts_push_bt(4 | BT_SIGNED);
568 o_num(n, 4 | BT_SIGNED);
569 return;
571 if (tok_see() != '(')
572 err("unknown symbol\n");
573 unkn.addr = out_mkundef(unkn.name, 0);
574 global_add(&unkn);
575 ts_push_bt(LONGSZ);
576 o_symaddr(unkn.addr, LONGSZ);
577 return;
579 if (!tok_jmp('(')) {
580 struct type t;
581 if (!readtype(&t)) {
582 struct type o;
583 tok_expect(')');
584 readpre();
585 ts_pop(&o);
586 ts_push(&t);
587 if (!t.ptr || !o.ptr)
588 o_cast(TYPE_BT(&t));
589 } else {
590 readexpr();
591 tok_expect(')');
593 return;
597 void arrayderef(struct type *t)
599 int sz = type_totsz(t);
600 if (sz > 1) {
601 o_num(sz, 4);
602 o_bop(O_MUL);
604 o_bop(O_ADD);
605 o_deref(TYPE_BT(t));
608 static void inc_post(int inc_one, int inc_many)
610 struct type *t = &ts[nts - 1];
611 int sz = type_szde(t);
612 o_tmpcopy();
613 o_load();
614 o_tmpswap();
615 if (!t->ptr || sz == 1) {
616 o_uop(inc_one);
617 } else {
618 o_tmpcopy();
619 o_num(sz, 4);
620 o_bop(inc_many);
621 o_assign(TYPE_BT(t));
623 o_tmpdrop(1);
626 static void readfield(void)
628 struct name *field;
629 struct type t;
630 tok_expect(TOK_NAME);
631 ts_pop(&t);
632 array2ptr(&t);
633 field = struct_field(t.id, tok_id());
634 if (field->addr) {
635 o_num(field->addr, 4);
636 o_bop(O_ADD);
638 o_deref(TYPE_BT(&field->type));
639 ts_push(&field->type);
642 #define MAXFUNCS (1 << 10)
644 static struct funcinfo {
645 struct type args[MAXFIELDS];
646 struct type ret;
647 int nargs;
648 } funcs[MAXFUNCS];
649 static int nfuncs;
650 static unsigned ret_bt;
652 static int func_create(struct type *ret, struct name *args, int nargs)
654 struct funcinfo *fi = &funcs[nfuncs++];
655 int i;
656 if (nfuncs >= MAXFUNCS)
657 err("nomem: MAXFUNCS reached!\n");
658 memcpy(&fi->ret, ret, sizeof(*ret));
659 for (i = 0; i < nargs; i++)
660 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
661 fi->nargs = nargs;
662 return fi - funcs;
665 static void readcall(void)
667 struct type t;
668 unsigned bt[MAXARGS];
669 struct funcinfo *fi;
670 int argc = 0;
671 int i;
672 ts_pop(&t);
673 if (t.flags & T_FUNC && t.ptr > 0)
674 o_deref(LONGSZ);
675 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
676 if (tok_see() != ')') {
677 readexpr();
678 ts_pop(&t);
679 bt[argc++] = TYPE_BT(&t);
681 while (!tok_jmp(',')) {
682 readexpr();
683 ts_pop(&t);
684 bt[argc++] = TYPE_BT(&t);
686 tok_expect(')');
687 if (fi)
688 for (i = 0; i < fi->nargs; i++)
689 bt[i] = TYPE_BT(&fi->args[i]);
690 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
691 if (fi)
692 ts_push(&fi->ret);
693 else
694 ts_push_bt(4 | BT_SIGNED);
697 static void readpost(void)
699 readprimary();
700 while (1) {
701 if (!tok_jmp('[')) {
702 struct type t;
703 ts_pop(&t);
704 readexpr();
705 ts_pop(NULL);
706 tok_expect(']');
707 array2ptr(&t);
708 t.ptr--;
709 arrayderef(&t);
710 ts_push(&t);
711 continue;
713 if (!tok_jmp('(')) {
714 readcall();
715 continue;
717 if (!tok_jmp(TOK2("++"))) {
718 inc_post(O_INC, O_ADD);
719 continue;
721 if (!tok_jmp(TOK2("--"))) {
722 inc_post(O_DEC, O_SUB);
723 continue;
725 if (!tok_jmp('.')) {
726 o_addr();
727 readfield();
728 continue;
730 if (!tok_jmp(TOK2("->"))) {
731 readfield();
732 continue;
734 break;
738 static void inc_pre(int inc_one, int inc_many)
740 struct type *t;
741 int sz;
742 readpre();
743 t = &ts[nts - 1];
744 sz = (t->flags & T_ARRAY || t->ptr) ? type_szde(t) : 1;
745 if (sz == 1) {
746 o_uop(inc_one);
747 } else {
748 o_tmpcopy();
749 o_num(sz, 4);
750 o_bop(inc_many);
751 o_assign(TYPE_BT(t));
755 static void readpre(void)
757 if (!tok_jmp('&')) {
758 struct type type;
759 readpre();
760 ts_pop(&type);
761 type.ptr++;
762 ts_push(&type);
763 o_addr();
764 return;
766 if (!tok_jmp('*')) {
767 struct type t;
768 readpre();
769 ts_pop(&t);
770 array2ptr(&t);
771 t.ptr--;
772 o_deref(TYPE_BT(&t));
773 ts_push(&t);
774 return;
776 if (!tok_jmp('!')) {
777 struct type type;
778 readpre();
779 ts_pop(&type);
780 o_uop(O_LNOT);
781 ts_push_bt(4 | BT_SIGNED);
782 return;
784 if (!tok_jmp('-')) {
785 readpre();
786 o_uop(O_NEG);
787 return;
789 if (!tok_jmp('~')) {
790 readpre();
791 o_uop(O_NOT);
792 return;
794 if (!tok_jmp(TOK2("++"))) {
795 inc_pre(O_INC, O_ADD);
796 return;
798 if (!tok_jmp(TOK2("--"))) {
799 inc_pre(O_DEC, O_SUB);
800 return;
802 if (!tok_jmp(TOK_SIZEOF)) {
803 struct type t;
804 int op = !tok_jmp('(');
805 if (readtype(&t)) {
806 int nogen = !o_nogen();
807 readexpr();
808 if (nogen)
809 o_dogen();
810 ts_pop(&t);
811 o_tmpdrop(1);
813 ts_push_bt(4);
814 o_num(type_totsz(&t), 4);
815 if (op)
816 tok_expect(')');
817 return;
819 readpost();
822 static void readmul(void)
824 readpre();
825 while (1) {
826 if (!tok_jmp('*')) {
827 readpre();
828 ts_binop(O_MUL);
829 continue;
831 if (!tok_jmp('/')) {
832 readpre();
833 ts_binop(O_DIV);
834 continue;
836 if (!tok_jmp('%')) {
837 readpre();
838 ts_binop(O_MOD);
839 continue;
841 break;
845 static void readadd(void)
847 readmul();
848 while (1) {
849 if (!tok_jmp('+')) {
850 readmul();
851 ts_addop(O_ADD);
852 continue;
854 if (!tok_jmp('-')) {
855 readmul();
856 ts_addop(O_SUB);
857 continue;
859 break;
863 static void shift(int op)
865 struct type t;
866 readadd();
867 ts_pop(NULL);
868 ts_pop(&t);
869 o_bop(op);
870 ts_push_bt(TYPE_BT(&t));
873 static void readshift(void)
875 readadd();
876 while (1) {
877 if (!tok_jmp(TOK2("<<"))) {
878 shift(O_SHL);
879 continue;
881 if (!tok_jmp(TOK2(">>"))) {
882 shift(O_SHR);
883 continue;
885 break;
889 static void cmp(int op)
891 readshift();
892 ts_pop(NULL);
893 ts_pop(NULL);
894 o_bop(op);
895 ts_push_bt(4 | BT_SIGNED);
898 static void readcmp(void)
900 readshift();
901 while (1) {
902 if (!tok_jmp('<')) {
903 cmp(O_LT);
904 continue;
906 if (!tok_jmp('>')) {
907 cmp(O_GT);
908 continue;
910 if (!tok_jmp(TOK2("<="))) {
911 cmp(O_LE);
912 continue;
914 if (!tok_jmp(TOK2(">="))) {
915 cmp(O_GE);
916 continue;
918 break;
922 static void eq(int op)
924 readcmp();
925 ts_pop(NULL);
926 ts_pop(NULL);
927 o_bop(op);
928 ts_push_bt(4 | BT_SIGNED);
931 static void readeq(void)
933 readcmp();
934 while (1) {
935 if (!tok_jmp(TOK2("=="))) {
936 eq(O_EQ);
937 continue;
939 if (!tok_jmp(TOK2("!="))) {
940 eq(O_NEQ);
941 continue;
943 break;
947 static void readbitand(void)
949 readeq();
950 while (!tok_jmp('&')) {
951 readeq();
952 ts_binop(O_AND);
956 static void readxor(void)
958 readbitand();
959 while (!tok_jmp('^')) {
960 readbitand();
961 ts_binop(O_XOR);
965 static void readbitor(void)
967 readxor();
968 while (!tok_jmp('|')) {
969 readxor();
970 ts_binop(O_OR);
974 #define MAXCOND (1 << 7)
976 static void readand(void)
978 long conds[MAXCOND];
979 int nconds = 0;
980 long passed;
981 int i;
982 readbitor();
983 if (tok_see() != TOK2("&&"))
984 return;
985 o_fork();
986 conds[nconds++] = o_jz(0);
987 ts_pop(NULL);
988 while (!tok_jmp(TOK2("&&"))) {
989 readbitor();
990 conds[nconds++] = o_jz(0);
991 ts_pop(NULL);
993 o_num(1, 4 | BT_SIGNED);
994 o_forkpush();
995 passed = o_jmp(0);
996 for (i = 0; i < nconds; i++)
997 o_filljmp(conds[i]);
998 o_num(0, 4 | BT_SIGNED);
999 o_forkpush();
1000 o_forkjoin();
1001 o_filljmp(passed);
1002 ts_push_bt(4 | BT_SIGNED);
1005 static void reador(void)
1007 long conds[MAXCOND];
1008 int nconds = 0;
1009 long failed;
1010 int i;
1011 readand();
1012 if (tok_see() != TOK2("||"))
1013 return;
1014 o_fork();
1015 conds[nconds++] = o_jnz(0);
1016 ts_pop(NULL);
1017 while (!tok_jmp(TOK2("||"))) {
1018 readand();
1019 conds[nconds++] = o_jnz(0);
1020 ts_pop(NULL);
1022 o_num(0, 4 | BT_SIGNED);
1023 o_forkpush();
1024 failed = o_jmp(0);
1025 for (i = 0; i < nconds; i++)
1026 o_filljmp(conds[i]);
1027 o_num(1, 4 | BT_SIGNED);
1028 o_forkpush();
1029 o_forkjoin();
1030 o_filljmp(failed);
1031 ts_push_bt(4 | BT_SIGNED);
1034 static int readcexpr_const(void)
1036 long c;
1037 int nogen;
1038 if (o_popnum(&c))
1039 return -1;
1040 if (!c)
1041 nogen = !o_nogen();
1042 reador();
1043 ts_pop(NULL);
1044 tok_expect(':');
1045 if (c) {
1046 nogen = !o_nogen();
1047 } else {
1048 if (nogen)
1049 o_dogen();
1050 o_tmpdrop(1);
1052 reador();
1053 if (c) {
1054 if (nogen)
1055 o_dogen();
1056 o_tmpdrop(1);
1058 return 0;
1061 static void readcexpr(void)
1063 long l1, l2;
1064 reador();
1065 if (tok_jmp('?'))
1066 return;
1067 ncexpr++;
1068 ts_pop(NULL);
1069 o_fork();
1070 if (readcexpr_const()) {
1071 l1 = o_jz(0);
1072 reador();
1073 o_forkpush();
1074 l2 = o_jmp(0);
1075 ts_pop(NULL);
1077 tok_expect(':');
1078 o_filljmp(l1);
1079 reador();
1080 o_forkpush();
1081 o_forkjoin();
1082 o_filljmp(l2);
1084 ncexpr--;
1087 static void opassign(int op, int ptrop)
1089 struct type *t = &ts[nts - 1];
1090 if (ptrop && (t->flags & T_ARRAY || t->ptr)) {
1091 o_tmpcopy();
1092 readexpr();
1093 ts_addop(op);
1094 o_assign(TYPE_BT(&ts[nts - 1]));
1095 ts_pop(NULL);
1096 } else {
1097 readexpr();
1098 o_bop(op | O_SET);
1099 ts_pop(NULL);
1103 static void doassign(void)
1105 struct type t;
1106 ts_pop(&t);
1107 if (!t.ptr && t.flags & T_STRUCT)
1108 o_memcpy(type_totsz(&t));
1109 else
1110 o_assign(TYPE_BT(&ts[nts - 1]));
1113 static void readexpr(void)
1115 readcexpr();
1116 if (!tok_jmp('=')) {
1117 readexpr();
1118 doassign();
1119 return;
1121 if (!tok_jmp(TOK2("+="))) {
1122 opassign(O_ADD, 1);
1123 return;
1125 if (!tok_jmp(TOK2("-="))) {
1126 opassign(O_SUB, 1);
1127 return;
1129 if (!tok_jmp(TOK2("*="))) {
1130 opassign(O_MUL, 0);
1131 return;
1133 if (!tok_jmp(TOK2("/="))) {
1134 opassign(O_DIV, 0);
1135 return;
1137 if (!tok_jmp(TOK2("%="))) {
1138 opassign(O_MOD, 0);
1139 return;
1141 if (!tok_jmp(TOK3("<<="))) {
1142 opassign(O_SHL, 0);
1143 return;
1145 if (!tok_jmp(TOK3(">>="))) {
1146 opassign(O_SHR, 0);
1147 return;
1149 if (!tok_jmp(TOK3("&="))) {
1150 opassign(O_AND, 0);
1151 return;
1153 if (!tok_jmp(TOK3("|="))) {
1154 opassign(O_OR, 0);
1155 return;
1157 if (!tok_jmp(TOK3("^="))) {
1158 opassign(O_XOR, 0);
1159 return;
1163 static void readestmt(void)
1165 do {
1166 o_tmpdrop(-1);
1167 nts = 0;
1168 readexpr();
1169 } while (!tok_jmp(','));
1172 static void o_localoff(long addr, int off, unsigned bt)
1174 o_local(addr, bt);
1175 if (off) {
1176 o_addr();
1177 o_num(off, 4);
1178 o_bop(O_ADD);
1179 o_deref(bt);
1183 static struct type *innertype(struct type *t)
1185 if (t->flags & T_ARRAY && !t->ptr)
1186 return innertype(&arrays[t->id].type);
1187 return t;
1190 static void initexpr(struct type *t, int off, void *obj,
1191 void (*set)(void *obj, int off, struct type *t))
1193 if (tok_jmp('{')) {
1194 set(obj, off, t);
1195 return;
1197 if (!t->ptr && t->flags & T_STRUCT) {
1198 struct structinfo *si = &structs[t->id];
1199 int i;
1200 for (i = 0; i < si->nfields; i++) {
1201 struct name *field = &si->fields[i];
1202 if (!tok_jmp('.')) {
1203 tok_expect(TOK_NAME);
1204 field = struct_field(t->id, tok_id());
1205 tok_expect('=');
1207 initexpr(&field->type, off + field->addr, obj, set);
1208 if (tok_jmp(',') || tok_see() == '}')
1209 break;
1211 } else if (t->flags & T_ARRAY) {
1212 struct type *t_de = &arrays[t->id].type;
1213 int i;
1214 for (i = 0; ; i++) {
1215 long idx = i;
1216 struct type *it = t_de;
1217 if (!tok_jmp('[')) {
1218 readexpr();
1219 o_popnum(&idx);
1220 ts_pop(NULL);
1221 tok_expect(']');
1222 tok_expect('=');
1224 if (tok_see() != '{')
1225 it = innertype(t_de);
1226 initexpr(it, off + type_totsz(it) * idx, obj, set);
1227 if (tok_jmp(',') || tok_see() == '}')
1228 break;
1231 tok_expect('}');
1234 static void jumpbrace(void)
1236 int depth = 0;
1237 while (tok_see() != '}' || depth--)
1238 if (tok_get() == '{')
1239 depth++;
1240 tok_expect('}');
1243 static int initsize(void)
1245 long addr = tok_addr();
1246 int n = 0;
1247 if (!tok_jmp(TOK_STR)) {
1248 n = tok_str(NULL);
1249 tok_jump(addr);
1250 return n;
1252 o_nogen();
1253 tok_expect('{');
1254 while (tok_jmp('}')) {
1255 long idx = n;
1256 if (!tok_jmp('[')) {
1257 readexpr();
1258 o_popnum(&idx);
1259 ts_pop(NULL);
1260 tok_expect(']');
1261 tok_expect('=');
1263 if (n < idx + 1)
1264 n = idx + 1;
1265 while (tok_see() != '}' && tok_see() != ',')
1266 if (tok_get() == '{')
1267 jumpbrace();
1268 tok_jmp(',');
1270 o_dogen();
1271 tok_jump(addr);
1272 return n;
1275 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1277 static void globalinit(void *obj, int off, struct type *t)
1279 long addr = *(long *) obj;
1280 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1281 struct type *t_de = &arrays[t->id].type;
1282 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1283 char buf[BUFSIZE];
1284 int len;
1285 tok_expect(TOK_STR);
1286 len = tok_str(buf);
1287 out_datcpy(addr, off, buf, len);
1288 return;
1291 readexpr();
1292 o_datset(addr, off, TYPE_BT(t));
1293 ts_pop(NULL);
1296 static void globaldef(void *data, struct name *name, unsigned flags)
1298 struct type *t = &name->type;
1299 char *varname = flags & F_STATIC ? NULL : name->name;
1300 int sz;
1301 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1302 if (~flags & F_EXTERN)
1303 arrays[t->id].n = initsize();
1304 sz = type_totsz(t);
1305 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1306 name->unused = 1;
1307 else if (flags & F_INIT)
1308 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1309 else
1310 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1311 global_add(name);
1312 if (flags & F_INIT)
1313 initexpr(t, 0, &name->addr, globalinit);
1316 static void localinit(void *obj, int off, struct type *t)
1318 long addr = *(long *) obj;
1319 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1320 struct type *t_de = &arrays[t->id].type;
1321 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1322 char buf[BUFSIZE];
1323 int len;
1324 tok_expect(TOK_STR);
1325 len = tok_str(buf);
1326 o_localoff(addr, off, TYPE_BT(t));
1327 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1328 o_memcpy(len);
1329 o_tmpdrop(1);
1330 return;
1333 o_localoff(addr, off, TYPE_BT(t));
1334 ts_push(t);
1335 readexpr();
1336 doassign();
1337 ts_pop(NULL);
1338 o_tmpdrop(1);
1341 static void localdef(void *data, struct name *name, unsigned flags)
1343 struct type *t = &name->type;
1344 if (flags & (F_STATIC | F_EXTERN)) {
1345 globaldef(data, name, flags);
1346 return;
1348 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1349 arrays[t->id].n = initsize();
1350 name->addr = o_mklocal(type_totsz(&name->type));
1351 local_add(name);
1352 if (flags & F_INIT) {
1353 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1354 o_local(name->addr, TYPE_BT(t));
1355 o_memset(0, type_totsz(t));
1356 o_tmpdrop(1);
1358 initexpr(t, 0, &name->addr, localinit);
1362 static void funcdef(char *name, struct type *type, struct name *args,
1363 int nargs, unsigned flags)
1365 struct name global;
1366 int i;
1367 strcpy(global.name, name);
1368 memcpy(&global.type, type, sizeof(*type));
1369 global.addr = o_func_beg(name, F_GLOBAL(flags));
1370 global.unused = 0;
1371 global_add(&global);
1372 ret_bt = TYPE_BT(&funcs[type->id].ret);
1373 for (i = 0; i < nargs; i++) {
1374 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1375 local_add(&args[i]);
1379 static int readargs(struct name *args)
1381 int nargs = 0;
1382 tok_expect('(');
1383 while (tok_see() != ')') {
1384 if (!tok_jmp(TOK3("...")))
1385 break;
1386 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1387 array2ptr(&args[nargs].type);
1388 nargs++;
1389 if (tok_jmp(','))
1390 break;
1392 tok_expect(')');
1393 if (nargs == 1 && !TYPE_BT(&args[0].type))
1394 return 0;
1395 return nargs;
1398 static int readname(struct type *main, char *name,
1399 struct type *base, unsigned flags)
1401 struct type tpool[3];
1402 int npool = 0;
1403 struct type *type = &tpool[npool++];
1404 struct type *func = NULL;
1405 struct type *ret = NULL;
1406 int arsz[10];
1407 int nar = 0;
1408 int i;
1409 memset(tpool, 0, sizeof(tpool));
1410 if (name)
1411 *name = '\0';
1412 if (!base) {
1413 if (basetype(type, &flags))
1414 return 1;
1415 } else {
1416 memcpy(type, base, sizeof(*base));
1418 readptrs(type);
1419 if (!tok_jmp('(')) {
1420 ret = type;
1421 type = &tpool[npool++];
1422 func = type;
1423 readptrs(type);
1425 if (!tok_jmp(TOK_NAME) && name)
1426 strcpy(name, tok_id());
1427 while (!tok_jmp('[')) {
1428 long n = 0;
1429 if (tok_jmp(']')) {
1430 readexpr();
1431 ts_pop(NULL);
1432 if (o_popnum(&n))
1433 err("const expr expected\n");
1434 tok_expect(']');
1436 arsz[nar++] = n;
1438 for (i = nar - 1; i >= 0; i--) {
1439 type->id = array_add(type, arsz[i]);
1440 if (func && i == nar - 1)
1441 func = &arrays[type->id].type;
1442 type->flags = T_ARRAY;
1443 type->bt = LONGSZ;
1444 type->ptr = 0;
1446 if (func)
1447 tok_expect(')');
1448 if (tok_see() == '(') {
1449 struct name args[MAXARGS];
1450 int nargs = readargs(args);
1451 int fdef = !func;
1452 if (!func) {
1453 ret = type;
1454 type = &tpool[npool++];
1455 func = type;
1457 func->flags = T_FUNC;
1458 func->bt = LONGSZ;
1459 func->id = func_create(ret, args, nargs);
1460 if (fdef && tok_see() == '{') {
1461 funcdef(name, func, args, nargs, flags);
1462 return 1;
1465 memcpy(main, type, sizeof(*type));
1466 return 0;
1469 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1470 void *data)
1472 struct type base;
1473 unsigned base_flags;
1474 if (basetype(&base, &base_flags))
1475 return 1;
1476 while (tok_see() != ';' && tok_see() != '{') {
1477 struct name name;
1478 unsigned flags = base_flags;
1479 name.unused = 0;
1480 if (readname(&name.type, name.name, &base, flags))
1481 break;
1482 if (!tok_jmp('='))
1483 flags |= F_INIT;
1484 def(data, &name, flags);
1485 tok_jmp(',');
1487 return 0;
1490 static void typedefdef(void *data, struct name *name, unsigned flags)
1492 typedef_add(name->name, &name->type);
1495 static void readstmt(void);
1497 #define MAXCASES (1 << 7)
1499 static void readswitch(void)
1501 int break_beg = nbreaks;
1502 long val_addr = o_mklocal(LONGSZ);
1503 long matched[MAXCASES];
1504 int nmatched = 0;
1505 struct type t;
1506 long next;
1507 int ref = 1;
1508 int i;
1509 tok_expect('(');
1510 readexpr();
1511 ts_pop(&t);
1512 o_local(val_addr, TYPE_BT(&t));
1513 o_tmpswap();
1514 o_assign(TYPE_BT(&t));
1515 o_tmpdrop(1);
1516 tok_expect(')');
1517 tok_expect('{');
1518 while (tok_jmp('}')) {
1519 int n = 0;
1520 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1521 if (n++ > 0)
1522 matched[nmatched++] = o_jmp(0);
1523 if (!ref++)
1524 o_filljmp(next);
1525 if (!tok_jmp(TOK_CASE)) {
1526 caseexpr = 1;
1527 readexpr();
1528 caseexpr = 0;
1529 o_local(val_addr, TYPE_BT(&t));
1530 o_bop(O_EQ);
1531 next = o_jz(0);
1532 ref = 0;
1533 tok_expect(':');
1534 o_tmpdrop(1);
1535 ts_pop(NULL);
1536 continue;
1538 if (!tok_jmp(TOK_DEFAULT)) {
1539 tok_expect(':');
1540 continue;
1543 for (i = 0; i < nmatched; i++)
1544 o_filljmp(matched[i]);
1545 nmatched = 0;
1546 readstmt();
1548 o_rmlocal(val_addr, LONGSZ);
1549 if (!ref++)
1550 o_filljmp(next);
1551 break_fill(o_mklabel(), break_beg);
1554 #define MAXGOTO (1 << 10)
1556 static struct gotoinfo {
1557 char name[NAMELEN];
1558 long addr;
1559 } gotos[MAXGOTO];
1560 static int ngotos;
1562 static struct labelinfo {
1563 char name[NAMELEN];
1564 long addr;
1565 } labels[MAXGOTO];
1566 static int nlabels;
1568 static void goto_add(char *name)
1570 strcpy(gotos[ngotos].name, name);
1571 gotos[ngotos++].addr = o_jmp(0);
1574 static void label_add(char *name)
1576 strcpy(labels[nlabels].name, name);
1577 labels[nlabels++].addr = o_mklabel();
1580 static void goto_fill(void)
1582 int i, j;
1583 for (i = 0; i < ngotos; i++)
1584 for (j = 0; j < nlabels; j++)
1585 if (!strcmp(gotos[i].name, labels[j].name)) {
1586 o_filljmp2(gotos[i].addr, labels[j].addr);
1587 break;
1591 static void readstmt(void)
1593 o_tmpdrop(-1);
1594 nts = 0;
1595 if (!tok_jmp('{')) {
1596 int _nlocals = nlocals;
1597 int _nglobals = nglobals;
1598 int _nenums = nenums;
1599 int _ntypedefs = ntypedefs;
1600 int _nstructs = nstructs;
1601 int _nfuncs = nfuncs;
1602 int _narrays = narrays;
1603 while (tok_jmp('}'))
1604 readstmt();
1605 nlocals = _nlocals;
1606 nenums = _nenums;
1607 ntypedefs = _ntypedefs;
1608 nstructs = _nstructs;
1609 nfuncs = _nfuncs;
1610 narrays = _narrays;
1611 nglobals = _nglobals;
1612 return;
1614 if (!readdefs(localdef, NULL)) {
1615 tok_expect(';');
1616 return;
1618 if (!tok_jmp(TOK_TYPEDEF)) {
1619 readdefs(typedefdef, NULL);
1620 tok_expect(';');
1621 return;
1623 if (!tok_jmp(TOK_IF)) {
1624 long l1, l2;
1625 tok_expect('(');
1626 readexpr();
1627 tok_expect(')');
1628 l1 = o_jz(0);
1629 readstmt();
1630 if (!tok_jmp(TOK_ELSE)) {
1631 l2 = o_jmp(0);
1632 o_filljmp(l1);
1633 readstmt();
1634 o_filljmp(l2);
1635 } else {
1636 o_filljmp(l1);
1638 return;
1640 if (!tok_jmp(TOK_WHILE)) {
1641 long l1, l2;
1642 int break_beg = nbreaks;
1643 int continue_beg = ncontinues;
1644 l1 = o_mklabel();
1645 tok_expect('(');
1646 readexpr();
1647 tok_expect(')');
1648 l2 = o_jz(0);
1649 readstmt();
1650 o_jmp(l1);
1651 o_filljmp(l2);
1652 break_fill(o_mklabel(), break_beg);
1653 continue_fill(l1, continue_beg);
1654 return;
1656 if (!tok_jmp(TOK_DO)) {
1657 long l1, l2;
1658 int break_beg = nbreaks;
1659 int continue_beg = ncontinues;
1660 l1 = o_mklabel();
1661 readstmt();
1662 tok_expect(TOK_WHILE);
1663 tok_expect('(');
1664 l2 = o_mklabel();
1665 readexpr();
1666 o_jnz(l1);
1667 tok_expect(')');
1668 break_fill(o_mklabel(), break_beg);
1669 continue_fill(l2, continue_beg);
1670 return;
1672 if (!tok_jmp(TOK_FOR)) {
1673 long l_check, l_jump, j_fail, j_pass;
1674 int break_beg = nbreaks;
1675 int continue_beg = ncontinues;
1676 int has_cond = 0;
1677 tok_expect('(');
1678 if (tok_see() != ';')
1679 readestmt();
1680 tok_expect(';');
1681 l_check = o_mklabel();
1682 if (tok_see() != ';') {
1683 readestmt();
1684 j_fail = o_jz(0);
1685 has_cond = 1;
1687 tok_expect(';');
1688 j_pass = o_jmp(0);
1689 l_jump = o_mklabel();
1690 if (tok_see() != ')')
1691 readestmt();
1692 tok_expect(')');
1693 o_jmp(l_check);
1694 o_filljmp(j_pass);
1695 readstmt();
1696 o_jmp(l_jump);
1697 if (has_cond)
1698 o_filljmp(j_fail);
1699 break_fill(o_mklabel(), break_beg);
1700 continue_fill(l_jump, continue_beg);
1701 return;
1703 if (!tok_jmp(TOK_SWITCH)) {
1704 readswitch();
1705 return;
1707 if (!tok_jmp(TOK_RETURN)) {
1708 int ret = tok_see() != ';';
1709 if (ret)
1710 readexpr();
1711 tok_expect(';');
1712 o_ret(ret_bt);
1713 return;
1715 if (!tok_jmp(TOK_BREAK)) {
1716 tok_expect(';');
1717 breaks[nbreaks++] = o_jmp(0);
1718 return;
1720 if (!tok_jmp(TOK_CONTINUE)) {
1721 tok_expect(';');
1722 continues[ncontinues++] = o_jmp(0);
1723 return;
1725 if (!tok_jmp(TOK_GOTO)) {
1726 tok_expect(TOK_NAME);
1727 goto_add(tok_id());
1728 tok_expect(';');
1729 return;
1731 readestmt();
1732 /* labels */
1733 if (!tok_jmp(':')) {
1734 label_add(tok_id());
1735 return;
1737 tok_expect(';');
1740 static void readdecl(void)
1742 if (!tok_jmp(TOK_TYPEDEF)) {
1743 readdefs(typedefdef, NULL);
1744 tok_expect(';');
1745 return;
1747 readdefs(globaldef, NULL);
1748 if (tok_see() == '{') {
1749 readstmt();
1750 goto_fill();
1751 o_func_end();
1752 nlocals = 0;
1753 ngotos = 0;
1754 nlabels = 0;
1755 return;
1757 tok_expect(';');
1760 static void parse(void)
1762 while (tok_see() != TOK_EOF)
1763 readdecl();
1766 int main(int argc, char *argv[])
1768 char obj[128];
1769 int ofd;
1770 int i = 1;
1771 while (i < argc && argv[i][0] == '-') {
1772 if (argv[i][1] == 'I')
1773 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1774 if (argv[i][1] == 'D') {
1775 char *name = argv[i] + 2;
1776 char *def = "";
1777 char *eq = strchr(name, '=');
1778 if (eq) {
1779 *eq = '\0';
1780 def = eq + 1;
1782 cpp_define(name, def);
1784 i++;
1786 if (i == argc)
1787 die("neatcc: no file given\n");
1788 if (cpp_init(argv[i]))
1789 die("neatcc: cannot open input file\n");
1790 parse();
1791 strcpy(obj, argv[i]);
1792 obj[strlen(obj) - 1] = 'o';
1793 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1794 out_write(ofd);
1795 close(ofd);
1796 return 0;