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.
15 #include <sys/types.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)
39 int id
; /* for structs, functions and arrays */
43 static struct type ts
[MAXTMP
];
46 static void ts_push_bt(unsigned 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
)
60 static void ts_pop(struct type
*type
)
76 int len
= cpp_loc(err
, tok_addr());
77 strcpy(err
+ len
, msg
);
85 int unused
; /* unreferenced external symbols */
88 static struct name locals
[MAXLOCALS
];
90 static struct name globals
[MAXGLOBALS
];
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
)
103 for (i
= 0; i
< nglobals
; i
++)
104 if (!strcmp(name
, globals
[i
].name
))
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
{
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
);
135 static int enum_find(int *val
, char *name
)
138 for (i
= nenums
- 1; i
>= 0; --i
)
139 if (!strcmp(name
, enums
[i
].name
)) {
146 #define MAXTYPEDEFS (1 << 10)
148 static struct typdefinfo
{
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
)
166 for (i
= ntypedefs
- 1; i
>= 0; --i
)
167 if (!strcmp(name
, typedefs
[i
].name
))
172 #define MAXARRAYS (1 << 10)
174 static struct array
{
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
));
190 static void array2ptr(struct type
*t
)
192 if (!(t
->flags
& T_ARRAY
) || t
->ptr
)
194 memcpy(t
, &arrays
[t
->id
].type
, sizeof(*t
));
198 #define MAXSTRUCTS (1 << 10)
199 #define MAXFIELDS (1 << 7)
201 static struct structinfo
{
203 struct name fields
[MAXFIELDS
];
207 } structs
[MAXSTRUCTS
];
210 static int struct_find(char *name
, int isunion
)
213 for (i
= nstructs
- 1; i
>= 0; --i
)
214 if (*structs
[i
].name
&& !strcmp(name
, structs
[i
].name
) &&
215 structs
[i
].isunion
== isunion
)
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
;
226 static struct name
*struct_field(int id
, char *name
)
228 struct structinfo
*si
= &structs
[id
];
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
];
240 static long continues
[MAXBREAK
];
241 static int ncontinues
;
243 static void break_fill(long addr
, int till
)
246 for (i
= till
; i
< nbreaks
; i
++)
247 o_filljmp2(breaks
[i
], addr
);
251 static void continue_fill(long addr
, int till
)
254 for (i
= till
; i
< ncontinues
; i
++)
255 o_filljmp2(continues
[i
], addr
);
259 static int type_totsz(struct type
*t
)
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
)
273 return type_totsz(&de
);
276 static int tok_jmp(int tok
)
278 if (tok_see() != tok
)
284 static void tok_expect(int tok
)
286 if (tok_get() != tok
)
287 err("syntax error\n");
290 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
292 unsigned s1
= BT_SZ(bt1
);
293 unsigned s2
= BT_SZ(bt2
);
294 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
297 static void ts_binop(void (*o_sth
)(void))
303 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
306 static void ts_binop_add(void (*o_sth
)(void))
313 if (!t1
.ptr
&& !t2
.ptr
) {
315 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
318 if (t1
.ptr
&& !t2
.ptr
) {
324 if (!t1
.ptr
&& t2
.ptr
)
325 if (type_szde(&t2
) > 1) {
326 o_num(type_szde(&t2
), 4);
330 if (t1
.ptr
&& t2
.ptr
) {
331 int sz
= type_szde(&t1
);
336 ts_push_bt(4 | BT_SIGNED
);
342 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
343 #define MIN(a, b) ((a) < (b) ? (a) : (b))
345 static int type_alignment(struct type
*t
)
347 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
348 return type_alignment(&arrays
[t
->id
].type
);
349 if (t
->flags
& T_STRUCT
&& !t
->ptr
)
350 return type_alignment(&structs
[t
->id
].fields
[0].type
);
351 return MIN(8, type_totsz(t
));
354 static void structdef(void *data
, struct name
*name
, unsigned flags
)
356 struct structinfo
*si
= data
;
359 if (si
->size
< type_totsz(&name
->type
))
360 si
->size
= type_totsz(&name
->type
);
362 struct type
*t
= &name
->type
;
363 int alignment
= type_alignment(t
);
364 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
365 alignment
= MIN(8, type_totsz(&arrays
[t
->id
].type
));
366 si
->size
= ALIGN(si
->size
, alignment
);
367 name
->addr
= si
->size
;
368 si
->size
+= type_totsz(&name
->type
);
370 memcpy(&si
->fields
[si
->nfields
++], name
, sizeof(*name
));
373 static int readdefs(void (*def
)(void *, struct name
*, unsigned f
), void *data
);
375 static int struct_create(char *name
, int isunion
)
377 int id
= struct_find(name
, isunion
);
378 struct structinfo
*si
= &structs
[id
];
380 while (tok_jmp('}')) {
381 readdefs(structdef
, si
);
387 static void readexpr(void);
389 static void enum_create(void)
393 while (tok_jmp('}')) {
395 tok_expect(TOK_NAME
);
396 strcpy(name
, tok_id());
397 if (tok_see() == '=') {
402 err("const expr expected!\n");
409 static int basetype(struct type
*type
, unsigned *flags
)
416 char name
[NAMELEN
] = "";
453 isunion
= tok_get() == TOK_UNION
;
454 if (!tok_jmp(TOK_NAME
))
455 strcpy(name
, tok_id());
456 if (tok_see() == '{')
457 type
->id
= struct_create(name
, isunion
);
459 type
->id
= struct_find(name
, isunion
);
460 type
->flags
|= T_STRUCT
;
466 if (tok_see() == '{')
468 type
->bt
= 4 | BT_SIGNED
;
471 if (tok_see() == TOK_NAME
) {
472 int id
= typedef_find(tok_id());
475 memcpy(type
, &typedefs
[id
].type
,
488 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
492 static int readname(struct type
*main
, char *name
,
493 struct type
*base
, unsigned flags
);
495 static int readtype(struct type
*type
)
497 return readname(type
, NULL
, NULL
, 0);
500 static void readptrs(struct type
*type
)
502 while (!tok_jmp('*')) {
509 /* used to differenciate labels from case and cond exprs */
513 static void readpre(void);
515 static void readprimary(void)
518 if (!tok_jmp(TOK_NUM
)) {
520 int bt
= tok_num(&n
);
525 if (!tok_jmp(TOK_STR
)) {
529 t
.bt
= 1 | BT_SIGNED
;
534 o_symaddr(out_mkdat(NULL
, buf
, len
, 0), TYPE_BT(&t
));
538 if (!tok_jmp(TOK_NAME
)) {
539 struct name unkn
= {0};
540 char *name
= unkn
.name
;
542 strcpy(name
, tok_id());
543 /* don't search for labels here */
544 if (!ncexpr
&& !caseexpr
&& tok_see() == ':')
546 for (i
= nlocals
- 1; i
>= 0; --i
) {
547 struct type
*t
= &locals
[i
].type
;
548 if (!strcmp(locals
[i
].name
, name
)) {
549 o_local(locals
[i
].addr
, TYPE_BT(t
));
554 if ((n
= global_find(name
)) != -1) {
555 struct name
*g
= &globals
[n
];
556 struct type
*t
= &g
->type
;
559 if (t
->flags
& T_FUNC
&& !t
->ptr
)
560 g
->addr
= out_mkundef(name
, 0);
562 g
->addr
= out_mkundef(name
, type_totsz(t
));
564 o_symaddr(g
->addr
, TYPE_BT(t
));
568 if (!enum_find(&n
, name
)) {
569 ts_push_bt(4 | BT_SIGNED
);
570 o_num(n
, 4 | BT_SIGNED
);
573 if (tok_see() != '(')
574 err("unknown symbol\n");
575 unkn
.addr
= out_mkundef(unkn
.name
, 0);
578 o_symaddr(unkn
.addr
, 8);
589 if (!t
.ptr
|| !o
.ptr
)
599 void arrayderef(struct type
*t
)
601 int sz
= type_totsz(t
);
610 static void inc_post(void (*op
)(void))
612 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
626 static void readfield(void)
630 tok_expect(TOK_NAME
);
633 field
= struct_field(t
.id
, tok_id());
635 o_num(field
->addr
, 4);
638 o_deref(TYPE_BT(&field
->type
));
639 ts_push(&field
->type
);
642 #define MAXFUNCS (1 << 10)
644 static struct funcinfo
{
645 struct type args
[MAXFIELDS
];
650 static unsigned ret_bt
;
652 static int func_create(struct type
*ret
, struct name
*args
, int nargs
)
654 struct funcinfo
*fi
= &funcs
[nfuncs
++];
656 if (nfuncs
>= MAXFUNCS
)
657 err("nomem: MAXFUNCS reached!\n");
658 memcpy(&fi
->ret
, ret
, sizeof(*ret
));
659 for (i
= 0; i
< nargs
; i
++)
660 memcpy(&fi
->args
[i
], &args
[i
].type
, sizeof(*ret
));
665 static void readcall(void)
668 unsigned bt
[MAXARGS
];
673 if (t
.flags
& T_FUNC
&& t
.ptr
> 0)
675 fi
= t
.flags
& T_FUNC
? &funcs
[t
.id
] : NULL
;
676 if (tok_see() != ')') {
679 bt
[argc
++] = TYPE_BT(&t
);
681 while (!tok_jmp(',')) {
684 bt
[argc
++] = TYPE_BT(&t
);
688 for (i
= 0; i
< fi
->nargs
; i
++)
689 bt
[i
] = TYPE_BT(&fi
->args
[i
]);
690 o_call(argc
, bt
, fi
? TYPE_BT(&fi
->ret
) : 4 | BT_SIGNED
);
694 ts_push_bt(4 | BT_SIGNED
);
697 static void readpost(void)
717 if (!tok_jmp(TOK2("++"))) {
721 if (!tok_jmp(TOK2("--"))) {
730 if (!tok_jmp(TOK2("->"))) {
738 static void inc_pre(void (*op
)(void))
742 bt
= TYPE_BT(&ts
[nts
- 1]);
752 static void readpre(void)
758 if (!(type
.flags
& T_FUNC
) && !type
.ptr
)
769 if (!(t
.flags
& T_FUNC
) || t
.ptr
> 0) {
771 o_deref(TYPE_BT(&t
));
781 ts_push_bt(4 | BT_SIGNED
);
794 if (!tok_jmp(TOK2("++"))) {
798 if (!tok_jmp(TOK2("--"))) {
802 if (!tok_jmp(TOK_SIZEOF
)) {
804 int op
= !tok_jmp('(');
806 int nogen
= !o_nogen();
814 o_num(type_totsz(&t
), 4);
822 static void readmul(void)
845 static void readadd(void)
863 static void shift(void (*op
)(void))
870 ts_push_bt(TYPE_BT(&t
));
873 static void readshift(void)
877 if (!tok_jmp(TOK2("<<"))) {
881 if (!tok_jmp(TOK2(">>"))) {
889 static void cmp(void (*op
)(void))
895 ts_push_bt(4 | BT_SIGNED
);
898 static void readcmp(void)
910 if (!tok_jmp(TOK2("<="))) {
914 if (!tok_jmp(TOK2(">="))) {
922 static void eq(void (*op
)(void))
928 ts_push_bt(4 | BT_SIGNED
);
931 static void readeq(void)
935 if (!tok_jmp(TOK2("=="))) {
939 if (!tok_jmp(TOK2("!="))) {
947 static void readbitand(void)
950 while (!tok_jmp('&')) {
956 static void readxor(void)
959 while (!tok_jmp('^')) {
965 static void readbitor(void)
968 while (!tok_jmp('|')) {
974 #define MAXCOND (1 << 7)
976 static void readand(void)
983 if (tok_see() != TOK2("&&"))
986 conds
[nconds
++] = o_jz(0);
988 while (!tok_jmp(TOK2("&&"))) {
990 conds
[nconds
++] = o_jz(0);
993 o_num(1, 4 | BT_SIGNED
);
996 for (i
= 0; i
< nconds
; i
++)
998 o_num(0, 4 | BT_SIGNED
);
1002 ts_push_bt(4 | BT_SIGNED
);
1005 static void reador(void)
1007 long conds
[MAXCOND
];
1012 if (tok_see() != TOK2("||"))
1015 conds
[nconds
++] = o_jnz(0);
1017 while (!tok_jmp(TOK2("||"))) {
1019 conds
[nconds
++] = o_jnz(0);
1022 o_num(0, 4 | BT_SIGNED
);
1025 for (i
= 0; i
< nconds
; i
++)
1026 o_filljmp(conds
[i
]);
1027 o_num(1, 4 | BT_SIGNED
);
1031 ts_push_bt(4 | BT_SIGNED
);
1034 static int readcexpr_const(void)
1061 static void readcexpr(void)
1070 if (readcexpr_const()) {
1087 static void opassign(void (*bop
)(void (*op
)(void)), void (*op
)(void))
1089 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
1097 static void doassign(void)
1101 if (!t
.ptr
&& t
.flags
& T_STRUCT
)
1102 o_memcpy(type_totsz(&t
));
1104 o_assign(TYPE_BT(&ts
[nts
- 1]));
1107 static void readexpr(void)
1110 if (!tok_jmp('=')) {
1115 if (!tok_jmp(TOK2("+="))) {
1116 opassign(ts_binop_add
, o_add
);
1119 if (!tok_jmp(TOK2("-="))) {
1120 opassign(ts_binop_add
, o_sub
);
1123 if (!tok_jmp(TOK2("*="))) {
1124 opassign(ts_binop
, o_mul
);
1127 if (!tok_jmp(TOK2("/="))) {
1128 opassign(ts_binop
, o_div
);
1131 if (!tok_jmp(TOK2("%="))) {
1132 opassign(ts_binop
, o_mod
);
1135 if (!tok_jmp(TOK3("<<="))) {
1136 opassign(ts_binop
, o_shl
);
1139 if (!tok_jmp(TOK3(">>="))) {
1140 opassign(ts_binop
, o_shr
);
1143 if (!tok_jmp(TOK3("&="))) {
1144 opassign(ts_binop
, o_and
);
1147 if (!tok_jmp(TOK3("|="))) {
1148 opassign(ts_binop
, o_or
);
1151 if (!tok_jmp(TOK3("^="))) {
1152 opassign(ts_binop
, o_xor
);
1157 static void readestmt(void)
1163 } while (!tok_jmp(','));
1166 static void o_localoff(long addr
, int off
, unsigned bt
)
1177 static struct type
*innertype(struct type
*t
)
1179 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
1180 return innertype(&arrays
[t
->id
].type
);
1184 static void initexpr(struct type
*t
, int off
, void *obj
,
1185 void (*set
)(void *obj
, int off
, struct type
*t
))
1191 if (!t
->ptr
&& t
->flags
& T_STRUCT
) {
1192 struct structinfo
*si
= &structs
[t
->id
];
1194 for (i
= 0; i
< si
->nfields
; i
++) {
1195 struct name
*field
= &si
->fields
[i
];
1196 if (!tok_jmp('.')) {
1197 tok_expect(TOK_NAME
);
1198 field
= struct_field(t
->id
, tok_id());
1201 initexpr(&field
->type
, off
+ field
->addr
, obj
, set
);
1202 if (tok_jmp(',') || tok_see() == '}')
1205 } else if (t
->flags
& T_ARRAY
) {
1206 struct type
*t_de
= &arrays
[t
->id
].type
;
1208 for (i
= 0; ; i
++) {
1210 struct type
*it
= t_de
;
1211 if (!tok_jmp('[')) {
1218 if (tok_see() != '{')
1219 it
= innertype(t_de
);
1220 initexpr(it
, off
+ type_totsz(it
) * idx
, obj
, set
);
1221 if (tok_jmp(',') || tok_see() == '}')
1228 static void jumpbrace(void)
1231 while (tok_see() != '}' || depth
--)
1232 if (tok_get() == '{')
1237 static int initsize(void)
1239 long addr
= tok_addr();
1241 if (!tok_jmp(TOK_STR
)) {
1248 while (tok_jmp('}')) {
1250 if (!tok_jmp('[')) {
1259 while (tok_see() != '}' && tok_see() != ',')
1260 if (tok_get() == '{')
1269 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1271 static void globalinit(void *obj
, int off
, struct type
*t
)
1273 long addr
= *(long *) obj
;
1274 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1275 struct type
*t_de
= &arrays
[t
->id
].type
;
1276 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1279 tok_expect(TOK_STR
);
1281 out_datcpy(addr
, off
, buf
, len
);
1286 o_datset(addr
, off
, TYPE_BT(t
));
1290 static void globaldef(void *data
, struct name
*name
, unsigned flags
)
1292 struct type
*t
= &name
->type
;
1293 char *varname
= flags
& F_STATIC
? NULL
: name
->name
;
1295 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1296 arrays
[t
->id
].n
= initsize();
1298 if (flags
& F_EXTERN
|| t
->flags
& T_FUNC
&& !t
->ptr
)
1300 else if (flags
& F_INIT
)
1301 name
->addr
= out_mkdat(varname
, NULL
, sz
, F_GLOBAL(flags
));
1303 name
->addr
= out_mkvar(varname
, sz
, F_GLOBAL(flags
));
1306 initexpr(t
, 0, &name
->addr
, globalinit
);
1309 static void localinit(void *obj
, int off
, struct type
*t
)
1311 long addr
= *(long *) obj
;
1312 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1313 struct type
*t_de
= &arrays
[t
->id
].type
;
1314 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1317 tok_expect(TOK_STR
);
1319 o_localoff(addr
, off
, TYPE_BT(t
));
1320 o_symaddr(out_mkdat(NULL
, buf
, len
, 0), TYPE_BT(t
));
1326 o_localoff(addr
, off
, TYPE_BT(t
));
1334 static void localdef(void *data
, struct name
*name
, unsigned flags
)
1336 struct type
*t
= &name
->type
;
1337 if (flags
& (F_STATIC
| F_EXTERN
)) {
1338 globaldef(data
, name
, flags
);
1341 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1342 arrays
[t
->id
].n
= initsize();
1343 name
->addr
= o_mklocal(type_totsz(&name
->type
));
1345 if (flags
& F_INIT
) {
1346 if (t
->flags
& (T_ARRAY
| T_STRUCT
) && !t
->ptr
) {
1347 o_local(name
->addr
, TYPE_BT(t
));
1348 o_memset(0, type_totsz(t
));
1351 initexpr(t
, 0, &name
->addr
, localinit
);
1355 static void funcdef(char *name
, struct type
*type
, struct name
*args
,
1356 int nargs
, unsigned flags
)
1360 strcpy(global
.name
, name
);
1361 memcpy(&global
.type
, type
, sizeof(*type
));
1362 global
.addr
= o_func_beg(name
, F_GLOBAL(flags
));
1364 global_add(&global
);
1365 ret_bt
= TYPE_BT(&funcs
[type
->id
].ret
);
1366 for (i
= 0; i
< nargs
; i
++) {
1367 args
[i
].addr
= o_arg(i
, type_totsz(&args
[i
].type
));
1368 local_add(&args
[i
]);
1372 static int readargs(struct name
*args
)
1376 while (tok_see() != ')') {
1377 if (!tok_jmp(TOK3("...")))
1379 readname(&args
[nargs
].type
, args
[nargs
].name
, NULL
, 0);
1380 array2ptr(&args
[nargs
].type
);
1386 if (nargs
== 1 && !TYPE_BT(&args
[0].type
))
1391 static int readname(struct type
*main
, char *name
,
1392 struct type
*base
, unsigned flags
)
1394 struct type tpool
[3];
1396 struct type
*type
= &tpool
[npool
++];
1397 struct type
*func
= NULL
;
1398 struct type
*ret
= NULL
;
1402 memset(tpool
, 0, sizeof(tpool
));
1406 if (basetype(type
, &flags
))
1409 memcpy(type
, base
, sizeof(*base
));
1412 if (!tok_jmp('(')) {
1414 type
= &tpool
[npool
++];
1418 if (!tok_jmp(TOK_NAME
) && name
)
1419 strcpy(name
, tok_id());
1420 while (!tok_jmp('[')) {
1426 err("const expr expected\n");
1431 for (i
= nar
- 1; i
>= 0; i
--) {
1432 type
->id
= array_add(type
, arsz
[i
]);
1433 if (type
->flags
& T_FUNC
)
1434 func
= &arrays
[type
->id
].type
;
1435 type
->flags
= T_ARRAY
;
1441 if (tok_see() == '(') {
1442 struct name args
[MAXARGS
];
1443 int nargs
= readargs(args
);
1447 type
= &tpool
[npool
++];
1450 func
->flags
= T_FUNC
;
1452 func
->id
= func_create(ret
, args
, nargs
);
1453 if (fdef
&& tok_see() == '{') {
1454 funcdef(name
, func
, args
, nargs
, flags
);
1458 memcpy(main
, type
, sizeof(*type
));
1462 static int readdefs(void (*def
)(void *data
, struct name
*name
, unsigned flags
),
1467 if (basetype(&base
, &flags
))
1469 while (tok_see() != ';' && tok_see() != '{') {
1472 if (readname(&name
.type
, name
.name
, &base
, flags
))
1476 def(data
, &name
, flags
);
1482 static void typedefdef(void *data
, struct name
*name
, unsigned flags
)
1484 typedef_add(name
->name
, &name
->type
);
1487 static void readstmt(void);
1489 #define MAXCASES (1 << 7)
1491 static void readswitch(void)
1493 int break_beg
= nbreaks
;
1494 long val_addr
= o_mklocal(8);
1495 long matched
[MAXCASES
];
1504 o_local(val_addr
, TYPE_BT(&t
));
1506 o_assign(TYPE_BT(&t
));
1510 while (tok_jmp('}')) {
1512 while (tok_see() == TOK_CASE
|| tok_see() == TOK_DEFAULT
) {
1514 matched
[nmatched
++] = o_jmp(0);
1517 if (!tok_jmp(TOK_CASE
)) {
1521 o_local(val_addr
, TYPE_BT(&t
));
1530 if (!tok_jmp(TOK_DEFAULT
)) {
1535 for (i
= 0; i
< nmatched
; i
++)
1536 o_filljmp(matched
[i
]);
1540 o_rmlocal(val_addr
, 8);
1543 break_fill(o_mklabel(), break_beg
);
1546 #define MAXGOTO (1 << 10)
1548 static struct gotoinfo
{
1554 static struct labelinfo
{
1560 static void goto_add(char *name
)
1562 strcpy(gotos
[ngotos
].name
, name
);
1563 gotos
[ngotos
++].addr
= o_jmp(0);
1566 static void label_add(char *name
)
1568 strcpy(labels
[nlabels
].name
, name
);
1569 labels
[nlabels
++].addr
= o_mklabel();
1572 static void goto_fill(void)
1575 for (i
= 0; i
< ngotos
; i
++)
1576 for (j
= 0; j
< nlabels
; j
++)
1577 if (!strcmp(gotos
[i
].name
, labels
[j
].name
)) {
1578 o_filljmp2(gotos
[i
].addr
, labels
[j
].addr
);
1583 static void readstmt(void)
1587 if (!tok_jmp('{')) {
1588 int _nlocals
= nlocals
;
1589 int _nglobals
= nglobals
;
1590 int _nenums
= nenums
;
1591 int _ntypedefs
= ntypedefs
;
1592 int _nstructs
= nstructs
;
1593 int _nfuncs
= nfuncs
;
1594 int _narrays
= narrays
;
1595 while (tok_jmp('}'))
1599 ntypedefs
= _ntypedefs
;
1600 nstructs
= _nstructs
;
1603 nglobals
= _nglobals
;
1606 if (!readdefs(localdef
, NULL
)) {
1610 if (!tok_jmp(TOK_TYPEDEF
)) {
1611 readdefs(typedefdef
, NULL
);
1615 if (!tok_jmp(TOK_IF
)) {
1622 if (!tok_jmp(TOK_ELSE
)) {
1632 if (!tok_jmp(TOK_WHILE
)) {
1634 int break_beg
= nbreaks
;
1635 int continue_beg
= ncontinues
;
1644 break_fill(o_mklabel(), break_beg
);
1645 continue_fill(l1
, continue_beg
);
1648 if (!tok_jmp(TOK_DO
)) {
1650 int break_beg
= nbreaks
;
1651 int continue_beg
= ncontinues
;
1654 tok_expect(TOK_WHILE
);
1660 break_fill(o_mklabel(), break_beg
);
1661 continue_fill(l2
, continue_beg
);
1664 if (!tok_jmp(TOK_FOR
)) {
1665 long l_check
, l_jump
, j_fail
, j_pass
;
1666 int break_beg
= nbreaks
;
1667 int continue_beg
= ncontinues
;
1670 if (tok_see() != ';')
1673 l_check
= o_mklabel();
1674 if (tok_see() != ';') {
1681 l_jump
= o_mklabel();
1682 if (tok_see() != ')')
1691 break_fill(o_mklabel(), break_beg
);
1692 continue_fill(l_jump
, continue_beg
);
1695 if (!tok_jmp(TOK_SWITCH
)) {
1699 if (!tok_jmp(TOK_RETURN
)) {
1700 int ret
= tok_see() != ';';
1707 if (!tok_jmp(TOK_BREAK
)) {
1709 breaks
[nbreaks
++] = o_jmp(0);
1712 if (!tok_jmp(TOK_CONTINUE
)) {
1714 continues
[ncontinues
++] = o_jmp(0);
1717 if (!tok_jmp(TOK_GOTO
)) {
1718 tok_expect(TOK_NAME
);
1725 if (!tok_jmp(':')) {
1726 label_add(tok_id());
1732 static void readdecl(void)
1734 if (!tok_jmp(TOK_TYPEDEF
)) {
1735 readdefs(typedefdef
, NULL
);
1739 readdefs(globaldef
, NULL
);
1740 if (tok_see() == '{') {
1752 static void parse(void)
1754 while (tok_see() != TOK_EOF
)
1758 int main(int argc
, char *argv
[])
1763 while (i
< argc
&& argv
[i
][0] == '-') {
1764 if (argv
[i
][1] == 'I')
1765 cpp_addpath(argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1766 if (argv
[i
][1] == 'D') {
1767 char *name
= argv
[i
] + 2;
1769 char *eq
= strchr(name
, '=');
1774 cpp_define(name
, def
);
1779 die("neatcc: no file given\n");
1780 if (cpp_init(argv
[i
]))
1781 die("neatcc: cannot open input file\n");
1783 strcpy(obj
, argv
[i
]);
1784 obj
[strlen(obj
) - 1] = 'o';
1785 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);