show syntax error location
[neatcc.git] / ncc.c
blobade09ff56dac9a152e87f5f7b16451dacc29cc79
1 /*
2 * neatcc - A small and simple x86_64 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 ? 8 : (t)->bt)
25 #define TYPE_SZ(t) ((t)->ptr ? 8 : (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 char err[1 << 7];
70 int len = cpp_loc(err, tok_addr());
71 strcpy(err + len, msg);
72 print(err);
73 exit(1);
76 struct name {
77 char name[NAMELEN];
78 struct type type;
79 long addr;
80 int unused; /* unreferenced external symbols */
83 static struct name locals[MAXLOCALS];
84 static int nlocals;
85 static struct name globals[MAXGLOBALS];
86 static int nglobals;
88 static void local_add(struct name *name)
90 if (nlocals >= MAXLOCALS)
91 die("nomem: MAXLOCALS reached!\n");
92 memcpy(&locals[nlocals++], name, sizeof(*name));
95 static int global_find(char *name)
97 int i;
98 for (i = 0; i < nglobals; i++)
99 if (!strcmp(name, globals[i].name))
100 return i;
101 return -1;
104 static void global_add(struct name *name)
106 int found = global_find(name->name);
107 int i = found == -1 ? nglobals++ : found;
108 if (nglobals >= MAXGLOBALS)
109 die("nomem: MAXGLOBALS reached!\n");
110 memcpy(&globals[i], name, sizeof(*name));
113 #define MAXENUMS (1 << 10)
115 static struct enumval {
116 char name[NAMELEN];
117 int n;
118 } enums[MAXENUMS];
119 static int nenums;
121 static void enum_add(char *name, int val)
123 struct enumval *ev = &enums[nenums++];
124 if (nenums >= MAXENUMS)
125 die("nomem: MAXENUMS reached!\n");
126 strcpy(ev->name, name);
127 ev->n = val;
130 static int enum_find(int *val, char *name)
132 int i;
133 for (i = nenums - 1; i >= 0; --i)
134 if (!strcmp(name, enums[i].name)) {
135 *val = enums[i].n;
136 return 0;
138 return 1;
141 #define MAXTYPEDEFS (1 << 10)
143 static struct typdefinfo {
144 char name[NAMELEN];
145 struct type type;
146 } typedefs[MAXTYPEDEFS];
147 static int ntypedefs;
149 static void typedef_add(char *name, struct type *type)
151 struct typdefinfo *ti = &typedefs[ntypedefs++];
152 if (ntypedefs >= MAXTYPEDEFS)
153 die("nomem: MAXTYPEDEFS reached!\n");
154 strcpy(ti->name, name);
155 memcpy(&ti->type, type, sizeof(*type));
158 static int typedef_find(char *name)
160 int i;
161 for (i = ntypedefs - 1; i >= 0; --i)
162 if (!strcmp(name, typedefs[i].name))
163 return i;
164 return -1;
167 #define MAXARRAYS (1 << 10)
169 static struct array {
170 struct type type;
171 int n;
172 } arrays[MAXARRAYS];
173 static int narrays;
175 static int array_add(struct type *type, int n)
177 struct array *a = &arrays[narrays++];
178 if (narrays >= MAXARRAYS)
179 die("nomem: MAXARRAYS reached!\n");
180 memcpy(&a->type, type, sizeof(*type));
181 a->n = n;
182 return a - arrays;
185 static void array2ptr(struct type *t)
187 if (!(t->flags & T_ARRAY) || t->ptr)
188 return;
189 memcpy(t, &arrays[t->id].type, sizeof(*t));
190 t->ptr++;
193 #define MAXSTRUCTS (1 << 10)
194 #define MAXFIELDS (1 << 7)
196 static struct structinfo {
197 char name[NAMELEN];
198 struct name fields[MAXFIELDS];
199 int nfields;
200 int isunion;
201 int size;
202 } structs[MAXSTRUCTS];
203 static int nstructs;
205 static int struct_find(char *name, int isunion)
207 int i;
208 for (i = nstructs - 1; i >= 0; --i)
209 if (*structs[i].name && !strcmp(name, structs[i].name) &&
210 structs[i].isunion == isunion)
211 return i;
212 i = nstructs++;
213 if (nstructs >= MAXSTRUCTS)
214 die("nomem: MAXTYPES reached!\n");
215 memset(&structs[i], 0, sizeof(structs[i]));
216 strcpy(structs[i].name, name);
217 structs[i].isunion = isunion;
218 return i;
221 static struct name *struct_field(int id, char *name)
223 struct structinfo *si = &structs[id];
224 int i;
225 for (i = 0; i < si->nfields; i++)
226 if (!strcmp(name, si->fields[i].name))
227 return &si->fields[i];
228 die("field not found\n");
231 #define MAXBREAK (1 << 7)
233 static long breaks[MAXBREAK];
234 static int nbreaks;
235 static long continues[MAXBREAK];
236 static int ncontinues;
238 static void break_fill(long addr, int till)
240 int i;
241 for (i = till; i < nbreaks; i++)
242 o_filljmp2(breaks[i], addr);
243 nbreaks = till;
246 static void continue_fill(long addr, int till)
248 int i;
249 for (i = till; i < ncontinues; i++)
250 o_filljmp2(continues[i], addr);
251 ncontinues = till;
254 static int type_totsz(struct type *t)
256 if (t->ptr)
257 return 8;
258 if (t->flags & T_ARRAY)
259 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
260 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
263 static unsigned type_szde(struct type *t)
265 if (t->flags & T_ARRAY)
266 return t->ptr > 0 ? 8 : TYPE_SZ(&arrays[t->id].type);
267 else
268 return t->ptr > 1 ? 8 : BT_SZ(t->bt);
271 static int tok_jmp(int tok)
273 if (tok_see() != tok)
274 return 1;
275 tok_get();
276 return 0;
279 static void tok_expect(int tok)
281 if (tok_get() != tok)
282 die("syntax error\n");
285 static unsigned bt_op(unsigned bt1, unsigned bt2)
287 unsigned s1 = BT_SZ(bt1);
288 unsigned s2 = BT_SZ(bt2);
289 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
292 static void ts_binop(void (*o_sth)(void))
294 struct type t1, t2;
295 ts_pop(&t1);
296 ts_pop(&t2);
297 o_sth();
298 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
301 static int shifts(int n)
303 int i = -1;
304 while (i++ < 16)
305 if (n == 1 << i)
306 break;
307 return i;
310 static void ts_binop_add(void (*o_sth)(void))
312 struct type t1, t2;
313 ts_pop(&t1);
314 ts_pop(&t2);
315 array2ptr(&t1);
316 array2ptr(&t2);
317 if (!t1.ptr && !t2.ptr) {
318 o_sth();
319 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
320 return;
322 if (t1.ptr && !t2.ptr) {
323 struct type t = t2;
324 t2 = t1;
325 t1 = t;
326 o_tmpswap();
328 if (!t1.ptr && t2.ptr)
329 if (type_szde(&t2) > 1) {
330 o_num(shifts(type_szde(&t2)), 1);
331 o_shl();
333 o_sth();
334 if (t1.ptr && t2.ptr) {
335 o_num(shifts(type_szde(&t1)), 1);
336 o_shr();
337 ts_push_bt(4 | BT_SIGNED);
338 } else {
339 ts_push(&t2);
343 static void structdef(void *data, struct name *name, unsigned flags)
345 struct structinfo *si = data;
346 if (si->isunion) {
347 name->addr = 0;
348 if (si->size < type_totsz(&name->type))
349 si->size = type_totsz(&name->type);
350 } else {
351 name->addr = si->size;
352 si->size += type_totsz(&name->type);
354 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
357 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
359 static int struct_create(char *name, int isunion)
361 int id = struct_find(name, isunion);
362 struct structinfo *si = &structs[id];
363 tok_expect('{');
364 while (tok_jmp('}')) {
365 readdefs(structdef, si);
366 tok_expect(';');
368 return id;
371 static void readexpr(void);
373 static void enum_create(void)
375 long n = 0;
376 tok_expect('{');
377 while (tok_jmp('}')) {
378 char name[NAMELEN];
379 tok_expect(TOK_NAME);
380 strcpy(name, tok_id());
381 if (tok_see() == '=') {
382 tok_get();
383 readexpr();
384 ts_pop(NULL);
385 if (o_popnum(&n))
386 die("const expr expected!\n");
388 enum_add(name, n++);
389 tok_jmp(',');
393 static int basetype(struct type *type, unsigned *flags)
395 int sign = 1;
396 int size = 4;
397 int done = 0;
398 int i = 0;
399 int isunion;
400 char name[NAMELEN] = "";
401 *flags = 0;
402 type->flags = 0;
403 type->ptr = 0;
404 while (!done) {
405 switch (tok_see()) {
406 case TOK_STATIC:
407 *flags |= F_STATIC;
408 break;
409 case TOK_EXTERN:
410 *flags |= F_EXTERN;
411 break;
412 case TOK_VOID:
413 sign = 0;
414 size = 0;
415 done = 1;
416 break;
417 case TOK_INT:
418 done = 1;
419 break;
420 case TOK_CHAR:
421 size = 1;
422 done = 1;
423 break;
424 case TOK_SHORT:
425 size = 2;
426 break;
427 case TOK_LONG:
428 size = 8;
429 break;
430 case TOK_SIGNED:
431 break;
432 case TOK_UNSIGNED:
433 sign = 0;
434 break;
435 case TOK_UNION:
436 case TOK_STRUCT:
437 isunion = tok_get() == TOK_UNION;
438 if (!tok_jmp(TOK_NAME))
439 strcpy(name, tok_id());
440 if (tok_see() == '{')
441 type->id = struct_create(name, isunion);
442 else
443 type->id = struct_find(name, isunion);
444 type->flags |= T_STRUCT;
445 type->bt = 8;
446 return 0;
447 case TOK_ENUM:
448 tok_get();
449 tok_jmp(TOK_NAME);
450 if (tok_see() == '{')
451 enum_create();
452 type->bt = 4 | BT_SIGNED;
453 return 0;
454 default:
455 if (tok_see() == TOK_NAME) {
456 int id = typedef_find(tok_id());
457 if (id != -1) {
458 tok_get();
459 memcpy(type, &typedefs[id].type,
460 sizeof(*type));
461 return 0;
464 if (!i)
465 return 1;
466 done = 1;
467 continue;
469 i++;
470 tok_get();
472 type->bt = size | (sign ? BT_SIGNED : 0);
473 return 0;
476 static int readname(struct type *main, char *name,
477 struct type *base, unsigned flags);
479 static int readtype(struct type *type)
481 return readname(type, NULL, NULL, 0);
484 static void readptrs(struct type *type)
486 while (!tok_jmp('*')) {
487 type->ptr++;
488 if (!type->bt)
489 type->bt = 1;
493 static int ncexpr;
495 static void readpre(void);
497 static void readprimary(void)
499 int i;
500 if (!tok_jmp(TOK_NUM)) {
501 ts_push_bt(4 | BT_SIGNED);
502 o_num(tok_num(), 4 | BT_SIGNED);
503 return;
505 if (!tok_jmp(TOK_STR)) {
506 struct type t;
507 char buf[BUFSIZE];
508 int len;
509 t.bt = 1 | BT_SIGNED;
510 t.ptr = 1;
511 t.flags = 0;
512 ts_push(&t);
513 len = tok_str(buf);
514 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
515 o_addr();
516 return;
518 if (!tok_jmp(TOK_NAME)) {
519 struct name unkn;
520 char *name = unkn.name;
521 int n;
522 strcpy(name, tok_id());
523 /* don't search for labels here */
524 if (!ncexpr && tok_see() == ':')
525 return;
526 for (i = nlocals - 1; i >= 0; --i) {
527 struct type *t = &locals[i].type;
528 if (!strcmp(locals[i].name, name)) {
529 o_local(locals[i].addr, TYPE_BT(t));
530 ts_push(t);
531 return;
534 if ((n = global_find(name)) != -1) {
535 struct name *g = &globals[n];
536 struct type *t = &g->type;
537 if (g->unused) {
538 g->unused = 0;
539 if (t->flags & T_FUNC && !t->ptr)
540 g->addr = out_mkundef(name, 0);
541 else
542 g->addr = out_mkundef(name, type_totsz(t));
544 o_symaddr(g->addr, TYPE_BT(t));
545 ts_push(t);
546 return;
548 if (!enum_find(&n, name)) {
549 ts_push_bt(4 | BT_SIGNED);
550 o_num(n, 4 | BT_SIGNED);
551 return;
553 if (tok_see() != '(')
554 die("unknown symbol\n");
555 unkn.addr = out_mkundef(unkn.name, 0);
556 global_add(&unkn);
557 ts_push_bt(8);
558 o_symaddr(unkn.addr, 8);
559 return;
561 if (!tok_jmp('(')) {
562 struct type t;
563 if (!readtype(&t)) {
564 struct type o;
565 tok_expect(')');
566 readpre();
567 ts_pop(&o);
568 ts_push(&t);
569 if (!t.ptr || !o.ptr)
570 o_cast(TYPE_BT(&t));
571 } else {
572 readexpr();
573 tok_expect(')');
575 return;
579 void arrayderef(struct type *t)
581 int sz = type_totsz(t);
582 if (sz > 1) {
583 o_num(sz, 4);
584 o_mul();
586 o_add();
587 o_deref(TYPE_BT(t));
590 static void inc_post(void (*op)(void))
592 unsigned bt = TYPE_BT(&ts[nts - 1]);
593 o_tmpcopy();
594 o_load();
595 o_tmpswap();
596 o_tmpcopy();
597 o_num(1, 4);
598 ts_push_bt(bt);
599 ts_push_bt(bt);
600 ts_binop_add(op);
601 ts_pop(NULL);
602 o_assign(bt);
603 o_tmpdrop(1);
606 static void readfield(void)
608 struct name *field;
609 struct type t;
610 tok_expect(TOK_NAME);
611 ts_pop(&t);
612 array2ptr(&t);
613 field = struct_field(t.id, tok_id());
614 if (field->addr) {
615 o_num(field->addr, 4);
616 o_add();
618 o_deref(TYPE_BT(&field->type));
619 ts_push(&field->type);
622 #define MAXFUNCS (1 << 10)
624 static struct funcinfo {
625 struct type args[MAXFIELDS];
626 struct type ret;
627 int nargs;
628 } funcs[MAXFUNCS];
629 static int nfuncs;
630 static unsigned ret_bt;
632 static int func_create(struct type *ret, struct name *args, int nargs)
634 struct funcinfo *fi = &funcs[nfuncs++];
635 int i;
636 if (nfuncs >= MAXFUNCS)
637 die("nomem: MAXFUNCS reached!\n");
638 memcpy(&fi->ret, ret, sizeof(*ret));
639 for (i = 0; i < nargs; i++)
640 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
641 fi->nargs = nargs;
642 return fi - funcs;
645 static void readcall(void)
647 struct type t;
648 unsigned bt[MAXARGS];
649 struct funcinfo *fi;
650 int argc = 0;
651 int i;
652 if (tok_see() != ')') {
653 readexpr();
654 ts_pop(&t);
655 bt[argc++] = TYPE_BT(&t);
657 while (!tok_jmp(',')) {
658 readexpr();
659 ts_pop(&t);
660 bt[argc++] = TYPE_BT(&t);
662 tok_expect(')');
663 ts_pop(&t);
664 if (t.flags & T_FUNC && t.ptr > 0)
665 o_deref(8);
666 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
667 if (fi)
668 for (i = 0; i < fi->nargs; i++)
669 bt[i] = TYPE_BT(&fi->args[i]);
670 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
671 if (fi)
672 ts_push(&fi->ret);
673 else
674 ts_push_bt(4 | BT_SIGNED);
677 static void readpost(void)
679 readprimary();
680 while (1) {
681 if (!tok_jmp('[')) {
682 struct type t;
683 ts_pop(&t);
684 readexpr();
685 ts_pop(NULL);
686 tok_expect(']');
687 array2ptr(&t);
688 t.ptr--;
689 arrayderef(&t);
690 ts_push(&t);
691 continue;
693 if (!tok_jmp('(')) {
694 readcall();
695 continue;
697 if (!tok_jmp(TOK2("++"))) {
698 inc_post(o_add);
699 continue;
701 if (!tok_jmp(TOK2("--"))) {
702 inc_post(o_sub);
703 continue;
705 if (!tok_jmp('.')) {
706 o_addr();
707 readfield();
708 continue;
710 if (!tok_jmp(TOK2("->"))) {
711 readfield();
712 continue;
714 break;
718 static void inc_pre(void (*op)(void))
720 unsigned bt = TYPE_BT(&ts[nts - 1]);
721 readpre();
722 o_tmpcopy();
723 o_num(1, 4);
724 ts_push_bt(bt);
725 ts_push_bt(bt);
726 ts_binop_add(op);
727 ts_pop(NULL);
728 o_assign(bt);
731 static void readpre(void)
733 if (!tok_jmp('&')) {
734 struct type type;
735 readpre();
736 ts_pop(&type);
737 if (!(type.flags & T_FUNC) && !type.ptr)
738 type.ptr++;
739 ts_push(&type);
740 o_addr();
741 return;
743 if (!tok_jmp('*')) {
744 struct type t;
745 readpre();
746 ts_pop(&t);
747 array2ptr(&t);
748 if (!(t.flags & T_FUNC) || t.ptr > 0) {
749 t.ptr--;
750 o_deref(TYPE_BT(&t));
752 ts_push(&t);
753 return;
755 if (!tok_jmp('!')) {
756 struct type type;
757 readpre();
758 ts_pop(&type);
759 o_lnot();
760 ts_push_bt(4 | BT_SIGNED);
761 return;
763 if (!tok_jmp('-')) {
764 readpre();
765 o_neg();
766 return;
768 if (!tok_jmp('~')) {
769 readpre();
770 o_not();
771 return;
773 if (!tok_jmp(TOK2("++"))) {
774 inc_pre(o_add);
775 return;
777 if (!tok_jmp(TOK2("--"))) {
778 inc_pre(o_sub);
779 return;
781 if (!tok_jmp(TOK_SIZEOF)) {
782 struct type t;
783 int op = !tok_jmp('(');
784 if (readtype(&t)) {
785 int nogen = !o_nogen();
786 readexpr();
787 if (nogen)
788 o_dogen();
789 ts_pop(&t);
790 o_tmpdrop(1);
792 ts_push_bt(4);
793 o_num(type_totsz(&t), 4);
794 if (op)
795 tok_expect(')');
796 return;
798 readpost();
801 static void readmul(void)
803 readpre();
804 while (1) {
805 if (!tok_jmp('*')) {
806 readpre();
807 ts_binop(o_mul);
808 continue;
810 if (!tok_jmp('/')) {
811 readpre();
812 ts_binop(o_div);
813 continue;
815 if (!tok_jmp('%')) {
816 readpre();
817 ts_binop(o_mod);
818 continue;
820 break;
824 static void readadd(void)
826 readmul();
827 while (1) {
828 if (!tok_jmp('+')) {
829 readmul();
830 ts_binop_add(o_add);
831 continue;
833 if (!tok_jmp('-')) {
834 readmul();
835 ts_binop_add(o_sub);
836 continue;
838 break;
842 static void shift(void (*op)(void))
844 struct type t;
845 readadd();
846 ts_pop(NULL);
847 ts_pop(&t);
848 op();
849 ts_push_bt(TYPE_BT(&t));
852 static void readshift(void)
854 readadd();
855 while (1) {
856 if (!tok_jmp(TOK2("<<"))) {
857 shift(o_shl);
858 continue;
860 if (!tok_jmp(TOK2(">>"))) {
861 shift(o_shr);
862 continue;
864 break;
868 static void cmp(void (*op)(void))
870 readshift();
871 ts_pop(NULL);
872 ts_pop(NULL);
873 op();
874 ts_push_bt(4 | BT_SIGNED);
877 static void readcmp(void)
879 readshift();
880 while (1) {
881 if (!tok_jmp('<')) {
882 cmp(o_lt);
883 continue;
885 if (!tok_jmp('>')) {
886 cmp(o_gt);
887 continue;
889 if (!tok_jmp(TOK2("<="))) {
890 cmp(o_le);
891 continue;
893 if (!tok_jmp(TOK2(">="))) {
894 cmp(o_ge);
895 continue;
897 break;
901 static void eq(void (*op)(void))
903 readcmp();
904 ts_pop(NULL);
905 ts_pop(NULL);
906 op();
907 ts_push_bt(4 | BT_SIGNED);
910 static void readeq(void)
912 readcmp();
913 while (1) {
914 if (!tok_jmp(TOK2("=="))) {
915 eq(o_eq);
916 continue;
918 if (!tok_jmp(TOK2("!="))) {
919 eq(o_neq);
920 continue;
922 break;
926 static void readbitand(void)
928 readeq();
929 while (!tok_jmp('&')) {
930 readeq();
931 ts_binop(o_and);
935 static void readxor(void)
937 readbitand();
938 while (!tok_jmp('^')) {
939 readbitand();
940 ts_binop(o_xor);
944 static void readbitor(void)
946 readxor();
947 while (!tok_jmp('|')) {
948 readxor();
949 ts_binop(o_or);
953 #define MAXCOND (1 << 7)
955 static void readand(void)
957 long conds[MAXCOND];
958 int nconds = 0;
959 long passed;
960 int i;
961 readbitor();
962 if (tok_see() != TOK2("&&"))
963 return;
964 conds[nconds++] = o_jz(0);
965 ts_pop(NULL);
966 while (!tok_jmp(TOK2("&&"))) {
967 readbitor();
968 conds[nconds++] = o_jz(0);
969 ts_pop(NULL);
971 o_num(1, 4 | BT_SIGNED);
972 o_tmpfork();
973 passed = o_jmp(0);
974 for (i = 0; i < nconds; i++)
975 o_filljmp(conds[i]);
976 o_num(0, 4 | BT_SIGNED);
977 o_tmpjoin();
978 o_filljmp(passed);
979 ts_push_bt(4 | BT_SIGNED);
982 static void reador(void)
984 long conds[MAXCOND];
985 int nconds = 0;
986 long failed;
987 int i;
988 readand();
989 if (tok_see() != TOK2("||"))
990 return;
991 conds[nconds++] = o_jnz(0);
992 ts_pop(NULL);
993 while (!tok_jmp(TOK2("||"))) {
994 readand();
995 conds[nconds++] = o_jnz(0);
996 ts_pop(NULL);
998 o_num(0, 4 | BT_SIGNED);
999 o_tmpfork();
1000 failed = o_jmp(0);
1001 for (i = 0; i < nconds; i++)
1002 o_filljmp(conds[i]);
1003 o_num(1, 4 | BT_SIGNED);
1004 o_tmpjoin();
1005 o_filljmp(failed);
1006 ts_push_bt(4 | BT_SIGNED);
1009 static void readcexpr(void)
1011 long l1, l2;
1012 long c;
1013 int cexpr, nogen;
1014 reador();
1015 if (tok_jmp('?'))
1016 return;
1017 ncexpr++;
1018 cexpr = !o_popnum(&c);
1019 ts_pop(NULL);
1020 if (cexpr) {
1021 if (!c)
1022 nogen = !o_nogen();
1023 } else {
1024 l1 = o_jz(0);
1026 reador();
1027 if (!cexpr) {
1028 o_tmpfork();
1029 l2 = o_jmp(0);
1031 ts_pop(NULL);
1032 tok_expect(':');
1033 if (cexpr) {
1034 if (c) {
1035 nogen = !o_nogen();
1036 } else {
1037 if (nogen)
1038 o_dogen();
1039 o_tmpdrop(1);
1041 } else {
1042 o_filljmp(l1);
1044 reador();
1045 if (cexpr) {
1046 if (c) {
1047 if (nogen)
1048 o_dogen();
1049 o_tmpdrop(1);
1051 } else {
1052 o_tmpjoin();
1053 o_filljmp(l2);
1055 ncexpr--;
1058 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1060 unsigned bt = TYPE_BT(&ts[nts - 1]);
1061 o_tmpcopy();
1062 readexpr();
1063 bop(op);
1064 ts_pop(NULL);
1065 o_assign(bt);
1068 static void doassign(void)
1070 struct type t;
1071 ts_pop(&t);
1072 if (!t.ptr && t.flags & T_STRUCT)
1073 o_memcpy(type_totsz(&t));
1074 else
1075 o_assign(TYPE_BT(&ts[nts - 1]));
1078 static void readexpr(void)
1080 readcexpr();
1081 if (!tok_jmp('=')) {
1082 readexpr();
1083 doassign();
1084 return;
1086 if (!tok_jmp(TOK2("+="))) {
1087 opassign(ts_binop_add, o_add);
1088 return;
1090 if (!tok_jmp(TOK2("-="))) {
1091 opassign(ts_binop_add, o_sub);
1092 return;
1094 if (!tok_jmp(TOK2("*="))) {
1095 opassign(ts_binop, o_mul);
1096 return;
1098 if (!tok_jmp(TOK2("/="))) {
1099 opassign(ts_binop, o_div);
1100 return;
1102 if (!tok_jmp(TOK2("%="))) {
1103 opassign(ts_binop, o_mod);
1104 return;
1106 if (!tok_jmp(TOK3("<<="))) {
1107 opassign(ts_binop, o_shl);
1108 return;
1110 if (!tok_jmp(TOK3(">>="))) {
1111 opassign(ts_binop, o_shr);
1112 return;
1114 if (!tok_jmp(TOK3("&="))) {
1115 opassign(ts_binop, o_and);
1116 return;
1118 if (!tok_jmp(TOK3("|="))) {
1119 opassign(ts_binop, o_or);
1120 return;
1122 if (!tok_jmp(TOK3("^="))) {
1123 opassign(ts_binop, o_xor);
1124 return;
1128 static void readestmt(void)
1130 do {
1131 o_tmpdrop(-1);
1132 nts = 0;
1133 readexpr();
1134 } while (!tok_jmp(','));
1137 static void o_localoff(long addr, int off, unsigned bt)
1139 o_local(addr, bt);
1140 if (off) {
1141 o_addr();
1142 o_num(off, 4);
1143 o_add();
1144 o_deref(bt);
1148 static struct type *innertype(struct type *t)
1150 if (t->flags & T_ARRAY && !t->ptr)
1151 return innertype(&arrays[t->id].type);
1152 return t;
1155 static void initexpr(struct type *t, int off, void *obj,
1156 void (*set)(void *obj, int off, struct type *t))
1158 if (tok_jmp('{')) {
1159 set(obj, off, t);
1160 return;
1162 if (!t->ptr && t->flags & T_STRUCT) {
1163 struct structinfo *si = &structs[t->id];
1164 int i;
1165 for (i = 0; i < si->nfields; i++) {
1166 struct name *field = &si->fields[i];
1167 if (!tok_jmp('.')) {
1168 tok_expect(TOK_NAME);
1169 field = struct_field(t->id, tok_id());
1170 tok_expect('=');
1172 initexpr(&field->type, off + field->addr, obj, set);
1173 if (tok_jmp(',') || tok_see() == '}')
1174 break;
1176 } else if (t->flags & T_ARRAY) {
1177 struct type *t_de = &arrays[t->id].type;
1178 int i;
1179 for (i = 0; ; i++) {
1180 long idx = i;
1181 struct type *it = t_de;
1182 if (!tok_jmp('[')) {
1183 readexpr();
1184 o_popnum(&idx);
1185 ts_pop(NULL);
1186 tok_expect(']');
1187 tok_expect('=');
1189 if (tok_see() != '{')
1190 it = innertype(t_de);
1191 initexpr(it, off + type_totsz(it) * idx, obj, set);
1192 if (tok_jmp(',') || tok_see() == '}')
1193 break;
1196 tok_expect('}');
1199 static void jumpbrace(void)
1201 int depth = 0;
1202 while (tok_see() != '}' || depth--)
1203 if (tok_get() == '{')
1204 depth++;
1205 tok_expect('}');
1208 static int initsize(void)
1210 long addr = tok_addr();
1211 int n = 0;
1212 if (!tok_jmp(TOK_STR)) {
1213 n = tok_str(NULL);
1214 tok_jump(addr);
1215 return n;
1217 o_nogen();
1218 tok_expect('{');
1219 while (tok_jmp('}')) {
1220 long idx = n;
1221 if (!tok_jmp('[')) {
1222 readexpr();
1223 o_popnum(&idx);
1224 ts_pop(NULL);
1225 tok_expect(']');
1226 tok_expect('=');
1228 if (n < idx + 1)
1229 n = idx + 1;
1230 while (tok_see() != '}' && tok_see() != ',')
1231 if (tok_get() == '{')
1232 jumpbrace();
1233 tok_jmp(',');
1235 o_dogen();
1236 tok_jump(addr);
1237 return n;
1240 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1242 static void globalinit(void *obj, int off, struct type *t)
1244 long addr = *(long *) obj;
1245 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1246 struct type *t_de = &arrays[t->id].type;
1247 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1248 char buf[BUFSIZE];
1249 int len;
1250 tok_expect(TOK_STR);
1251 len = tok_str(buf);
1252 out_datcpy(addr, off, buf, len);
1253 return;
1256 readexpr();
1257 o_datset(addr, off, TYPE_BT(t));
1258 ts_pop(NULL);
1261 static void globaldef(void *data, struct name *name, unsigned flags)
1263 struct type *t = &name->type;
1264 char *varname = flags & F_STATIC ? NULL : name->name;
1265 int sz;
1266 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1267 arrays[t->id].n = initsize();
1268 sz = type_totsz(t);
1269 if (flags & F_EXTERN || t->flags & T_FUNC && !t->ptr)
1270 name->unused = 1;
1271 else if (flags & F_INIT)
1272 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1273 else
1274 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1275 global_add(name);
1276 if (flags & F_INIT)
1277 initexpr(t, 0, &name->addr, globalinit);
1280 static void localinit(void *obj, int off, struct type *t)
1282 long addr = *(long *) obj;
1283 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1284 struct type *t_de = &arrays[t->id].type;
1285 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1286 char buf[BUFSIZE];
1287 int len;
1288 tok_expect(TOK_STR);
1289 len = tok_str(buf);
1290 o_localoff(addr, off, TYPE_BT(t));
1291 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1292 o_memcpy(len);
1293 o_tmpdrop(1);
1294 return;
1297 o_localoff(addr, off, TYPE_BT(t));
1298 ts_push(t);
1299 readexpr();
1300 doassign();
1301 ts_pop(NULL);
1302 o_tmpdrop(1);
1305 static void localdef(void *data, struct name *name, unsigned flags)
1307 struct type *t = &name->type;
1308 if (flags & (F_STATIC | F_EXTERN)) {
1309 globaldef(data, name, flags);
1310 return;
1312 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1313 arrays[t->id].n = initsize();
1314 name->addr = o_mklocal(type_totsz(&name->type));
1315 local_add(name);
1316 if (flags & F_INIT) {
1317 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1318 o_local(name->addr, TYPE_BT(t));
1319 o_memset(0, type_totsz(t));
1320 o_tmpdrop(1);
1322 initexpr(t, 0, &name->addr, localinit);
1326 static void funcdef(char *name, struct type *type, struct name *args,
1327 int nargs, unsigned flags)
1329 struct name global;
1330 int i;
1331 strcpy(global.name, name);
1332 memcpy(&global.type, type, sizeof(*type));
1333 global.addr = o_func_beg(name, F_GLOBAL(flags));
1334 global.unused = 0;
1335 global_add(&global);
1336 ret_bt = TYPE_BT(&funcs[type->id].ret);
1337 for (i = 0; i < nargs; i++) {
1338 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1339 local_add(&args[i]);
1343 static int readargs(struct name *args)
1345 int nargs = 0;
1346 tok_expect('(');
1347 while (tok_see() != ')') {
1348 if (!tok_jmp(TOK3("...")))
1349 break;
1350 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1351 array2ptr(&args[nargs].type);
1352 nargs++;
1353 if (tok_jmp(','))
1354 break;
1356 tok_expect(')');
1357 if (nargs == 1 && !TYPE_BT(&args[0].type))
1358 return 0;
1359 return nargs;
1362 static int readname(struct type *main, char *name,
1363 struct type *base, unsigned flags)
1365 struct type tpool[3];
1366 int npool = 0;
1367 struct type *type = &tpool[npool++];
1368 struct type *func = NULL;
1369 struct type *ret = NULL;
1370 int arsz[10];
1371 int nar = 0;
1372 int i;
1373 memset(tpool, 0, sizeof(tpool));
1374 if (name)
1375 *name = '\0';
1376 if (!base) {
1377 if (basetype(type, &flags))
1378 return 1;
1379 } else {
1380 memcpy(type, base, sizeof(*base));
1382 readptrs(type);
1383 if (!tok_jmp('(')) {
1384 ret = type;
1385 type = &tpool[npool++];
1386 func = type;
1387 readptrs(type);
1389 if (!tok_jmp(TOK_NAME) && name)
1390 strcpy(name, tok_id());
1391 while (!tok_jmp('[')) {
1392 long n = 0;
1393 if (tok_jmp(']')) {
1394 readexpr();
1395 ts_pop(NULL);
1396 if (o_popnum(&n))
1397 die("const expr expected\n");
1398 tok_expect(']');
1400 arsz[nar++] = n;
1402 for (i = nar - 1; i >= 0; i--) {
1403 type->id = array_add(type, arsz[i]);
1404 if (type->flags & T_FUNC)
1405 func = &arrays[type->id].type;
1406 type->flags = T_ARRAY;
1407 type->bt = 8;
1408 type->ptr = 0;
1410 if (func)
1411 tok_expect(')');
1412 if (tok_see() == '(') {
1413 struct name args[MAXARGS];
1414 int nargs = readargs(args);
1415 int fdef = !func;
1416 if (!func) {
1417 ret = type;
1418 type = &tpool[npool++];
1419 func = type;
1421 func->flags = T_FUNC;
1422 func->bt = 8;
1423 func->id = func_create(ret, args, nargs);
1424 if (fdef && tok_see() == '{') {
1425 funcdef(name, func, args, nargs, flags);
1426 return 1;
1429 memcpy(main, type, sizeof(*type));
1430 return 0;
1433 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1434 void *data)
1436 struct type base;
1437 unsigned flags;
1438 if (basetype(&base, &flags))
1439 return 1;
1440 while (tok_see() != ';' && tok_see() != '{') {
1441 struct name name;
1442 name.unused = 0;
1443 if (readname(&name.type, name.name, &base, flags))
1444 break;
1445 if (!tok_jmp('='))
1446 flags |= F_INIT;
1447 def(data, &name, flags);
1448 tok_jmp(',');
1450 return 0;
1453 static void typedefdef(void *data, struct name *name, unsigned flags)
1455 typedef_add(name->name, &name->type);
1458 static void readstmt(void);
1460 #define MAXCASES (1 << 7)
1462 static void readswitch(void)
1464 int break_beg = nbreaks;
1465 long val_addr = o_mklocal(8);
1466 long matched[MAXCASES];
1467 int nmatched = 0;
1468 struct type t;
1469 long next;
1470 int ref = 1;
1471 int i;
1472 tok_expect('(');
1473 readexpr();
1474 ts_pop(&t);
1475 o_local(val_addr, TYPE_BT(&t));
1476 o_tmpswap();
1477 o_assign(TYPE_BT(&t));
1478 o_tmpdrop(1);
1479 tok_expect(')');
1480 tok_expect('{');
1481 while (tok_jmp('}')) {
1482 int n = 0;
1483 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1484 if (n++ > 0)
1485 matched[nmatched++] = o_jmp(0);
1486 if (!ref++)
1487 o_filljmp(next);
1488 if (!tok_jmp(TOK_CASE)) {
1489 readexpr();
1490 o_local(val_addr, TYPE_BT(&t));
1491 o_eq();
1492 next = o_jz(0);
1493 ref = 0;
1494 tok_expect(':');
1495 o_tmpdrop(1);
1496 ts_pop(NULL);
1497 continue;
1499 if (!tok_jmp(TOK_DEFAULT)) {
1500 tok_expect(':');
1501 continue;
1504 for (i = 0; i < nmatched; i++)
1505 o_filljmp(matched[i]);
1506 nmatched = 0;
1507 readstmt();
1509 o_rmlocal(val_addr, 8);
1510 if (!ref++)
1511 o_filljmp(next);
1512 break_fill(o_mklabel(), break_beg);
1515 #define MAXGOTO (1 << 10)
1517 static struct gotoinfo {
1518 char name[NAMELEN];
1519 long addr;
1520 } gotos[MAXGOTO];
1521 static int ngotos;
1523 static struct labelinfo {
1524 char name[NAMELEN];
1525 long addr;
1526 } labels[MAXGOTO];
1527 static int nlabels;
1529 static void goto_add(char *name)
1531 strcpy(gotos[ngotos].name, name);
1532 gotos[ngotos++].addr = o_jmp(0);
1535 static void label_add(char *name)
1537 strcpy(labels[nlabels].name, name);
1538 labels[nlabels++].addr = o_mklabel();
1541 static void goto_fill(void)
1543 int i, j;
1544 for (i = 0; i < ngotos; i++)
1545 for (j = 0; j < nlabels; j++)
1546 if (!strcmp(gotos[i].name, labels[j].name)) {
1547 o_filljmp2(gotos[i].addr, labels[j].addr);
1548 break;
1552 static void readstmt(void)
1554 o_tmpdrop(-1);
1555 nts = 0;
1556 if (!tok_jmp('{')) {
1557 int _nlocals = nlocals;
1558 int _nglobals = nglobals;
1559 int _nenums = nenums;
1560 int _ntypedefs = ntypedefs;
1561 int _nstructs = nstructs;
1562 int _nfuncs = nfuncs;
1563 int _narrays = narrays;
1564 while (tok_jmp('}'))
1565 readstmt();
1566 nlocals = _nlocals;
1567 nenums = _nenums;
1568 ntypedefs = _ntypedefs;
1569 nstructs = _nstructs;
1570 nfuncs = _nfuncs;
1571 narrays = _narrays;
1572 nglobals = _nglobals;
1573 return;
1575 if (!readdefs(localdef, NULL)) {
1576 tok_expect(';');
1577 return;
1579 if (!tok_jmp(TOK_TYPEDEF)) {
1580 readdefs(typedefdef, NULL);
1581 tok_expect(';');
1582 return;
1584 if (!tok_jmp(TOK_IF)) {
1585 long l1, l2;
1586 tok_expect('(');
1587 readexpr();
1588 tok_expect(')');
1589 l1 = o_jz(0);
1590 readstmt();
1591 if (!tok_jmp(TOK_ELSE)) {
1592 l2 = o_jmp(0);
1593 o_filljmp(l1);
1594 readstmt();
1595 o_filljmp(l2);
1596 } else {
1597 o_filljmp(l1);
1599 return;
1601 if (!tok_jmp(TOK_WHILE)) {
1602 long l1, l2;
1603 int break_beg = nbreaks;
1604 int continue_beg = ncontinues;
1605 l1 = o_mklabel();
1606 tok_expect('(');
1607 readexpr();
1608 tok_expect(')');
1609 l2 = o_jz(0);
1610 readstmt();
1611 o_jmp(l1);
1612 o_filljmp(l2);
1613 break_fill(o_mklabel(), break_beg);
1614 continue_fill(l1, continue_beg);
1615 return;
1617 if (!tok_jmp(TOK_DO)) {
1618 long l1, l2;
1619 int break_beg = nbreaks;
1620 int continue_beg = ncontinues;
1621 l1 = o_mklabel();
1622 readstmt();
1623 tok_expect(TOK_WHILE);
1624 tok_expect('(');
1625 l2 = o_mklabel();
1626 readexpr();
1627 o_jnz(l1);
1628 tok_expect(')');
1629 break_fill(o_mklabel(), break_beg);
1630 continue_fill(l2, continue_beg);
1631 return;
1633 if (!tok_jmp(TOK_FOR)) {
1634 long l_check, l_jump, j_fail, j_pass;
1635 int break_beg = nbreaks;
1636 int continue_beg = ncontinues;
1637 int has_cond = 0;
1638 tok_expect('(');
1639 if (tok_see() != ';')
1640 readestmt();
1641 tok_expect(';');
1642 l_check = o_mklabel();
1643 if (tok_see() != ';') {
1644 readestmt();
1645 j_fail = o_jz(0);
1646 has_cond = 1;
1648 tok_expect(';');
1649 j_pass = o_jmp(0);
1650 l_jump = o_mklabel();
1651 if (tok_see() != ')')
1652 readestmt();
1653 tok_expect(')');
1654 o_jmp(l_check);
1655 o_filljmp(j_pass);
1656 readstmt();
1657 o_jmp(l_jump);
1658 if (has_cond)
1659 o_filljmp(j_fail);
1660 break_fill(o_mklabel(), break_beg);
1661 continue_fill(l_jump, continue_beg);
1662 return;
1664 if (!tok_jmp(TOK_SWITCH)) {
1665 readswitch();
1666 return;
1668 if (!tok_jmp(TOK_RETURN)) {
1669 int ret = tok_see() != ';';
1670 if (ret)
1671 readexpr();
1672 tok_expect(';');
1673 o_ret(ret_bt);
1674 return;
1676 if (!tok_jmp(TOK_BREAK)) {
1677 tok_expect(';');
1678 breaks[nbreaks++] = o_jmp(0);
1679 return;
1681 if (!tok_jmp(TOK_CONTINUE)) {
1682 tok_expect(';');
1683 continues[ncontinues++] = o_jmp(0);
1684 return;
1686 if (!tok_jmp(TOK_GOTO)) {
1687 tok_expect(TOK_NAME);
1688 goto_add(tok_id());
1689 tok_expect(';');
1690 return;
1692 readestmt();
1693 /* labels */
1694 if (!tok_jmp(':')) {
1695 label_add(tok_id());
1696 return;
1698 tok_expect(';');
1701 static void readdecl(void)
1703 if (!tok_jmp(TOK_TYPEDEF)) {
1704 readdefs(typedefdef, NULL);
1705 tok_expect(';');
1706 return;
1708 readdefs(globaldef, NULL);
1709 if (tok_see() == '{') {
1710 readstmt();
1711 goto_fill();
1712 o_func_end();
1713 nlocals = 0;
1714 ngotos = 0;
1715 nlabels = 0;
1716 return;
1718 tok_expect(';');
1721 static void parse(void)
1723 while (tok_see() != TOK_EOF)
1724 readdecl();
1727 int main(int argc, char *argv[])
1729 char obj[128];
1730 int ofd;
1731 int i = 1;
1732 while (i < argc && argv[i][0] == '-') {
1733 if (argv[i][1] == 'I')
1734 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1735 if (argv[i][1] == 'D') {
1736 char *name = argv[i] + 2;
1737 char *def = "";
1738 char *eq = strchr(name, '=');
1739 if (eq) {
1740 *eq = '\0';
1741 def = eq + 1;
1743 cpp_define(name, def);
1745 i++;
1747 if (i == argc)
1748 die("no file given\n");
1749 cpp_init(argv[i]);
1750 parse();
1751 strcpy(obj, argv[i]);
1752 obj[strlen(obj) - 1] = 'o';
1753 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1754 out_write(ofd);
1755 close(ofd);
1756 return 0;