10 #define MAXLOCALS (1 << 10)
11 #define MAXARGS (1 << 5)
12 #define print(s) write(2, (s), strlen(s));
14 #define TYPE_BT(t) ((t)->ptr ? 8 : (t)->bt)
15 #define TYPE_SZ(t) ((t)->ptr ? 8 : (t)->bt & BT_SZMASK)
16 #define TYPE_DEREF_BT(t) ((t)->ptr > 1 ? 8 : (t)->bt)
17 #define TYPE_DEREF_SZ(t) ((t)->ptr > 1 ? 8 : (t)->bt & BT_SZMASK)
28 static struct type ts
[MAXTMP
];
31 static void ts_push_bt(unsigned bt
)
38 static void ts_push(struct type
*type
)
43 static void ts_pop(struct type
*type
)
57 static void local_add(char *name
, long addr
, struct type type
)
59 strcpy(locals
[nlocals
].name
, name
);
60 locals
[nlocals
].addr
= addr
;
61 locals
[nlocals
].type
= type
;
65 static void die(char *s
)
71 static int tok_jmp(int tok
)
79 static void tok_expect(int tok
)
82 die("syntax error\n");
85 static void readexpr(void);
87 static int basetype(struct type
*type
)
118 tok_expect(TOK_NAME
);
130 type
->bt
= size
| (sign
? BT_SIGNED
: 0);
135 static void readptrs(struct type
*type
)
137 while (!tok_jmp('*'))
141 static int readtype(struct type
*type
)
149 static void readprimary(void)
152 if (!tok_jmp(TOK_NUM
)) {
153 ts_push_bt(4 | BT_SIGNED
);
154 o_num(atoi(tok_id()), 4 | BT_SIGNED
);
157 if (!tok_jmp(TOK_NAME
)) {
158 for (i
= 0; i
< nlocals
; i
++) {
159 struct type
*t
= &locals
[i
].type
;
160 if (!strcmp(locals
[i
].name
, tok_id())) {
162 o_local(locals
[i
].addr
, TYPE_BT(t
));
163 if (t
->flags
& T_ARRAY
)
169 o_symaddr(tok_id(), 8);
179 void arrayderef(unsigned bt
)
189 static void inc_post(void (*op
)(void))
191 struct type
*t
= &ts
[nts
- 1];
203 static void readpost(void)
212 arrayderef(TYPE_DEREF_BT(&t1
));
219 unsigned bt
[MAXARGS
];
220 if (tok_see() != ')') {
222 bt
[argc
++] = 4 | BT_SIGNED
;
225 while (!tok_jmp(',')) {
227 bt
[argc
++] = 4 | BT_SIGNED
;
232 o_call(argc
, bt
, 4 | BT_SIGNED
);
233 ts_push_bt(4 | BT_SIGNED
);
236 if (!tok_jmp(TOK2("++"))) {
240 if (!tok_jmp(TOK2("--"))) {
246 static void inc_pre(void (*op
)(void))
248 struct type
*t
= &ts
[nts
- 1];
256 static void readpre(void)
273 o_deref(TYPE_BT(&type
));
280 o_num(0, TYPE_BT(&type
));
282 ts_push_bt(4 | BT_SIGNED
);
295 if (!tok_jmp(TOK2("++"))) {
299 if (!tok_jmp(TOK2("--"))) {
306 static int shifts(int n
)
315 static unsigned bt_op(unsigned bt1
, unsigned bt2
)
317 unsigned s1
= BT_SZ(bt1
);
318 unsigned s2
= BT_SZ(bt2
);
319 return (bt1
| bt2
) & BT_SIGNED
| (s1
> s2
? s1
: s2
);
322 static void ts_binop(void (*o_sth
)(void))
328 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
331 static void ts_binop_add(void (*o_sth
)(void))
336 if (!t1
.ptr
&& !t2
.ptr
) {
338 ts_push_bt(bt_op(TYPE_BT(&t1
), TYPE_BT(&t2
)));
341 if (t1
.ptr
&& !t2
.ptr
) {
347 if (!t1
.ptr
&& t2
.ptr
)
348 if (TYPE_DEREF_SZ(&t2
) > 1) {
349 o_num(shifts(TYPE_DEREF_SZ(&t2
)), 1);
353 if (t1
.ptr
&& t2
.ptr
) {
354 o_num(shifts(TYPE_DEREF_SZ(&t1
)), 1);
356 ts_push_bt(4 | BT_SIGNED
);
362 static void readmul(void)
385 static void readadd(void)
403 static void shift(void (*op
)(void))
410 ts_push_bt(TYPE_BT(&t
));
413 static void readshift(void)
416 if (!tok_jmp(TOK2("<<"))) {
420 if (!tok_jmp(TOK2(">>"))) {
426 static void cmp(void (*op
)(void))
432 ts_push_bt(4 | BT_SIGNED
);
435 static void readcmp(void)
446 if (!tok_jmp(TOK2("<="))) {
450 if (!tok_jmp(TOK2(">="))) {
456 static void eq(void (*op
)(void))
462 ts_push_bt(4 | BT_SIGNED
);
465 static void readeq(void)
468 if (!tok_jmp(TOK2("=="))) {
472 if (!tok_jmp(TOK2("!="))) {
478 static void readbitand(void)
481 while (!tok_jmp('&')) {
487 static void readxor(void)
490 while (!tok_jmp('^')) {
496 static void readbitor(void)
499 while (!tok_jmp('|')) {
505 static void readcexpr(void)
524 static void opassign(void (*op
)(void))
526 unsigned bt
= TYPE_BT(&ts
[nts
- 1]);
533 static void readexpr(void)
538 o_assign(TYPE_BT(&ts
[nts
- 1]));
541 if (!tok_jmp(TOK2("+="))) {
545 if (!tok_jmp(TOK2("-="))) {
549 if (!tok_jmp(TOK2("*="))) {
553 if (!tok_jmp(TOK2("/="))) {
557 if (!tok_jmp(TOK2("%="))) {
561 if (!tok_jmp(TOK3("<<="))) {
565 if (!tok_jmp(TOK3(">>="))) {
571 static void readestmt(void)
577 } while (!tok_jmp(','));
580 static void readstmt(void)
582 struct type base
= {0};
590 if (!basetype(&base
)) {
591 struct type type
= base
;
595 tok_expect(TOK_NAME
);
596 strcpy(name
, tok_id());
601 type
.flags
= T_ARRAY
;
604 local_add(name
, o_mklocal(TYPE_SZ(&type
) * n
), type
);
607 struct type
*t
= &locals
[nlocals
- 1].type
;
608 o_local(locals
[nlocals
- 1].addr
, TYPE_BT(t
));
611 ts_push_bt(TYPE_BT(t
));
612 o_assign(TYPE_BT(t
));
617 if (!tok_jmp(TOK_IF
)) {
624 if (!tok_jmp(TOK_ELSE
)) {
634 if (!tok_jmp(TOK_WHILE
)) {
646 if (!tok_jmp(TOK_FOR
)) {
647 long check
, jump
, end
, body
;
649 if (tok_see() != ';')
653 if (tok_see() != ';')
659 if (tok_see() != ')')
669 if (!tok_jmp(TOK_RETURN
)) {
670 int ret
= tok_see() != ';';
674 o_ret(4 | BT_SIGNED
);
681 static void readdecl(void)
686 tok_expect(TOK_NAME
);
687 strcpy(name
, tok_id());
692 char args
[MAXARGS
][NAMELEN
];
693 struct type types
[MAXARGS
];
696 while (tok_see() != ')') {
697 readtype(&types
[nargs
]);
698 if (!tok_jmp(TOK_NAME
))
699 strcpy(args
[nargs
++], tok_id());
707 for (i
= 0; i
< nargs
; i
++)
708 local_add(args
[i
], o_arg(i
, TYPE_BT(&types
[i
])),
714 die("syntax error\n");
717 static void parse(void)
719 while (tok_see() != TOK_EOF
)
723 int main(int argc
, char *argv
[])
728 ifd
= open(src
, O_RDONLY
);
734 obj
[strlen(obj
) - 1] = 'o';
735 ofd
= open(obj
, O_WRONLY
| O_TRUNC
| O_CREAT
, 0600);