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.
13 #include <sys/types.h>
17 #define MAXLOCALS (1 << 10)
18 #define MAXGLOBALS (1 << 10)
19 #define MAXARGS (1 << 5)
21 #define TYPE_BT(t) ((t)->ptr ? LONGSZ : (t)->bt)
22 #define TYPE_SZ(t) ((t)->ptr ? LONGSZ : (t)->bt & BT_SZMASK)
36 int id
; /* for structs, functions and arrays */
40 static struct type ts
[MAXTMP
];
43 static void ts_push_bt(unsigned bt
)
50 static void ts_push(struct type
*t
)
52 memcpy(&ts
[nts
++], t
, sizeof(*t
));
53 if (t
->flags
& (T_FUNC
| T_ARRAY
) && !t
->ptr
)
57 static void ts_pop(struct type
*type
)
67 int len
= cpp_loc(err
, tok_addr());
68 strcpy(err
+ len
, msg
);
76 int unused
; /* unreferenced external symbols */
79 static struct name locals
[MAXLOCALS
];
81 static struct name globals
[MAXGLOBALS
];
84 static void local_add(struct name
*name
)
86 if (nlocals
>= MAXLOCALS
)
87 err("nomem: MAXLOCALS reached!\n");
88 memcpy(&locals
[nlocals
++], name
, sizeof(*name
));
91 static int global_find(char *name
)
94 for (i
= 0; i
< nglobals
; i
++)
95 if (!strcmp(name
, globals
[i
].name
))
100 static void global_add(struct name
*name
)
102 int found
= global_find(name
->name
);
103 int i
= found
== -1 ? nglobals
++ : found
;
104 if (nglobals
>= MAXGLOBALS
)
105 err("nomem: MAXGLOBALS reached!\n");
106 memcpy(&globals
[i
], name
, sizeof(*name
));
109 #define MAXENUMS (1 << 10)
111 static struct enumval
{
117 static void enum_add(char *name
, int val
)
119 struct enumval
*ev
= &enums
[nenums
++];
120 if (nenums
>= MAXENUMS
)
121 err("nomem: MAXENUMS reached!\n");
122 strcpy(ev
->name
, name
);
126 static int enum_find(int *val
, char *name
)
129 for (i
= nenums
- 1; i
>= 0; --i
)
130 if (!strcmp(name
, enums
[i
].name
)) {
137 #define MAXTYPEDEFS (1 << 10)
139 static struct typdefinfo
{
142 } typedefs
[MAXTYPEDEFS
];
143 static int ntypedefs
;
145 static void typedef_add(char *name
, struct type
*type
)
147 struct typdefinfo
*ti
= &typedefs
[ntypedefs
++];
148 if (ntypedefs
>= MAXTYPEDEFS
)
149 err("nomem: MAXTYPEDEFS reached!\n");
150 strcpy(ti
->name
, name
);
151 memcpy(&ti
->type
, type
, sizeof(*type
));
154 static int typedef_find(char *name
)
157 for (i
= ntypedefs
- 1; i
>= 0; --i
)
158 if (!strcmp(name
, typedefs
[i
].name
))
163 #define MAXARRAYS (1 << 10)
165 static struct array
{
171 static int array_add(struct type
*type
, int n
)
173 struct array
*a
= &arrays
[narrays
++];
174 if (narrays
>= MAXARRAYS
)
175 err("nomem: MAXARRAYS reached!\n");
176 memcpy(&a
->type
, type
, sizeof(*type
));
181 static void array2ptr(struct type
*t
)
183 if (!(t
->flags
& T_ARRAY
) || t
->ptr
)
185 memcpy(t
, &arrays
[t
->id
].type
, sizeof(*t
));
189 #define MAXSTRUCTS (1 << 10)
190 #define MAXFIELDS (1 << 7)
192 static struct structinfo
{
194 struct name fields
[MAXFIELDS
];
198 } structs
[MAXSTRUCTS
];
201 static int struct_find(char *name
, int isunion
)
204 for (i
= nstructs
- 1; i
>= 0; --i
)
205 if (*structs
[i
].name
&& !strcmp(name
, structs
[i
].name
) &&
206 structs
[i
].isunion
== isunion
)
209 if (nstructs
>= MAXSTRUCTS
)
210 err("nomem: MAXTYPES reached!\n");
211 memset(&structs
[i
], 0, sizeof(structs
[i
]));
212 strcpy(structs
[i
].name
, name
);
213 structs
[i
].isunion
= isunion
;
217 static struct name
*struct_field(int id
, char *name
)
219 struct structinfo
*si
= &structs
[id
];
221 for (i
= 0; i
< si
->nfields
; i
++)
222 if (!strcmp(name
, si
->fields
[i
].name
))
223 return &si
->fields
[i
];
224 err("field not found\n");
227 #define MAXBREAK (1 << 7)
229 static long breaks
[MAXBREAK
];
231 static long continues
[MAXBREAK
];
232 static int ncontinues
;
234 static void break_fill(long addr
, int till
)
237 for (i
= till
; i
< nbreaks
; i
++)
238 o_filljmp2(breaks
[i
], addr
);
242 static void continue_fill(long addr
, int till
)
245 for (i
= till
; i
< ncontinues
; i
++)
246 o_filljmp2(continues
[i
], addr
);
250 static int type_totsz(struct type
*t
)
254 if (t
->flags
& T_ARRAY
)
255 return arrays
[t
->id
].n
* type_totsz(&arrays
[t
->id
].type
);
256 return t
->flags
& T_STRUCT
? structs
[t
->id
].size
: BT_SZ(t
->bt
);
259 static unsigned type_szde(struct type
*t
)
264 return type_totsz(&de
);
267 static int tok_jmp(int tok
)
269 if (tok_see() != tok
)
275 static void tok_expect(int tok
)
277 if (tok_get() != tok
)
278 err("syntax error\n");
281 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
283 unsigned s1
= BT_SZ(bt1
);
284 unsigned s2
= BT_SZ(bt2
);
285 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
288 static void ts_binop(int op
)
294 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
297 static void ts_addop(int op
)
304 if (!t1
.ptr
&& !t2
.ptr
) {
306 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
309 if (t1
.ptr
&& !t2
.ptr
)
311 if (!t1
.ptr
&& t2
.ptr
)
312 if (type_szde(&t2
) > 1) {
313 o_num(type_szde(&t2
), 4);
316 if (t1
.ptr
&& !t2
.ptr
)
319 if (t1
.ptr
&& t2
.ptr
) {
320 int sz
= type_szde(&t1
);
325 ts_push_bt(4 | BT_SIGNED
);
327 ts_push(t1
.ptr
? &t1
: &t2
);
331 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
332 #define MIN(a, b) ((a) < (b) ? (a) : (b))
334 static int type_alignment(struct type
*t
)
336 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
337 return type_alignment(&arrays
[t
->id
].type
);
338 if (t
->flags
& T_STRUCT
&& !t
->ptr
)
339 return type_alignment(&structs
[t
->id
].fields
[0].type
);
340 return MIN(LONGSZ
, type_totsz(t
));
343 static void structdef(void *data
, struct name
*name
, unsigned flags
)
345 struct structinfo
*si
= data
;
348 if (si
->size
< type_totsz(&name
->type
))
349 si
->size
= type_totsz(&name
->type
);
351 struct type
*t
= &name
->type
;
352 int alignment
= type_alignment(t
);
353 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
354 alignment
= MIN(LONGSZ
, type_totsz(&arrays
[t
->id
].type
));
355 si
->size
= ALIGN(si
->size
, alignment
);
356 name
->addr
= si
->size
;
357 si
->size
+= type_totsz(&name
->type
);
359 memcpy(&si
->fields
[si
->nfields
++], name
, sizeof(*name
));
362 static int readdefs(void (*def
)(void *, struct name
*, unsigned f
), void *data
);
364 static int struct_create(char *name
, int isunion
)
366 int id
= struct_find(name
, isunion
);
367 struct structinfo
*si
= &structs
[id
];
369 while (tok_jmp('}')) {
370 readdefs(structdef
, si
);
376 static void readexpr(void);
378 static void enum_create(void)
382 while (tok_jmp('}')) {
384 tok_expect(TOK_NAME
);
385 strcpy(name
, tok_id());
386 if (tok_see() == '=') {
391 err("const expr expected!\n");
398 static int basetype(struct type
*type
, unsigned *flags
)
405 char name
[NAMELEN
] = "";
442 isunion
= tok_get() == TOK_UNION
;
443 if (!tok_jmp(TOK_NAME
))
444 strcpy(name
, tok_id());
445 if (tok_see() == '{')
446 type
->id
= struct_create(name
, isunion
);
448 type
->id
= struct_find(name
, isunion
);
449 type
->flags
|= T_STRUCT
;
455 if (tok_see() == '{')
457 type
->bt
= 4 | BT_SIGNED
;
460 if (tok_see() == TOK_NAME
) {
461 int id
= typedef_find(tok_id());
464 memcpy(type
, &typedefs
[id
].type
,
477 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
481 static int readname(struct type
*main
, char *name
,
482 struct type
*base
, unsigned flags
);
484 static int readtype(struct type
*type
)
486 return readname(type
, NULL
, NULL
, 0);
489 static void readptrs(struct type
*type
)
491 while (!tok_jmp('*')) {
498 /* used to differenciate labels from case and cond exprs */
502 static void readpre(void);
504 static void readprimary(void)
507 if (!tok_jmp(TOK_NUM
)) {
509 int bt
= tok_num(&n
);
514 if (!tok_jmp(TOK_STR
)) {
518 t
.bt
= 1 | BT_SIGNED
;
523 o_symaddr(out_mkdat(NULL
, buf
, len
, 0), TYPE_BT(&t
));
527 if (!tok_jmp(TOK_NAME
)) {
528 struct name unkn
= {""};
529 char *name
= unkn
.name
;
531 strcpy(name
, tok_id());
532 /* don't search for labels here */
533 if (!ncexpr
&& !caseexpr
&& tok_see() == ':')
535 for (i
= nlocals
- 1; i
>= 0; --i
) {
536 struct type
*t
= &locals
[i
].type
;
537 if (!strcmp(locals
[i
].name
, name
)) {
538 o_local(locals
[i
].addr
, TYPE_BT(t
));
543 if ((n
= global_find(name
)) != -1) {
544 struct name
*g
= &globals
[n
];
545 struct type
*t
= &g
->type
;
548 if (t
->flags
& T_FUNC
&& !t
->ptr
)
549 g
->addr
= out_mkundef(name
, 0);
551 g
->addr
= out_mkundef(name
, type_totsz(t
));
553 o_symaddr(g
->addr
, TYPE_BT(t
));
557 if (!enum_find(&n
, name
)) {
558 ts_push_bt(4 | BT_SIGNED
);
559 o_num(n
, 4 | BT_SIGNED
);
562 if (tok_see() != '(')
563 err("unknown symbol\n");
564 unkn
.addr
= out_mkundef(unkn
.name
, 0);
567 o_symaddr(unkn
.addr
, LONGSZ
);
578 if (!t
.ptr
|| !o
.ptr
)
588 void arrayderef(struct type
*t
)
590 int sz
= type_totsz(t
);
599 static void inc_post(int inc_one
, int inc_many
)
601 struct type
*t
= &ts
[nts
- 1];
602 int sz
= type_szde(t
);
606 if (!t
->ptr
|| sz
== 1) {
612 o_assign(TYPE_BT(t
));
617 static void readfield(void)
621 tok_expect(TOK_NAME
);
624 field
= struct_field(t
.id
, tok_id());
626 o_num(field
->addr
, 4);
629 o_deref(TYPE_BT(&field
->type
));
630 ts_push(&field
->type
);
633 #define MAXFUNCS (1 << 10)
635 static struct funcinfo
{
636 struct type args
[MAXFIELDS
];
641 static unsigned ret_bt
;
643 static int func_create(struct type
*ret
, struct name
*args
, int nargs
)
645 struct funcinfo
*fi
= &funcs
[nfuncs
++];
647 if (nfuncs
>= MAXFUNCS
)
648 err("nomem: MAXFUNCS reached!\n");
649 memcpy(&fi
->ret
, ret
, sizeof(*ret
));
650 for (i
= 0; i
< nargs
; i
++)
651 memcpy(&fi
->args
[i
], &args
[i
].type
, sizeof(*ret
));
656 static void readcall(void)
659 unsigned bt
[MAXARGS
];
664 if (t
.flags
& T_FUNC
&& t
.ptr
> 0)
666 fi
= t
.flags
& T_FUNC
? &funcs
[t
.id
] : NULL
;
667 if (tok_see() != ')') {
670 bt
[argc
++] = TYPE_BT(&t
);
672 while (!tok_jmp(',')) {
675 bt
[argc
++] = TYPE_BT(&t
);
679 for (i
= 0; i
< fi
->nargs
; i
++)
680 bt
[i
] = TYPE_BT(&fi
->args
[i
]);
681 o_call(argc
, bt
, fi
? TYPE_BT(&fi
->ret
) : 4 | BT_SIGNED
);
685 ts_push_bt(4 | BT_SIGNED
);
688 static void readpost(void)
708 if (!tok_jmp(TOK2("++"))) {
709 inc_post(O_INC
, O_ADD
);
712 if (!tok_jmp(TOK2("--"))) {
713 inc_post(O_DEC
, O_SUB
);
721 if (!tok_jmp(TOK2("->"))) {
729 static void inc_pre(int inc_one
, int inc_many
)
735 sz
= (t
->flags
& T_ARRAY
|| t
->ptr
) ? type_szde(t
) : 1;
742 o_assign(TYPE_BT(t
));
746 static void readpre(void)
763 o_deref(TYPE_BT(&t
));
772 ts_push_bt(4 | BT_SIGNED
);
785 if (!tok_jmp(TOK2("++"))) {
786 inc_pre(O_INC
, O_ADD
);
789 if (!tok_jmp(TOK2("--"))) {
790 inc_pre(O_DEC
, O_SUB
);
793 if (!tok_jmp(TOK_SIZEOF
)) {
795 int op
= !tok_jmp('(');
797 int nogen
= !o_nogen();
805 o_num(type_totsz(&t
), 4);
813 static void readmul(void)
836 static void readadd(void)
854 static void shift(int op
)
861 ts_push_bt(TYPE_BT(&t
));
864 static void readshift(void)
868 if (!tok_jmp(TOK2("<<"))) {
872 if (!tok_jmp(TOK2(">>"))) {
880 static void cmp(int op
)
886 ts_push_bt(4 | BT_SIGNED
);
889 static void readcmp(void)
901 if (!tok_jmp(TOK2("<="))) {
905 if (!tok_jmp(TOK2(">="))) {
913 static void eq(int op
)
919 ts_push_bt(4 | BT_SIGNED
);
922 static void readeq(void)
926 if (!tok_jmp(TOK2("=="))) {
930 if (!tok_jmp(TOK2("!="))) {
938 static void readbitand(void)
941 while (!tok_jmp('&')) {
947 static void readxor(void)
950 while (!tok_jmp('^')) {
956 static void readbitor(void)
959 while (!tok_jmp('|')) {
965 #define MAXCOND (1 << 7)
967 static void readand(void)
974 if (tok_see() != TOK2("&&"))
977 conds
[nconds
++] = o_jz(0);
979 while (!tok_jmp(TOK2("&&"))) {
981 conds
[nconds
++] = o_jz(0);
984 o_num(1, 4 | BT_SIGNED
);
987 for (i
= 0; i
< nconds
; i
++)
989 o_num(0, 4 | BT_SIGNED
);
993 ts_push_bt(4 | BT_SIGNED
);
996 static void reador(void)
1003 if (tok_see() != TOK2("||"))
1006 conds
[nconds
++] = o_jnz(0);
1008 while (!tok_jmp(TOK2("||"))) {
1010 conds
[nconds
++] = o_jnz(0);
1013 o_num(0, 4 | BT_SIGNED
);
1016 for (i
= 0; i
< nconds
; i
++)
1017 o_filljmp(conds
[i
]);
1018 o_num(1, 4 | BT_SIGNED
);
1022 ts_push_bt(4 | BT_SIGNED
);
1025 static int readcexpr_const(void)
1052 static void readcexpr(void)
1061 if (readcexpr_const()) {
1078 static void opassign(int op
, int ptrop
)
1080 struct type
*t
= &ts
[nts
- 1];
1081 if (ptrop
&& (t
->flags
& T_ARRAY
|| t
->ptr
)) {
1085 o_assign(TYPE_BT(&ts
[nts
- 1]));
1094 static void doassign(void)
1098 if (!t
.ptr
&& t
.flags
& T_STRUCT
)
1099 o_memcpy(type_totsz(&t
));
1101 o_assign(TYPE_BT(&ts
[nts
- 1]));
1104 static void readexpr(void)
1107 if (!tok_jmp('=')) {
1112 if (!tok_jmp(TOK2("+="))) {
1116 if (!tok_jmp(TOK2("-="))) {
1120 if (!tok_jmp(TOK2("*="))) {
1124 if (!tok_jmp(TOK2("/="))) {
1128 if (!tok_jmp(TOK2("%="))) {
1132 if (!tok_jmp(TOK3("<<="))) {
1136 if (!tok_jmp(TOK3(">>="))) {
1140 if (!tok_jmp(TOK3("&="))) {
1144 if (!tok_jmp(TOK3("|="))) {
1148 if (!tok_jmp(TOK3("^="))) {
1154 static void readestmt(void)
1160 } while (!tok_jmp(','));
1163 static void o_localoff(long addr
, int off
, unsigned bt
)
1174 static struct type
*innertype(struct type
*t
)
1176 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
1177 return innertype(&arrays
[t
->id
].type
);
1181 static void initexpr(struct type
*t
, int off
, void *obj
,
1182 void (*set
)(void *obj
, int off
, struct type
*t
))
1188 if (!t
->ptr
&& t
->flags
& T_STRUCT
) {
1189 struct structinfo
*si
= &structs
[t
->id
];
1191 for (i
= 0; i
< si
->nfields
; i
++) {
1192 struct name
*field
= &si
->fields
[i
];
1193 if (!tok_jmp('.')) {
1194 tok_expect(TOK_NAME
);
1195 field
= struct_field(t
->id
, tok_id());
1198 initexpr(&field
->type
, off
+ field
->addr
, obj
, set
);
1199 if (tok_jmp(',') || tok_see() == '}')
1202 } else if (t
->flags
& T_ARRAY
) {
1203 struct type
*t_de
= &arrays
[t
->id
].type
;
1205 for (i
= 0; ; i
++) {
1207 struct type
*it
= t_de
;
1208 if (!tok_jmp('[')) {
1215 if (tok_see() != '{')
1216 it
= innertype(t_de
);
1217 initexpr(it
, off
+ type_totsz(it
) * idx
, obj
, set
);
1218 if (tok_jmp(',') || tok_see() == '}')
1225 static void jumpbrace(void)
1228 while (tok_see() != '}' || depth
--)
1229 if (tok_get() == '{')
1234 static int initsize(void)
1236 long addr
= tok_addr();
1238 if (!tok_jmp(TOK_STR
)) {
1245 while (tok_jmp('}')) {
1247 if (!tok_jmp('[')) {
1256 while (tok_see() != '}' && tok_see() != ',')
1257 if (tok_get() == '{')
1266 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1268 static void globalinit(void *obj
, int off
, struct type
*t
)
1270 long addr
= *(long *) obj
;
1271 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1272 struct type
*t_de
= &arrays
[t
->id
].type
;
1273 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1276 tok_expect(TOK_STR
);
1278 out_datcpy(addr
, off
, buf
, len
);
1283 o_datset(addr
, off
, TYPE_BT(t
));
1287 static void globaldef(void *data
, struct name
*name
, unsigned flags
)
1289 struct type
*t
= &name
->type
;
1290 char *varname
= flags
& F_STATIC
? NULL
: name
->name
;
1292 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1293 if (~flags
& F_EXTERN
)
1294 arrays
[t
->id
].n
= initsize();
1296 if (flags
& F_EXTERN
|| t
->flags
& T_FUNC
&& !t
->ptr
)
1298 else if (flags
& F_INIT
)
1299 name
->addr
= out_mkdat(varname
, NULL
, sz
, F_GLOBAL(flags
));
1301 name
->addr
= out_mkvar(varname
, sz
, F_GLOBAL(flags
));
1304 initexpr(t
, 0, &name
->addr
, globalinit
);
1307 static void localinit(void *obj
, int off
, struct type
*t
)
1309 long addr
= *(long *) obj
;
1310 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1311 struct type
*t_de
= &arrays
[t
->id
].type
;
1312 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1315 tok_expect(TOK_STR
);
1317 o_localoff(addr
, off
, TYPE_BT(t
));
1318 o_symaddr(out_mkdat(NULL
, buf
, len
, 0), TYPE_BT(t
));
1324 o_localoff(addr
, off
, TYPE_BT(t
));
1332 static void localdef(void *data
, struct name
*name
, unsigned flags
)
1334 struct type
*t
= &name
->type
;
1335 if (flags
& (F_STATIC
| F_EXTERN
)) {
1336 globaldef(data
, name
, flags
);
1339 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1340 arrays
[t
->id
].n
= initsize();
1341 name
->addr
= o_mklocal(type_totsz(&name
->type
));
1343 if (flags
& F_INIT
) {
1344 if (t
->flags
& (T_ARRAY
| T_STRUCT
) && !t
->ptr
) {
1345 o_local(name
->addr
, TYPE_BT(t
));
1346 o_memset(0, type_totsz(t
));
1349 initexpr(t
, 0, &name
->addr
, localinit
);
1353 static void funcdef(char *name
, struct type
*type
, struct name
*args
,
1354 int nargs
, unsigned flags
)
1358 strcpy(global
.name
, name
);
1359 memcpy(&global
.type
, type
, sizeof(*type
));
1360 global
.addr
= o_func_beg(name
, F_GLOBAL(flags
));
1362 global_add(&global
);
1363 ret_bt
= TYPE_BT(&funcs
[type
->id
].ret
);
1364 for (i
= 0; i
< nargs
; i
++) {
1365 args
[i
].addr
= o_arg(i
, type_totsz(&args
[i
].type
));
1366 local_add(&args
[i
]);
1370 static int readargs(struct name
*args
)
1374 while (tok_see() != ')') {
1375 if (!tok_jmp(TOK3("...")))
1377 readname(&args
[nargs
].type
, args
[nargs
].name
, NULL
, 0);
1378 array2ptr(&args
[nargs
].type
);
1384 if (nargs
== 1 && !TYPE_BT(&args
[0].type
))
1389 static int readname(struct type
*main
, char *name
,
1390 struct type
*base
, unsigned flags
)
1392 struct type tpool
[3];
1394 struct type
*type
= &tpool
[npool
++];
1395 struct type
*func
= NULL
;
1396 struct type
*ret
= NULL
;
1400 memset(tpool
, 0, sizeof(tpool
));
1404 if (basetype(type
, &flags
))
1407 memcpy(type
, base
, sizeof(*base
));
1410 if (!tok_jmp('(')) {
1412 type
= &tpool
[npool
++];
1416 if (!tok_jmp(TOK_NAME
) && name
)
1417 strcpy(name
, tok_id());
1418 while (!tok_jmp('[')) {
1424 err("const expr expected\n");
1429 for (i
= nar
- 1; i
>= 0; i
--) {
1430 type
->id
= array_add(type
, arsz
[i
]);
1431 if (func
&& i
== nar
- 1)
1432 func
= &arrays
[type
->id
].type
;
1433 type
->flags
= T_ARRAY
;
1439 if (tok_see() == '(') {
1440 struct name args
[MAXARGS
];
1441 int nargs
= readargs(args
);
1445 type
= &tpool
[npool
++];
1448 func
->flags
= T_FUNC
;
1450 func
->id
= func_create(ret
, args
, nargs
);
1451 if (fdef
&& tok_see() == '{') {
1452 funcdef(name
, func
, args
, nargs
, flags
);
1456 memcpy(main
, type
, sizeof(*type
));
1460 static int readdefs(void (*def
)(void *data
, struct name
*name
, unsigned flags
),
1464 unsigned base_flags
;
1465 if (basetype(&base
, &base_flags
))
1467 while (tok_see() != ';' && tok_see() != '{') {
1469 unsigned flags
= base_flags
;
1471 if (readname(&name
.type
, name
.name
, &base
, flags
))
1475 def(data
, &name
, flags
);
1481 static void typedefdef(void *data
, struct name
*name
, unsigned flags
)
1483 typedef_add(name
->name
, &name
->type
);
1486 static void readstmt(void);
1488 #define MAXCASES (1 << 7)
1490 static void readswitch(void)
1492 int break_beg
= nbreaks
;
1493 long val_addr
= o_mklocal(LONGSZ
);
1494 long matched
[MAXCASES
];
1503 o_local(val_addr
, TYPE_BT(&t
));
1505 o_assign(TYPE_BT(&t
));
1509 while (tok_jmp('}')) {
1511 while (tok_see() == TOK_CASE
|| tok_see() == TOK_DEFAULT
) {
1513 matched
[nmatched
++] = o_jmp(0);
1516 if (!tok_jmp(TOK_CASE
)) {
1520 o_local(val_addr
, TYPE_BT(&t
));
1529 if (!tok_jmp(TOK_DEFAULT
)) {
1534 for (i
= 0; i
< nmatched
; i
++)
1535 o_filljmp(matched
[i
]);
1539 o_rmlocal(val_addr
, LONGSZ
);
1542 break_fill(o_mklabel(), break_beg
);
1545 #define MAXGOTO (1 << 10)
1547 static struct gotoinfo
{
1553 static struct labelinfo
{
1559 static void goto_add(char *name
)
1561 strcpy(gotos
[ngotos
].name
, name
);
1562 gotos
[ngotos
++].addr
= o_jmp(0);
1565 static void label_add(char *name
)
1567 strcpy(labels
[nlabels
].name
, name
);
1568 labels
[nlabels
++].addr
= o_mklabel();
1571 static void goto_fill(void)
1574 for (i
= 0; i
< ngotos
; i
++)
1575 for (j
= 0; j
< nlabels
; j
++)
1576 if (!strcmp(gotos
[i
].name
, labels
[j
].name
)) {
1577 o_filljmp2(gotos
[i
].addr
, labels
[j
].addr
);
1582 static void readstmt(void)
1586 if (!tok_jmp('{')) {
1587 int _nlocals
= nlocals
;
1588 int _nglobals
= nglobals
;
1589 int _nenums
= nenums
;
1590 int _ntypedefs
= ntypedefs
;
1591 int _nstructs
= nstructs
;
1592 int _nfuncs
= nfuncs
;
1593 int _narrays
= narrays
;
1594 while (tok_jmp('}'))
1598 ntypedefs
= _ntypedefs
;
1599 nstructs
= _nstructs
;
1602 nglobals
= _nglobals
;
1605 if (!readdefs(localdef
, NULL
)) {
1609 if (!tok_jmp(TOK_TYPEDEF
)) {
1610 readdefs(typedefdef
, NULL
);
1614 if (!tok_jmp(TOK_IF
)) {
1621 if (!tok_jmp(TOK_ELSE
)) {
1631 if (!tok_jmp(TOK_WHILE
)) {
1633 int break_beg
= nbreaks
;
1634 int continue_beg
= ncontinues
;
1643 break_fill(o_mklabel(), break_beg
);
1644 continue_fill(l1
, continue_beg
);
1647 if (!tok_jmp(TOK_DO
)) {
1649 int break_beg
= nbreaks
;
1650 int continue_beg
= ncontinues
;
1653 tok_expect(TOK_WHILE
);
1659 break_fill(o_mklabel(), break_beg
);
1660 continue_fill(l2
, continue_beg
);
1663 if (!tok_jmp(TOK_FOR
)) {
1664 long l_check
, l_jump
, j_fail
, j_pass
;
1665 int break_beg
= nbreaks
;
1666 int continue_beg
= ncontinues
;
1669 if (tok_see() != ';')
1672 l_check
= o_mklabel();
1673 if (tok_see() != ';') {
1680 l_jump
= o_mklabel();
1681 if (tok_see() != ')')
1690 break_fill(o_mklabel(), break_beg
);
1691 continue_fill(l_jump
, continue_beg
);
1694 if (!tok_jmp(TOK_SWITCH
)) {
1698 if (!tok_jmp(TOK_RETURN
)) {
1699 int ret
= tok_see() != ';';
1706 if (!tok_jmp(TOK_BREAK
)) {
1708 breaks
[nbreaks
++] = o_jmp(0);
1711 if (!tok_jmp(TOK_CONTINUE
)) {
1713 continues
[ncontinues
++] = o_jmp(0);
1716 if (!tok_jmp(TOK_GOTO
)) {
1717 tok_expect(TOK_NAME
);
1724 if (!tok_jmp(':')) {
1725 label_add(tok_id());
1731 static void readdecl(void)
1733 if (!tok_jmp(TOK_TYPEDEF
)) {
1734 readdefs(typedefdef
, NULL
);
1738 readdefs(globaldef
, NULL
);
1739 if (tok_see() == '{') {
1751 static void parse(void)
1753 while (tok_see() != TOK_EOF
)
1757 int main(int argc
, char *argv
[])
1762 while (i
< argc
&& argv
[i
][0] == '-') {
1763 if (argv
[i
][1] == 'I')
1764 cpp_addpath(argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1765 if (argv
[i
][1] == 'D') {
1766 char *name
= argv
[i
] + 2;
1768 char *eq
= strchr(name
, '=');
1773 cpp_define(name
, def
);
1778 die("neatcc: no file given\n");
1779 if (cpp_init(argv
[i
]))
1780 die("neatcc: cannot open input file\n");
1782 strcpy(obj
, argv
[i
]);
1783 obj
[strlen(obj
) - 1] = 'o';
1784 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);