ncc: dereference the not expression of cexprs
[neatcc/cc.git] / ncc.c
blob79bc920ea0b522d795634f6f5563ed1ca2f5f21f
1 /*
2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This file is released under GNU GPL version 2.
7 */
8 #include <fcntl.h>
9 #include <unistd.h>
10 #include <stdlib.h>
11 #include <string.h>
12 #include <stdio.h>
13 #include <sys/stat.h>
14 #include <sys/types.h>
15 #include "gen.h"
16 #include "tok.h"
17 #include "out.h"
19 #define MAXLOCALS (1 << 10)
20 #define MAXGLOBALS (1 << 10)
21 #define MAXARGS (1 << 5)
23 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
24 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
26 #define T_ARRAY 0x01
27 #define T_STRUCT 0x02
28 #define T_FUNC 0x04
30 #define F_INIT 0x01
31 #define F_STATIC 0x02
32 #define F_EXTERN 0x04
34 struct type {
35 unsigned bt;
36 unsigned flags;
37 int ptr;
38 int id; /* for structs, functions and arrays */
39 int addr; /* the address is passed to gen.c; deref for value */
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].addr = 0;
51 ts[nts++].bt = bt;
54 static void ts_push(struct type *t)
56 struct type *d = &ts[nts++];
57 memcpy(d, t, sizeof(*t));
60 static void ts_push_addr(struct type *t)
62 ts_push(t);
63 ts[nts - 1].addr = 1;
66 static void ts_pop(struct type *type)
68 nts--;
69 if (type)
70 *type = ts[nts];
73 void err(char *msg)
75 char err[1 << 7];
76 int len = cpp_loc(err, tok_addr());
77 strcpy(err + len, msg);
78 die(err);
81 struct name {
82 char name[NAMELEN];
83 char elfname[NAMELEN]; /* local elf name for static variables in function */
84 struct type type;
85 long addr; /* local stack offset, global data addr, struct offset */
88 static struct name locals[MAXLOCALS];
89 static int nlocals;
90 static struct name globals[MAXGLOBALS];
91 static int nglobals;
93 static void local_add(struct name *name)
95 if (nlocals >= MAXLOCALS)
96 err("nomem: MAXLOCALS reached!\n");
97 memcpy(&locals[nlocals++], name, sizeof(*name));
100 static int global_find(char *name)
102 int i;
103 for (i = 0; i < nglobals; i++)
104 if (!strcmp(name, globals[i].name))
105 return i;
106 return -1;
109 static void global_add(struct name *name)
111 int found = global_find(name->name);
112 int i = found == -1 ? nglobals++ : found;
113 if (nglobals >= MAXGLOBALS)
114 err("nomem: MAXGLOBALS reached!\n");
115 memcpy(&globals[i], name, sizeof(*name));
118 #define MAXENUMS (1 << 10)
120 static struct enumval {
121 char name[NAMELEN];
122 int n;
123 } enums[MAXENUMS];
124 static int nenums;
126 static void enum_add(char *name, int val)
128 struct enumval *ev = &enums[nenums++];
129 if (nenums >= MAXENUMS)
130 err("nomem: MAXENUMS reached!\n");
131 strcpy(ev->name, name);
132 ev->n = val;
135 static int enum_find(int *val, char *name)
137 int i;
138 for (i = nenums - 1; i >= 0; --i)
139 if (!strcmp(name, enums[i].name)) {
140 *val = enums[i].n;
141 return 0;
143 return 1;
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo {
149 char name[NAMELEN];
150 struct type type;
151 } typedefs[MAXTYPEDEFS];
152 static int ntypedefs;
154 static void typedef_add(char *name, struct type *type)
156 struct typdefinfo *ti = &typedefs[ntypedefs++];
157 if (ntypedefs >= MAXTYPEDEFS)
158 err("nomem: MAXTYPEDEFS reached!\n");
159 strcpy(ti->name, name);
160 memcpy(&ti->type, type, sizeof(*type));
163 static int typedef_find(char *name)
165 int i;
166 for (i = ntypedefs - 1; i >= 0; --i)
167 if (!strcmp(name, typedefs[i].name))
168 return i;
169 return -1;
172 #define MAXARRAYS (1 << 10)
174 static struct array {
175 struct type type;
176 int n;
177 } arrays[MAXARRAYS];
178 static int narrays;
180 static int array_add(struct type *type, int n)
182 struct array *a = &arrays[narrays++];
183 if (narrays >= MAXARRAYS)
184 err("nomem: MAXARRAYS reached!\n");
185 memcpy(&a->type, type, sizeof(*type));
186 a->n = n;
187 return a - arrays;
190 static void array2ptr(struct type *t)
192 if (t->flags & T_ARRAY && !t->ptr) {
193 memcpy(t, &arrays[t->id].type, sizeof(*t));
194 t->ptr++;
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo {
202 char name[NAMELEN];
203 struct name fields[MAXFIELDS];
204 int nfields;
205 int isunion;
206 int size;
207 } structs[MAXSTRUCTS];
208 static int nstructs;
210 static int struct_find(char *name, int isunion)
212 int i;
213 for (i = nstructs - 1; i >= 0; --i)
214 if (*structs[i].name && !strcmp(name, structs[i].name) &&
215 structs[i].isunion == isunion)
216 return i;
217 i = nstructs++;
218 if (nstructs >= MAXSTRUCTS)
219 err("nomem: MAXTYPES reached!\n");
220 memset(&structs[i], 0, sizeof(structs[i]));
221 strcpy(structs[i].name, name);
222 structs[i].isunion = isunion;
223 return i;
226 static struct name *struct_field(int id, char *name)
228 struct structinfo *si = &structs[id];
229 int i;
230 for (i = 0; i < si->nfields; i++)
231 if (!strcmp(name, si->fields[i].name))
232 return &si->fields[i];
233 err("field not found\n");
236 #define MAXBREAK (1 << 7)
238 static long breaks[MAXBREAK];
239 static int nbreaks;
240 static long continues[MAXBREAK];
241 static int ncontinues;
243 static void break_fill(long addr, int till)
245 int i;
246 for (i = till; i < nbreaks; i++)
247 o_filljmp2(breaks[i], addr);
248 nbreaks = till;
251 static void continue_fill(long addr, int till)
253 int i;
254 for (i = till; i < ncontinues; i++)
255 o_filljmp2(continues[i], addr);
256 ncontinues = till;
259 static int type_totsz(struct type *t)
261 if (t->ptr)
262 return LONGSZ;
263 if (t->flags & T_ARRAY)
264 return arrays[t->id].n * type_totsz(&arrays[t->id].type);
265 return t->flags & T_STRUCT ? structs[t->id].size : BT_SZ(t->bt);
268 static unsigned type_szde(struct type *t)
270 struct type de = *t;
271 array2ptr(&de);
272 de.ptr--;
273 return type_totsz(&de);
276 static void ts_de(int deref)
278 struct type *t = &ts[nts - 1];
279 if (deref && t->addr && (!(t->flags & T_ARRAY) || (t->ptr)))
280 o_deref(TYPE_BT(t));
281 t->addr = 0;
284 static void ts_pop_de(struct type *t)
286 struct type de;
287 if (!t)
288 t = &de;
289 ts_pop(t);
290 array2ptr(t);
291 if (t->addr && !(t->flags & T_FUNC))
292 o_deref(TYPE_BT(t));
293 t->addr = 0;
296 static void ts_pop_de2(struct type *t1, struct type *t2)
298 ts_pop_de(t1);
299 o_tmpswap();
300 ts_pop_de(t2);
301 o_tmpswap();
304 static int tok_jmp(int tok)
306 if (tok_see() != tok)
307 return 1;
308 tok_get();
309 return 0;
312 static void tok_expect(int tok)
314 if (tok_get() != tok)
315 err("syntax error\n");
318 static unsigned bt_op(unsigned bt1, unsigned bt2)
320 unsigned s1 = BT_SZ(bt1);
321 unsigned s2 = BT_SZ(bt2);
322 return (bt1 | bt2) & BT_SIGNED | (s1 > s2 ? s1 : s2);
325 static void ts_binop(int op)
327 struct type t1, t2;
328 ts_pop_de2(&t1, &t2);
329 o_bop(op);
330 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
333 static void ts_addop(int op)
335 struct type t1, t2;
336 ts_pop_de2(&t1, &t2);
337 if (!t1.ptr && !t2.ptr) {
338 o_bop(op);
339 ts_push_bt(bt_op(TYPE_BT(&t1), TYPE_BT(&t2)));
340 return;
342 if (t1.ptr && !t2.ptr)
343 o_tmpswap();
344 if (!t1.ptr && t2.ptr)
345 if (type_szde(&t2) > 1) {
346 o_num(type_szde(&t2));
347 o_bop(O_MUL);
349 if (t1.ptr && !t2.ptr)
350 o_tmpswap();
351 o_bop(op);
352 if (t1.ptr && t2.ptr) {
353 int sz = type_szde(&t1);
354 if (sz > 1) {
355 o_num(sz);
356 o_bop(O_DIV);
358 ts_push_bt(4 | BT_SIGNED);
359 } else {
360 ts_push(t1.ptr ? &t1 : &t2);
364 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
365 #define MIN(a, b) ((a) < (b) ? (a) : (b))
367 static int type_alignment(struct type *t)
369 if (t->flags & T_ARRAY && !t->ptr)
370 return type_alignment(&arrays[t->id].type);
371 if (t->flags & T_STRUCT && !t->ptr)
372 return type_alignment(&structs[t->id].fields[0].type);
373 return MIN(LONGSZ, type_totsz(t));
376 static void structdef(void *data, struct name *name, unsigned flags)
378 struct structinfo *si = data;
379 if (si->isunion) {
380 name->addr = 0;
381 if (si->size < type_totsz(&name->type))
382 si->size = type_totsz(&name->type);
383 } else {
384 struct type *t = &name->type;
385 int alignment = type_alignment(t);
386 if (t->flags & T_ARRAY && !t->ptr)
387 alignment = MIN(LONGSZ, type_totsz(&arrays[t->id].type));
388 si->size = ALIGN(si->size, alignment);
389 name->addr = si->size;
390 si->size += type_totsz(&name->type);
392 memcpy(&si->fields[si->nfields++], name, sizeof(*name));
395 static int readdefs(void (*def)(void *, struct name *, unsigned f), void *data);
397 static int struct_create(char *name, int isunion)
399 int id = struct_find(name, isunion);
400 struct structinfo *si = &structs[id];
401 tok_expect('{');
402 while (tok_jmp('}')) {
403 readdefs(structdef, si);
404 tok_expect(';');
406 return id;
409 static void readexpr(void);
411 static void enum_create(void)
413 long n = 0;
414 tok_expect('{');
415 while (tok_jmp('}')) {
416 char name[NAMELEN];
417 tok_expect(TOK_NAME);
418 strcpy(name, tok_id());
419 if (tok_see() == '=') {
420 tok_get();
421 readexpr();
422 ts_pop(NULL);
423 if (o_popnum(&n))
424 err("const expr expected!\n");
426 enum_add(name, n++);
427 tok_jmp(',');
431 static int basetype(struct type *type, unsigned *flags)
433 int sign = 1;
434 int size = 4;
435 int done = 0;
436 int i = 0;
437 int isunion;
438 char name[NAMELEN] = "";
439 *flags = 0;
440 type->flags = 0;
441 type->ptr = 0;
442 type->addr = 0;
443 while (!done) {
444 switch (tok_see()) {
445 case TOK_STATIC:
446 *flags |= F_STATIC;
447 break;
448 case TOK_EXTERN:
449 *flags |= F_EXTERN;
450 break;
451 case TOK_VOID:
452 sign = 0;
453 size = 0;
454 done = 1;
455 break;
456 case TOK_INT:
457 done = 1;
458 break;
459 case TOK_CHAR:
460 size = 1;
461 done = 1;
462 break;
463 case TOK_SHORT:
464 size = 2;
465 break;
466 case TOK_LONG:
467 size = LONGSZ;
468 break;
469 case TOK_SIGNED:
470 break;
471 case TOK_UNSIGNED:
472 sign = 0;
473 break;
474 case TOK_UNION:
475 case TOK_STRUCT:
476 isunion = tok_get() == TOK_UNION;
477 if (!tok_jmp(TOK_NAME))
478 strcpy(name, tok_id());
479 if (tok_see() == '{')
480 type->id = struct_create(name, isunion);
481 else
482 type->id = struct_find(name, isunion);
483 type->flags |= T_STRUCT;
484 type->bt = LONGSZ;
485 return 0;
486 case TOK_ENUM:
487 tok_get();
488 tok_jmp(TOK_NAME);
489 if (tok_see() == '{')
490 enum_create();
491 type->bt = 4 | BT_SIGNED;
492 return 0;
493 default:
494 if (tok_see() == TOK_NAME) {
495 int id = typedef_find(tok_id());
496 if (id != -1) {
497 tok_get();
498 memcpy(type, &typedefs[id].type,
499 sizeof(*type));
500 return 0;
503 if (!i)
504 return 1;
505 done = 1;
506 continue;
508 i++;
509 tok_get();
511 type->bt = size | (sign ? BT_SIGNED : 0);
512 return 0;
515 static int readname(struct type *main, char *name,
516 struct type *base, unsigned flags);
518 static int readtype(struct type *type)
520 return readname(type, NULL, NULL, 0);
523 static void readptrs(struct type *type)
525 while (!tok_jmp('*')) {
526 type->ptr++;
527 if (!type->bt)
528 type->bt = 1;
532 /* used to differenciate labels from case and cond exprs */
533 static int ncexpr;
534 static int caseexpr;
536 static void readpre(void);
538 static char *tmp_str(char *buf, int len)
540 static char name[NAMELEN];
541 static int id;
542 void *dat;
543 sprintf(name, "__neatcc.s%d", id++);
544 dat = dat_dat(name, len, 0);
545 memcpy(dat, buf, len);
546 return name;
549 static void readprimary(void)
551 int i;
552 if (!tok_jmp(TOK_NUM)) {
553 long n;
554 int bt = tok_num(&n);
555 ts_push_bt(bt);
556 o_num(n);
557 return;
559 if (!tok_jmp(TOK_STR)) {
560 struct type t;
561 char buf[BUFSIZE];
562 int len;
563 t.bt = 1 | BT_SIGNED;
564 t.ptr = 1;
565 t.addr = 0;
566 t.flags = 0;
567 ts_push(&t);
568 len = tok_str(buf);
569 o_sym(tmp_str(buf, len));
570 return;
572 if (!tok_jmp(TOK_NAME)) {
573 struct name unkn = {""};
574 char *name = unkn.name;
575 int n;
576 strcpy(name, tok_id());
577 /* don't search for labels here */
578 if (!ncexpr && !caseexpr && tok_see() == ':')
579 return;
580 for (i = nlocals - 1; i >= 0; --i) {
581 struct type *t = &locals[i].type;
582 if (!strcmp(locals[i].name, name)) {
583 o_local(locals[i].addr);
584 ts_push_addr(t);
585 return;
588 if ((n = global_find(name)) != -1) {
589 struct name *g = &globals[n];
590 struct type *t = &g->type;
591 char *elfname = *g->elfname ? g->elfname : g->name;
592 o_sym(elfname);
593 ts_push_addr(t);
594 return;
596 if (!enum_find(&n, name)) {
597 ts_push_bt(4 | BT_SIGNED);
598 o_num(n);
599 return;
601 if (tok_see() != '(')
602 err("unknown symbol\n");
603 global_add(&unkn);
604 ts_push_bt(LONGSZ);
605 o_sym(unkn.name);
606 return;
608 if (!tok_jmp('(')) {
609 struct type t;
610 if (!readtype(&t)) {
611 struct type o;
612 tok_expect(')');
613 readpre();
614 ts_pop_de(&o);
615 ts_push(&t);
616 if (!t.ptr || !o.ptr)
617 o_cast(TYPE_BT(&t));
618 } else {
619 readexpr();
620 tok_expect(')');
622 return;
626 static void arrayderef(void)
628 struct type t;
629 int sz;
630 ts_pop_de(NULL);
631 ts_pop(&t);
632 if (!(t.flags & T_ARRAY) && t.addr) {
633 o_tmpswap();
634 o_deref(TYPE_BT(&t));
635 o_tmpswap();
637 array2ptr(&t);
638 t.ptr--;
639 sz = type_totsz(&t);
640 t.addr = 1;
641 if (sz > 1) {
642 o_num(sz);
643 o_bop(O_MUL);
645 o_bop(O_ADD);
646 ts_push(&t);
649 static void inc_post(int op)
651 struct type t = ts[nts - 1];
652 /* pushing the value before inc */
653 o_tmpcopy();
654 ts_de(1);
655 o_load();
656 o_tmpswap();
658 /* increment by 1 or pointer size */
659 o_tmpcopy();
660 ts_push(&t);
661 ts_pop_de(&t);
662 o_num(t.ptr > 0 ? type_szde(&t) : 1);
663 o_bop(op);
665 /* assign back */
666 o_assign(TYPE_BT(&t));
667 o_tmpdrop(1);
670 static void readfield(void)
672 struct name *field;
673 struct type t;
674 tok_expect(TOK_NAME);
675 ts_pop(&t);
676 array2ptr(&t);
677 field = struct_field(t.id, tok_id());
678 if (field->addr) {
679 o_num(field->addr);
680 o_bop(O_ADD);
682 ts_push_addr(&field->type);
685 #define MAXFUNCS (1 << 10)
687 static struct funcinfo {
688 struct type args[MAXFIELDS];
689 struct type ret;
690 int nargs;
691 } funcs[MAXFUNCS];
692 static int nfuncs;
694 static int func_create(struct type *ret, struct name *args, int nargs)
696 struct funcinfo *fi = &funcs[nfuncs++];
697 int i;
698 if (nfuncs >= MAXFUNCS)
699 err("nomem: MAXFUNCS reached!\n");
700 memcpy(&fi->ret, ret, sizeof(*ret));
701 for (i = 0; i < nargs; i++)
702 memcpy(&fi->args[i], &args[i].type, sizeof(*ret));
703 fi->nargs = nargs;
704 return fi - funcs;
707 static void readcall(void)
709 struct type t;
710 struct funcinfo *fi;
711 int argc = 0;
712 ts_pop(&t);
713 if (t.flags & T_FUNC && t.ptr > 0)
714 o_deref(LONGSZ);
715 fi = t.flags & T_FUNC ? &funcs[t.id] : NULL;
716 if (tok_see() != ')') {
717 do {
718 readexpr();
719 ts_pop_de(NULL);
720 argc++;
721 } while (!tok_jmp(','));
723 tok_expect(')');
724 o_call(argc, fi ? TYPE_BT(&fi->ret) : 4 | BT_SIGNED);
725 if (fi) {
726 if (TYPE_BT(&fi->ret))
727 o_cast(TYPE_BT(&fi->ret));
728 ts_push(&fi->ret);
729 } else {
730 ts_push_bt(4 | BT_SIGNED);
734 static void readpost(void)
736 readprimary();
737 while (1) {
738 if (!tok_jmp('[')) {
739 readexpr();
740 tok_expect(']');
741 arrayderef();
742 continue;
744 if (!tok_jmp('(')) {
745 readcall();
746 continue;
748 if (!tok_jmp(TOK2("++"))) {
749 inc_post(O_ADD);
750 continue;
752 if (!tok_jmp(TOK2("--"))) {
753 inc_post(O_SUB);
754 continue;
756 if (!tok_jmp('.')) {
757 readfield();
758 continue;
760 if (!tok_jmp(TOK2("->"))) {
761 ts_de(1);
762 readfield();
763 continue;
765 break;
769 static void inc_pre(int op)
771 struct type t;
772 readpre();
773 /* copy the destination */
774 o_tmpcopy();
775 ts_push(&ts[nts - 1]);
776 /* increment by 1 or pointer size */
777 ts_pop_de(&t);
778 o_num(t.ptr > 0 ? type_szde(&t) : 1);
779 o_bop(op);
780 /* assign the result */
781 o_assign(TYPE_BT(&t));
782 ts_de(0);
785 static void readpre(void)
787 if (!tok_jmp('&')) {
788 struct type type;
789 readpre();
790 ts_pop(&type);
791 if (!type.addr)
792 die("cannot use the address\n");
793 type.ptr++;
794 type.addr = 0;
795 ts_push(&type);
796 return;
798 if (!tok_jmp('*')) {
799 struct type t;
800 readpre();
801 ts_pop(&t);
802 array2ptr(&t);
803 if (!t.ptr)
804 err("dereferencing non-pointer\n");
805 if (t.addr)
806 o_deref(TYPE_BT(&t));
807 t.ptr--;
808 t.addr = 1;
809 ts_push(&t);
810 return;
812 if (!tok_jmp('!')) {
813 readpre();
814 ts_pop_de(NULL);
815 o_uop(O_LNOT);
816 ts_push_bt(4 | BT_SIGNED);
817 return;
819 if (!tok_jmp('-')) {
820 readpre();
821 ts_de(1);
822 o_uop(O_NEG);
823 return;
825 if (!tok_jmp('~')) {
826 readpre();
827 ts_de(1);
828 o_uop(O_NOT);
829 return;
831 if (!tok_jmp(TOK2("++"))) {
832 inc_pre(O_ADD);
833 return;
835 if (!tok_jmp(TOK2("--"))) {
836 inc_pre(O_SUB);
837 return;
839 if (!tok_jmp(TOK_SIZEOF)) {
840 struct type t;
841 int op = !tok_jmp('(');
842 if (readtype(&t)) {
843 int nogen = !o_nogen();
844 readexpr();
845 if (nogen)
846 o_dogen();
847 ts_pop(&t);
848 o_tmpdrop(1);
850 ts_push_bt(4);
851 o_num(type_totsz(&t));
852 if (op)
853 tok_expect(')');
854 return;
856 readpost();
859 static void readmul(void)
861 readpre();
862 while (1) {
863 if (!tok_jmp('*')) {
864 readpre();
865 ts_binop(O_MUL);
866 continue;
868 if (!tok_jmp('/')) {
869 readpre();
870 ts_binop(O_DIV);
871 continue;
873 if (!tok_jmp('%')) {
874 readpre();
875 ts_binop(O_MOD);
876 continue;
878 break;
882 static void readadd(void)
884 readmul();
885 while (1) {
886 if (!tok_jmp('+')) {
887 readmul();
888 ts_addop(O_ADD);
889 continue;
891 if (!tok_jmp('-')) {
892 readmul();
893 ts_addop(O_SUB);
894 continue;
896 break;
900 static void shift(int op)
902 struct type t;
903 readadd();
904 ts_pop_de2(NULL, &t);
905 o_bop(op | (BT_SIGNED & TYPE_BT(&t) ? O_SIGNED : 0));
906 ts_push_bt(TYPE_BT(&t));
909 static void readshift(void)
911 readadd();
912 while (1) {
913 if (!tok_jmp(TOK2("<<"))) {
914 shift(O_SHL);
915 continue;
917 if (!tok_jmp(TOK2(">>"))) {
918 shift(O_SHR);
919 continue;
921 break;
925 static void cmp(int op)
927 struct type t1, t2;
928 int bt;
929 readshift();
930 ts_pop_de2(&t1, &t2);
931 bt = bt_op(TYPE_BT(&t1), TYPE_BT(&t2));
932 o_bop(op | (bt & BT_SIGNED ? O_SIGNED : 0));
933 ts_push_bt(4 | BT_SIGNED);
936 static void readcmp(void)
938 readshift();
939 while (1) {
940 if (!tok_jmp('<')) {
941 cmp(O_LT);
942 continue;
944 if (!tok_jmp('>')) {
945 cmp(O_GT);
946 continue;
948 if (!tok_jmp(TOK2("<="))) {
949 cmp(O_LE);
950 continue;
952 if (!tok_jmp(TOK2(">="))) {
953 cmp(O_GE);
954 continue;
956 break;
960 static void eq(int op)
962 readcmp();
963 ts_pop_de2(NULL, NULL);
964 o_bop(op);
965 ts_push_bt(4 | BT_SIGNED);
968 static void readeq(void)
970 readcmp();
971 while (1) {
972 if (!tok_jmp(TOK2("=="))) {
973 eq(O_EQ);
974 continue;
976 if (!tok_jmp(TOK2("!="))) {
977 eq(O_NEQ);
978 continue;
980 break;
984 static void readbitand(void)
986 readeq();
987 while (!tok_jmp('&')) {
988 readeq();
989 ts_binop(O_AND);
993 static void readxor(void)
995 readbitand();
996 while (!tok_jmp('^')) {
997 readbitand();
998 ts_binop(O_XOR);
1002 static void readbitor(void)
1004 readxor();
1005 while (!tok_jmp('|')) {
1006 readxor();
1007 ts_binop(O_OR);
1011 #define MAXCOND (1 << 7)
1013 static void readand(void)
1015 long conds[MAXCOND];
1016 int nconds = 0;
1017 long passed;
1018 int i;
1019 readbitor();
1020 if (tok_see() != TOK2("&&"))
1021 return;
1022 o_fork();
1023 ts_pop_de(NULL);
1024 conds[nconds++] = o_jz(0);
1025 while (!tok_jmp(TOK2("&&"))) {
1026 readbitor();
1027 ts_pop_de(NULL);
1028 conds[nconds++] = o_jz(0);
1030 o_num(1);
1031 o_forkpush();
1032 passed = o_jmp(0);
1033 for (i = 0; i < nconds; i++)
1034 o_filljmp(conds[i]);
1035 o_num(0);
1036 o_forkpush();
1037 o_forkjoin();
1038 o_filljmp(passed);
1039 ts_push_bt(4 | BT_SIGNED);
1042 static void reador(void)
1044 long conds[MAXCOND];
1045 int nconds = 0;
1046 long failed;
1047 int i;
1048 readand();
1049 if (tok_see() != TOK2("||"))
1050 return;
1051 o_fork();
1052 ts_pop_de(NULL);
1053 conds[nconds++] = o_jnz(0);
1054 while (!tok_jmp(TOK2("||"))) {
1055 readand();
1056 ts_pop_de(NULL);
1057 conds[nconds++] = o_jnz(0);
1059 o_num(0);
1060 o_forkpush();
1061 failed = o_jmp(0);
1062 for (i = 0; i < nconds; i++)
1063 o_filljmp(conds[i]);
1064 o_num(1);
1065 o_forkpush();
1066 o_forkjoin();
1067 o_filljmp(failed);
1068 ts_push_bt(4 | BT_SIGNED);
1071 static int readcexpr_const(void)
1073 long c;
1074 int nogen;
1075 if (o_popnum(&c))
1076 return -1;
1077 if (!c)
1078 nogen = !o_nogen();
1079 reador();
1080 ts_pop(NULL);
1081 tok_expect(':');
1082 if (c) {
1083 nogen = !o_nogen();
1084 } else {
1085 if (nogen)
1086 o_dogen();
1087 o_tmpdrop(1);
1089 reador();
1090 if (c) {
1091 if (nogen)
1092 o_dogen();
1093 o_tmpdrop(1);
1095 return 0;
1098 static void readcexpr(void)
1100 long l1, l2;
1101 reador();
1102 if (tok_jmp('?'))
1103 return;
1104 ncexpr++;
1105 ts_pop_de(NULL);
1106 o_fork();
1107 if (readcexpr_const()) {
1108 l1 = o_jz(0);
1109 reador();
1110 o_forkpush();
1111 l2 = o_jmp(0);
1112 ts_pop(NULL);
1114 tok_expect(':');
1115 o_filljmp(l1);
1116 reador();
1117 ts_de(1);
1118 o_forkpush();
1119 o_forkjoin();
1120 o_filljmp(l2);
1122 ncexpr--;
1125 static void opassign(int op, int ptrop)
1127 struct type t = ts[nts - 1];
1128 o_tmpcopy();
1129 ts_push(&t);
1130 readexpr();
1131 ts_addop(op);
1132 o_assign(TYPE_BT(&ts[nts - 1]));
1133 ts_pop(NULL);
1134 ts_de(0);
1137 static void doassign(void)
1139 struct type t = ts[nts - 1];
1140 if (!t.ptr && t.flags & T_STRUCT) {
1141 ts_pop(NULL);
1142 o_num(type_totsz(&t));
1143 o_memcpy();
1144 } else {
1145 ts_pop_de(NULL);
1146 o_assign(TYPE_BT(&ts[nts - 1]));
1147 ts_de(0);
1151 static void readexpr(void)
1153 readcexpr();
1154 if (!tok_jmp('=')) {
1155 readexpr();
1156 doassign();
1157 return;
1159 if (!tok_jmp(TOK2("+="))) {
1160 opassign(O_ADD, 1);
1161 return;
1163 if (!tok_jmp(TOK2("-="))) {
1164 opassign(O_SUB, 1);
1165 return;
1167 if (!tok_jmp(TOK2("*="))) {
1168 opassign(O_MUL, 0);
1169 return;
1171 if (!tok_jmp(TOK2("/="))) {
1172 opassign(O_DIV, 0);
1173 return;
1175 if (!tok_jmp(TOK2("%="))) {
1176 opassign(O_MOD, 0);
1177 return;
1179 if (!tok_jmp(TOK3("<<="))) {
1180 opassign(O_SHL, 0);
1181 return;
1183 if (!tok_jmp(TOK3(">>="))) {
1184 opassign(O_SHR, 0);
1185 return;
1187 if (!tok_jmp(TOK3("&="))) {
1188 opassign(O_AND, 0);
1189 return;
1191 if (!tok_jmp(TOK3("|="))) {
1192 opassign(O_OR, 0);
1193 return;
1195 if (!tok_jmp(TOK3("^="))) {
1196 opassign(O_XOR, 0);
1197 return;
1201 static void readestmt(void)
1203 do {
1204 o_tmpdrop(-1);
1205 nts = 0;
1206 readexpr();
1207 } while (!tok_jmp(','));
1210 static void o_localoff(long addr, int off)
1212 o_local(addr);
1213 if (off) {
1214 o_num(off);
1215 o_bop(O_ADD);
1219 static struct type *innertype(struct type *t)
1221 if (t->flags & T_ARRAY && !t->ptr)
1222 return innertype(&arrays[t->id].type);
1223 return t;
1226 static void initexpr(struct type *t, int off, void *obj,
1227 void (*set)(void *obj, int off, struct type *t))
1229 if (tok_jmp('{')) {
1230 set(obj, off, t);
1231 return;
1233 if (!t->ptr && t->flags & T_STRUCT) {
1234 struct structinfo *si = &structs[t->id];
1235 int i;
1236 for (i = 0; i < si->nfields; i++) {
1237 struct name *field = &si->fields[i];
1238 if (!tok_jmp('.')) {
1239 tok_expect(TOK_NAME);
1240 field = struct_field(t->id, tok_id());
1241 tok_expect('=');
1243 initexpr(&field->type, off + field->addr, obj, set);
1244 if (tok_jmp(',') || tok_see() == '}')
1245 break;
1247 } else if (t->flags & T_ARRAY) {
1248 struct type *t_de = &arrays[t->id].type;
1249 int i;
1250 for (i = 0; ; i++) {
1251 long idx = i;
1252 struct type *it = t_de;
1253 if (!tok_jmp('[')) {
1254 readexpr();
1255 o_popnum(&idx);
1256 ts_pop(NULL);
1257 tok_expect(']');
1258 tok_expect('=');
1260 if (tok_see() != '{')
1261 it = innertype(t_de);
1262 initexpr(it, off + type_totsz(it) * idx, obj, set);
1263 if (tok_jmp(',') || tok_see() == '}')
1264 break;
1267 tok_expect('}');
1270 static void jumpbrace(void)
1272 int depth = 0;
1273 while (tok_see() != '}' || depth--)
1274 if (tok_get() == '{')
1275 depth++;
1276 tok_expect('}');
1279 static int initsize(void)
1281 long addr = tok_addr();
1282 int n = 0;
1283 if (!tok_jmp(TOK_STR)) {
1284 n = tok_str(NULL);
1285 tok_jump(addr);
1286 return n;
1288 o_nogen();
1289 tok_expect('{');
1290 while (tok_jmp('}')) {
1291 long idx = n;
1292 if (!tok_jmp('[')) {
1293 readexpr();
1294 o_popnum(&idx);
1295 ts_pop(NULL);
1296 tok_expect(']');
1297 tok_expect('=');
1299 if (n < idx + 1)
1300 n = idx + 1;
1301 while (tok_see() != '}' && tok_see() != ',')
1302 if (tok_get() == '{')
1303 jumpbrace();
1304 tok_jmp(',');
1306 o_dogen();
1307 tok_jump(addr);
1308 return n;
1311 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1313 static void globalinit(void *obj, int off, struct type *t)
1315 struct name *name = obj;
1316 char *elfname = *name->elfname ? name->elfname : name->name;
1317 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1318 struct type *t_de = &arrays[t->id].type;
1319 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1320 char buf[BUFSIZE];
1321 int len;
1322 tok_expect(TOK_STR);
1323 len = tok_str(buf);
1324 memcpy((void *) name->addr + off, buf, len);
1325 return;
1328 readexpr();
1329 o_datset(elfname, off, TYPE_BT(t));
1330 ts_pop(NULL);
1333 static void globaldef(void *data, struct name *name, unsigned flags)
1335 struct type *t = &name->type;
1336 char *elfname = *name->elfname ? name->elfname : name->name;
1337 int sz;
1338 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1339 if (~flags & F_EXTERN)
1340 arrays[t->id].n = initsize();
1341 sz = type_totsz(t);
1342 if (!(flags & F_EXTERN) && (!(t->flags & T_FUNC) || t->ptr)) {
1343 if (flags & F_INIT)
1344 name->addr = (long) dat_dat(elfname, sz, F_GLOBAL(flags));
1345 else
1346 dat_bss(elfname, sz, F_GLOBAL(flags));
1348 global_add(name);
1349 if (flags & F_INIT)
1350 initexpr(t, 0, name, globalinit);
1353 static void localinit(void *obj, int off, struct type *t)
1355 long addr = *(long *) obj;
1356 if (t->flags & T_ARRAY && tok_see() == TOK_STR) {
1357 struct type *t_de = &arrays[t->id].type;
1358 if (!t_de->ptr && !t_de->flags && TYPE_SZ(t_de) == 1) {
1359 char buf[BUFSIZE];
1360 int len;
1361 tok_expect(TOK_STR);
1362 len = tok_str(buf);
1363 o_localoff(addr, off);
1364 o_sym(tmp_str(buf, len));
1365 o_num(len);
1366 o_memcpy();
1367 o_tmpdrop(1);
1368 return;
1371 o_localoff(addr, off);
1372 ts_push(t);
1373 readexpr();
1374 doassign();
1375 ts_pop(NULL);
1376 o_tmpdrop(1);
1379 /* current function name */
1380 static char func_name[NAMELEN];
1382 static void localdef(void *data, struct name *name, unsigned flags)
1384 struct type *t = &name->type;
1385 if (flags & (F_STATIC | F_EXTERN)) {
1386 sprintf(name->elfname, "__neatcc.%s.%s", func_name, name->name);
1387 globaldef(data, name, flags);
1388 return;
1390 if (t->flags & T_ARRAY && !t->ptr && !arrays[t->id].n)
1391 arrays[t->id].n = initsize();
1392 name->addr = o_mklocal(type_totsz(&name->type));
1393 local_add(name);
1394 if (flags & F_INIT) {
1395 if (t->flags & (T_ARRAY | T_STRUCT) && !t->ptr) {
1396 o_local(name->addr);
1397 o_num(0);
1398 o_num(type_totsz(t));
1399 o_memset();
1400 o_tmpdrop(1);
1402 initexpr(t, 0, &name->addr, localinit);
1406 static void funcdef(char *name, struct type *type, struct name *args,
1407 int nargs, unsigned flags)
1409 struct name global = {""};
1410 int i;
1411 strcpy(global.name, name);
1412 strcpy(func_name, name);
1413 memcpy(&global.type, type, sizeof(*type));
1414 o_func_beg(name, F_GLOBAL(flags));
1415 global_add(&global);
1416 for (i = 0; i < nargs; i++) {
1417 args[i].addr = o_arg(i);
1418 local_add(&args[i]);
1422 static int readargs(struct name *args)
1424 int nargs = 0;
1425 tok_expect('(');
1426 while (tok_see() != ')') {
1427 if (!tok_jmp(TOK3("...")))
1428 break;
1429 readname(&args[nargs].type, args[nargs].name, NULL, 0);
1430 array2ptr(&args[nargs].type);
1431 nargs++;
1432 if (tok_jmp(','))
1433 break;
1435 tok_expect(')');
1436 if (nargs == 1 && !TYPE_BT(&args[0].type))
1437 return 0;
1438 return nargs;
1441 static int readname(struct type *main, char *name,
1442 struct type *base, unsigned flags)
1444 struct type tpool[3];
1445 int npool = 0;
1446 struct type *type = &tpool[npool++];
1447 struct type *func = NULL;
1448 struct type *ret = NULL;
1449 int arsz[10];
1450 int nar = 0;
1451 int i;
1452 memset(tpool, 0, sizeof(tpool));
1453 if (name)
1454 *name = '\0';
1455 if (!base) {
1456 if (basetype(type, &flags))
1457 return 1;
1458 } else {
1459 memcpy(type, base, sizeof(*base));
1461 readptrs(type);
1462 if (!tok_jmp('(')) {
1463 ret = type;
1464 type = &tpool[npool++];
1465 func = type;
1466 readptrs(type);
1468 if (!tok_jmp(TOK_NAME) && name)
1469 strcpy(name, tok_id());
1470 while (!tok_jmp('[')) {
1471 long n = 0;
1472 if (tok_jmp(']')) {
1473 readexpr();
1474 ts_pop(NULL);
1475 if (o_popnum(&n))
1476 err("const expr expected\n");
1477 tok_expect(']');
1479 arsz[nar++] = n;
1481 for (i = nar - 1; i >= 0; i--) {
1482 type->id = array_add(type, arsz[i]);
1483 if (func && i == nar - 1)
1484 func = &arrays[type->id].type;
1485 type->flags = T_ARRAY;
1486 type->bt = LONGSZ;
1487 type->ptr = 0;
1489 if (func)
1490 tok_expect(')');
1491 if (tok_see() == '(') {
1492 struct name args[MAXARGS] = {{""}};
1493 int nargs = readargs(args);
1494 int fdef = !func;
1495 if (!func) {
1496 ret = type;
1497 type = &tpool[npool++];
1498 func = type;
1500 func->flags = T_FUNC;
1501 func->bt = LONGSZ;
1502 func->id = func_create(ret, args, nargs);
1503 if (fdef && tok_see() == '{') {
1504 funcdef(name, func, args, nargs, flags);
1505 return 1;
1508 memcpy(main, type, sizeof(*type));
1509 return 0;
1512 static int readdefs(void (*def)(void *data, struct name *name, unsigned flags),
1513 void *data)
1515 struct type base;
1516 unsigned base_flags;
1517 if (basetype(&base, &base_flags))
1518 return 1;
1519 while (tok_see() != ';' && tok_see() != '{') {
1520 struct name name = {{""}};
1521 unsigned flags = base_flags;
1522 if (readname(&name.type, name.name, &base, flags))
1523 break;
1524 if (!tok_jmp('='))
1525 flags |= F_INIT;
1526 def(data, &name, flags);
1527 tok_jmp(',');
1529 return 0;
1532 static void typedefdef(void *data, struct name *name, unsigned flags)
1534 typedef_add(name->name, &name->type);
1537 static void readstmt(void);
1539 #define MAXCASES (1 << 7)
1541 static void readswitch(void)
1543 int break_beg = nbreaks;
1544 long val_addr = o_mklocal(LONGSZ);
1545 long matched[MAXCASES];
1546 int nmatched = 0;
1547 struct type t;
1548 long next;
1549 int ref = 1;
1550 int i;
1551 tok_expect('(');
1552 readexpr();
1553 ts_pop_de(&t);
1554 o_local(val_addr);
1555 o_tmpswap();
1556 o_assign(TYPE_BT(&t));
1557 ts_de(0);
1558 o_tmpdrop(1);
1559 tok_expect(')');
1560 tok_expect('{');
1561 while (tok_jmp('}')) {
1562 int n = 0;
1563 while (tok_see() == TOK_CASE || tok_see() == TOK_DEFAULT) {
1564 if (n++ > 0)
1565 matched[nmatched++] = o_jmp(0);
1566 if (!ref++)
1567 o_filljmp(next);
1568 if (!tok_jmp(TOK_CASE)) {
1569 caseexpr = 1;
1570 readexpr();
1571 ts_pop_de(NULL);
1572 caseexpr = 0;
1573 o_local(val_addr);
1574 o_deref(TYPE_BT(&t));
1575 o_bop(O_EQ);
1576 next = o_jz(0);
1577 ref = 0;
1578 tok_expect(':');
1579 o_tmpdrop(1);
1580 continue;
1582 if (!tok_jmp(TOK_DEFAULT)) {
1583 tok_expect(':');
1584 continue;
1587 for (i = 0; i < nmatched; i++)
1588 o_filljmp(matched[i]);
1589 nmatched = 0;
1590 readstmt();
1592 o_rmlocal(val_addr, LONGSZ);
1593 if (!ref++)
1594 o_filljmp(next);
1595 break_fill(o_mklabel(), break_beg);
1598 #define MAXGOTO (1 << 10)
1600 static struct gotoinfo {
1601 char name[NAMELEN];
1602 long addr;
1603 } gotos[MAXGOTO];
1604 static int ngotos;
1606 static struct labelinfo {
1607 char name[NAMELEN];
1608 long addr;
1609 } labels[MAXGOTO];
1610 static int nlabels;
1612 static void goto_add(char *name)
1614 strcpy(gotos[ngotos].name, name);
1615 gotos[ngotos++].addr = o_jmp(0);
1618 static void label_add(char *name)
1620 strcpy(labels[nlabels].name, name);
1621 labels[nlabels++].addr = o_mklabel();
1624 static void goto_fill(void)
1626 int i, j;
1627 for (i = 0; i < ngotos; i++)
1628 for (j = 0; j < nlabels; j++)
1629 if (!strcmp(gotos[i].name, labels[j].name)) {
1630 o_filljmp2(gotos[i].addr, labels[j].addr);
1631 break;
1635 static void readstmt(void)
1637 o_tmpdrop(-1);
1638 nts = 0;
1639 if (!tok_jmp('{')) {
1640 int _nlocals = nlocals;
1641 int _nglobals = nglobals;
1642 int _nenums = nenums;
1643 int _ntypedefs = ntypedefs;
1644 int _nstructs = nstructs;
1645 int _nfuncs = nfuncs;
1646 int _narrays = narrays;
1647 while (tok_jmp('}'))
1648 readstmt();
1649 nlocals = _nlocals;
1650 nenums = _nenums;
1651 ntypedefs = _ntypedefs;
1652 nstructs = _nstructs;
1653 nfuncs = _nfuncs;
1654 narrays = _narrays;
1655 nglobals = _nglobals;
1656 return;
1658 if (!readdefs(localdef, NULL)) {
1659 tok_expect(';');
1660 return;
1662 if (!tok_jmp(TOK_TYPEDEF)) {
1663 readdefs(typedefdef, NULL);
1664 tok_expect(';');
1665 return;
1667 if (!tok_jmp(TOK_IF)) {
1668 long l1, l2;
1669 tok_expect('(');
1670 readexpr();
1671 tok_expect(')');
1672 ts_pop_de(NULL);
1673 l1 = o_jz(0);
1674 readstmt();
1675 if (!tok_jmp(TOK_ELSE)) {
1676 l2 = o_jmp(0);
1677 o_filljmp(l1);
1678 readstmt();
1679 o_filljmp(l2);
1680 } else {
1681 o_filljmp(l1);
1683 return;
1685 if (!tok_jmp(TOK_WHILE)) {
1686 long l1, l2;
1687 int break_beg = nbreaks;
1688 int continue_beg = ncontinues;
1689 l1 = o_mklabel();
1690 tok_expect('(');
1691 readexpr();
1692 tok_expect(')');
1693 ts_pop_de(NULL);
1694 l2 = o_jz(0);
1695 readstmt();
1696 o_jmp(l1);
1697 o_filljmp(l2);
1698 break_fill(o_mklabel(), break_beg);
1699 continue_fill(l1, continue_beg);
1700 return;
1702 if (!tok_jmp(TOK_DO)) {
1703 long l1, l2;
1704 int break_beg = nbreaks;
1705 int continue_beg = ncontinues;
1706 l1 = o_mklabel();
1707 readstmt();
1708 tok_expect(TOK_WHILE);
1709 tok_expect('(');
1710 l2 = o_mklabel();
1711 readexpr();
1712 ts_pop_de(NULL);
1713 o_jnz(l1);
1714 tok_expect(')');
1715 break_fill(o_mklabel(), break_beg);
1716 continue_fill(l2, continue_beg);
1717 return;
1719 if (!tok_jmp(TOK_FOR)) {
1720 long l_check, l_jump, j_fail, j_pass;
1721 int break_beg = nbreaks;
1722 int continue_beg = ncontinues;
1723 int has_cond = 0;
1724 tok_expect('(');
1725 if (tok_see() != ';')
1726 readestmt();
1727 tok_expect(';');
1728 l_check = o_mklabel();
1729 if (tok_see() != ';') {
1730 readestmt();
1731 ts_pop_de(NULL);
1732 j_fail = o_jz(0);
1733 has_cond = 1;
1735 tok_expect(';');
1736 j_pass = o_jmp(0);
1737 l_jump = o_mklabel();
1738 if (tok_see() != ')')
1739 readestmt();
1740 tok_expect(')');
1741 o_jmp(l_check);
1742 o_filljmp(j_pass);
1743 readstmt();
1744 o_jmp(l_jump);
1745 if (has_cond)
1746 o_filljmp(j_fail);
1747 break_fill(o_mklabel(), break_beg);
1748 continue_fill(l_jump, continue_beg);
1749 return;
1751 if (!tok_jmp(TOK_SWITCH)) {
1752 readswitch();
1753 return;
1755 if (!tok_jmp(TOK_RETURN)) {
1756 int ret = tok_see() != ';';
1757 if (ret) {
1758 readexpr();
1759 ts_pop_de(NULL);
1761 tok_expect(';');
1762 o_ret(ret);
1763 return;
1765 if (!tok_jmp(TOK_BREAK)) {
1766 tok_expect(';');
1767 breaks[nbreaks++] = o_jmp(0);
1768 return;
1770 if (!tok_jmp(TOK_CONTINUE)) {
1771 tok_expect(';');
1772 continues[ncontinues++] = o_jmp(0);
1773 return;
1775 if (!tok_jmp(TOK_GOTO)) {
1776 tok_expect(TOK_NAME);
1777 goto_add(tok_id());
1778 tok_expect(';');
1779 return;
1781 readestmt();
1782 /* labels */
1783 if (!tok_jmp(':')) {
1784 label_add(tok_id());
1785 return;
1787 tok_expect(';');
1790 static void readdecl(void)
1792 if (!tok_jmp(TOK_TYPEDEF)) {
1793 readdefs(typedefdef, NULL);
1794 tok_expect(';');
1795 return;
1797 readdefs(globaldef, NULL);
1798 if (tok_see() == '{') {
1799 readstmt();
1800 goto_fill();
1801 o_func_end();
1802 func_name[0] = '\0';
1803 nlocals = 0;
1804 ngotos = 0;
1805 nlabels = 0;
1806 return;
1808 tok_expect(';');
1811 static void parse(void)
1813 while (tok_see() != TOK_EOF)
1814 readdecl();
1817 int main(int argc, char *argv[])
1819 char obj[128];
1820 int ofd;
1821 int i = 1;
1822 while (i < argc && argv[i][0] == '-') {
1823 if (argv[i][1] == 'I')
1824 cpp_addpath(argv[i][2] ? argv[i] + 2 : argv[++i]);
1825 if (argv[i][1] == 'D') {
1826 char *name = argv[i] + 2;
1827 char *def = "";
1828 char *eq = strchr(name, '=');
1829 if (eq) {
1830 *eq = '\0';
1831 def = eq + 1;
1833 cpp_define(name, def);
1835 i++;
1837 if (i == argc)
1838 die("neatcc: no file given\n");
1839 if (cpp_init(argv[i]))
1840 die("neatcc: cannot open input file\n");
1841 parse();
1842 strcpy(obj, argv[i]);
1843 obj[strlen(obj) - 1] = 'o';
1844 ofd = open(obj, O_WRONLY | O_TRUNC | O_CREAT, 0600);
1845 o_write(ofd);
1846 close(ofd);
1847 return 0;