support initializer for static variables
[neatcc/cc.git] / ncc.c
blob2b68b494758926a6ebc42dfa282d876d9501eae5
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 field = struct_field(t.id, tok_id());
589 if (field->addr) {
590 o_num(field->addr, 4);
591 o_add();
593 o_deref(TYPE_BT(&field->type));
594 ts_push(&field->type);
597 #define MAXFUNCS (1 << 10)
599 static struct funcinfo {
600 struct type args[MAXFIELDS];
601 struct type ret;
602 int nargs;
603 } funcs[MAXFUNCS];
604 static int nfuncs;
605 static unsigned ret_bt;
607 static int func_create(struct type *ret, struct name *args, int nargs)
609 struct funcinfo *fi = &funcs[nfuncs++];
610 int i;
611 memcpy(&fi->ret, ret, sizeof(*ret));
612 for (i = 0; i < nargs; i++)
613 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
614 fi->nargs = nargs;
615 return fi - funcs;
618 static void readcall(void)
620 struct type t;
621 unsigned bt[MAXARGS];
622 struct funcinfo *fi;
623 int argc = 0;
624 int i;
625 if (tok_see() != ')') {
626 readexpr();
627 ts_pop(&t);
628 bt[argc++] = TYPE_BT(&t);
630 while (!tok_jmp(',')) {
631 readexpr();
632 ts_pop(&t);
633 bt[argc++] = TYPE_BT(&t);
635 tok_expect(')');
636 ts_pop(&t);
637 if (t.flags & T_FUNC && t.ptr > 0)
638 o_deref(8);
639 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
640 if (fi)
641 for (i = 0; i < fi->nargs; i++)
642 bt[i] = TYPE_BT(&fi->args[i]);
643 o_call(argc, bt, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
644 if (fi)
645 ts_push(&fi->ret);
646 else
647 ts_push_bt(4 | BT_SIGNED);
650 static void readpost(void)
652 readprimary();
653 while (1) {
654 if (!tok_jmp('[')) {
655 struct type t;
656 ts_pop(&t);
657 readexpr();
658 ts_pop(NULL);
659 tok_expect(']');
660 array2ptr(&t);
661 t.ptr--;
662 arrayderef(&t);
663 ts_push(&t);
664 continue;
666 if (!tok_jmp('(')) {
667 readcall();
668 continue;
670 if (!tok_jmp(TOK2("++"))) {
671 inc_post(o_add);
672 continue;
674 if (!tok_jmp(TOK2("--"))) {
675 inc_post(o_sub);
676 continue;
678 if (!tok_jmp('.')) {
679 o_addr();
680 readfield();
681 continue;
683 if (!tok_jmp(TOK2("->"))) {
684 readfield();
685 continue;
687 break;
691 static void inc_pre(void (*op)(void))
693 unsigned bt = TYPE_BT(&ts[nts - 1]);
694 readpre();
695 o_tmpcopy();
696 o_num(1, 4);
697 ts_push_bt(bt);
698 ts_push_bt(bt);
699 ts_binop_add(op);
700 ts_pop(NULL);
701 o_assign(bt);
704 static void readpre(void)
706 if (!tok_jmp('&')) {
707 struct type type;
708 readpre();
709 ts_pop(&type);
710 if (!(type.flags & T_FUNC) && !type.ptr)
711 type.ptr++;
712 ts_push(&type);
713 o_addr();
714 return;
716 if (!tok_jmp('*')) {
717 struct type t;
718 readpre();
719 ts_pop(&t);
720 array2ptr(&t);
721 if (!(t.flags & T_FUNC) || t.ptr > 0) {
722 t.ptr--;
723 o_deref(TYPE_BT(&t));
725 ts_push(&t);
726 return;
728 if (!tok_jmp('!')) {
729 struct type type;
730 readpre();
731 ts_pop(&type);
732 o_lnot();
733 ts_push_bt(4 | BT_SIGNED);
734 return;
736 if (!tok_jmp('-')) {
737 readpre();
738 o_neg();
739 return;
741 if (!tok_jmp('~')) {
742 readpre();
743 o_not();
744 return;
746 if (!tok_jmp(TOK2("++"))) {
747 inc_pre(o_add);
748 return;
750 if (!tok_jmp(TOK2("--"))) {
751 inc_pre(o_sub);
752 return;
754 if (!tok_jmp(TOK_SIZEOF)) {
755 struct type t;
756 int op = !tok_jmp('(');
757 if (readtype(&t)) {
758 int nogen = !o_nogen();
759 readexpr();
760 if (nogen)
761 o_dogen();
762 ts_pop(&t);
763 o_tmpdrop(1);
765 ts_push_bt(4);
766 o_num(type_totsz(&t), 4);
767 if (op)
768 tok_expect(')');
769 return;
771 readpost();
774 static void readmul(void)
776 readpre();
777 while (1) {
778 if (!tok_jmp('*')) {
779 readpre();
780 ts_binop(o_mul);
781 continue;
783 if (!tok_jmp('/')) {
784 readpre();
785 ts_binop(o_div);
786 continue;
788 if (!tok_jmp('%')) {
789 readpre();
790 ts_binop(o_mod);
791 continue;
793 break;
797 static void readadd(void)
799 readmul();
800 while (1) {
801 if (!tok_jmp('+')) {
802 readmul();
803 ts_binop_add(o_add);
804 continue;
806 if (!tok_jmp('-')) {
807 readmul();
808 ts_binop_add(o_sub);
809 continue;
811 break;
815 static void shift(void (*op)(void))
817 struct type t;
818 readadd();
819 ts_pop(NULL);
820 ts_pop(&t);
821 op();
822 ts_push_bt(TYPE_BT(&t));
825 static void readshift(void)
827 readadd();
828 while (1) {
829 if (!tok_jmp(TOK2("<<"))) {
830 shift(o_shl);
831 continue;
833 if (!tok_jmp(TOK2(">>"))) {
834 shift(o_shr);
835 continue;
837 break;
841 static void cmp(void (*op)(void))
843 readshift();
844 ts_pop(NULL);
845 ts_pop(NULL);
846 op();
847 ts_push_bt(4 | BT_SIGNED);
850 static void readcmp(void)
852 readshift();
853 while (1) {
854 if (!tok_jmp('<')) {
855 cmp(o_lt);
856 continue;
858 if (!tok_jmp('>')) {
859 cmp(o_gt);
860 continue;
862 if (!tok_jmp(TOK2("<="))) {
863 cmp(o_le);
864 continue;
866 if (!tok_jmp(TOK2(">="))) {
867 cmp(o_ge);
868 continue;
870 break;
874 static void eq(void (*op)(void))
876 readcmp();
877 ts_pop(NULL);
878 ts_pop(NULL);
879 op();
880 ts_push_bt(4 | BT_SIGNED);
883 static void readeq(void)
885 readcmp();
886 while (1) {
887 if (!tok_jmp(TOK2("=="))) {
888 eq(o_eq);
889 continue;
891 if (!tok_jmp(TOK2("!="))) {
892 eq(o_neq);
893 continue;
895 break;
899 static void readbitand(void)
901 readeq();
902 while (!tok_jmp('&')) {
903 readeq();
904 ts_binop(o_and);
908 static void readxor(void)
910 readbitand();
911 while (!tok_jmp('^')) {
912 readbitand();
913 ts_binop(o_xor);
917 static void readbitor(void)
919 readxor();
920 while (!tok_jmp('|')) {
921 readxor();
922 ts_binop(o_or);
926 #define MAXCOND (1 << 7)
928 static void readand(void)
930 long conds[MAXCOND];
931 int nconds = 0;
932 long passed;
933 int i;
934 readbitor();
935 if (tok_see() != TOK2("&&"))
936 return;
937 conds[nconds++] = o_jz(0);
938 ts_pop(NULL);
939 while (!tok_jmp(TOK2("&&"))) {
940 readbitor();
941 conds[nconds++] = o_jz(0);
942 ts_pop(NULL);
944 o_num(1, 4 | BT_SIGNED);
945 o_tmpfork();
946 passed = o_jmp(0);
947 for (i = 0; i < nconds; i++)
948 o_filljmp(conds[i]);
949 o_num(0, 4 | BT_SIGNED);
950 o_tmpjoin();
951 o_filljmp(passed);
952 ts_push_bt(4 | BT_SIGNED);
955 static void reador(void)
957 long conds[MAXCOND];
958 int nconds = 0;
959 long failed;
960 int i;
961 readand();
962 if (tok_see() != TOK2("||"))
963 return;
964 conds[nconds++] = o_jnz(0);
965 ts_pop(NULL);
966 while (!tok_jmp(TOK2("||"))) {
967 readand();
968 conds[nconds++] = o_jnz(0);
969 ts_pop(NULL);
971 o_num(0, 4 | BT_SIGNED);
972 o_tmpfork();
973 failed = o_jmp(0);
974 for (i = 0; i < nconds; i++)
975 o_filljmp(conds[i]);
976 o_num(1, 4 | BT_SIGNED);
977 o_tmpjoin();
978 o_filljmp(failed);
979 ts_push_bt(4 | BT_SIGNED);
982 static void readcexpr(void)
984 long l1, l2;
985 long c;
986 int cexpr, nogen;
987 reador();
988 if (tok_jmp('?'))
989 return;
990 ncexpr++;
991 cexpr = !o_popnum(&c);
992 ts_pop(NULL);
993 if (cexpr) {
994 if (!c)
995 nogen = !o_nogen();
996 } else {
997 l1 = o_jz(0);
999 reador();
1000 if (!cexpr) {
1001 o_tmpfork();
1002 l2 = o_jmp(0);
1004 ts_pop(NULL);
1005 tok_expect(':');
1006 if (cexpr) {
1007 if (c) {
1008 nogen = !o_nogen();
1009 } else {
1010 if (nogen)
1011 o_dogen();
1012 o_tmpdrop(1);
1014 } else {
1015 o_filljmp(l1);
1017 reador();
1018 if (cexpr) {
1019 if (c) {
1020 if (nogen)
1021 o_dogen();
1022 o_tmpdrop(1);
1024 } else {
1025 o_tmpjoin();
1026 o_filljmp(l2);
1028 ncexpr--;
1031 static void opassign(void (*bop)(void (*op)(void)), void (*op)(void))
1033 unsigned bt = TYPE_BT(&ts[nts - 1]);
1034 o_tmpcopy();
1035 readexpr();
1036 bop(op);
1037 ts_pop(NULL);
1038 o_assign(bt);
1041 static void doassign(void)
1043 struct type t;
1044 ts_pop(&t);
1045 if (!t.ptr && t.flags & T_STRUCT)
1046 o_memcpy(type_totsz(&t));
1047 else
1048 o_assign(TYPE_BT(&ts[nts - 1]));
1051 static void readexpr(void)
1053 readcexpr();
1054 if (!tok_jmp('=')) {
1055 readexpr();
1056 doassign();
1057 return;
1059 if (!tok_jmp(TOK2("+="))) {
1060 opassign(ts_binop_add, o_add);
1061 return;
1063 if (!tok_jmp(TOK2("-="))) {
1064 opassign(ts_binop_add, o_sub);
1065 return;
1067 if (!tok_jmp(TOK2("*="))) {
1068 opassign(ts_binop, o_mul);
1069 return;
1071 if (!tok_jmp(TOK2("/="))) {
1072 opassign(ts_binop, o_div);
1073 return;
1075 if (!tok_jmp(TOK2("%="))) {
1076 opassign(ts_binop, o_mod);
1077 return;
1079 if (!tok_jmp(TOK3("<<="))) {
1080 opassign(ts_binop, o_shl);
1081 return;
1083 if (!tok_jmp(TOK3(">>="))) {
1084 opassign(ts_binop, o_shr);
1085 return;
1087 if (!tok_jmp(TOK3("&="))) {
1088 opassign(ts_binop, o_and);
1089 return;
1091 if (!tok_jmp(TOK3("|="))) {
1092 opassign(ts_binop, o_or);
1093 return;
1095 if (!tok_jmp(TOK3("^="))) {
1096 opassign(ts_binop, o_xor);
1097 return;
1101 static void readestmt(void)
1103 do {
1104 o_tmpdrop(-1);
1105 nts = 0;
1106 readexpr();
1107 } while (!tok_jmp(','));
1110 static void o_localoff(long addr, int off, unsigned bt)
1112 o_local(addr, bt);
1113 if (off) {
1114 o_addr();
1115 o_num(off, 4);
1116 o_add();
1117 o_deref(bt);
1121 static struct type *innertype(struct type *t)
1123 if (t->flags & T_ARRAY && !t->ptr)
1124 return innertype(&arrays[t->id].type);
1125 return t;
1128 static void initexpr(struct type *t, int off, void *obj,
1129 void (*set)(void *obj, int off, struct type *t))
1131 if (tok_jmp('{')) {
1132 set(obj, off, t);
1133 return;
1135 if (!t->ptr && t->flags & T_STRUCT) {
1136 struct structinfo *si = &structs[t->id];
1137 int i;
1138 for (i = 0; i < si->nfields; i++) {
1139 struct name *field = &si->fields[i];
1140 if (!tok_jmp('.')) {
1141 tok_expect(TOK_NAME);
1142 field = struct_field(t->id, tok_id());
1143 tok_expect('=');
1145 initexpr(&field->type, off + field->addr, obj, set);
1146 if (tok_jmp(',') || tok_see() == '}')
1147 break;
1149 } else if (t->flags & T_ARRAY) {
1150 struct type *t_de = &arrays[t->id].type;
1151 int i;
1152 for (i = 0; ; i++) {
1153 long idx = i;
1154 struct type *it = t_de;
1155 if (!tok_jmp('[')) {
1156 readexpr();
1157 o_popnum(&idx);
1158 ts_pop(NULL);
1159 tok_expect(']');
1160 tok_expect('=');
1162 if (tok_see() != '{')
1163 it = innertype(t_de);
1164 initexpr(it, off + type_totsz(it) * idx, obj, set);
1165 if (tok_jmp(',') || tok_see() == '}')
1166 break;
1169 tok_expect('}');
1172 static void jumpbrace(void)
1174 int depth = 0;
1175 while (tok_see() != '}' || depth--)
1176 if (tok_get() == '{')
1177 depth++;
1178 tok_expect('}');
1181 static int initsize(void)
1183 long addr = tok_addr();
1184 int n = 0;
1185 if (!tok_jmp(TOK_STR)) {
1186 n = tok_str(NULL);
1187 tok_jump(addr);
1188 return n;
1190 o_nogen();
1191 tok_expect('{');
1192 while (tok_jmp('}')) {
1193 long idx = n;
1194 if (!tok_jmp('[')) {
1195 readexpr();
1196 o_popnum(&idx);
1197 ts_pop(NULL);
1198 tok_expect(']');
1199 tok_expect('=');
1201 if (n < idx + 1)
1202 n = idx + 1;
1203 while (tok_see() != '}' && tok_see() != ',')
1204 if (tok_get() == '{')
1205 jumpbrace();
1206 tok_jmp(',');
1208 o_dogen();
1209 tok_jump(addr);
1210 return n;
1213 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1215 static void globalinit(void *obj, int off, struct type *t)
1217 long addr = *(long *) obj;
1218 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1219 struct type *t_de = &arrays[t->id].type;
1220 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1221 char buf[BUFSIZE];
1222 int len;
1223 tok_expect(TOK_STR);
1224 len = tok_str(buf);
1225 out_datcpy(addr, off, buf, len);
1226 return;
1229 readexpr();
1230 o_datset(addr, off, TYPE_BT(t));
1231 ts_pop(NULL);
1234 static void globaldef(void *data, struct name *name, unsigned flags)
1236 struct type *t = &name->type;
1237 char *varname = flags & F_STATIC ? NULL : name->name;
1238 int sz;
1239 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1240 arrays[t->id].n = initsize();
1241 sz = type_totsz(t);
1242 if (flags & F_EXTERN)
1243 name->addr = out_mkundef(varname, sz);
1244 else if (flags & F_INIT)
1245 name->addr = out_mkdat(varname, NULL, sz, F_GLOBAL(flags));
1246 else
1247 name->addr = out_mkvar(varname, sz, F_GLOBAL(flags));
1248 global_add(name);
1249 if (flags & F_INIT)
1250 initexpr(t, 0, &name->addr, globalinit);
1253 static void localinit(void *obj, int off, struct type *t)
1255 long addr = *(long *) obj;
1256 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1257 struct type *t_de = &arrays[t->id].type;
1258 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1259 char buf[BUFSIZE];
1260 int len;
1261 tok_expect(TOK_STR);
1262 len = tok_str(buf);
1263 o_localoff(addr, off, TYPE_BT(t));
1264 o_symaddr(out_mkdat(NULL, buf, len, 0), TYPE_BT(t));
1265 o_memcpy(len);
1266 o_tmpdrop(1);
1267 return;
1270 o_localoff(addr, off, TYPE_BT(t));
1271 ts_push(t);
1272 readexpr();
1273 doassign();
1274 ts_pop(NULL);
1275 o_tmpdrop(1);
1278 static void localdef(void *data, struct name *name, unsigned flags)
1280 struct type *t = &name->type;
1281 if (flags & (F_STATIC | F_EXTERN)) {
1282 globaldef(data, name, flags);
1283 return;
1285 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1286 arrays[t->id].n = initsize();
1287 name->addr = o_mklocal(type_totsz(&name->type));
1288 local_add(name);
1289 if (flags & F_INIT) {
1290 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1291 o_local(name->addr, TYPE_BT(t));
1292 o_memset(0, type_totsz(t));
1293 o_tmpdrop(1);
1295 initexpr(t, 0, &name->addr, localinit);
1299 static void funcdef(char *name, struct type *type, struct name *args,
1300 int nargs, unsigned flags)
1302 int i;
1303 struct name global;
1304 strcpy(global.name, name);
1305 memcpy(&global.type, type, sizeof(*type));
1306 global.addr = o_func_beg(name, F_GLOBAL(flags));
1307 global_add(&global);
1308 ret_bt = TYPE_BT(&funcs[type->id].ret);
1309 for (i = 0; i < nargs; i++) {
1310 args[i].addr = o_arg(i, type_totsz(&args[i].type));
1311 local_add(&args[i]);
1315 static int readargs(struct name *args)
1317 int nargs = 0;
1318 tok_expect('(');
1319 while (tok_see() != ')') {
1320 if (!tok_jmp(TOK3("...")))
1321 break;
1322 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1323 array2ptr(&args[nargs].type);
1324 nargs++;
1325 if (tok_jmp(','))
1326 break;
1328 tok_expect(')');
1329 if (nargs == 1 && !TYPE_BT(&args[0].type))
1330 return 0;
1331 return nargs;
1334 static int readname(struct type *main, char *name,
1335 struct type *base, unsigned flags)
1337 struct type tpool[3];
1338 int npool = 0;
1339 struct type *type = &tpool[npool++];
1340 struct type *func = NULL;
1341 struct type *ret = NULL;
1342 memset(tpool, 0, sizeof(tpool));
1343 if (name)
1344 *name = '\0';
1345 if (!base) {
1346 if (basetype(type, &flags))
1347 return 1;
1348 } else {
1349 memcpy(type, base, sizeof(*base));
1351 readptrs(type);
1352 if (!tok_jmp('(')) {
1353 ret = type;
1354 type = &tpool[npool++];
1355 func = type;
1356 readptrs(type);
1358 if (!tok_jmp(TOK_NAME) && name)
1359 strcpy(name, tok_id());
1360 while (!tok_jmp('[')) {
1361 long n = 0;
1362 if (tok_jmp(']')) {
1363 readexpr();
1364 ts_pop(NULL);
1365 if (o_popnum(&n))
1366 die("const expr expected\n");
1367 tok_expect(']');
1369 type->id = array_add(type, n);
1370 if (type->flags & T_FUNC)
1371 func = &arrays[type->id].type;
1372 type->flags = T_ARRAY;
1373 type->bt = 8;
1374 type->ptr = 0;
1376 if (func)
1377 tok_expect(')');
1378 if (tok_see() == '(') {
1379 struct name args[MAXARGS];
1380 int nargs = readargs(args);
1381 int fdef = !func;
1382 if (!func) {
1383 ret = type;
1384 type = &tpool[npool++];
1385 func = type;
1387 func->flags = T_FUNC;
1388 func->bt = 8;
1389 func->id = func_create(ret, args, nargs);
1390 if (fdef && tok_see() == '{') {
1391 funcdef(name, func, args, nargs, flags);
1392 return 1;
1395 memcpy(main, type, sizeof(*type));
1396 return 0;
1399 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1400 void *data)
1402 struct type base;
1403 unsigned flags;
1404 if (basetype(&base, &flags))
1405 return 1;
1406 while (tok_see() != ';' && tok_see() != '{') {
1407 struct name name;
1408 if (readname(&name.type, name.name, &base, flags))
1409 break;
1410 if (!tok_jmp('='))
1411 flags |= F_INIT;
1412 def(data, &name, flags);
1413 tok_jmp(',');
1415 return 0;
1418 static void typedefdef(void *data, struct name *name, unsigned flags)
1420 typedef_add(name->name, &name->type);
1423 static void readstmt(void);
1425 #define MAXCASES (1 << 7)
1427 static void readswitch(void)
1429 int break_beg = nbreaks;
1430 long val_addr = o_mklocal(8);
1431 long matched[MAXCASES];
1432 int nmatched = 0;
1433 struct type t;
1434 long next;
1435 int ref = 1;
1436 int i;
1437 tok_expect('(');
1438 readexpr();
1439 ts_pop(&t);
1440 o_local(val_addr, TYPE_BT(&t));
1441 o_tmpswap();
1442 o_assign(TYPE_BT(&t));
1443 o_tmpdrop(1);
1444 tok_expect(')');
1445 tok_expect('{');
1446 while (tok_jmp('}')) {
1447 int n = 0;
1448 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1449 if (n++ > 0)
1450 matched[nmatched++] = o_jmp(0);
1451 if (!ref++)
1452 o_filljmp(next);
1453 if (!tok_jmp(TOK_CASE)) {
1454 readexpr();
1455 o_local(val_addr, TYPE_BT(&t));
1456 o_eq();
1457 next = o_jz(0);
1458 ref = 0;
1459 tok_expect(':');
1460 o_tmpdrop(1);
1461 ts_pop(NULL);
1462 continue;
1464 if (!tok_jmp(TOK_DEFAULT)) {
1465 tok_expect(':');
1466 continue;
1469 for (i = 0; i < nmatched; i++)
1470 o_filljmp(matched[i]);
1471 nmatched = 0;
1472 readstmt();
1474 o_rmlocal(val_addr, 8);
1475 if (!ref++)
1476 o_filljmp(next);
1477 break_fill(o_mklabel(), break_beg);
1480 #define MAXGOTO (1 << 10)
1482 static struct gotoinfo {
1483 char name[NAMELEN];
1484 long addr;
1485 } gotos[MAXGOTO];
1486 static int ngotos;
1488 static struct labelinfo {
1489 char name[NAMELEN];
1490 long addr;
1491 } labels[MAXGOTO];
1492 static int nlabels;
1494 static void goto_add(char *name)
1496 strcpy(gotos[ngotos].name, name);
1497 gotos[ngotos++].addr = o_jmp(0);
1500 static void label_add(char *name)
1502 strcpy(labels[nlabels].name, name);
1503 labels[nlabels++].addr = o_mklabel();
1506 static void goto_fill(void)
1508 int i, j;
1509 for (i = 0; i < ngotos; i++)
1510 for (j = 0; j < nlabels; j++)
1511 if (!strcmp(gotos[i].name, labels[j].name)) {
1512 o_filljmp2(gotos[i].addr, labels[j].addr);
1513 break;
1517 static void readstmt(void)
1519 o_tmpdrop(-1);
1520 nts = 0;
1521 if (!tok_jmp('{')) {
1522 int _nlocals = nlocals;
1523 int _nglobals = nglobals;
1524 int _nenums = nenums;
1525 int _ntypedefs = ntypedefs;
1526 int _nstructs = nstructs;
1527 int _nfuncs = nfuncs;
1528 int _narrays = narrays;
1529 while (tok_jmp('}'))
1530 readstmt();
1531 nlocals = _nlocals;
1532 nenums = _nenums;
1533 ntypedefs = _ntypedefs;
1534 nstructs = _nstructs;
1535 nfuncs = _nfuncs;
1536 narrays = _narrays;
1537 nglobals = _nglobals;
1538 return;
1540 if (!readdefs(localdef, NULL)) {
1541 tok_expect(';');
1542 return;
1544 if (!tok_jmp(TOK_TYPEDEF)) {
1545 readdefs(typedefdef, NULL);
1546 tok_expect(';');
1547 return;
1549 if (!tok_jmp(TOK_IF)) {
1550 long l1, l2;
1551 tok_expect('(');
1552 readexpr();
1553 tok_expect(')');
1554 l1 = o_jz(0);
1555 readstmt();
1556 if (!tok_jmp(TOK_ELSE)) {
1557 l2 = o_jmp(0);
1558 o_filljmp(l1);
1559 readstmt();
1560 o_filljmp(l2);
1561 } else {
1562 o_filljmp(l1);
1564 return;
1566 if (!tok_jmp(TOK_WHILE)) {
1567 long l1, l2;
1568 int break_beg = nbreaks;
1569 int continue_beg = ncontinues;
1570 l1 = o_mklabel();
1571 tok_expect('(');
1572 readexpr();
1573 tok_expect(')');
1574 l2 = o_jz(0);
1575 readstmt();
1576 o_jmp(l1);
1577 o_filljmp(l2);
1578 break_fill(o_mklabel(), break_beg);
1579 continue_fill(l1, continue_beg);
1580 return;
1582 if (!tok_jmp(TOK_DO)) {
1583 long l1, l2;
1584 int break_beg = nbreaks;
1585 int continue_beg = ncontinues;
1586 l1 = o_mklabel();
1587 readstmt();
1588 tok_expect(TOK_WHILE);
1589 tok_expect('(');
1590 l2 = o_mklabel();
1591 readexpr();
1592 o_jnz(l1);
1593 tok_expect(')');
1594 break_fill(o_mklabel(), break_beg);
1595 continue_fill(l2, continue_beg);
1596 return;
1598 if (!tok_jmp(TOK_FOR)) {
1599 long check, jump, end, body;
1600 int break_beg = nbreaks;
1601 int continue_beg = ncontinues;
1602 tok_expect('(');
1603 if (tok_see() != ';')
1604 readestmt();
1605 tok_expect(';');
1606 check = o_mklabel();
1607 if (tok_see() != ';')
1608 readestmt();
1609 tok_expect(';');
1610 end = o_jz(0);
1611 body = o_jmp(0);
1612 jump = o_mklabel();
1613 if (tok_see() != ')')
1614 readestmt();
1615 tok_expect(')');
1616 o_jmp(check);
1617 o_filljmp(body);
1618 readstmt();
1619 o_jmp(jump);
1620 o_filljmp(end);
1621 break_fill(o_mklabel(), break_beg);
1622 continue_fill(jump, continue_beg);
1623 return;
1625 if (!tok_jmp(TOK_SWITCH)) {
1626 readswitch();
1627 return;
1629 if (!tok_jmp(TOK_RETURN)) {
1630 int ret = tok_see() != ';';
1631 if (ret)
1632 readexpr();
1633 tok_expect(';');
1634 o_ret(ret_bt);
1635 return;
1637 if (!tok_jmp(TOK_BREAK)) {
1638 tok_expect(';');
1639 breaks[nbreaks++] = o_jmp(0);
1640 return;
1642 if (!tok_jmp(TOK_CONTINUE)) {
1643 tok_expect(';');
1644 continues[ncontinues++] = o_jmp(0);
1645 return;
1647 if (!tok_jmp(TOK_GOTO)) {
1648 tok_expect(TOK_NAME);
1649 goto_add(tok_id());
1650 tok_expect(';');
1651 return;
1653 readestmt();
1654 /* labels */
1655 if (!tok_jmp(':')) {
1656 label_add(tok_id());
1657 return;
1659 tok_expect(';');
1662 static void readdecl(void)
1664 if (!tok_jmp(TOK_TYPEDEF)) {
1665 readdefs(typedefdef, NULL);
1666 tok_expect(';');
1667 return;
1669 readdefs(globaldef, NULL);
1670 if (tok_see() == '{') {
1671 readstmt();
1672 goto_fill();
1673 o_func_end();
1674 nlocals = 0;
1675 ngotos = 0;
1676 nlabels = 0;
1677 return;
1679 tok_expect(';');
1682 static void parse(void)
1684 while (tok_see() != TOK_EOF)
1685 readdecl();
1688 int main(int argc, char *argv[])
1690 char obj[128];
1691 int ifd, ofd;
1692 int i = 1;
1693 while (i < argc && argv[i][0] == '-')
1694 i++;
1695 if (i == argc)
1696 die("no file given\n");
1697 ifd = open(argv[i], O_RDONLY);
1698 tok_init(ifd);
1699 close(ifd);
1700 parse();
1702 strcpy(obj, argv[i]);
1703 obj[strlen(obj) - 1] = 'o';
1704 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1705 out_write(ofd);
1706 close(ofd);
1707 return 0;