2 * neatcc - a small and simple C compiler
4 * Copyright (C) 2010-2011 Ali Gholami Rudi
6 * This program is released under GNU GPL version 2.
14 #include <sys/types.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)
38 int id
; /* for structs, functions and arrays */
39 int addr
; /* the address is passed to gen.c; deref for value */
43 static struct type ts
[MAXTMP
];
46 static void ts_push_bt(unsigned 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
)
66 static void ts_pop(struct type
*type
)
76 int len
= cpp_loc(err
, tok_addr());
77 strcpy(err
+ len
, msg
);
83 char elfname
[NAMELEN
]; /* local elf name for static variables in function */
85 long addr
; /* local stack offset, global data addr, struct offset */
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
) {
193 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 void ts_de(int deref
)
278 struct type
*t
= &ts
[nts
- 1];
279 if (deref
&& t
->addr
&& (!(t
->flags
& T_ARRAY
) || (t
->ptr
)))
284 static void ts_pop_de(struct type
*t
)
291 if (t
->addr
&& (t
->ptr
|| !(t
->flags
& T_FUNC
)))
296 static void ts_pop_de2(struct type
*t1
, struct type
*t2
)
304 static int tok_jmp(int tok
)
306 if (tok_see() != tok
)
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
)
329 ts_pop_de2(&t1
, &t2
);
330 if (op
== O_DIV
|| op
== O_MOD
)
333 bt
= bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
));
334 o_bop(op
| (bt
& BT_SIGNED
? O_SIGNED
: 0));
338 static void ts_addop(int op
)
341 ts_pop_de2(&t1
, &t2
);
342 if (!t1
.ptr
&& !t2
.ptr
) {
344 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
347 if (t1
.ptr
&& !t2
.ptr
)
349 if (!t1
.ptr
&& t2
.ptr
)
350 if (type_szde(&t2
) > 1) {
351 o_num(type_szde(&t2
));
354 if (t1
.ptr
&& !t2
.ptr
)
357 if (t1
.ptr
&& t2
.ptr
) {
358 int sz
= type_szde(&t1
);
363 ts_push_bt(4 | BT_SIGNED
);
365 ts_push(t1
.ptr
? &t1
: &t2
);
369 #define ALIGN(x, a) (((x) + (a) - 1) & ~((a) - 1))
370 #define MIN(a, b) ((a) < (b) ? (a) : (b))
372 static int type_alignment(struct type
*t
)
374 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
375 return type_alignment(&arrays
[t
->id
].type
);
376 if (t
->flags
& T_STRUCT
&& !t
->ptr
)
377 return type_alignment(&structs
[t
->id
].fields
[0].type
);
378 return MIN(LONGSZ
, type_totsz(t
));
381 static void structdef(void *data
, struct name
*name
, unsigned flags
)
383 struct structinfo
*si
= data
;
386 if (si
->size
< type_totsz(&name
->type
))
387 si
->size
= type_totsz(&name
->type
);
389 struct type
*t
= &name
->type
;
390 int alignment
= type_alignment(t
);
391 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
392 alignment
= MIN(LONGSZ
, type_totsz(&arrays
[t
->id
].type
));
393 si
->size
= ALIGN(si
->size
, alignment
);
394 name
->addr
= si
->size
;
395 si
->size
+= type_totsz(&name
->type
);
397 memcpy(&si
->fields
[si
->nfields
++], name
, sizeof(*name
));
400 static int readdefs(void (*def
)(void *, struct name
*, unsigned f
), void *data
);
402 static int struct_create(char *name
, int isunion
)
404 int id
= struct_find(name
, isunion
);
405 struct structinfo
*si
= &structs
[id
];
407 while (tok_jmp('}')) {
408 readdefs(structdef
, si
);
414 static void readexpr(void);
416 static void enum_create(void)
420 while (tok_jmp('}')) {
422 tok_expect(TOK_NAME
);
423 strcpy(name
, tok_id());
428 err("const expr expected!\n");
435 static int basetype(struct type
*type
, unsigned *flags
)
442 char name
[NAMELEN
] = "";
480 isunion
= tok_get() == TOK_UNION
;
481 if (!tok_jmp(TOK_NAME
))
482 strcpy(name
, tok_id());
483 if (tok_see() == '{')
484 type
->id
= struct_create(name
, isunion
);
486 type
->id
= struct_find(name
, isunion
);
487 type
->flags
|= T_STRUCT
;
493 if (tok_see() == '{')
495 type
->bt
= 4 | BT_SIGNED
;
498 if (tok_see() == TOK_NAME
) {
499 int id
= typedef_find(tok_id());
502 memcpy(type
, &typedefs
[id
].type
,
515 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
519 static int readname(struct type
*main
, char *name
,
520 struct type
*base
, unsigned flags
);
522 static int readtype(struct type
*type
)
524 return readname(type
, NULL
, NULL
, 0);
527 static void readptrs(struct type
*type
)
529 while (!tok_jmp('*')) {
536 /* used to differenciate labels from case and cond exprs */
540 static void readpre(void);
542 static char *tmp_str(char *buf
, int len
)
544 static char name
[NAMELEN
];
547 sprintf(name
, "__neatcc.s%d", id
++);
548 dat
= o_mkdat(name
, len
, 0);
549 memcpy(dat
, buf
, len
);
553 static void readprimary(void)
556 if (!tok_jmp(TOK_NUM
)) {
558 int bt
= tok_num(&n
);
563 if (!tok_jmp(TOK_STR
)) {
567 t
.bt
= 1 | BT_SIGNED
;
573 o_sym(tmp_str(buf
, len
));
576 if (!tok_jmp(TOK_NAME
)) {
577 struct name unkn
= {""};
578 char *name
= unkn
.name
;
580 strcpy(name
, tok_id());
581 /* don't search for labels here */
582 if (!ncexpr
&& !caseexpr
&& tok_see() == ':')
584 for (i
= nlocals
- 1; i
>= 0; --i
) {
585 struct type
*t
= &locals
[i
].type
;
586 if (!strcmp(locals
[i
].name
, name
)) {
587 o_local(locals
[i
].addr
);
592 if ((n
= global_find(name
)) != -1) {
593 struct name
*g
= &globals
[n
];
594 struct type
*t
= &g
->type
;
595 char *elfname
= *g
->elfname
? g
->elfname
: g
->name
;
600 if (!enum_find(&n
, name
)) {
601 ts_push_bt(4 | BT_SIGNED
);
605 if (tok_see() != '(')
606 err("unknown symbol\n");
620 if (!t
.ptr
|| !o
.ptr
)
630 static void arrayderef(void)
636 if (!(t
.flags
& T_ARRAY
) && t
.addr
) {
638 o_deref(TYPE_BT(&t
));
653 static void inc_post(int op
)
655 struct type t
= ts
[nts
- 1];
656 /* pushing the value before inc */
662 /* increment by 1 or pointer size */
666 o_num(t
.ptr
> 0 ? type_szde(&t
) : 1);
670 o_assign(TYPE_BT(&t
));
674 static void readfield(void)
678 tok_expect(TOK_NAME
);
681 field
= struct_field(t
.id
, tok_id());
686 ts_push_addr(&field
->type
);
689 #define MAXFUNCS (1 << 10)
691 static struct funcinfo
{
692 struct type args
[MAXFIELDS
];
699 static int func_create(struct type
*ret
, struct name
*args
, int nargs
)
701 struct funcinfo
*fi
= &funcs
[nfuncs
++];
703 if (nfuncs
>= MAXFUNCS
)
704 err("nomem: MAXFUNCS reached!\n");
705 memcpy(&fi
->ret
, ret
, sizeof(*ret
));
706 for (i
= 0; i
< nargs
; i
++)
707 memcpy(&fi
->args
[i
], &args
[i
].type
, sizeof(*ret
));
712 static void readcall(void)
718 if (t
.flags
& T_FUNC
&& t
.ptr
> 0)
720 fi
= t
.flags
& T_FUNC
? &funcs
[t
.id
] : NULL
;
721 if (tok_see() != ')') {
726 } while (!tok_jmp(','));
729 o_call(argc
, fi
? TYPE_BT(&fi
->ret
) : 4 | BT_SIGNED
);
731 if (TYPE_BT(&fi
->ret
))
732 o_cast(TYPE_BT(&fi
->ret
));
735 ts_push_bt(4 | BT_SIGNED
);
739 static void readpost(void)
753 if (!tok_jmp(TOK2("++"))) {
757 if (!tok_jmp(TOK2("--"))) {
765 if (!tok_jmp(TOK2("->"))) {
774 static void inc_pre(int op
)
778 /* copy the destination */
780 ts_push(&ts
[nts
- 1]);
781 /* increment by 1 or pointer size */
783 o_num(t
.ptr
> 0 ? type_szde(&t
) : 1);
785 /* assign the result */
786 o_assign(TYPE_BT(&t
));
790 static void readpre(void)
797 die("cannot use the address\n");
809 err("dereferencing non-pointer\n");
811 o_deref(TYPE_BT(&t
));
821 ts_push_bt(4 | BT_SIGNED
);
836 if (!tok_jmp(TOK2("++"))) {
840 if (!tok_jmp(TOK2("--"))) {
844 if (!tok_jmp(TOK_SIZEOF
)) {
846 int op
= !tok_jmp('(');
855 o_num(type_totsz(&t
));
863 static void readmul(void)
886 static void readadd(void)
904 static void shift(int op
)
908 ts_pop_de2(NULL
, &t
);
909 o_bop(op
| (BT_SIGNED
& TYPE_BT(&t
) ? O_SIGNED
: 0));
910 ts_push_bt(TYPE_BT(&t
));
913 static void readshift(void)
917 if (!tok_jmp(TOK2("<<"))) {
921 if (!tok_jmp(TOK2(">>"))) {
929 static void cmp(int op
)
934 ts_pop_de2(&t1
, &t2
);
935 bt
= bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
));
936 o_bop(op
| (bt
& BT_SIGNED
? O_SIGNED
: 0));
937 ts_push_bt(4 | BT_SIGNED
);
940 static void readcmp(void)
952 if (!tok_jmp(TOK2("<="))) {
956 if (!tok_jmp(TOK2(">="))) {
964 static void eq(int op
)
967 ts_pop_de2(NULL
, NULL
);
969 ts_push_bt(4 | BT_SIGNED
);
972 static void readeq(void)
976 if (!tok_jmp(TOK2("=="))) {
980 if (!tok_jmp(TOK2("!="))) {
988 static void readbitand(void)
991 while (!tok_jmp('&')) {
997 static void readxor(void)
1000 while (!tok_jmp('^')) {
1006 static void readbitor(void)
1009 while (!tok_jmp('|')) {
1015 #define MAXCOND (1 << 7)
1017 static void readand(void)
1019 long conds
[MAXCOND
];
1024 if (tok_see() != TOK2("&&"))
1028 conds
[nconds
++] = o_jz(0);
1029 while (!tok_jmp(TOK2("&&"))) {
1032 conds
[nconds
++] = o_jz(0);
1037 for (i
= 0; i
< nconds
; i
++)
1038 o_filljmp(conds
[i
]);
1043 ts_push_bt(4 | BT_SIGNED
);
1046 static void reador(void)
1048 long conds
[MAXCOND
];
1053 if (tok_see() != TOK2("||"))
1057 conds
[nconds
++] = o_jnz(0);
1058 while (!tok_jmp(TOK2("||"))) {
1061 conds
[nconds
++] = o_jnz(0);
1066 for (i
= 0; i
< nconds
; i
++)
1067 o_filljmp(conds
[i
]);
1072 ts_push_bt(4 | BT_SIGNED
);
1075 static int readcexpr_const(void)
1099 static void readcexpr(void)
1108 if (readcexpr_const()) {
1127 static void opassign(int op
, int ptrop
)
1129 struct type t
= ts
[nts
- 1];
1134 o_assign(TYPE_BT(&ts
[nts
- 1]));
1139 static void doassign(void)
1141 struct type t
= ts
[nts
- 1];
1142 if (!t
.ptr
&& t
.flags
& T_STRUCT
) {
1144 o_num(type_totsz(&t
));
1148 o_assign(TYPE_BT(&ts
[nts
- 1]));
1153 static void readexpr(void)
1156 if (!tok_jmp('=')) {
1161 if (!tok_jmp(TOK2("+="))) {
1165 if (!tok_jmp(TOK2("-="))) {
1169 if (!tok_jmp(TOK2("*="))) {
1173 if (!tok_jmp(TOK2("/="))) {
1177 if (!tok_jmp(TOK2("%="))) {
1181 if (!tok_jmp(TOK3("<<="))) {
1185 if (!tok_jmp(TOK3(">>="))) {
1189 if (!tok_jmp(TOK3("&="))) {
1193 if (!tok_jmp(TOK3("|="))) {
1197 if (!tok_jmp(TOK3("^="))) {
1203 static void readestmt(void)
1209 } while (!tok_jmp(','));
1212 static void o_localoff(long addr
, int off
)
1221 static struct type
*innertype(struct type
*t
)
1223 if (t
->flags
& T_ARRAY
&& !t
->ptr
)
1224 return innertype(&arrays
[t
->id
].type
);
1228 static void initexpr(struct type
*t
, int off
, void *obj
,
1229 void (*set
)(void *obj
, int off
, struct type
*t
))
1235 if (!t
->ptr
&& t
->flags
& T_STRUCT
) {
1236 struct structinfo
*si
= &structs
[t
->id
];
1238 for (i
= 0; i
< si
->nfields
; i
++) {
1239 struct name
*field
= &si
->fields
[i
];
1240 if (!tok_jmp('.')) {
1241 tok_expect(TOK_NAME
);
1242 field
= struct_field(t
->id
, tok_id());
1245 initexpr(&field
->type
, off
+ field
->addr
, obj
, set
);
1246 if (tok_jmp(',') || tok_see() == '}')
1249 } else if (t
->flags
& T_ARRAY
) {
1250 struct type
*t_de
= &arrays
[t
->id
].type
;
1252 for (i
= 0; ; i
++) {
1254 struct type
*it
= t_de
;
1255 if (!tok_jmp('[')) {
1262 if (tok_see() != '{')
1263 it
= innertype(t_de
);
1264 initexpr(it
, off
+ type_totsz(it
) * idx
, obj
, set
);
1265 if (tok_jmp(',') || tok_see() == '}')
1272 static void jumpbrace(void)
1275 while (tok_see() != '}' || depth
--)
1276 if (tok_get() == '{')
1281 static int initsize(void)
1283 long addr
= tok_addr();
1285 if (!tok_jmp(TOK_STR
)) {
1292 while (tok_jmp('}')) {
1294 if (!tok_jmp('[')) {
1303 while (tok_see() != '}' && tok_see() != ',')
1304 if (tok_get() == '{')
1313 #define F_GLOBAL(flags) (!((flags) & F_STATIC))
1315 static void globalinit(void *obj
, int off
, struct type
*t
)
1317 struct name
*name
= obj
;
1318 char *elfname
= *name
->elfname
? name
->elfname
: name
->name
;
1319 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1320 struct type
*t_de
= &arrays
[t
->id
].type
;
1321 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1324 tok_expect(TOK_STR
);
1326 memcpy((void *) name
->addr
+ off
, buf
, len
);
1331 o_datset(elfname
, off
, TYPE_BT(t
));
1335 static void globaldef(void *data
, struct name
*name
, unsigned flags
)
1337 struct type
*t
= &name
->type
;
1338 char *elfname
= *name
->elfname
? name
->elfname
: name
->name
;
1340 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1341 if (~flags
& F_EXTERN
)
1342 arrays
[t
->id
].n
= initsize();
1344 if (!(flags
& F_EXTERN
) && (!(t
->flags
& T_FUNC
) || t
->ptr
)) {
1346 name
->addr
= (long) o_mkdat(elfname
, sz
, F_GLOBAL(flags
));
1348 o_mkbss(elfname
, sz
, F_GLOBAL(flags
));
1352 initexpr(t
, 0, name
, globalinit
);
1355 static void localinit(void *obj
, int off
, struct type
*t
)
1357 long addr
= *(long *) obj
;
1358 if (t
->flags
& T_ARRAY
&& tok_see() == TOK_STR
) {
1359 struct type
*t_de
= &arrays
[t
->id
].type
;
1360 if (!t_de
->ptr
&& !t_de
->flags
&& TYPE_SZ(t_de
) == 1) {
1363 tok_expect(TOK_STR
);
1365 o_localoff(addr
, off
);
1366 o_sym(tmp_str(buf
, len
));
1373 o_localoff(addr
, off
);
1381 /* current function name */
1382 static char func_name
[NAMELEN
];
1384 static void localdef(void *data
, struct name
*name
, unsigned flags
)
1386 struct type
*t
= &name
->type
;
1387 if ((flags
& F_EXTERN
) || (t
->flags
& T_FUNC
) && !t
->ptr
) {
1391 if (flags
& F_STATIC
) {
1392 sprintf(name
->elfname
, "__neatcc.%s.%s", func_name
, name
->name
);
1393 globaldef(data
, name
, flags
);
1396 if (t
->flags
& T_ARRAY
&& !t
->ptr
&& !arrays
[t
->id
].n
)
1397 arrays
[t
->id
].n
= initsize();
1398 name
->addr
= o_mklocal(type_totsz(&name
->type
));
1400 if (flags
& F_INIT
) {
1401 if (t
->flags
& (T_ARRAY
| T_STRUCT
) && !t
->ptr
) {
1402 o_local(name
->addr
);
1404 o_num(type_totsz(t
));
1408 initexpr(t
, 0, &name
->addr
, localinit
);
1412 static void funcdef(char *name
, struct type
*type
, struct name
*args
,
1413 int nargs
, int varg
, unsigned flags
)
1415 struct name global
= {""};
1417 strcpy(global
.name
, name
);
1418 strcpy(func_name
, name
);
1419 memcpy(&global
.type
, type
, sizeof(*type
));
1420 o_func_beg(name
, nargs
, F_GLOBAL(flags
), varg
);
1421 global_add(&global
);
1422 for (i
= 0; i
< nargs
; i
++) {
1423 args
[i
].addr
= o_arg2loc(i
);
1424 local_add(&args
[i
]);
1428 static int readargs(struct name
*args
, int *varg
)
1433 while (tok_see() != ')') {
1434 if (!tok_jmp(TOK3("..."))) {
1438 readname(&args
[nargs
].type
, args
[nargs
].name
, NULL
, 0);
1439 array2ptr(&args
[nargs
].type
);
1445 if (nargs
== 1 && !TYPE_BT(&args
[0].type
))
1450 static int readname(struct type
*main
, char *name
,
1451 struct type
*base
, unsigned flags
)
1453 struct type tpool
[3];
1455 struct type
*type
= &tpool
[npool
++];
1456 struct type
*func
= NULL
;
1457 struct type
*ret
= NULL
;
1461 memset(tpool
, 0, sizeof(tpool
));
1465 if (basetype(type
, &flags
))
1468 memcpy(type
, base
, sizeof(*base
));
1471 if (!tok_jmp('(')) {
1473 type
= &tpool
[npool
++];
1477 if (!tok_jmp(TOK_NAME
) && name
)
1478 strcpy(name
, tok_id());
1479 while (!tok_jmp('[')) {
1485 err("const expr expected\n");
1490 for (i
= nar
- 1; i
>= 0; i
--) {
1491 type
->id
= array_add(type
, arsz
[i
]);
1492 if (func
&& i
== nar
- 1)
1493 func
= &arrays
[type
->id
].type
;
1494 type
->flags
= T_ARRAY
;
1500 if (tok_see() == '(') {
1501 struct name args
[MAXARGS
] = {{""}};
1503 int nargs
= readargs(args
, &varg
);
1507 type
= &tpool
[npool
++];
1510 func
->flags
= T_FUNC
;
1512 func
->id
= func_create(ret
, args
, nargs
);
1513 if (fdef
&& tok_see() == '{') {
1514 funcdef(name
, func
, args
, nargs
, varg
, flags
);
1518 memcpy(main
, type
, sizeof(*type
));
1522 static int readdefs(void (*def
)(void *data
, struct name
*name
, unsigned flags
),
1526 unsigned base_flags
;
1527 if (basetype(&base
, &base_flags
))
1529 while (tok_see() != ';' && tok_see() != '{') {
1530 struct name name
= {{""}};
1531 unsigned flags
= base_flags
;
1532 if (readname(&name
.type
, name
.name
, &base
, flags
))
1536 def(data
, &name
, flags
);
1542 static void typedefdef(void *data
, struct name
*name
, unsigned flags
)
1544 typedef_add(name
->name
, &name
->type
);
1547 static void readstmt(void);
1549 #define MAXCASES (1 << 7)
1551 static void readswitch(void)
1553 int break_beg
= nbreaks
;
1554 long val_addr
= o_mklocal(LONGSZ
);
1555 long matched
[MAXCASES
];
1566 o_assign(TYPE_BT(&t
));
1571 while (tok_jmp('}')) {
1573 while (tok_see() == TOK_CASE
|| tok_see() == TOK_DEFAULT
) {
1575 matched
[nmatched
++] = o_jmp(0);
1578 if (!tok_jmp(TOK_CASE
)) {
1584 o_deref(TYPE_BT(&t
));
1592 if (!tok_jmp(TOK_DEFAULT
)) {
1597 for (i
= 0; i
< nmatched
; i
++)
1598 o_filljmp(matched
[i
]);
1602 o_rmlocal(val_addr
, LONGSZ
);
1605 break_fill(o_mklabel(), break_beg
);
1608 #define MAXGOTO (1 << 10)
1610 static struct gotoinfo
{
1616 static struct labelinfo
{
1622 static void goto_add(char *name
)
1624 strcpy(gotos
[ngotos
].name
, name
);
1625 gotos
[ngotos
++].addr
= o_jmp(0);
1628 static void label_add(char *name
)
1630 strcpy(labels
[nlabels
].name
, name
);
1631 labels
[nlabels
++].addr
= o_mklabel();
1634 static void goto_fill(void)
1637 for (i
= 0; i
< ngotos
; i
++)
1638 for (j
= 0; j
< nlabels
; j
++)
1639 if (!strcmp(gotos
[i
].name
, labels
[j
].name
)) {
1640 o_filljmp2(gotos
[i
].addr
, labels
[j
].addr
);
1645 static void readstmt(void)
1649 if (!tok_jmp('{')) {
1650 int _nlocals
= nlocals
;
1651 int _nglobals
= nglobals
;
1652 int _nenums
= nenums
;
1653 int _ntypedefs
= ntypedefs
;
1654 int _nstructs
= nstructs
;
1655 int _nfuncs
= nfuncs
;
1656 int _narrays
= narrays
;
1657 while (tok_jmp('}'))
1661 ntypedefs
= _ntypedefs
;
1662 nstructs
= _nstructs
;
1665 nglobals
= _nglobals
;
1668 if (!readdefs(localdef
, NULL
)) {
1672 if (!tok_jmp(TOK_TYPEDEF
)) {
1673 readdefs(typedefdef
, NULL
);
1677 if (!tok_jmp(TOK_IF
)) {
1685 if (!tok_jmp(TOK_ELSE
)) {
1695 if (!tok_jmp(TOK_WHILE
)) {
1697 int break_beg
= nbreaks
;
1698 int continue_beg
= ncontinues
;
1708 break_fill(o_mklabel(), break_beg
);
1709 continue_fill(l1
, continue_beg
);
1712 if (!tok_jmp(TOK_DO
)) {
1714 int break_beg
= nbreaks
;
1715 int continue_beg
= ncontinues
;
1718 tok_expect(TOK_WHILE
);
1725 break_fill(o_mklabel(), break_beg
);
1726 continue_fill(l2
, continue_beg
);
1729 if (!tok_jmp(TOK_FOR
)) {
1730 long l_check
, l_jump
, j_fail
, j_pass
;
1731 int break_beg
= nbreaks
;
1732 int continue_beg
= ncontinues
;
1735 if (tok_see() != ';')
1738 l_check
= o_mklabel();
1739 if (tok_see() != ';') {
1747 l_jump
= o_mklabel();
1748 if (tok_see() != ')')
1757 break_fill(o_mklabel(), break_beg
);
1758 continue_fill(l_jump
, continue_beg
);
1761 if (!tok_jmp(TOK_SWITCH
)) {
1765 if (!tok_jmp(TOK_RETURN
)) {
1766 int ret
= tok_see() != ';';
1775 if (!tok_jmp(TOK_BREAK
)) {
1777 breaks
[nbreaks
++] = o_jmp(0);
1780 if (!tok_jmp(TOK_CONTINUE
)) {
1782 continues
[ncontinues
++] = o_jmp(0);
1785 if (!tok_jmp(TOK_GOTO
)) {
1786 tok_expect(TOK_NAME
);
1793 if (!tok_jmp(':')) {
1794 label_add(tok_id());
1800 static void readdecl(void)
1802 if (!tok_jmp(TOK_TYPEDEF
)) {
1803 readdefs(typedefdef
, NULL
);
1807 readdefs(globaldef
, NULL
);
1808 if (tok_see() == '{') {
1812 func_name
[0] = '\0';
1821 static void parse(void)
1823 while (tok_see() != TOK_EOF
)
1827 static void compat_macros(void)
1829 cpp_define("__STDC__", "");
1830 cpp_define("__arm__", "");
1831 cpp_define("__linux__", "");
1833 /* ignored keywords */
1834 cpp_define("const", "");
1835 cpp_define("register", "");
1836 cpp_define("volatile", "");
1837 cpp_define("inline", "");
1838 cpp_define("restrict", "");
1839 cpp_define("__inline__", "");
1840 cpp_define("__restrict__", "");
1841 cpp_define("__attribute__(x)", "");
1842 cpp_define("__builtin_va_list__", "long");
1845 int main(int argc
, char *argv
[])
1851 while (i
< argc
&& argv
[i
][0] == '-') {
1852 if (argv
[i
][1] == 'I')
1853 cpp_addpath(argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1854 if (argv
[i
][1] == 'D') {
1855 char *name
= argv
[i
] + 2;
1857 char *eq
= strchr(name
, '=');
1862 cpp_define(name
, def
);
1864 if (argv
[i
][1] == 'o')
1865 strcpy(obj
, argv
[i
][2] ? argv
[i
] + 2 : argv
[++i
]);
1869 die("neatcc: no file given\n");
1870 if (cpp_init(argv
[i
]))
1871 die("neatcc: cannot open input file\n");
1874 strcpy(obj
, argv
[i
]);
1875 obj
[strlen(obj
) - 1] = 'o';
1877 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);