aboutsummaryrefslogtreecommitdiff
path: root/tcc.c
diff options
context:
space:
mode:
authorbellard <bellard>2001-10-28 22:24:16 +0000
committerbellard <bellard>2001-10-28 22:24:16 +0000
commit9c1b84560e27277f5e05b9c042cda22928e80177 (patch)
treeb1f081449872acd1d99d05ce8dadcb9f20d0586c /tcc.c
parent58f3296a6efe1ea51a73abc31a3503bffa0e1a82 (diff)
downloadtinycc-9c1b84560e27277f5e05b9c042cda22928e80177.tar.gz
tinycc-9c1b84560e27277f5e05b9c042cda22928e80177.tar.bz2
added 'x'= operators
Diffstat (limited to 'tcc.c')
-rw-r--r--tcc.c54
1 files changed, 43 insertions, 11 deletions
diff --git a/tcc.c b/tcc.c
index 264e336..6bc1e58 100644
--- a/tcc.c
+++ b/tcc.c
@@ -88,9 +88,21 @@ char *idtable, *idptr, *idlast, *filename;
#define TOK_MID 0xa3 /* inc/dec, to void constant */
#define TOK_INC 0xa4
-#define TOK_SHL 0xe0 /* warning: depend on asm code */
-#define TOK_SHR 0xf8 /* warning: depend on asm code */
+#define TOK_SHL 0x01
+#define TOK_SHR 0x02
+/* assignement operators : normal operator or 0x80 */
+#define TOK_A_MOD 0xa5
+#define TOK_A_AND 0xa6
+#define TOK_A_MUL 0xaa
+#define TOK_A_ADD 0xab
+#define TOK_A_SUB 0xad
+#define TOK_A_DIV 0xaf
+#define TOK_A_XOR 0xde
+#define TOK_A_OR 0xfc
+#define TOK_A_SHL 0x81
+#define TOK_A_SHR 0x82
+
#ifdef TINY
#define expr_eq() expr()
#endif
@@ -242,13 +254,20 @@ void next()
#ifdef TINY
q = "<=\236>=\235!=\225++\244--\242==\224";
#else
- q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\340>>\370";
+ q = "<=\236>=\235!=\225&&\240||\241++\244--\242==\224<<\1>>\2+=\253-=\255*=\252/=\257%=\245&=\246^=\336|=\374";
#endif
/* two chars */
v = inp();
while (*q) {
if (*q == c & q[1] == v) {
tok = q[2] & 0xff;
+ if (tok == TOK_SHL | tok == TOK_SHR) {
+ v = inp();
+ if (v == '=')
+ tok = tok | 0x80;
+ else
+ ungetc(v, file);
+ }
return;
}
q = q + 3;
@@ -416,8 +435,10 @@ void gen_op(op, l)
t = vt;
o(0x50); /* push %eax */
next();
- if (l < 0)
+ if (l == -1)
expr();
+ else if (l == -2)
+ expr_eq();
else
sum(l);
gv();
@@ -441,7 +462,10 @@ void gen_op(op, l)
#ifndef TINY
else if (op == TOK_SHL | op == TOK_SHR) {
o(0xd391); /* xchg %ecx, %eax, shl/sar %cl, %eax */
- o(op);
+ if (op == TOK_SHL)
+ o(0xe0);
+ else
+ o(0xf8);
}
#endif
else if (op == '/' | op == '%') {
@@ -760,20 +784,26 @@ void uneq()
int ft, fc, b;
unary();
- if (tok == '=') {
+ if (tok == '=' |
+ (tok >= TOK_A_MOD & TOK_A_DIV) |
+ tok == TOK_A_XOR | tok == TOK_A_OR |
+ tok == TOK_A_SHL | tok == TOK_A_SHR) {
test_lvalue();
- next();
fc = vc;
ft = vt;
b = (vt & VT_TYPE) == VT_BYTE;
if (ft & VT_VAR)
o(0x50); /* push %eax */
- expr_eq();
+ if (tok == '=') {
+ next();
+ expr_eq();
#ifndef TINY
- if ((vt & VT_PTRMASK) != (ft & VT_PTRMASK))
- warning("incompatible type");
+ if ((vt & VT_PTRMASK) != (ft & VT_PTRMASK))
+ warning("incompatible type");
#endif
- gv(); /* generate value */
+ gv(); /* generate value */
+ } else
+ gen_op(tok & 0x7f, -2); /* XXX: incorrect, must call expr_eq */
if (ft & VT_VAR) {
o(0x59); /* pop %ecx */
@@ -1068,8 +1098,10 @@ int main(int c, char **v)
}
#else
t = vac[TOK_MAIN];
+#ifndef TINY
if (!t)
error("main() not defined");
+#endif
return (*t)(c - 1, v);
#endif
}