ncc: cast return value
[neatcc.git] / ncc.c
bloba0edd974ebf7e54ff0f58e91de808d90f6f3334e
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
34 struct type {
35 unsigned bt;
36 unsigned flags;
37 int ptr;
38 int id; /* for structs, functions and arrays */
41 /* type stack */
42 static struct type ts[MAXTMP];
43 static int nts;
45 static void ts_push_bt(unsigned bt)
47 ts[nts].ptr = 0;
48 ts[nts].flags = 0;
49 ts[nts++].bt = bt;
52 static void ts_push(struct type *t)
54 memcpy(&ts[nts++], t, sizeof(*t));
55 if (t->flags & (T_FUNC | T_ARRAY) && !t->ptr)
56 o_addr();
59 static void ts_pop(struct type *type)
61 nts--;
62 if (type)
63 *type = ts[nts];
66 struct name {
67 char name[NAMELEN];
68 struct type type;
69 long addr;
72 static struct name locals[MAXLOCALS];
73 static int nlocals;
74 static struct name globals[MAXGLOBALS];
75 static int nglobals;
77 static void local_add(struct name *name)
79 memcpy(&locals[nlocals++], name, sizeof(*name));
82 static void global_add(struct name *name)
84 memcpy(&globals[nglobals++], name, sizeof(*name));
87 static void die(char *s)
89 print(s);
90 exit(1);
93 #define MAXENUMS (1 << 10)
95 static struct enumval {
96 char name[NAMELEN];
97 int n;
98 } enums[MAXENUMS];
99 static int nenums;
101 static void enum_add(char *name, int val)
103 struct enumval *ev = &enums[nenums++];
104 strcpy(ev->name, name);
105 ev->n = val;
108 static int enum_find(int *val, char *name)
110 int i;
111 for (i = nenums - 1; i >= 0; --i)
112 if (!strcmp(name, enums[i].name)) {
113 *val = enums[i].n;
114 return 0;
116 return 1;
119 #define MAXTYPEDEFS (1 << 5)
121 static struct typdefinfo {
122 char name[NAMELEN];
123 struct type type;
124 } typedefs[MAXTYPEDEFS];
125 static int ntypedefs;
127 static void typedef_add(char *name, struct type *type)
129 struct typdefinfo *ti = &typedefs[ntypedefs++];
130 strcpy(ti->name, name);
131 memcpy(&ti->type, type, sizeof(*type));
134 static int typedef_find(char *name)
136 int i;
137 for (i = ntypedefs - 1; i >= 0; --i)
138 if (!strcmp(name, typedefs[i].name))
139 return i;
140 return -1;
143 #define MAXARRAYS (1 << 5)
145 static struct array {
146 struct type type;
147 int n;
148 } arrays[MAXARRAYS];
149 static int narrays;
151 static int array_add(struct type *type, int n)
153 struct array *a = &arrays[narrays++];
154 memcpy(&a->type, type, sizeof(*type));
155 a->n = n;
156 return a - arrays;
159 static void array2ptr(struct type *t)
161 if (!(t->flags & T_ARRAY) || t->ptr)
162 return;
163 memcpy(t, &arrays[t->id].type, sizeof(*t));
164 t->ptr++;
167 #define MAXTYPES (1 << 7)
168 #define MAXFIELDS (1 << 5)
170 static struct structinfo {
171 char name[NAMELEN];
172 struct name fields[MAXFIELDS];
173 int nfields;
174 int isunion;
175 int size;
176 } structs[MAXTYPES];
177 static int nstructs;
179 static int struct_find(char *name, int isunion)
181 int i;
182 for (i = nstructs - 1; i >= 0; --i)
183 if (!strcmp(name, structs[i].name) &&
184 structs[i].isunion == isunion)
185 return i;
186 die("struct not found\n");
189 static struct name *struct_field(int id, char *name)
191 struct structinfo *si = &structs[id];
192 int i;
193 for (i = 0; i < si->nfields; i++)
194 if (!strcmp(name, si->fields[i].name))
195 return &si->fields[i];
196 die("field not found\n");
199 #define MAXBREAK (1 << 7)
200 static long breaks[MAXBREAK];
201 static int nbreaks;
202 static long continues[MAXBREAK];
203 static int ncontinues;
205 static void break_fill(long addr, int till)
207 int i;
208 for (i = till; i < nbreaks; i++)
209 o_filljmp2(breaks[i], addr);
210 nbreaks = till;
213 static void continue_fill(long addr, int till)
215 int i;
216 for (i = till; i < ncontinues; i++)
217 o_filljmp2(continues[i], addr);
218 ncontinues = till;
221 static int type_totsz(struct type *t)
223 if (t->ptr)
224 return 8;
225 if (t->flags & T_ARRAY)
226 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
227 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
230 static unsigned type_szde(struct type *t)
232 if (t->flags & T_ARRAY)
233 return t->ptr > 0 ? 8 : TYPE_SZ(&arrays[t->id].type);
234 else
235 return t->ptr > 1 ? 8 : BT_SZ(t->bt);
238 static int tok_jmp(int tok)
240 if (tok_see() != tok)
241 return 1;
242 tok_get();
243 return 0;
246 static void tok_expect(int tok)
248 if (tok_get() != tok)
249 die("syntax error\n");
252 static unsigned bt_op(unsigned bt1, unsigned bt2)
254 unsigned s1 = BT_SZ(bt1);
255 unsigned s2 = BT_SZ(bt2);
256 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
259 static void ts_binop(void (*o_sth)(void))
261 struct type t1, t2;
262 ts_pop(&t1);
263 ts_pop(&t2);
264 o_sth();
265 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
268 static int shifts(int n)
270 int i = -1;
271 while (i++ < 16)
272 if (n == 1 << i)
273 break;
274 return i;
277 static void ts_binop_add(void (*o_sth)(void))
279 struct type t1, t2;
280 ts_pop(&t1);
281 ts_pop(&t2);
282 array2ptr(&t1);
283 array2ptr(&t2);
284 if (!t1.ptr && !t2.ptr) {
285 o_sth();
286 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
287 return;
289 if (t1.ptr && !t2.ptr) {
290 struct type t = t2;
291 t2 = t1;
292 t1 = t;
293 o_tmpswap();
295 if (!t1.ptr && t2.ptr)
296 if (type_szde(&t2) > 1) {
297 o_num(shifts(type_szde(&t2)), 1);
298 o_shl();
300 o_sth();
301 if (t1.ptr && t2.ptr) {
302 o_num(shifts(type_szde(&t1)), 1);
303 o_shr();
304 ts_push_bt(4 | BT_SIGNED);
305 } else {
306 ts_push(&t2);
310 static void structdef(void *data, struct name *name, unsigned flags)
312 struct structinfo *si = data;
313 if (si->isunion) {
314 name->addr = 0;
315 if (si->size < type_totsz(&name->type))
316 si->size = type_totsz(&name->type);
317 } else {
318 name->addr = si->size;
319 si->size += type_totsz(&name->type);
321 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
324 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
326 static int struct_create(char *name, int isunion)
328 int id = nstructs++;
329 struct structinfo *si = &structs[id];
330 strcpy(si->name, name);
331 si->isunion = isunion;
332 tok_expect('{');
333 while (tok_jmp('}')) {
334 readdefs(structdef, si);
335 tok_expect(';');
337 return id;
340 static void readexpr(void);
342 static void enum_create(void)
344 long n = 0;
345 tok_expect('{');
346 while (tok_jmp('}')) {
347 char name[NAMELEN];
348 tok_expect(TOK_NAME);
349 strcpy(name, tok_id());
350 if (tok_see() == '=') {
351 tok_get();
352 readexpr();
353 ts_pop(NULL);
354 if (o_popnum(&n))
355 die("const expr expected!\n");
357 enum_add(name, n++);
358 tok_jmp(',');
362 static int basetype(struct type *type, unsigned *flags)
364 int sign = 1;
365 int size = 4;
366 int done = 0;
367 int i = 0;
368 int isunion;
369 char name[NAMELEN];
370 *flags = 0;
371 type->flags = 0;
372 type->ptr = 0;
373 while (!done) {
374 switch (tok_see()) {
375 case TOK_STATIC:
376 *flags |= F_STATIC;
377 break;
378 case TOK_VOID:
379 sign = 0;
380 size = 0;
381 done = 1;
382 break;
383 case TOK_INT:
384 done = 1;
385 break;
386 case TOK_CHAR:
387 size = 1;
388 done = 1;
389 break;
390 case TOK_SHORT:
391 size = 2;
392 break;
393 case TOK_LONG:
394 size = 8;
395 break;
396 case TOK_UNSIGNED:
397 sign = 0;
398 break;
399 case TOK_UNION:
400 case TOK_STRUCT:
401 isunion = tok_get() == TOK_UNION;
402 tok_expect(TOK_NAME);
403 strcpy(name, tok_id());
404 if (tok_see() == '{')
405 type->id = struct_create(name, isunion);
406 else
407 type->id = struct_find(name, isunion);
408 type->flags |= T_STRUCT;
409 type->bt = 8;
410 return 0;
411 case TOK_ENUM:
412 tok_get();
413 tok_expect(TOK_NAME);
414 if (tok_see() == '{')
415 enum_create();
416 type->bt = 4 | BT_SIGNED;
417 return 0;
418 default:
419 if (tok_see() == TOK_NAME) {
420 int id = typedef_find(tok_id());
421 if (id != -1) {
422 tok_get();
423 memcpy(type, &typedefs[id].type,
424 sizeof(*type));
425 return 0;
428 if (!i)
429 return 1;
430 done = 1;
431 continue;
433 i++;
434 tok_get();
436 type->bt = size | (sign ? BT_SIGNED : 0);
437 return 0;
440 static void readptrs(struct type *type)
442 while (!tok_jmp('*'))
443 type->ptr++;
446 static int readtype(struct type *type)
448 unsigned flags;
449 if (basetype(type, &flags))
450 return 1;
451 readptrs(type);
452 return 0;
455 static void readpre(void);
457 static void readprimary(void)
459 struct name name;
460 int i;
461 if (!tok_jmp(TOK_NUM)) {
462 ts_push_bt(4 | BT_SIGNED);
463 o_num(tok_num(), 4 | BT_SIGNED);
464 return;
466 if (!tok_jmp(TOK_STR)) {
467 struct type t;
468 char buf[BUFSIZE];
469 int len;
470 t.bt = 1 | BT_SIGNED;
471 t.ptr = 1;
472 t.flags = 0;
473 ts_push(&t);
474 len = tok_str(buf);
475 o_symaddr(o_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
476 o_addr();
477 return;
479 if (!tok_jmp(TOK_NAME)) {
480 int n;
481 for (i = nlocals - 1; i >= 0; --i) {
482 struct type *t = &locals[i].type;
483 if (!strcmp(locals[i].name, tok_id())) {
484 o_local(locals[i].addr, TYPE_BT(t));
485 ts_push(t);
486 return;
489 for (i = 0; i < nglobals; i++) {
490 struct type *t = &globals[i].type;
491 if (!strcmp(globals[i].name, tok_id())) {
492 o_symaddr(globals[i].addr, TYPE_BT(t));
493 ts_push(t);
494 return;
497 if (!enum_find(&n, tok_id())) {
498 ts_push_bt(4 | BT_SIGNED);
499 o_num(n, 4 | BT_SIGNED);
500 return;
502 strcpy(name.name, tok_id());
503 name.addr = o_mkundef(name.name);
504 global_add(&name);
505 ts_push_bt(8);
506 o_symaddr(name.addr, 8);
507 return;
509 if (!tok_jmp('(')) {
510 struct type t;
511 if (!readtype(&t)) {
512 struct type o;
513 tok_expect(')');
514 readpre();
515 ts_pop(&o);
516 ts_push(&t);
517 if (!t.ptr || !o.ptr)
518 o_cast(TYPE_BT(&t));
519 } else {
520 readexpr();
521 tok_expect(')');
523 return;
527 void arrayderef(struct type *t)
529 int sz = type_totsz(t);
530 if (sz > 1) {
531 o_num(sz, 4);
532 o_mul();
534 o_add();
535 o_deref(TYPE_BT(t));
538 static void inc_post(void (*op)(void))
540 unsigned bt = TYPE_BT(&ts[nts - 1]);
541 o_tmpcopy();
542 o_load();
543 o_tmpswap();
544 o_tmpcopy();
545 o_num(1, 4);
546 ts_push_bt(bt);
547 ts_push_bt(bt);
548 ts_binop_add(op);
549 ts_pop(NULL);
550 o_assign(bt);
551 o_tmpdrop(1);
554 static void readfield(void)
556 struct name *field;
557 struct type t;
558 tok_expect(TOK_NAME);
559 ts_pop(&t);
560 field = struct_field(t.id, tok_id());
561 if (field->addr) {
562 o_num(field->addr, 4);
563 o_add();
565 o_deref(TYPE_BT(&field->type));
566 ts_push(&field->type);
569 #define MAXFUNCS (1 << 10)
571 static struct funcinfo {
572 struct type args[MAXFIELDS];
573 struct type ret;
574 int nargs;
575 } funcs[MAXFUNCS];
576 static int nfuncs;
577 static unsigned ret_bt;
579 static int func_create(struct type *ret, struct name *args, int nargs)
581 struct funcinfo *fi = &funcs[nfuncs++];
582 int i;
583 memcpy(&fi->ret, ret, sizeof(*ret));
584 for (i = 0; i < nargs; i++)
585 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
586 fi->nargs = nargs;
587 return fi - funcs;
590 static void readcall(void)
592 struct type t;
593 unsigned bt[MAXARGS];
594 struct funcinfo *fi;
595 int argc = 0;
596 int i;
597 if (tok_see() != ')') {
598 readexpr();
599 ts_pop(&t);
600 bt[argc++] = TYPE_BT(&t);
602 while (!tok_jmp(',')) {
603 readexpr();
604 ts_pop(&t);
605 bt[argc++] = TYPE_BT(&t);
607 tok_expect(')');
608 ts_pop(&t);
609 if (t.flags & T_FUNC && t.ptr > 0)
610 o_deref(8);
611 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
612 if (fi)
613 for (i = 0; i < fi->nargs; i++)
614 bt[i] = TYPE_BT(&fi->args[i]);
615 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
616 if (fi)
617 ts_push(&fi->ret);
618 else
619 ts_push_bt(4 | BT_SIGNED);
622 static void readpost(void)
624 readprimary();
625 while (1) {
626 if (!tok_jmp('[')) {
627 struct type t;
628 ts_pop(&t);
629 readexpr();
630 ts_pop(NULL);
631 tok_expect(']');
632 array2ptr(&t);
633 t.ptr--;
634 arrayderef(&t);
635 ts_push(&t);
636 continue;
638 if (!tok_jmp('(')) {
639 readcall();
640 continue;
642 if (!tok_jmp(TOK2("++"))) {
643 inc_post(o_add);
644 continue;
646 if (!tok_jmp(TOK2("--"))) {
647 inc_post(o_sub);
648 continue;
650 if (!tok_jmp('.')) {
651 o_addr();
652 readfield();
653 continue;
655 if (!tok_jmp(TOK2("->"))) {
656 readfield();
657 continue;
659 break;
663 static void inc_pre(void (*op)(void))
665 unsigned bt = TYPE_BT(&ts[nts - 1]);
666 readpre();
667 o_tmpcopy();
668 o_num(1, 4);
669 ts_push_bt(bt);
670 ts_push_bt(bt);
671 ts_binop_add(op);
672 ts_pop(NULL);
673 o_assign(bt);
676 static void readpre(void)
678 if (!tok_jmp('&')) {
679 struct type type;
680 readpre();
681 ts_pop(&type);
682 if (!(type.flags & T_FUNC) && !type.ptr)
683 type.ptr++;
684 ts_push(&type);
685 o_addr();
686 return;
688 if (!tok_jmp('*')) {
689 struct type t;
690 readpre();
691 ts_pop(&t);
692 array2ptr(&t);
693 if (!(t.flags & T_FUNC) || t.ptr > 0) {
694 t.ptr--;
695 o_deref(TYPE_BT(&t));
697 ts_push(&t);
698 return;
700 if (!tok_jmp('!')) {
701 struct type type;
702 readpre();
703 ts_pop(&type);
704 o_lnot();
705 ts_push_bt(4 | BT_SIGNED);
706 return;
708 if (!tok_jmp('-')) {
709 readpre();
710 o_neg();
711 return;
713 if (!tok_jmp('~')) {
714 readpre();
715 o_not();
716 return;
718 if (!tok_jmp(TOK2("++"))) {
719 inc_pre(o_add);
720 return;
722 if (!tok_jmp(TOK2("--"))) {
723 inc_pre(o_sub);
724 return;
726 if (!tok_jmp(TOK_SIZEOF)) {
727 struct type t;
728 int op = !tok_jmp('(');
729 if (readtype(&t)) {
730 int nogen = !o_nogen();
731 readexpr();
732 if (nogen)
733 o_dogen();
734 ts_pop(&t);
735 o_tmpdrop(1);
737 ts_push_bt(4);
738 o_num(type_totsz(&t), 4);
739 if (op)
740 tok_expect(')');
741 return;
743 readpost();
746 static void readmul(void)
748 readpre();
749 while (1) {
750 if (!tok_jmp('*')) {
751 readpre();
752 ts_binop(o_mul);
753 continue;
755 if (!tok_jmp('/')) {
756 readpre();
757 ts_binop(o_div);
758 continue;
760 if (!tok_jmp('%')) {
761 readpre();
762 ts_binop(o_mod);
763 continue;
765 break;
769 static void readadd(void)
771 readmul();
772 while (1) {
773 if (!tok_jmp('+')) {
774 readmul();
775 ts_binop_add(o_add);
776 continue;
778 if (!tok_jmp('-')) {
779 readmul();
780 ts_binop_add(o_sub);
781 continue;
783 break;
787 static void shift(void (*op)(void))
789 struct type t;
790 readadd();
791 ts_pop(NULL);
792 ts_pop(&t);
793 op();
794 ts_push_bt(TYPE_BT(&t));
797 static void readshift(void)
799 readadd();
800 while (1) {
801 if (!tok_jmp(TOK2("<<"))) {
802 shift(o_shl);
803 continue;
805 if (!tok_jmp(TOK2(">>"))) {
806 shift(o_shr);
807 continue;
809 break;
813 static void cmp(void (*op)(void))
815 readshift();
816 ts_pop(NULL);
817 ts_pop(NULL);
818 op();
819 ts_push_bt(4 | BT_SIGNED);
822 static void readcmp(void)
824 readshift();
825 while (1) {
826 if (!tok_jmp('<')) {
827 cmp(o_lt);
828 continue;
830 if (!tok_jmp('>')) {
831 cmp(o_gt);
832 continue;
834 if (!tok_jmp(TOK2("<="))) {
835 cmp(o_le);
836 continue;
838 if (!tok_jmp(TOK2(">="))) {
839 cmp(o_ge);
840 continue;
842 break;
846 static void eq(void (*op)(void))
848 readcmp();
849 ts_pop(NULL);
850 ts_pop(NULL);
851 op();
852 ts_push_bt(4 | BT_SIGNED);
855 static void readeq(void)
857 readcmp();
858 while (1) {
859 if (!tok_jmp(TOK2("=="))) {
860 eq(o_eq);
861 continue;
863 if (!tok_jmp(TOK2("!="))) {
864 eq(o_neq);
865 continue;
867 break;
871 static void readbitand(void)
873 readeq();
874 while (!tok_jmp('&')) {
875 readeq();
876 ts_binop(o_and);
880 static void readxor(void)
882 readbitand();
883 while (!tok_jmp('^')) {
884 readbitand();
885 ts_binop(o_xor);
889 static void readbitor(void)
891 readxor();
892 while (!tok_jmp('|')) {
893 readxor();
894 ts_binop(o_or);
898 #define MAXCOND (1 << 5)
900 static void readand(void)
902 long conds[MAXCOND];
903 int nconds = 0;
904 long passed;
905 int i;
906 readbitor();
907 if (tok_see() != TOK2("&&"))
908 return;
909 conds[nconds++] = o_jz(0);
910 ts_pop(NULL);
911 while (!tok_jmp(TOK2("&&"))) {
912 readbitor();
913 conds[nconds++] = o_jz(0);
914 ts_pop(NULL);
916 o_num(1, 4 | BT_SIGNED);
917 o_tmpfork();
918 passed = o_jmp(0);
919 for (i = 0; i < nconds; i++)
920 o_filljmp(conds[i]);
921 o_num(0, 4 | BT_SIGNED);
922 o_tmpjoin();
923 o_filljmp(passed);
924 ts_push_bt(4 | BT_SIGNED);
927 static void reador(void)
929 long conds[MAXCOND];
930 int nconds = 0;
931 long failed;
932 int i;
933 readand();
934 if (tok_see() != TOK2("||"))
935 return;
936 conds[nconds++] = o_jnz(0);
937 ts_pop(NULL);
938 while (!tok_jmp(TOK2("||"))) {
939 readand();
940 conds[nconds++] = o_jnz(0);
941 ts_pop(NULL);
943 o_num(0, 4 | BT_SIGNED);
944 o_tmpfork();
945 failed = o_jmp(0);
946 for (i = 0; i < nconds; i++)
947 o_filljmp(conds[i]);
948 o_num(1, 4 | BT_SIGNED);
949 o_tmpjoin();
950 o_filljmp(failed);
951 ts_push_bt(4 | BT_SIGNED);
954 static void readcexpr(void)
956 long l1, l2;
957 long c;
958 int cexpr, nogen;
959 reador();
960 if (tok_jmp('?'))
961 return;
962 cexpr = !o_popnum(&c);
963 ts_pop(NULL);
964 if (cexpr) {
965 if (!c)
966 nogen = !o_nogen();
967 } else {
968 l1 = o_jz(0);
970 reador();
971 if (!cexpr) {
972 o_tmpfork();
973 l2 = o_jmp(0);
975 ts_pop(NULL);
976 tok_expect(':');
977 if (cexpr) {
978 if (c) {
979 nogen = !o_nogen();
980 } else {
981 if (nogen)
982 o_dogen();
983 o_tmpdrop(1);
985 } else {
986 o_filljmp(l1);
988 reador();
989 if (cexpr) {
990 if (c) {
991 if (nogen)
992 o_dogen();
993 o_tmpdrop(1);
995 } else {
996 o_tmpjoin();
997 o_filljmp(l2);
1001 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1003 unsigned bt = TYPE_BT(&ts[nts - 1]);
1004 o_tmpcopy();
1005 readexpr();
1006 bop(op);
1007 ts_pop(NULL);
1008 o_assign(bt);
1011 static void readexpr(void)
1013 readcexpr();
1014 if (!tok_jmp('=')) {
1015 readexpr();
1016 ts_pop(NULL);
1017 o_assign(TYPE_BT(&ts[nts - 1]));
1018 return;
1020 if (!tok_jmp(TOK2("+="))) {
1021 opassign(ts_binop_add, o_add);
1022 return;
1024 if (!tok_jmp(TOK2("-="))) {
1025 opassign(ts_binop_add, o_sub);
1026 return;
1028 if (!tok_jmp(TOK2("*="))) {
1029 opassign(ts_binop, o_mul);
1030 return;
1032 if (!tok_jmp(TOK2("/="))) {
1033 opassign(ts_binop, o_div);
1034 return;
1036 if (!tok_jmp(TOK2("%="))) {
1037 opassign(ts_binop, o_mod);
1038 return;
1040 if (!tok_jmp(TOK3("<<="))) {
1041 opassign(ts_binop, o_shl);
1042 return;
1044 if (!tok_jmp(TOK3(">>="))) {
1045 opassign(ts_binop, o_shr);
1046 return;
1048 if (!tok_jmp(TOK3("&="))) {
1049 opassign(ts_binop, o_and);
1050 return;
1052 if (!tok_jmp(TOK3("|="))) {
1053 opassign(ts_binop, o_or);
1054 return;
1056 if (!tok_jmp(TOK3("^="))) {
1057 opassign(ts_binop, o_xor);
1058 return;
1062 static void readestmt(void)
1064 do {
1065 o_tmpdrop(-1);
1066 nts = 0;
1067 readexpr();
1068 } while (!tok_jmp(','));
1071 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1073 static void globaldef(void *data, struct name *name, unsigned flags)
1075 char *varname = flags & F_STATIC ? NULL : name->name;
1076 name->addr = o_mkvar(varname, type_totsz(&name->type), F_GLOBAL(flags));
1077 global_add(name);
1080 static void localdef(void *data, struct name *name, unsigned flags)
1082 if (flags & F_STATIC) {
1083 globaldef(data, name, flags);
1084 return;
1086 name->addr = o_mklocal(type_totsz(&name->type));
1087 local_add(name);
1088 if (flags & F_INIT) {
1089 struct type *t = &name->type;
1090 o_local(locals[nlocals - 1].addr, TYPE_BT(t));
1091 readexpr();
1092 o_assign(TYPE_BT(t));
1096 static void funcdef(struct name *name, struct name *args,
1097 int nargs, unsigned flags)
1099 int i;
1100 name->addr = o_func_beg(name->name, F_GLOBAL(flags));
1101 global_add(name);
1102 ret_bt = TYPE_BT(&funcs[name->addr].ret);
1103 for (i = 0; i < nargs; i++) {
1104 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1105 local_add(&args[i]);
1109 static int readargs(struct name *args)
1111 int nargs = 0;
1112 tok_expect('(');
1113 while (tok_see() != ')') {
1114 readtype(&args[nargs].type);
1115 if (!tok_jmp(TOK_NAME))
1116 strcpy(args[nargs++].name, tok_id());
1117 if (tok_jmp(','))
1118 break;
1120 tok_expect(')');
1121 return nargs;
1124 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1125 void *data)
1127 struct type base;
1128 unsigned flags;
1129 if (basetype(&base, &flags))
1130 return 1;
1131 while (tok_see() != ';' && tok_see() != '{') {
1132 struct type tpool[3];
1133 struct name name;
1134 int npool = 0;
1135 struct type *type = &tpool[npool++];
1136 struct type *func = NULL;
1137 struct type *ret = NULL;
1138 memset(tpool, 0, sizeof(tpool));
1139 memcpy(type, &base, sizeof(base));
1140 readptrs(type);
1141 if (!tok_jmp('(')) {
1142 ret = type;
1143 type = &tpool[npool++];
1144 func = type;
1145 readptrs(type);
1147 tok_expect(TOK_NAME);
1148 strcpy(name.name, tok_id());
1149 while (!tok_jmp('[')) {
1150 long n;
1151 readexpr();
1152 ts_pop(NULL);
1153 if (o_popnum(&n))
1154 die("const expr expected\n");
1155 type->id = array_add(type, n);
1156 if (type->flags & T_FUNC)
1157 func = &arrays[type->id].type;
1158 type->flags = T_ARRAY;
1159 type->bt = 8;
1160 type->ptr = 0;
1161 tok_expect(']');
1163 if (func)
1164 tok_expect(')');
1165 if (tok_see() == '(') {
1166 struct name args[MAXARGS];
1167 int nargs = readargs(args);
1168 int fdef = !func;
1169 if (!func) {
1170 ret = type;
1171 type = &tpool[npool++];
1172 func = type;
1174 func->flags = T_FUNC;
1175 func->bt = 8;
1176 func->id = func_create(ret, args, nargs);
1177 if (fdef) {
1178 if (tok_see() != '{')
1179 continue;
1180 memcpy(&name.type, func, sizeof(*func));
1181 funcdef(&name, args, nargs, flags);
1182 return 0;
1185 memcpy(&name.type, type, sizeof(*type));
1186 if (!tok_jmp('='))
1187 flags |= F_INIT;
1188 def(data, &name, flags);
1189 tok_jmp(',');
1191 return 0;
1194 static void typedefdef(void *data, struct name *name, unsigned flags)
1196 typedef_add(name->name, &name->type);
1199 #define MAXCASES (1 << 7)
1201 static void readstmt(void);
1203 static void readswitch(void)
1205 int break_beg = nbreaks;
1206 long val_addr = o_mklocal(8);
1207 long matched[MAXCASES];
1208 int nmatched = 0;
1209 struct type t;
1210 long next;
1211 int ref = 1;
1212 int i;
1213 tok_expect('(');
1214 readexpr();
1215 ts_pop(&t);
1216 o_local(val_addr, TYPE_BT(&t));
1217 o_tmpswap();
1218 o_assign(TYPE_BT(&t));
1219 o_tmpdrop(1);
1220 tok_expect(')');
1221 tok_expect('{');
1222 while (tok_jmp('}')) {
1223 int n = 0;
1224 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1225 if (n++ > 0)
1226 matched[nmatched++] = o_jmp(0);
1227 if (!ref++)
1228 o_filljmp(next);
1229 if (!tok_jmp(TOK_CASE)) {
1230 readexpr();
1231 o_local(val_addr, TYPE_BT(&t));
1232 o_eq();
1233 next = o_jz(0);
1234 ref = 0;
1235 tok_expect(':');
1236 o_tmpdrop(1);
1237 ts_pop(NULL);
1238 continue;
1240 if (!tok_jmp(TOK_DEFAULT)) {
1241 tok_expect(':');
1242 continue;
1245 for (i = 0; i < nmatched; i++)
1246 o_filljmp(matched[i]);
1247 nmatched = 0;
1248 readstmt();
1250 o_rmlocal(val_addr, 8);
1251 if (!ref++)
1252 o_filljmp(next);
1253 break_fill(o_mklabel(), break_beg);
1256 static void readstmt(void)
1258 o_tmpdrop(-1);
1259 nts = 0;
1260 if (!tok_jmp('{')) {
1261 int _nlocals = nlocals;
1262 int _nglobals = nglobals;
1263 int _nenums = nenums;
1264 int _ntypedefs = ntypedefs;
1265 int _nstructs = nstructs;
1266 int _nfuncs = nfuncs;
1267 int _narrays = narrays;
1268 while (tok_jmp('}'))
1269 readstmt();
1270 nlocals = _nlocals;
1271 nenums = _nenums;
1272 ntypedefs = _ntypedefs;
1273 nstructs = _nstructs;
1274 nfuncs = _nfuncs;
1275 narrays = _narrays;
1276 nglobals = _nglobals;
1277 return;
1279 if (!readdefs(localdef, NULL)) {
1280 tok_expect(';');
1281 return;
1283 if (!tok_jmp(TOK_TYPEDEF)) {
1284 readdefs(typedefdef, NULL);
1285 tok_expect(';');
1286 return;
1288 if (!tok_jmp(TOK_IF)) {
1289 long l1, l2;
1290 tok_expect('(');
1291 readexpr();
1292 tok_expect(')');
1293 l1 = o_jz(0);
1294 readstmt();
1295 if (!tok_jmp(TOK_ELSE)) {
1296 l2 = o_jmp(0);
1297 o_filljmp(l1);
1298 readstmt();
1299 o_filljmp(l2);
1300 } else {
1301 o_filljmp(l1);
1303 return;
1305 if (!tok_jmp(TOK_WHILE)) {
1306 long l1, l2;
1307 int break_beg = nbreaks;
1308 int continue_beg = ncontinues;
1309 l1 = o_mklabel();
1310 tok_expect('(');
1311 readexpr();
1312 tok_expect(')');
1313 l2 = o_jz(0);
1314 readstmt();
1315 o_jmp(l1);
1316 o_filljmp(l2);
1317 break_fill(o_mklabel(), break_beg);
1318 continue_fill(l1, continue_beg);
1319 return;
1321 if (!tok_jmp(TOK_DO)) {
1322 long l1, l2;
1323 int break_beg = nbreaks;
1324 int continue_beg = ncontinues;
1325 l1 = o_mklabel();
1326 readstmt();
1327 tok_expect(TOK_WHILE);
1328 tok_expect('(');
1329 l2 = o_mklabel();
1330 readexpr();
1331 o_jnz(l1);
1332 tok_expect(')');
1333 break_fill(o_mklabel(), break_beg);
1334 continue_fill(l2, continue_beg);
1335 return;
1337 if (!tok_jmp(TOK_FOR)) {
1338 long check, jump, end, body;
1339 int break_beg = nbreaks;
1340 int continue_beg = ncontinues;
1341 tok_expect('(');
1342 if (tok_see() != ';')
1343 readestmt();
1344 tok_expect(';');
1345 check = o_mklabel();
1346 if (tok_see() != ';')
1347 readestmt();
1348 tok_expect(';');
1349 end = o_jz(0);
1350 body = o_jmp(0);
1351 jump = o_mklabel();
1352 if (tok_see() != ')')
1353 readestmt();
1354 tok_expect(')');
1355 o_jmp(check);
1356 o_filljmp(body);
1357 readstmt();
1358 o_jmp(jump);
1359 o_filljmp(end);
1360 break_fill(o_mklabel(), break_beg);
1361 continue_fill(jump, continue_beg);
1362 return;
1364 if (!tok_jmp(TOK_SWITCH)) {
1365 readswitch();
1366 return;
1368 if (!tok_jmp(TOK_RETURN)) {
1369 int ret = tok_see() != ';';
1370 if (ret)
1371 readexpr();
1372 tok_expect(';');
1373 o_ret(ret_bt);
1374 return;
1376 if (!tok_jmp(TOK_BREAK)) {
1377 tok_expect(';');
1378 breaks[nbreaks++] = o_jmp(0);
1379 return;
1381 if (!tok_jmp(TOK_CONTINUE)) {
1382 tok_expect(';');
1383 continues[ncontinues++] = o_jmp(0);
1384 return;
1386 readestmt();
1387 tok_expect(';');
1390 static void readdecl(void)
1392 if (!tok_jmp(TOK_TYPEDEF)) {
1393 readdefs(typedefdef, NULL);
1394 tok_expect(';');
1395 return;
1397 readdefs(globaldef, NULL);
1398 if (tok_see() == '{') {
1399 readstmt();
1400 o_func_end();
1401 nlocals = 0;
1402 return;
1404 tok_expect(';');
1407 static void parse(void)
1409 while (tok_see() != TOK_EOF)
1410 readdecl();
1413 int main(int argc, char *argv[])
1415 char obj[128];
1416 int ifd, ofd;
1417 int i = 1;
1418 while (i < argc && argv[i][0] == '-')
1419 i++;
1420 if (i == argc)
1421 die("no file given\n");
1422 ifd = open(argv[i], O_RDONLY);
1423 tok_init(ifd);
1424 close(ifd);
1425 parse();
1427 strcpy(obj, argv[i]);
1428 obj[strlen(obj) - 1] = 'o';
1429 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1430 out_write(ofd);
1431 close(ofd);
1432 return 0;