10 #define MAXLOCALS (1 << 10)
11 #define MAXGLOBALS (1 << 10)
12 #define MAXARGS (1 << 5)
13 #define print(s) write(2, (s), strlen(s));
15 #define TYPE_BT(t) ((t)->ptr ? 8 : (t)->bt)
16 #define TYPE_SZ(t) ((t)->ptr ? 8 : (t)->bt & BT_SZMASK)
17 #define TYPE_DEREF_BT(t) ((t)->ptr > 1 ? 8 : (t)->bt)
18 #define TYPE_DEREF_SZ(t) ((t)->ptr > 1 ? 8 : (t)->bt & BT_SZMASK)
30 static struct type ts
[MAXTMP
];
33 static void ts_push_bt(unsigned bt
)
40 static void ts_push(struct type
*type
)
45 static void ts_pop(struct type
*type
)
52 static int type_totsz(struct type
*t
)
54 if (!t
->ptr
|| t
->flags
& T_ARRAY
&& (t
)->ptr
== 1)
55 return BT_SZ(t
->bt
) * t
->n
;
65 static struct name locals
[MAXLOCALS
];
67 static struct name globals
[MAXGLOBALS
];
70 static void local_add(struct name
*name
)
72 memcpy(&locals
[nlocals
++], name
, sizeof(*name
));
75 static void global_add(struct name
*name
)
77 memcpy(&globals
[nglobals
++], name
, sizeof(*name
));
80 static void die(char *s
)
86 static int tok_jmp(int tok
)
94 static void tok_expect(int tok
)
97 die("syntax error\n");
100 static void readexpr(void);
102 static int basetype(struct type
*type
)
133 tok_expect(TOK_NAME
);
145 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
151 static void readptrs(struct type
*type
)
153 while (!tok_jmp('*'))
157 static int readtype(struct type
*type
)
165 static void readprimary(void)
169 if (!tok_jmp(TOK_NUM
)) {
170 ts_push_bt(4 | BT_SIGNED
);
171 o_num(tok_num(), 4 | BT_SIGNED
);
174 if (!tok_jmp(TOK_NAME
)) {
175 for (i
= 0; i
< nlocals
; i
++) {
176 struct type
*t
= &locals
[i
].type
;
177 if (!strcmp(locals
[i
].name
, tok_id())) {
179 o_local(locals
[i
].addr
, TYPE_BT(t
));
180 if (t
->flags
& T_ARRAY
)
185 for (i
= 0; i
< nglobals
; i
++) {
186 struct type
*t
= &globals
[i
].type
;
187 if (!strcmp(globals
[i
].name
, tok_id())) {
189 o_symaddr(globals
[i
].addr
, TYPE_BT(t
));
190 if (t
->flags
& T_ARRAY
)
195 strcpy(name
.name
, tok_id());
196 name
.addr
= o_mkundef(name
.name
);
199 o_symaddr(name
.addr
, 8);
209 void arrayderef(unsigned bt
)
219 static void inc_post(void (*op
)(void))
221 struct type
*t
= &ts
[nts
- 1];
233 static void readpost(void)
242 arrayderef(TYPE_DEREF_BT(&t1
));
249 unsigned bt
[MAXARGS
];
250 if (tok_see() != ')') {
252 bt
[argc
++] = 4 | BT_SIGNED
;
255 while (!tok_jmp(',')) {
257 bt
[argc
++] = 4 | BT_SIGNED
;
262 o_call(argc
, bt
, 4 | BT_SIGNED
);
263 ts_push_bt(4 | BT_SIGNED
);
266 if (!tok_jmp(TOK2("++"))) {
270 if (!tok_jmp(TOK2("--"))) {
276 static void inc_pre(void (*op
)(void))
278 struct type
*t
= &ts
[nts
- 1];
286 static void readpre(void)
303 o_deref(TYPE_BT(&type
));
311 ts_push_bt(4 | BT_SIGNED
);
324 if (!tok_jmp(TOK2("++"))) {
328 if (!tok_jmp(TOK2("--"))) {
335 static int shifts(int n
)
344 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
346 unsigned s1
= BT_SZ(bt1
);
347 unsigned s2
= BT_SZ(bt2
);
348 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
351 static void ts_binop(void (*o_sth
)(void))
357 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
360 static void ts_binop_add(void (*o_sth
)(void))
365 if (!t1
.ptr
&& !t2
.ptr
) {
367 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
370 if (t1
.ptr
&& !t2
.ptr
) {
376 if (!t1
.ptr
&& t2
.ptr
)
377 if (TYPE_DEREF_SZ(&t2
) > 1) {
378 o_num(shifts(TYPE_DEREF_SZ(&t2
)), 1);
382 if (t1
.ptr
&& t2
.ptr
) {
383 o_num(shifts(TYPE_DEREF_SZ(&t1
)), 1);
385 ts_push_bt(4 | BT_SIGNED
);
391 static void readmul(void)
414 static void readadd(void)
432 static void shift(void (*op
)(void))
439 ts_push_bt(TYPE_BT(&t
));
442 static void readshift(void)
445 if (!tok_jmp(TOK2("<<"))) {
449 if (!tok_jmp(TOK2(">>"))) {
455 static void cmp(void (*op
)(void))
461 ts_push_bt(4 | BT_SIGNED
);
464 static void readcmp(void)
475 if (!tok_jmp(TOK2("<="))) {
479 if (!tok_jmp(TOK2(">="))) {
485 static void eq(void (*op
)(void))
491 ts_push_bt(4 | BT_SIGNED
);
494 static void readeq(void)
497 if (!tok_jmp(TOK2("=="))) {
501 if (!tok_jmp(TOK2("!="))) {
507 static void readbitand(void)
510 while (!tok_jmp('&')) {
516 static void readxor(void)
519 while (!tok_jmp('^')) {
525 static void readbitor(void)
528 while (!tok_jmp('|')) {
534 #define MAXCOND (1 << 5)
536 static void readand(void)
543 if (tok_see() != TOK2("&&"))
545 conds
[nconds
++] = o_jz(0);
547 while (!tok_jmp(TOK2("&&"))) {
549 conds
[nconds
++] = o_jz(0);
552 o_num(1, 4 | BT_SIGNED
);
555 for (i
= 0; i
< nconds
; i
++)
557 o_num(0, 4 | BT_SIGNED
);
560 ts_push_bt(4 | BT_SIGNED
);
563 static void reador(void)
570 if (tok_see() != TOK2("||"))
572 conds
[nconds
++] = o_jnz(0);
574 while (!tok_jmp(TOK2("||"))) {
576 conds
[nconds
++] = o_jnz(0);
579 o_num(0, 4 | BT_SIGNED
);
582 for (i
= 0; i
< nconds
; i
++)
584 o_num(1, 4 | BT_SIGNED
);
587 ts_push_bt(4 | BT_SIGNED
);
590 static void readcexpr(void)
609 static void opassign(void (*op
)(void))
615 o_assign(TYPE_BT(&ts
[nts
- 1]));
618 static void readexpr(void)
624 o_assign(TYPE_BT(&ts
[nts
- 1]));
627 if (!tok_jmp(TOK2("+="))) {
631 if (!tok_jmp(TOK2("-="))) {
635 if (!tok_jmp(TOK2("*="))) {
639 if (!tok_jmp(TOK2("/="))) {
643 if (!tok_jmp(TOK2("%="))) {
647 if (!tok_jmp(TOK3("<<="))) {
651 if (!tok_jmp(TOK3(">>="))) {
655 if (!tok_jmp(TOK3("&="))) {
659 if (!tok_jmp(TOK3("|="))) {
663 if (!tok_jmp(TOK3("^="))) {
669 static void readestmt(void)
675 } while (!tok_jmp(','));
678 static void localdef(struct name
*name
, int init
)
680 name
->addr
= o_mklocal(type_totsz(&name
->type
));
683 struct type
*t
= &name
->type
;
684 o_local(locals
[nlocals
- 1].addr
, TYPE_BT(t
));
686 o_assign(TYPE_BT(t
));
690 static void funcdef(struct name
*name
, struct name
*args
, int nargs
)
693 name
->addr
= o_func_beg(name
->name
);
695 for (i
= 0; i
< nargs
; i
++) {
696 args
[i
].addr
= o_arg(i
, type_totsz(&args
[i
].type
));
701 static int readdefs(void (*def
)(struct name
*name
, int init
))
706 while (tok_see() != ';' && tok_see() != '{') {
708 struct type
*type
= &name
.type
;
709 memcpy(type
, &base
, sizeof(base
));
711 tok_expect(TOK_NAME
);
712 strcpy(name
.name
, tok_id());
717 type
->flags
= T_ARRAY
;
721 struct name args
[MAXARGS
];
723 while (tok_see() != ')') {
724 readtype(&args
[nargs
].type
);
725 if (!tok_jmp(TOK_NAME
))
726 strcpy(args
[nargs
++].name
, tok_id());
731 if (tok_see() != '{')
733 funcdef(&name
, args
, nargs
);
736 def(&name
, !tok_jmp('='));
741 static void readstmt(void)
750 if (!readdefs(localdef
)) {
754 if (!tok_jmp(TOK_IF
)) {
761 if (!tok_jmp(TOK_ELSE
)) {
771 if (!tok_jmp(TOK_WHILE
)) {
783 if (!tok_jmp(TOK_FOR
)) {
784 long check
, jump
, end
, body
;
786 if (tok_see() != ';')
790 if (tok_see() != ';')
796 if (tok_see() != ')')
806 if (!tok_jmp(TOK_RETURN
)) {
807 int ret
= tok_see() != ';';
811 o_ret(4 | BT_SIGNED
);
818 static void globaldef(struct name
*name
, int init
)
820 name
->addr
= o_mkvar(name
->name
, type_totsz(&name
->type
));
824 static void readdecl(void)
827 if (tok_see() == '{') {
836 static void parse(void)
838 while (tok_see() != TOK_EOF
)
842 int main(int argc
, char *argv
[])
847 ifd
= open(src
, O_RDONLY
);
853 obj
[strlen(obj
) - 1] = 'o';
854 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);