for statements with no condition
[neatcc/cc.git] / ncc.c
blob5dfc6c50d4d4db312110ff136fc769990f868b54
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 struct name {
68 char name[NAMELEN];
69 struct type type;
70 long addr;
73 static struct name locals[MAXLOCALS];
74 static int nlocals;
75 static struct name globals[MAXGLOBALS];
76 static int nglobals;
78 static void local_add(struct name *name)
80 memcpy(&locals[nlocals++], name, sizeof(*name));
83 static int global_find(char *name)
85 int i;
86 for (i = 0; i < nglobals; i++)
87 if (!strcmp(name, globals[i].name))
88 return i;
89 return -1;
92 static void global_add(struct name *name)
94 int found = global_find(name->name);
95 int i = found == -1 ? nglobals++ : found;
96 memcpy(&globals[i], name, sizeof(*name));
99 static void die(char *s)
101 print(s);
102 exit(1);
105 #define MAXENUMS (1 << 10)
107 static struct enumval {
108 char name[NAMELEN];
109 int n;
110 } enums[MAXENUMS];
111 static int nenums;
113 static void enum_add(char *name, int val)
115 struct enumval *ev = &enums[nenums++];
116 strcpy(ev->name, name);
117 ev->n = val;
120 static int enum_find(int *val, char *name)
122 int i;
123 for (i = nenums - 1; i >= 0; --i)
124 if (!strcmp(name, enums[i].name)) {
125 *val = enums[i].n;
126 return 0;
128 return 1;
131 #define MAXTYPEDEFS (1 << 10)
133 static struct typdefinfo {
134 char name[NAMELEN];
135 struct type type;
136 } typedefs[MAXTYPEDEFS];
137 static int ntypedefs;
139 static void typedef_add(char *name, struct type *type)
141 struct typdefinfo *ti = &typedefs[ntypedefs++];
142 strcpy(ti->name, name);
143 memcpy(&ti->type, type, sizeof(*type));
146 static int typedef_find(char *name)
148 int i;
149 for (i = ntypedefs - 1; i >= 0; --i)
150 if (!strcmp(name, typedefs[i].name))
151 return i;
152 return -1;
155 #define MAXARRAYS (1 << 10)
157 static struct array {
158 struct type type;
159 int n;
160 } arrays[MAXARRAYS];
161 static int narrays;
163 static int array_add(struct type *type, int n)
165 struct array *a = &arrays[narrays++];
166 memcpy(&a->type, type, sizeof(*type));
167 a->n = n;
168 return a - arrays;
171 static void array2ptr(struct type *t)
173 if (!(t->flags & T_ARRAY) || t->ptr)
174 return;
175 memcpy(t, &arrays[t->id].type, sizeof(*t));
176 t->ptr++;
179 #define MAXTYPES (1 << 10)
180 #define MAXFIELDS (1 << 7)
182 static struct structinfo {
183 char name[NAMELEN];
184 struct name fields[MAXFIELDS];
185 int nfields;
186 int isunion;
187 int size;
188 } structs[MAXTYPES];
189 static int nstructs;
191 static int struct_find(char *name, int isunion)
193 int i;
194 for (i = nstructs - 1; i >= 0; --i)
195 if (*structs[i].name && !strcmp(name, structs[i].name) &&
196 structs[i].isunion == isunion)
197 return i;
198 i = nstructs++;
199 memset(&structs[i], 0, sizeof(structs[i]));
200 strcpy(structs[i].name, name);
201 structs[i].isunion = isunion;
202 return i;
205 static struct name *struct_field(int id, char *name)
207 struct structinfo *si = &structs[id];
208 int i;
209 for (i = 0; i < si->nfields; i++)
210 if (!strcmp(name, si->fields[i].name))
211 return &si->fields[i];
212 die("field not found\n");
215 #define MAXBREAK (1 << 7)
217 static long breaks[MAXBREAK];
218 static int nbreaks;
219 static long continues[MAXBREAK];
220 static int ncontinues;
222 static void break_fill(long addr, int till)
224 int i;
225 for (i = till; i < nbreaks; i++)
226 o_filljmp2(breaks[i], addr);
227 nbreaks = till;
230 static void continue_fill(long addr, int till)
232 int i;
233 for (i = till; i < ncontinues; i++)
234 o_filljmp2(continues[i], addr);
235 ncontinues = till;
238 static int type_totsz(struct type *t)
240 if (t->ptr)
241 return 8;
242 if (t->flags & T_ARRAY)
243 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
244 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
247 static unsigned type_szde(struct type *t)
249 if (t->flags & T_ARRAY)
250 return t->ptr > 0 ? 8 : TYPE_SZ(&arrays[t->id].type);
251 else
252 return t->ptr > 1 ? 8 : BT_SZ(t->bt);
255 static int tok_jmp(int tok)
257 if (tok_see() != tok)
258 return 1;
259 tok_get();
260 return 0;
263 static void tok_expect(int tok)
265 if (tok_get() != tok)
266 die("syntax error\n");
269 static unsigned bt_op(unsigned bt1, unsigned bt2)
271 unsigned s1 = BT_SZ(bt1);
272 unsigned s2 = BT_SZ(bt2);
273 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
276 static void ts_binop(void (*o_sth)(void))
278 struct type t1, t2;
279 ts_pop(&t1);
280 ts_pop(&t2);
281 o_sth();
282 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
285 static int shifts(int n)
287 int i = -1;
288 while (i++ < 16)
289 if (n == 1 << i)
290 break;
291 return i;
294 static void ts_binop_add(void (*o_sth)(void))
296 struct type t1, t2;
297 ts_pop(&t1);
298 ts_pop(&t2);
299 array2ptr(&t1);
300 array2ptr(&t2);
301 if (!t1.ptr && !t2.ptr) {
302 o_sth();
303 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
304 return;
306 if (t1.ptr && !t2.ptr) {
307 struct type t = t2;
308 t2 = t1;
309 t1 = t;
310 o_tmpswap();
312 if (!t1.ptr && t2.ptr)
313 if (type_szde(&t2) > 1) {
314 o_num(shifts(type_szde(&t2)), 1);
315 o_shl();
317 o_sth();
318 if (t1.ptr && t2.ptr) {
319 o_num(shifts(type_szde(&t1)), 1);
320 o_shr();
321 ts_push_bt(4 | BT_SIGNED);
322 } else {
323 ts_push(&t2);
327 static void structdef(void *data, struct name *name, unsigned flags)
329 struct structinfo *si = data;
330 if (si->isunion) {
331 name->addr = 0;
332 if (si->size < type_totsz(&name->type))
333 si->size = type_totsz(&name->type);
334 } else {
335 name->addr = si->size;
336 si->size += type_totsz(&name->type);
338 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
341 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
343 static int struct_create(char *name, int isunion)
345 int id = struct_find(name, isunion);
346 struct structinfo *si = &structs[id];
347 tok_expect('{');
348 while (tok_jmp('}')) {
349 readdefs(structdef, si);
350 tok_expect(';');
352 return id;
355 static void readexpr(void);
357 static void enum_create(void)
359 long n = 0;
360 tok_expect('{');
361 while (tok_jmp('}')) {
362 char name[NAMELEN];
363 tok_expect(TOK_NAME);
364 strcpy(name, tok_id());
365 if (tok_see() == '=') {
366 tok_get();
367 readexpr();
368 ts_pop(NULL);
369 if (o_popnum(&n))
370 die("const expr expected!\n");
372 enum_add(name, n++);
373 tok_jmp(',');
377 static int basetype(struct type *type, unsigned *flags)
379 int sign = 1;
380 int size = 4;
381 int done = 0;
382 int i = 0;
383 int isunion;
384 char name[NAMELEN] = "";
385 *flags = 0;
386 type->flags = 0;
387 type->ptr = 0;
388 while (!done) {
389 switch (tok_see()) {
390 case TOK_STATIC:
391 *flags |= F_STATIC;
392 break;
393 case TOK_EXTERN:
394 *flags |= F_EXTERN;
395 break;
396 case TOK_VOID:
397 sign = 0;
398 size = 0;
399 done = 1;
400 break;
401 case TOK_INT:
402 done = 1;
403 break;
404 case TOK_CHAR:
405 size = 1;
406 done = 1;
407 break;
408 case TOK_SHORT:
409 size = 2;
410 break;
411 case TOK_LONG:
412 size = 8;
413 break;
414 case TOK_SIGNED:
415 break;
416 case TOK_UNSIGNED:
417 sign = 0;
418 break;
419 case TOK_UNION:
420 case TOK_STRUCT:
421 isunion = tok_get() == TOK_UNION;
422 if (!tok_jmp(TOK_NAME))
423 strcpy(name, tok_id());
424 if (tok_see() == '{')
425 type->id = struct_create(name, isunion);
426 else
427 type->id = struct_find(name, isunion);
428 type->flags |= T_STRUCT;
429 type->bt = 8;
430 return 0;
431 case TOK_ENUM:
432 tok_get();
433 tok_jmp(TOK_NAME);
434 if (tok_see() == '{')
435 enum_create();
436 type->bt = 4 | BT_SIGNED;
437 return 0;
438 default:
439 if (tok_see() == TOK_NAME) {
440 int id = typedef_find(tok_id());
441 if (id != -1) {
442 tok_get();
443 memcpy(type, &typedefs[id].type,
444 sizeof(*type));
445 return 0;
448 if (!i)
449 return 1;
450 done = 1;
451 continue;
453 i++;
454 tok_get();
456 type->bt = size | (sign ? BT_SIGNED : 0);
457 return 0;
460 static int readname(struct type *main, char *name,
461 struct type *base, unsigned flags);
463 static int readtype(struct type *type)
465 return readname(type, NULL, NULL, 0);
468 static void readptrs(struct type *type)
470 while (!tok_jmp('*')) {
471 type->ptr++;
472 if (!type->bt)
473 type->bt = 1;
477 static int ncexpr;
479 static void readpre(void);
481 static void readprimary(void)
483 int i;
484 if (!tok_jmp(TOK_NUM)) {
485 ts_push_bt(4 | BT_SIGNED);
486 o_num(tok_num(), 4 | BT_SIGNED);
487 return;
489 if (!tok_jmp(TOK_STR)) {
490 struct type t;
491 char buf[BUFSIZE];
492 int len;
493 t.bt = 1 | BT_SIGNED;
494 t.ptr = 1;
495 t.flags = 0;
496 ts_push(&t);
497 len = tok_str(buf);
498 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(&t));
499 o_addr();
500 return;
502 if (!tok_jmp(TOK_NAME)) {
503 struct name unkn;
504 char *name = unkn.name;
505 int n;
506 strcpy(name, tok_id());
507 /* don't search for labels here */
508 if (!ncexpr && tok_see() == ':')
509 return;
510 for (i = nlocals - 1; i >= 0; --i) {
511 struct type *t = &locals[i].type;
512 if (!strcmp(locals[i].name, name)) {
513 o_local(locals[i].addr, TYPE_BT(t));
514 ts_push(t);
515 return;
518 if ((n = global_find(name)) != -1) {
519 struct type *t = &globals[n].type;
520 o_symaddr(globals[n].addr, TYPE_BT(t));
521 ts_push(t);
522 return;
524 if (!enum_find(&n, name)) {
525 ts_push_bt(4 | BT_SIGNED);
526 o_num(n, 4 | BT_SIGNED);
527 return;
529 if (tok_see() != '(')
530 die("unknown symbol\n");
531 unkn.addr = out_mkundef(unkn.name, 0);
532 global_add(&unkn);
533 ts_push_bt(8);
534 o_symaddr(unkn.addr, 8);
535 return;
537 if (!tok_jmp('(')) {
538 struct type t;
539 if (!readtype(&t)) {
540 struct type o;
541 tok_expect(')');
542 readpre();
543 ts_pop(&o);
544 ts_push(&t);
545 if (!t.ptr || !o.ptr)
546 o_cast(TYPE_BT(&t));
547 } else {
548 readexpr();
549 tok_expect(')');
551 return;
555 void arrayderef(struct type *t)
557 int sz = type_totsz(t);
558 if (sz > 1) {
559 o_num(sz, 4);
560 o_mul();
562 o_add();
563 o_deref(TYPE_BT(t));
566 static void inc_post(void (*op)(void))
568 unsigned bt = TYPE_BT(&ts[nts - 1]);
569 o_tmpcopy();
570 o_load();
571 o_tmpswap();
572 o_tmpcopy();
573 o_num(1, 4);
574 ts_push_bt(bt);
575 ts_push_bt(bt);
576 ts_binop_add(op);
577 ts_pop(NULL);
578 o_assign(bt);
579 o_tmpdrop(1);
582 static void readfield(void)
584 struct name *field;
585 struct type t;
586 tok_expect(TOK_NAME);
587 ts_pop(&t);
588 array2ptr(&t);
589 field = struct_field(t.id, tok_id());
590 if (field->addr) {
591 o_num(field->addr, 4);
592 o_add();
594 o_deref(TYPE_BT(&field->type));
595 ts_push(&field->type);
598 #define MAXFUNCS (1 << 10)
600 static struct funcinfo {
601 struct type args[MAXFIELDS];
602 struct type ret;
603 int nargs;
604 } funcs[MAXFUNCS];
605 static int nfuncs;
606 static unsigned ret_bt;
608 static int func_create(struct type *ret, struct name *args, int nargs)
610 struct funcinfo *fi = &funcs[nfuncs++];
611 int i;
612 memcpy(&fi->ret, ret, sizeof(*ret));
613 for (i = 0; i < nargs; i++)
614 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
615 fi->nargs = nargs;
616 return fi - funcs;
619 static void readcall(void)
621 struct type t;
622 unsigned bt[MAXARGS];
623 struct funcinfo *fi;
624 int argc = 0;
625 int i;
626 if (tok_see() != ')') {
627 readexpr();
628 ts_pop(&t);
629 bt[argc++] = TYPE_BT(&t);
631 while (!tok_jmp(',')) {
632 readexpr();
633 ts_pop(&t);
634 bt[argc++] = TYPE_BT(&t);
636 tok_expect(')');
637 ts_pop(&t);
638 if (t.flags & T_FUNC && t.ptr > 0)
639 o_deref(8);
640 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
641 if (fi)
642 for (i = 0; i < fi->nargs; i++)
643 bt[i] = TYPE_BT(&fi->args[i]);
644 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
645 if (fi)
646 ts_push(&fi->ret);
647 else
648 ts_push_bt(4 | BT_SIGNED);
651 static void readpost(void)
653 readprimary();
654 while (1) {
655 if (!tok_jmp('[')) {
656 struct type t;
657 ts_pop(&t);
658 readexpr();
659 ts_pop(NULL);
660 tok_expect(']');
661 array2ptr(&t);
662 t.ptr--;
663 arrayderef(&t);
664 ts_push(&t);
665 continue;
667 if (!tok_jmp('(')) {
668 readcall();
669 continue;
671 if (!tok_jmp(TOK2("++"))) {
672 inc_post(o_add);
673 continue;
675 if (!tok_jmp(TOK2("--"))) {
676 inc_post(o_sub);
677 continue;
679 if (!tok_jmp('.')) {
680 o_addr();
681 readfield();
682 continue;
684 if (!tok_jmp(TOK2("->"))) {
685 readfield();
686 continue;
688 break;
692 static void inc_pre(void (*op)(void))
694 unsigned bt = TYPE_BT(&ts[nts - 1]);
695 readpre();
696 o_tmpcopy();
697 o_num(1, 4);
698 ts_push_bt(bt);
699 ts_push_bt(bt);
700 ts_binop_add(op);
701 ts_pop(NULL);
702 o_assign(bt);
705 static void readpre(void)
707 if (!tok_jmp('&')) {
708 struct type type;
709 readpre();
710 ts_pop(&type);
711 if (!(type.flags & T_FUNC) && !type.ptr)
712 type.ptr++;
713 ts_push(&type);
714 o_addr();
715 return;
717 if (!tok_jmp('*')) {
718 struct type t;
719 readpre();
720 ts_pop(&t);
721 array2ptr(&t);
722 if (!(t.flags & T_FUNC) || t.ptr > 0) {
723 t.ptr--;
724 o_deref(TYPE_BT(&t));
726 ts_push(&t);
727 return;
729 if (!tok_jmp('!')) {
730 struct type type;
731 readpre();
732 ts_pop(&type);
733 o_lnot();
734 ts_push_bt(4 | BT_SIGNED);
735 return;
737 if (!tok_jmp('-')) {
738 readpre();
739 o_neg();
740 return;
742 if (!tok_jmp('~')) {
743 readpre();
744 o_not();
745 return;
747 if (!tok_jmp(TOK2("++"))) {
748 inc_pre(o_add);
749 return;
751 if (!tok_jmp(TOK2("--"))) {
752 inc_pre(o_sub);
753 return;
755 if (!tok_jmp(TOK_SIZEOF)) {
756 struct type t;
757 int op = !tok_jmp('(');
758 if (readtype(&t)) {
759 int nogen = !o_nogen();
760 readexpr();
761 if (nogen)
762 o_dogen();
763 ts_pop(&t);
764 o_tmpdrop(1);
766 ts_push_bt(4);
767 o_num(type_totsz(&t), 4);
768 if (op)
769 tok_expect(')');
770 return;
772 readpost();
775 static void readmul(void)
777 readpre();
778 while (1) {
779 if (!tok_jmp('*')) {
780 readpre();
781 ts_binop(o_mul);
782 continue;
784 if (!tok_jmp('/')) {
785 readpre();
786 ts_binop(o_div);
787 continue;
789 if (!tok_jmp('%')) {
790 readpre();
791 ts_binop(o_mod);
792 continue;
794 break;
798 static void readadd(void)
800 readmul();
801 while (1) {
802 if (!tok_jmp('+')) {
803 readmul();
804 ts_binop_add(o_add);
805 continue;
807 if (!tok_jmp('-')) {
808 readmul();
809 ts_binop_add(o_sub);
810 continue;
812 break;
816 static void shift(void (*op)(void))
818 struct type t;
819 readadd();
820 ts_pop(NULL);
821 ts_pop(&t);
822 op();
823 ts_push_bt(TYPE_BT(&t));
826 static void readshift(void)
828 readadd();
829 while (1) {
830 if (!tok_jmp(TOK2("<<"))) {
831 shift(o_shl);
832 continue;
834 if (!tok_jmp(TOK2(">>"))) {
835 shift(o_shr);
836 continue;
838 break;
842 static void cmp(void (*op)(void))
844 readshift();
845 ts_pop(NULL);
846 ts_pop(NULL);
847 op();
848 ts_push_bt(4 | BT_SIGNED);
851 static void readcmp(void)
853 readshift();
854 while (1) {
855 if (!tok_jmp('<')) {
856 cmp(o_lt);
857 continue;
859 if (!tok_jmp('>')) {
860 cmp(o_gt);
861 continue;
863 if (!tok_jmp(TOK2("<="))) {
864 cmp(o_le);
865 continue;
867 if (!tok_jmp(TOK2(">="))) {
868 cmp(o_ge);
869 continue;
871 break;
875 static void eq(void (*op)(void))
877 readcmp();
878 ts_pop(NULL);
879 ts_pop(NULL);
880 op();
881 ts_push_bt(4 | BT_SIGNED);
884 static void readeq(void)
886 readcmp();
887 while (1) {
888 if (!tok_jmp(TOK2("=="))) {
889 eq(o_eq);
890 continue;
892 if (!tok_jmp(TOK2("!="))) {
893 eq(o_neq);
894 continue;
896 break;
900 static void readbitand(void)
902 readeq();
903 while (!tok_jmp('&')) {
904 readeq();
905 ts_binop(o_and);
909 static void readxor(void)
911 readbitand();
912 while (!tok_jmp('^')) {
913 readbitand();
914 ts_binop(o_xor);
918 static void readbitor(void)
920 readxor();
921 while (!tok_jmp('|')) {
922 readxor();
923 ts_binop(o_or);
927 #define MAXCOND (1 << 7)
929 static void readand(void)
931 long conds[MAXCOND];
932 int nconds = 0;
933 long passed;
934 int i;
935 readbitor();
936 if (tok_see() != TOK2("&&"))
937 return;
938 conds[nconds++] = o_jz(0);
939 ts_pop(NULL);
940 while (!tok_jmp(TOK2("&&"))) {
941 readbitor();
942 conds[nconds++] = o_jz(0);
943 ts_pop(NULL);
945 o_num(1, 4 | BT_SIGNED);
946 o_tmpfork();
947 passed = o_jmp(0);
948 for (i = 0; i < nconds; i++)
949 o_filljmp(conds[i]);
950 o_num(0, 4 | BT_SIGNED);
951 o_tmpjoin();
952 o_filljmp(passed);
953 ts_push_bt(4 | BT_SIGNED);
956 static void reador(void)
958 long conds[MAXCOND];
959 int nconds = 0;
960 long failed;
961 int i;
962 readand();
963 if (tok_see() != TOK2("||"))
964 return;
965 conds[nconds++] = o_jnz(0);
966 ts_pop(NULL);
967 while (!tok_jmp(TOK2("||"))) {
968 readand();
969 conds[nconds++] = o_jnz(0);
970 ts_pop(NULL);
972 o_num(0, 4 | BT_SIGNED);
973 o_tmpfork();
974 failed = o_jmp(0);
975 for (i = 0; i < nconds; i++)
976 o_filljmp(conds[i]);
977 o_num(1, 4 | BT_SIGNED);
978 o_tmpjoin();
979 o_filljmp(failed);
980 ts_push_bt(4 | BT_SIGNED);
983 static void readcexpr(void)
985 long l1, l2;
986 long c;
987 int cexpr, nogen;
988 reador();
989 if (tok_jmp('?'))
990 return;
991 ncexpr++;
992 cexpr = !o_popnum(&c);
993 ts_pop(NULL);
994 if (cexpr) {
995 if (!c)
996 nogen = !o_nogen();
997 } else {
998 l1 = o_jz(0);
1000 reador();
1001 if (!cexpr) {
1002 o_tmpfork();
1003 l2 = o_jmp(0);
1005 ts_pop(NULL);
1006 tok_expect(':');
1007 if (cexpr) {
1008 if (c) {
1009 nogen = !o_nogen();
1010 } else {
1011 if (nogen)
1012 o_dogen();
1013 o_tmpdrop(1);
1015 } else {
1016 o_filljmp(l1);
1018 reador();
1019 if (cexpr) {
1020 if (c) {
1021 if (nogen)
1022 o_dogen();
1023 o_tmpdrop(1);
1025 } else {
1026 o_tmpjoin();
1027 o_filljmp(l2);
1029 ncexpr--;
1032 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1034 unsigned bt = TYPE_BT(&ts[nts - 1]);
1035 o_tmpcopy();
1036 readexpr();
1037 bop(op);
1038 ts_pop(NULL);
1039 o_assign(bt);
1042 static void doassign(void)
1044 struct type t;
1045 ts_pop(&t);
1046 if (!t.ptr && t.flags & T_STRUCT)
1047 o_memcpy(type_totsz(&t));
1048 else
1049 o_assign(TYPE_BT(&ts[nts - 1]));
1052 static void readexpr(void)
1054 readcexpr();
1055 if (!tok_jmp('=')) {
1056 readexpr();
1057 doassign();
1058 return;
1060 if (!tok_jmp(TOK2("+="))) {
1061 opassign(ts_binop_add, o_add);
1062 return;
1064 if (!tok_jmp(TOK2("-="))) {
1065 opassign(ts_binop_add, o_sub);
1066 return;
1068 if (!tok_jmp(TOK2("*="))) {
1069 opassign(ts_binop, o_mul);
1070 return;
1072 if (!tok_jmp(TOK2("/="))) {
1073 opassign(ts_binop, o_div);
1074 return;
1076 if (!tok_jmp(TOK2("%="))) {
1077 opassign(ts_binop, o_mod);
1078 return;
1080 if (!tok_jmp(TOK3("<<="))) {
1081 opassign(ts_binop, o_shl);
1082 return;
1084 if (!tok_jmp(TOK3(">>="))) {
1085 opassign(ts_binop, o_shr);
1086 return;
1088 if (!tok_jmp(TOK3("&="))) {
1089 opassign(ts_binop, o_and);
1090 return;
1092 if (!tok_jmp(TOK3("|="))) {
1093 opassign(ts_binop, o_or);
1094 return;
1096 if (!tok_jmp(TOK3("^="))) {
1097 opassign(ts_binop, o_xor);
1098 return;
1102 static void readestmt(void)
1104 do {
1105 o_tmpdrop(-1);
1106 nts = 0;
1107 readexpr();
1108 } while (!tok_jmp(','));
1111 static void o_localoff(long addr, int off, unsigned bt)
1113 o_local(addr, bt);
1114 if (off) {
1115 o_addr();
1116 o_num(off, 4);
1117 o_add();
1118 o_deref(bt);
1122 static struct type *innertype(struct type *t)
1124 if (t->flags & T_ARRAY && !t->ptr)
1125 return innertype(&arrays[t->id].type);
1126 return t;
1129 static void initexpr(struct type *t, int off, void *obj,
1130 void (*set)(void *obj, int off, struct type *t))
1132 if (tok_jmp('{')) {
1133 set(obj, off, t);
1134 return;
1136 if (!t->ptr && t->flags & T_STRUCT) {
1137 struct structinfo *si = &structs[t->id];
1138 int i;
1139 for (i = 0; i < si->nfields; i++) {
1140 struct name *field = &si->fields[i];
1141 if (!tok_jmp('.')) {
1142 tok_expect(TOK_NAME);
1143 field = struct_field(t->id, tok_id());
1144 tok_expect('=');
1146 initexpr(&field->type, off + field->addr, obj, set);
1147 if (tok_jmp(',') || tok_see() == '}')
1148 break;
1150 } else if (t->flags & T_ARRAY) {
1151 struct type *t_de = &arrays[t->id].type;
1152 int i;
1153 for (i = 0; ; i++) {
1154 long idx = i;
1155 struct type *it = t_de;
1156 if (!tok_jmp('[')) {
1157 readexpr();
1158 o_popnum(&idx);
1159 ts_pop(NULL);
1160 tok_expect(']');
1161 tok_expect('=');
1163 if (tok_see() != '{')
1164 it = innertype(t_de);
1165 initexpr(it, off + type_totsz(it) * idx, obj, set);
1166 if (tok_jmp(',') || tok_see() == '}')
1167 break;
1170 tok_expect('}');
1173 static void jumpbrace(void)
1175 int depth = 0;
1176 while (tok_see() != '}' || depth--)
1177 if (tok_get() == '{')
1178 depth++;
1179 tok_expect('}');
1182 static int initsize(void)
1184 long addr = tok_addr();
1185 int n = 0;
1186 if (!tok_jmp(TOK_STR)) {
1187 n = tok_str(NULL);
1188 tok_jump(addr);
1189 return n;
1191 o_nogen();
1192 tok_expect('{');
1193 while (tok_jmp('}')) {
1194 long idx = n;
1195 if (!tok_jmp('[')) {
1196 readexpr();
1197 o_popnum(&idx);
1198 ts_pop(NULL);
1199 tok_expect(']');
1200 tok_expect('=');
1202 if (n < idx + 1)
1203 n = idx + 1;
1204 while (tok_see() != '}' && tok_see() != ',')
1205 if (tok_get() == '{')
1206 jumpbrace();
1207 tok_jmp(',');
1209 o_dogen();
1210 tok_jump(addr);
1211 return n;
1214 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1216 static void globalinit(void *obj, int off, struct type *t)
1218 long addr = *(long *) obj;
1219 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1220 struct type *t_de = &arrays[t->id].type;
1221 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1222 char buf[BUFSIZE];
1223 int len;
1224 tok_expect(TOK_STR);
1225 len = tok_str(buf);
1226 out_datcpy(addr, off, buf, len);
1227 return;
1230 readexpr();
1231 o_datset(addr, off, TYPE_BT(t));
1232 ts_pop(NULL);
1235 static void globaldef(void *data, struct name *name, unsigned flags)
1237 struct type *t = &name->type;
1238 char *varname = flags & F_STATIC ? NULL : name->name;
1239 int sz;
1240 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1241 arrays[t->id].n = initsize();
1242 sz = type_totsz(t);
1243 if (flags & F_EXTERN)
1244 name->addr = out_mkundef(varname, sz);
1245 else if (flags & F_INIT)
1246 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1247 else
1248 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1249 global_add(name);
1250 if (flags & F_INIT)
1251 initexpr(t, 0, &name->addr, globalinit);
1254 static void localinit(void *obj, int off, struct type *t)
1256 long addr = *(long *) obj;
1257 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1258 struct type *t_de = &arrays[t->id].type;
1259 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1260 char buf[BUFSIZE];
1261 int len;
1262 tok_expect(TOK_STR);
1263 len = tok_str(buf);
1264 o_localoff(addr, off, TYPE_BT(t));
1265 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1266 o_memcpy(len);
1267 o_tmpdrop(1);
1268 return;
1271 o_localoff(addr, off, TYPE_BT(t));
1272 ts_push(t);
1273 readexpr();
1274 doassign();
1275 ts_pop(NULL);
1276 o_tmpdrop(1);
1279 static void localdef(void *data, struct name *name, unsigned flags)
1281 struct type *t = &name->type;
1282 if (flags & (F_STATIC | F_EXTERN)) {
1283 globaldef(data, name, flags);
1284 return;
1286 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1287 arrays[t->id].n = initsize();
1288 name->addr = o_mklocal(type_totsz(&name->type));
1289 local_add(name);
1290 if (flags & F_INIT) {
1291 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1292 o_local(name->addr, TYPE_BT(t));
1293 o_memset(0, type_totsz(t));
1294 o_tmpdrop(1);
1296 initexpr(t, 0, &name->addr, localinit);
1300 static void funcdef(char *name, struct type *type, struct name *args,
1301 int nargs, unsigned flags)
1303 int i;
1304 struct name global;
1305 strcpy(global.name, name);
1306 memcpy(&global.type, type, sizeof(*type));
1307 global.addr = o_func_beg(name, F_GLOBAL(flags));
1308 global_add(&global);
1309 ret_bt = TYPE_BT(&funcs[type->id].ret);
1310 for (i = 0; i < nargs; i++) {
1311 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1312 local_add(&args[i]);
1316 static int readargs(struct name *args)
1318 int nargs = 0;
1319 tok_expect('(');
1320 while (tok_see() != ')') {
1321 if (!tok_jmp(TOK3("...")))
1322 break;
1323 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1324 array2ptr(&args[nargs].type);
1325 nargs++;
1326 if (tok_jmp(','))
1327 break;
1329 tok_expect(')');
1330 if (nargs == 1 && !TYPE_BT(&args[0].type))
1331 return 0;
1332 return nargs;
1335 static int readname(struct type *main, char *name,
1336 struct type *base, unsigned flags)
1338 struct type tpool[3];
1339 int npool = 0;
1340 struct type *type = &tpool[npool++];
1341 struct type *func = NULL;
1342 struct type *ret = NULL;
1343 memset(tpool, 0, sizeof(tpool));
1344 if (name)
1345 *name = '\0';
1346 if (!base) {
1347 if (basetype(type, &flags))
1348 return 1;
1349 } else {
1350 memcpy(type, base, sizeof(*base));
1352 readptrs(type);
1353 if (!tok_jmp('(')) {
1354 ret = type;
1355 type = &tpool[npool++];
1356 func = type;
1357 readptrs(type);
1359 if (!tok_jmp(TOK_NAME) && name)
1360 strcpy(name, tok_id());
1361 while (!tok_jmp('[')) {
1362 long n = 0;
1363 if (tok_jmp(']')) {
1364 readexpr();
1365 ts_pop(NULL);
1366 if (o_popnum(&n))
1367 die("const expr expected\n");
1368 tok_expect(']');
1370 type->id = array_add(type, n);
1371 if (type->flags & T_FUNC)
1372 func = &arrays[type->id].type;
1373 type->flags = T_ARRAY;
1374 type->bt = 8;
1375 type->ptr = 0;
1377 if (func)
1378 tok_expect(')');
1379 if (tok_see() == '(') {
1380 struct name args[MAXARGS];
1381 int nargs = readargs(args);
1382 int fdef = !func;
1383 if (!func) {
1384 ret = type;
1385 type = &tpool[npool++];
1386 func = type;
1388 func->flags = T_FUNC;
1389 func->bt = 8;
1390 func->id = func_create(ret, args, nargs);
1391 if (fdef && tok_see() == '{') {
1392 funcdef(name, func, args, nargs, flags);
1393 return 1;
1396 memcpy(main, type, sizeof(*type));
1397 return 0;
1400 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1401 void *data)
1403 struct type base;
1404 unsigned flags;
1405 if (basetype(&base, &flags))
1406 return 1;
1407 while (tok_see() != ';' && tok_see() != '{') {
1408 struct name name;
1409 if (readname(&name.type, name.name, &base, flags))
1410 break;
1411 if (!tok_jmp('='))
1412 flags |= F_INIT;
1413 def(data, &name, flags);
1414 tok_jmp(',');
1416 return 0;
1419 static void typedefdef(void *data, struct name *name, unsigned flags)
1421 typedef_add(name->name, &name->type);
1424 static void readstmt(void);
1426 #define MAXCASES (1 << 7)
1428 static void readswitch(void)
1430 int break_beg = nbreaks;
1431 long val_addr = o_mklocal(8);
1432 long matched[MAXCASES];
1433 int nmatched = 0;
1434 struct type t;
1435 long next;
1436 int ref = 1;
1437 int i;
1438 tok_expect('(');
1439 readexpr();
1440 ts_pop(&t);
1441 o_local(val_addr, TYPE_BT(&t));
1442 o_tmpswap();
1443 o_assign(TYPE_BT(&t));
1444 o_tmpdrop(1);
1445 tok_expect(')');
1446 tok_expect('{');
1447 while (tok_jmp('}')) {
1448 int n = 0;
1449 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1450 if (n++ > 0)
1451 matched[nmatched++] = o_jmp(0);
1452 if (!ref++)
1453 o_filljmp(next);
1454 if (!tok_jmp(TOK_CASE)) {
1455 readexpr();
1456 o_local(val_addr, TYPE_BT(&t));
1457 o_eq();
1458 next = o_jz(0);
1459 ref = 0;
1460 tok_expect(':');
1461 o_tmpdrop(1);
1462 ts_pop(NULL);
1463 continue;
1465 if (!tok_jmp(TOK_DEFAULT)) {
1466 tok_expect(':');
1467 continue;
1470 for (i = 0; i < nmatched; i++)
1471 o_filljmp(matched[i]);
1472 nmatched = 0;
1473 readstmt();
1475 o_rmlocal(val_addr, 8);
1476 if (!ref++)
1477 o_filljmp(next);
1478 break_fill(o_mklabel(), break_beg);
1481 #define MAXGOTO (1 << 10)
1483 static struct gotoinfo {
1484 char name[NAMELEN];
1485 long addr;
1486 } gotos[MAXGOTO];
1487 static int ngotos;
1489 static struct labelinfo {
1490 char name[NAMELEN];
1491 long addr;
1492 } labels[MAXGOTO];
1493 static int nlabels;
1495 static void goto_add(char *name)
1497 strcpy(gotos[ngotos].name, name);
1498 gotos[ngotos++].addr = o_jmp(0);
1501 static void label_add(char *name)
1503 strcpy(labels[nlabels].name, name);
1504 labels[nlabels++].addr = o_mklabel();
1507 static void goto_fill(void)
1509 int i, j;
1510 for (i = 0; i < ngotos; i++)
1511 for (j = 0; j < nlabels; j++)
1512 if (!strcmp(gotos[i].name, labels[j].name)) {
1513 o_filljmp2(gotos[i].addr, labels[j].addr);
1514 break;
1518 static void readstmt(void)
1520 o_tmpdrop(-1);
1521 nts = 0;
1522 if (!tok_jmp('{')) {
1523 int _nlocals = nlocals;
1524 int _nglobals = nglobals;
1525 int _nenums = nenums;
1526 int _ntypedefs = ntypedefs;
1527 int _nstructs = nstructs;
1528 int _nfuncs = nfuncs;
1529 int _narrays = narrays;
1530 while (tok_jmp('}'))
1531 readstmt();
1532 nlocals = _nlocals;
1533 nenums = _nenums;
1534 ntypedefs = _ntypedefs;
1535 nstructs = _nstructs;
1536 nfuncs = _nfuncs;
1537 narrays = _narrays;
1538 nglobals = _nglobals;
1539 return;
1541 if (!readdefs(localdef, NULL)) {
1542 tok_expect(';');
1543 return;
1545 if (!tok_jmp(TOK_TYPEDEF)) {
1546 readdefs(typedefdef, NULL);
1547 tok_expect(';');
1548 return;
1550 if (!tok_jmp(TOK_IF)) {
1551 long l1, l2;
1552 tok_expect('(');
1553 readexpr();
1554 tok_expect(')');
1555 l1 = o_jz(0);
1556 readstmt();
1557 if (!tok_jmp(TOK_ELSE)) {
1558 l2 = o_jmp(0);
1559 o_filljmp(l1);
1560 readstmt();
1561 o_filljmp(l2);
1562 } else {
1563 o_filljmp(l1);
1565 return;
1567 if (!tok_jmp(TOK_WHILE)) {
1568 long l1, l2;
1569 int break_beg = nbreaks;
1570 int continue_beg = ncontinues;
1571 l1 = o_mklabel();
1572 tok_expect('(');
1573 readexpr();
1574 tok_expect(')');
1575 l2 = o_jz(0);
1576 readstmt();
1577 o_jmp(l1);
1578 o_filljmp(l2);
1579 break_fill(o_mklabel(), break_beg);
1580 continue_fill(l1, continue_beg);
1581 return;
1583 if (!tok_jmp(TOK_DO)) {
1584 long l1, l2;
1585 int break_beg = nbreaks;
1586 int continue_beg = ncontinues;
1587 l1 = o_mklabel();
1588 readstmt();
1589 tok_expect(TOK_WHILE);
1590 tok_expect('(');
1591 l2 = o_mklabel();
1592 readexpr();
1593 o_jnz(l1);
1594 tok_expect(')');
1595 break_fill(o_mklabel(), break_beg);
1596 continue_fill(l2, continue_beg);
1597 return;
1599 if (!tok_jmp(TOK_FOR)) {
1600 long l_check, l_jump, j_fail, j_pass;
1601 int break_beg = nbreaks;
1602 int continue_beg = ncontinues;
1603 int has_cond = 0;
1604 tok_expect('(');
1605 if (tok_see() != ';')
1606 readestmt();
1607 tok_expect(';');
1608 l_check = o_mklabel();
1609 if (tok_see() != ';') {
1610 readestmt();
1611 j_fail = o_jz(0);
1612 has_cond = 1;
1614 tok_expect(';');
1615 j_pass = o_jmp(0);
1616 l_jump = o_mklabel();
1617 if (tok_see() != ')')
1618 readestmt();
1619 tok_expect(')');
1620 o_jmp(l_check);
1621 o_filljmp(j_pass);
1622 readstmt();
1623 o_jmp(l_jump);
1624 if (has_cond)
1625 o_filljmp(j_fail);
1626 break_fill(o_mklabel(), break_beg);
1627 continue_fill(l_jump, continue_beg);
1628 return;
1630 if (!tok_jmp(TOK_SWITCH)) {
1631 readswitch();
1632 return;
1634 if (!tok_jmp(TOK_RETURN)) {
1635 int ret = tok_see() != ';';
1636 if (ret)
1637 readexpr();
1638 tok_expect(';');
1639 o_ret(ret_bt);
1640 return;
1642 if (!tok_jmp(TOK_BREAK)) {
1643 tok_expect(';');
1644 breaks[nbreaks++] = o_jmp(0);
1645 return;
1647 if (!tok_jmp(TOK_CONTINUE)) {
1648 tok_expect(';');
1649 continues[ncontinues++] = o_jmp(0);
1650 return;
1652 if (!tok_jmp(TOK_GOTO)) {
1653 tok_expect(TOK_NAME);
1654 goto_add(tok_id());
1655 tok_expect(';');
1656 return;
1658 readestmt();
1659 /* labels */
1660 if (!tok_jmp(':')) {
1661 label_add(tok_id());
1662 return;
1664 tok_expect(';');
1667 static void readdecl(void)
1669 if (!tok_jmp(TOK_TYPEDEF)) {
1670 readdefs(typedefdef, NULL);
1671 tok_expect(';');
1672 return;
1674 readdefs(globaldef, NULL);
1675 if (tok_see() == '{') {
1676 readstmt();
1677 goto_fill();
1678 o_func_end();
1679 nlocals = 0;
1680 ngotos = 0;
1681 nlabels = 0;
1682 return;
1684 tok_expect(';');
1687 static void parse(void)
1689 while (tok_see() != TOK_EOF)
1690 readdecl();
1693 int main(int argc, char *argv[])
1695 char obj[128];
1696 int ifd, ofd;
1697 int i = 1;
1698 while (i < argc && argv[i][0] == '-')
1699 i++;
1700 if (i == argc)
1701 die("no file given\n");
1702 ifd = open(argv[i], O_RDONLY);
1703 tok_init(ifd);
1704 close(ifd);
1705 parse();
1707 strcpy(obj, argv[i]);
1708 obj[strlen(obj) - 1] = 'o';
1709 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1710 out_write(ofd);
1711 close(ofd);
1712 return 0;