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)
38 int id
; /* for structs, functions and arrays */
42 static struct type ts
[MAXTMP
];
45 static void ts_push_bt(unsigned bt
)
52 static void ts_push(struct type
*t
)
54 memcpy(&ts
[nts
++], t
, sizeof(*t
));
55 if (t
->flags
& (T_FUNC
| T_ARRAY
) && !t
->ptr
)
59 static void ts_pop(struct type
*type
)
72 static struct name locals
[MAXLOCALS
];
74 static struct name globals
[MAXGLOBALS
];
77 static void local_add(struct name
*name
)
79 memcpy(&locals
[nlocals
++], name
, sizeof(*name
));
82 static int global_find(char *name
)
85 for (i
= 0; i
< nglobals
; i
++)
86 if (!strcmp(name
, globals
[i
].name
))
91 static void global_add(struct name
*name
)
93 int found
= global_find(name
->name
);
94 int i
= found
== -1 ? nglobals
++ : found
;
95 memcpy(&globals
[i
], name
, sizeof(*name
));
98 static void die(char *s
)
104 #define MAXENUMS (1 << 10)
106 static struct enumval
{
112 static void enum_add(char *name
, int val
)
114 struct enumval
*ev
= &enums
[nenums
++];
115 strcpy(ev
->name
, name
);
119 static int enum_find(int *val
, char *name
)
122 for (i
= nenums
- 1; i
>= 0; --i
)
123 if (!strcmp(name
, enums
[i
].name
)) {
130 #define MAXTYPEDEFS (1 << 5)
132 static struct typdefinfo
{
135 } typedefs
[MAXTYPEDEFS
];
136 static int ntypedefs
;
138 static void typedef_add(char *name
, struct type
*type
)
140 struct typdefinfo
*ti
= &typedefs
[ntypedefs
++];
141 strcpy(ti
->name
, name
);
142 memcpy(&ti
->type
, type
, sizeof(*type
));
145 static int typedef_find(char *name
)
148 for (i
= ntypedefs
- 1; i
>= 0; --i
)
149 if (!strcmp(name
, typedefs
[i
].name
))
154 #define MAXARRAYS (1 << 5)
156 static struct array
{
162 static int array_add(struct type
*type
, int n
)
164 struct array
*a
= &arrays
[narrays
++];
165 memcpy(&a
->type
, type
, sizeof(*type
));
170 static void array2ptr(struct type
*t
)
172 if (!(t
->flags
& T_ARRAY
) || t
->ptr
)
174 memcpy(t
, &arrays
[t
->id
].type
, sizeof(*t
));
178 #define MAXTYPES (1 << 7)
179 #define MAXFIELDS (1 << 5)
181 static struct structinfo
{
183 struct name fields
[MAXFIELDS
];
190 static int struct_find(char *name
, int isunion
)
193 for (i
= nstructs
- 1; i
>= 0; --i
)
194 if (*structs
[i
].name
&& !strcmp(name
, structs
[i
].name
) &&
195 structs
[i
].isunion
== isunion
)
198 memset(&structs
[i
], 0, sizeof(structs
[i
]));
199 strcpy(structs
[i
].name
, name
);
200 structs
[i
].isunion
= isunion
;
204 static struct name
*struct_field(int id
, char *name
)
206 struct structinfo
*si
= &structs
[id
];
208 for (i
= 0; i
< si
->nfields
; i
++)
209 if (!strcmp(name
, si
->fields
[i
].name
))
210 return &si
->fields
[i
];
211 die("field not found\n");
214 #define MAXBREAK (1 << 7)
215 static long breaks
[MAXBREAK
];
217 static long continues
[MAXBREAK
];
218 static int ncontinues
;
220 static void break_fill(long addr
, int till
)
223 for (i
= till
; i
< nbreaks
; i
++)
224 o_filljmp2(breaks
[i
], addr
);
228 static void continue_fill(long addr
, int till
)
231 for (i
= till
; i
< ncontinues
; i
++)
232 o_filljmp2(continues
[i
], addr
);
236 static int type_totsz(struct type
*t
)
240 if (t
->flags
& T_ARRAY
)
241 return arrays
[t
->id
].n
* type_totsz(&arrays
[t
->id
].type
);
242 return t
->flags
& T_STRUCT
? structs
[t
->id
].size
: BT_SZ(t
->bt
);
245 static unsigned type_szde(struct type
*t
)
247 if (t
->flags
& T_ARRAY
)
248 return t
->ptr
> 0 ? 8 : TYPE_SZ(&arrays
[t
->id
].type
);
250 return t
->ptr
> 1 ? 8 : BT_SZ(t
->bt
);
253 static int tok_jmp(int tok
)
255 if (tok_see() != tok
)
261 static void tok_expect(int tok
)
263 if (tok_get() != tok
)
264 die("syntax error\n");
267 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
269 unsigned s1
= BT_SZ(bt1
);
270 unsigned s2
= BT_SZ(bt2
);
271 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
274 static void ts_binop(void (*o_sth
)(void))
280 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
283 static int shifts(int n
)
292 static void ts_binop_add(void (*o_sth
)(void))
299 if (!t1
.ptr
&& !t2
.ptr
) {
301 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
304 if (t1
.ptr
&& !t2
.ptr
) {
310 if (!t1
.ptr
&& t2
.ptr
)
311 if (type_szde(&t2
) > 1) {
312 o_num(shifts(type_szde(&t2
)), 1);
316 if (t1
.ptr
&& t2
.ptr
) {
317 o_num(shifts(type_szde(&t1
)), 1);
319 ts_push_bt(4 | BT_SIGNED
);
325 static void structdef(void *data
, struct name
*name
, unsigned flags
)
327 struct structinfo
*si
= data
;
330 if (si
->size
< type_totsz(&name
->type
))
331 si
->size
= type_totsz(&name
->type
);
333 name
->addr
= si
->size
;
334 si
->size
+= type_totsz(&name
->type
);
336 memcpy(&si
->fields
[si
->nfields
++], name
, sizeof(*name
));
339 static int readdefs(void (*def
)(void *, struct name
*, unsigned f
), void *data
);
341 static int struct_create(char *name
, int isunion
)
343 int id
= struct_find(name
, isunion
);
344 struct structinfo
*si
= &structs
[id
];
346 while (tok_jmp('}')) {
347 readdefs(structdef
, si
);
353 static void readexpr(void);
355 static void enum_create(void)
359 while (tok_jmp('}')) {
361 tok_expect(TOK_NAME
);
362 strcpy(name
, tok_id());
363 if (tok_see() == '=') {
368 die("const expr expected!\n");
375 static int basetype(struct type
*type
, unsigned *flags
)
382 char name
[NAMELEN
] = "";
414 isunion
= tok_get() == TOK_UNION
;
415 if (!tok_jmp(TOK_NAME
))
416 strcpy(name
, tok_id());
417 if (tok_see() == '{')
418 type
->id
= struct_create(name
, isunion
);
420 type
->id
= struct_find(name
, isunion
);
421 type
->flags
|= T_STRUCT
;
427 if (tok_see() == '{')
429 type
->bt
= 4 | BT_SIGNED
;
432 if (tok_see() == TOK_NAME
) {
433 int id
= typedef_find(tok_id());
436 memcpy(type
, &typedefs
[id
].type
,
449 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
453 static void readptrs(struct type
*type
)
455 while (!tok_jmp('*'))
459 static int readtype(struct type
*type
)
462 if (basetype(type
, &flags
))
468 static void readpre(void);
470 static void readprimary(void)
474 if (!tok_jmp(TOK_NUM
)) {
475 ts_push_bt(4 | BT_SIGNED
);
476 o_num(tok_num(), 4 | BT_SIGNED
);
479 if (!tok_jmp(TOK_STR
)) {
483 t
.bt
= 1 | BT_SIGNED
;
488 o_symaddr(o_mkdat(NULL
, buf
, len
, 0), TYPE_BT(&t
));
492 if (!tok_jmp(TOK_NAME
)) {
494 for (i
= nlocals
- 1; i
>= 0; --i
) {
495 struct type
*t
= &locals
[i
].type
;
496 if (!strcmp(locals
[i
].name
, tok_id())) {
497 o_local(locals
[i
].addr
, TYPE_BT(t
));
502 if ((n
= global_find(tok_id())) != -1) {
503 struct type
*t
= &globals
[n
].type
;
504 o_symaddr(globals
[n
].addr
, TYPE_BT(t
));
508 if (!enum_find(&n
, tok_id())) {
509 ts_push_bt(4 | BT_SIGNED
);
510 o_num(n
, 4 | BT_SIGNED
);
513 strcpy(name
.name
, tok_id());
514 name
.addr
= o_mkundef(name
.name
);
517 o_symaddr(name
.addr
, 8);
528 if (!t
.ptr
|| !o
.ptr
)
538 void arrayderef(struct type
*t
)
540 int sz
= type_totsz(t
);
549 static void inc_post(void (*op
)(void))
551 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
565 static void readfield(void)
569 tok_expect(TOK_NAME
);
571 field
= struct_field(t
.id
, tok_id());
573 o_num(field
->addr
, 4);
576 o_deref(TYPE_BT(&field
->type
));
577 ts_push(&field
->type
);
580 #define MAXFUNCS (1 << 10)
582 static struct funcinfo
{
583 struct type args
[MAXFIELDS
];
588 static unsigned ret_bt
;
590 static int func_create(struct type
*ret
, struct name
*args
, int nargs
)
592 struct funcinfo
*fi
= &funcs
[nfuncs
++];
594 memcpy(&fi
->ret
, ret
, sizeof(*ret
));
595 for (i
= 0; i
< nargs
; i
++)
596 memcpy(&fi
->args
[i
], &args
[i
].type
, sizeof(*ret
));
601 static void readcall(void)
604 unsigned bt
[MAXARGS
];
608 if (tok_see() != ')') {
611 bt
[argc
++] = TYPE_BT(&t
);
613 while (!tok_jmp(',')) {
616 bt
[argc
++] = TYPE_BT(&t
);
620 if (t
.flags
& T_FUNC
&& t
.ptr
> 0)
622 fi
= t
.flags
& T_FUNC
? &funcs
[t
.id
] : NULL
;
624 for (i
= 0; i
< fi
->nargs
; i
++)
625 bt
[i
] = TYPE_BT(&fi
->args
[i
]);
626 o_call(argc
, bt
, fi
? TYPE_BT(&fi
->ret
) : 4 | BT_SIGNED
);
630 ts_push_bt(4 | BT_SIGNED
);
633 static void readpost(void)
653 if (!tok_jmp(TOK2("++"))) {
657 if (!tok_jmp(TOK2("--"))) {
666 if (!tok_jmp(TOK2("->"))) {
674 static void inc_pre(void (*op
)(void))
676 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
687 static void readpre(void)
693 if (!(type
.flags
& T_FUNC
) && !type
.ptr
)
704 if (!(t
.flags
& T_FUNC
) || t
.ptr
> 0) {
706 o_deref(TYPE_BT(&t
));
716 ts_push_bt(4 | BT_SIGNED
);
729 if (!tok_jmp(TOK2("++"))) {
733 if (!tok_jmp(TOK2("--"))) {
737 if (!tok_jmp(TOK_SIZEOF
)) {
739 int op
= !tok_jmp('(');
741 int nogen
= !o_nogen();
749 o_num(type_totsz(&t
), 4);
757 static void readmul(void)
780 static void readadd(void)
798 static void shift(void (*op
)(void))
805 ts_push_bt(TYPE_BT(&t
));
808 static void readshift(void)
812 if (!tok_jmp(TOK2("<<"))) {
816 if (!tok_jmp(TOK2(">>"))) {
824 static void cmp(void (*op
)(void))
830 ts_push_bt(4 | BT_SIGNED
);
833 static void readcmp(void)
845 if (!tok_jmp(TOK2("<="))) {
849 if (!tok_jmp(TOK2(">="))) {
857 static void eq(void (*op
)(void))
863 ts_push_bt(4 | BT_SIGNED
);
866 static void readeq(void)
870 if (!tok_jmp(TOK2("=="))) {
874 if (!tok_jmp(TOK2("!="))) {
882 static void readbitand(void)
885 while (!tok_jmp('&')) {
891 static void readxor(void)
894 while (!tok_jmp('^')) {
900 static void readbitor(void)
903 while (!tok_jmp('|')) {
909 #define MAXCOND (1 << 5)
911 static void readand(void)
918 if (tok_see() != TOK2("&&"))
920 conds
[nconds
++] = o_jz(0);
922 while (!tok_jmp(TOK2("&&"))) {
924 conds
[nconds
++] = o_jz(0);
927 o_num(1, 4 | BT_SIGNED
);
930 for (i
= 0; i
< nconds
; i
++)
932 o_num(0, 4 | BT_SIGNED
);
935 ts_push_bt(4 | BT_SIGNED
);
938 static void reador(void)
945 if (tok_see() != TOK2("||"))
947 conds
[nconds
++] = o_jnz(0);
949 while (!tok_jmp(TOK2("||"))) {
951 conds
[nconds
++] = o_jnz(0);
954 o_num(0, 4 | BT_SIGNED
);
957 for (i
= 0; i
< nconds
; i
++)
959 o_num(1, 4 | BT_SIGNED
);
962 ts_push_bt(4 | BT_SIGNED
);
965 static void readcexpr(void)
973 cexpr
= !o_popnum(&c
);
1012 static void opassign(void (*bop
)(void (*op
)(void)), void (*op
)(void))
1014 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
1022 static void doassign(void)
1026 if (!t
.ptr
&& t
.flags
& T_STRUCT
)
1027 o_memcpy(type_totsz(&t
));
1029 o_assign(TYPE_BT(&ts
[nts
- 1]));
1032 static void readexpr(void)
1035 if (!tok_jmp('=')) {
1040 if (!tok_jmp(TOK2("+="))) {
1041 opassign(ts_binop_add
, o_add
);
1044 if (!tok_jmp(TOK2("-="))) {
1045 opassign(ts_binop_add
, o_sub
);
1048 if (!tok_jmp(TOK2("*="))) {
1049 opassign(ts_binop
, o_mul
);
1052 if (!tok_jmp(TOK2("/="))) {
1053 opassign(ts_binop
, o_div
);
1056 if (!tok_jmp(TOK2("%="))) {
1057 opassign(ts_binop
, o_mod
);
1060 if (!tok_jmp(TOK3("<<="))) {
1061 opassign(ts_binop
, o_shl
);
1064 if (!tok_jmp(TOK3(">>="))) {
1065 opassign(ts_binop
, o_shr
);
1068 if (!tok_jmp(TOK3("&="))) {
1069 opassign(ts_binop
, o_and
);
1072 if (!tok_jmp(TOK3("|="))) {
1073 opassign(ts_binop
, o_or
);
1076 if (!tok_jmp(TOK3("^="))) {
1077 opassign(ts_binop
, o_xor
);
1082 static void readestmt(void)
1088 } while (!tok_jmp(','));
1091 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1093 static void globaldef(void *data
, struct name
*name
, unsigned flags
)
1095 char *varname
= flags
& F_STATIC
? NULL
: name
->name
;
1096 name
->addr
= o_mkvar(varname
, type_totsz(&name
->type
), F_GLOBAL(flags
));
1100 static void o_localoff(long addr
, int off
, unsigned bt
)
1111 static struct type
*innertype(struct type
*t
)
1113 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
1114 return innertype(&arrays
[t
->id
].type
);
1118 static void initexpr(struct type
*t
, long addr
, int off
)
1120 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1121 struct type
*t_de
= &arrays
[t
->id
].type
;
1122 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1125 tok_expect(TOK_STR
);
1127 o_localoff(addr
, off
, TYPE_BT(t
));
1128 o_symaddr(o_mkdat(NULL
, buf
, len
, 0), TYPE_BT(t
));
1131 o_localoff(addr
, off
+ len
, TYPE_BT(t
));
1132 o_memset(0, arrays
[t
->id
].n
- len
);
1138 o_localoff(addr
, off
, TYPE_BT(t
));
1146 if (!t
->ptr
&& t
->flags
& T_STRUCT
) {
1147 struct structinfo
*si
= &structs
[t
->id
];
1149 for (i
= 0; i
< si
->nfields
; i
++) {
1150 struct name
*field
= &si
->fields
[i
];
1151 if (!tok_jmp('.')) {
1152 tok_expect(TOK_NAME
);
1153 field
= struct_field(t
->id
, tok_id());
1156 initexpr(&field
->type
, addr
, off
+ field
->addr
);
1157 if (tok_jmp(',') || tok_see() == '}')
1160 } else if (t
->flags
& T_ARRAY
) {
1161 struct type
*t_de
= &arrays
[t
->id
].type
;
1163 for (i
= 0; ; i
++) {
1165 struct type
*it
= t_de
;
1166 if (!tok_jmp('[')) {
1173 if (tok_see() != '{')
1174 it
= innertype(t_de
);
1175 initexpr(it
, addr
, off
+ type_totsz(it
) * idx
);
1176 if (tok_jmp(',') || tok_see() == '}')
1183 static void localdef(void *data
, struct name
*name
, unsigned flags
)
1185 if (flags
& F_STATIC
) {
1186 globaldef(data
, name
, flags
);
1189 name
->addr
= o_mklocal(type_totsz(&name
->type
));
1191 if (flags
& F_INIT
) {
1192 struct type
*t
= &name
->type
;
1193 if (tok_see() == '{') {
1194 o_local(name
->addr
, TYPE_BT(t
));
1195 o_memset(0, type_totsz(t
));
1198 initexpr(t
, name
->addr
, 0);
1202 static void funcdef(struct name
*name
, struct name
*args
,
1203 int nargs
, unsigned flags
)
1206 name
->addr
= o_func_beg(name
->name
, F_GLOBAL(flags
));
1208 ret_bt
= TYPE_BT(&funcs
[name
->type
.id
].ret
);
1209 for (i
= 0; i
< nargs
; i
++) {
1210 args
[i
].addr
= o_arg(i
, type_totsz(&args
[i
].type
));
1211 local_add(&args
[i
]);
1215 static int readargs(struct name
*args
)
1219 while (tok_see() != ')') {
1220 readtype(&args
[nargs
].type
);
1221 if (!tok_jmp(TOK_NAME
))
1222 strcpy(args
[nargs
++].name
, tok_id());
1230 static int readdefs(void (*def
)(void *data
, struct name
*name
, unsigned flags
),
1235 if (basetype(&base
, &flags
))
1237 while (tok_see() != ';' && tok_see() != '{') {
1238 struct type tpool
[3];
1241 struct type
*type
= &tpool
[npool
++];
1242 struct type
*func
= NULL
;
1243 struct type
*ret
= NULL
;
1244 memset(tpool
, 0, sizeof(tpool
));
1245 memcpy(type
, &base
, sizeof(base
));
1247 if (!tok_jmp('(')) {
1249 type
= &tpool
[npool
++];
1253 tok_expect(TOK_NAME
);
1254 strcpy(name
.name
, tok_id());
1255 while (!tok_jmp('[')) {
1260 die("const expr expected\n");
1261 type
->id
= array_add(type
, n
);
1262 if (type
->flags
& T_FUNC
)
1263 func
= &arrays
[type
->id
].type
;
1264 type
->flags
= T_ARRAY
;
1271 if (tok_see() == '(') {
1272 struct name args
[MAXARGS
];
1273 int nargs
= readargs(args
);
1277 type
= &tpool
[npool
++];
1280 func
->flags
= T_FUNC
;
1282 func
->id
= func_create(ret
, args
, nargs
);
1283 if (fdef
&& tok_see() == '{') {
1284 memcpy(&name
.type
, func
, sizeof(*func
));
1285 funcdef(&name
, args
, nargs
, flags
);
1289 memcpy(&name
.type
, type
, sizeof(*type
));
1292 def(data
, &name
, flags
);
1298 static void typedefdef(void *data
, struct name
*name
, unsigned flags
)
1300 typedef_add(name
->name
, &name
->type
);
1303 #define MAXCASES (1 << 7)
1305 static void readstmt(void);
1307 static void readswitch(void)
1309 int break_beg
= nbreaks
;
1310 long val_addr
= o_mklocal(8);
1311 long matched
[MAXCASES
];
1320 o_local(val_addr
, TYPE_BT(&t
));
1322 o_assign(TYPE_BT(&t
));
1326 while (tok_jmp('}')) {
1328 while (tok_see() == TOK_CASE
|| tok_see() == TOK_DEFAULT
) {
1330 matched
[nmatched
++] = o_jmp(0);
1333 if (!tok_jmp(TOK_CASE
)) {
1335 o_local(val_addr
, TYPE_BT(&t
));
1344 if (!tok_jmp(TOK_DEFAULT
)) {
1349 for (i
= 0; i
< nmatched
; i
++)
1350 o_filljmp(matched
[i
]);
1354 o_rmlocal(val_addr
, 8);
1357 break_fill(o_mklabel(), break_beg
);
1360 #define MAXGOTO (1 << 7)
1362 static struct gotoinfo
{
1368 static struct labelinfo
{
1374 static void goto_add(char *name
)
1376 strcpy(gotos
[ngotos
].name
, name
);
1377 gotos
[ngotos
++].addr
= o_jmp(0);
1380 static void label_add(char *name
)
1382 strcpy(labels
[nlabels
].name
, name
);
1383 labels
[nlabels
++].addr
= o_mklabel();
1386 static void goto_fill(void)
1389 for (i
= 0; i
< ngotos
; i
++)
1390 for (j
= 0; j
< nlabels
; j
++)
1391 if (!strcmp(gotos
[i
].name
, labels
[j
].name
)) {
1392 o_filljmp2(gotos
[i
].addr
, labels
[j
].addr
);
1397 static void readstmt(void)
1401 if (!tok_jmp('{')) {
1402 int _nlocals
= nlocals
;
1403 int _nglobals
= nglobals
;
1404 int _nenums
= nenums
;
1405 int _ntypedefs
= ntypedefs
;
1406 int _nstructs
= nstructs
;
1407 int _nfuncs
= nfuncs
;
1408 int _narrays
= narrays
;
1409 while (tok_jmp('}'))
1413 ntypedefs
= _ntypedefs
;
1414 nstructs
= _nstructs
;
1417 nglobals
= _nglobals
;
1420 if (!readdefs(localdef
, NULL
)) {
1424 if (!tok_jmp(TOK_TYPEDEF
)) {
1425 readdefs(typedefdef
, NULL
);
1429 if (!tok_jmp(TOK_IF
)) {
1436 if (!tok_jmp(TOK_ELSE
)) {
1446 if (!tok_jmp(TOK_WHILE
)) {
1448 int break_beg
= nbreaks
;
1449 int continue_beg
= ncontinues
;
1458 break_fill(o_mklabel(), break_beg
);
1459 continue_fill(l1
, continue_beg
);
1462 if (!tok_jmp(TOK_DO
)) {
1464 int break_beg
= nbreaks
;
1465 int continue_beg
= ncontinues
;
1468 tok_expect(TOK_WHILE
);
1474 break_fill(o_mklabel(), break_beg
);
1475 continue_fill(l2
, continue_beg
);
1478 if (!tok_jmp(TOK_FOR
)) {
1479 long check
, jump
, end
, body
;
1480 int break_beg
= nbreaks
;
1481 int continue_beg
= ncontinues
;
1483 if (tok_see() != ';')
1486 check
= o_mklabel();
1487 if (tok_see() != ';')
1493 if (tok_see() != ')')
1501 break_fill(o_mklabel(), break_beg
);
1502 continue_fill(jump
, continue_beg
);
1505 if (!tok_jmp(TOK_SWITCH
)) {
1509 if (!tok_jmp(TOK_RETURN
)) {
1510 int ret
= tok_see() != ';';
1517 if (!tok_jmp(TOK_BREAK
)) {
1519 breaks
[nbreaks
++] = o_jmp(0);
1522 if (!tok_jmp(TOK_CONTINUE
)) {
1524 continues
[ncontinues
++] = o_jmp(0);
1527 if (!tok_jmp(TOK_GOTO
)) {
1528 tok_expect(TOK_NAME
);
1535 if (!tok_jmp(':')) {
1536 label_add(tok_id());
1542 static void readdecl(void)
1544 if (!tok_jmp(TOK_TYPEDEF
)) {
1545 readdefs(typedefdef
, NULL
);
1549 readdefs(globaldef
, NULL
);
1550 if (tok_see() == '{') {
1562 static void parse(void)
1564 while (tok_see() != TOK_EOF
)
1568 int main(int argc
, char *argv
[])
1573 while (i
< argc
&& argv
[i
][0] == '-')
1576 die("no file given\n");
1577 ifd
= open(argv
[i
], O_RDONLY
);
1582 strcpy(obj
, argv
[i
]);
1583 obj
[strlen(obj
) - 1] = 'o';
1584 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);