Skip to content

Commit bacc9f1

Browse files
committed
Support all assignment operators
Previously, only "+=", "-=", "|=", and "&=" assignment operators are supported, in this commit, we've support the remaining assignment operators, which are "*=", "/=", "%=", "<<=", ">>=", and "^=". Additionally, this commit also refactors some assignment operations with the operators introduced in this commit.
1 parent fefe803 commit bacc9f1

11 files changed

+94
-35
lines changed

lib/c.c

+6-6
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ void __str_base10(char *pb, int val)
151151
q += (q >> 4);
152152
q += (q >> 8);
153153
q += (q >> 16);
154-
q = q >> 3;
154+
q >>= 3;
155155
r = val - (((q << 2) + q) << 1);
156156
t = ((r + 6) >> 4);
157157
q += t;
158-
r = r - (((t << 2) + t) << 1);
158+
r -= (((t << 2) + t) << 1);
159159

160160
pb[i] += r;
161161
val = q;
@@ -181,7 +181,7 @@ void __str_base8(char *pb, int val)
181181
for (int i = 0; i < times; i++) {
182182
v = val & 0x7;
183183
pb[c] = '0' + v;
184-
val = val >> 3;
184+
val >>= 3;
185185
c--;
186186
}
187187
v = val & 0x3;
@@ -202,7 +202,7 @@ void __str_base16(char *pb, int val)
202202
abort();
203203
break;
204204
}
205-
val = val >> 4;
205+
val >>= 4;
206206
c--;
207207
}
208208
}
@@ -315,7 +315,7 @@ void printf(char *str, ...)
315315
w = str[si] - '0';
316316
si++;
317317
while (str[si] >= '0' && str[si] <= '9') {
318-
w = w * 10;
318+
w *= 10;
319319
w += str[si] - '0';
320320
si++;
321321
}
@@ -382,7 +382,7 @@ void sprintf(char *buffer, char *str, ...)
382382
w = str[si] - '0';
383383
si++;
384384
if (str[si] >= '0' && str[si] <= '9') {
385-
w = w * 10;
385+
w *= 10;
386386
w += str[si] - '0';
387387
si++;
388388
}

src/arm.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -114,8 +114,8 @@ int arm_extract_bits(int imm, int i_start, int i_end, int d_start, int d_end)
114114
error("Invalid bit copy");
115115

116116
int v = imm >> i_start;
117-
v = v & ((2 << (i_end - i_start)) - 1);
118-
v = v << d_start;
117+
v &= ((2 << (i_end - i_start)) - 1);
118+
v <<= d_start;
119119
return v;
120120
}
121121

@@ -136,7 +136,7 @@ int __mov(arm_cond_t cond, int io, int opcode, int s, int rn, int rd, int op2)
136136
shift = 16; /* full rotation */
137137
while ((op2 & 3) == 0) {
138138
/* we can shift by two bits */
139-
op2 = op2 >> 2;
139+
op2 >>= 2;
140140
shift -= 1;
141141
}
142142
if (op2 > 255)
@@ -176,7 +176,7 @@ int __movw(arm_cond_t cond, arm_reg rd, int imm)
176176

177177
int __movt(arm_cond_t cond, arm_reg rd, int imm)
178178
{
179-
imm = imm >> 16;
179+
imm >>= 16;
180180
return arm_encode(cond, 52, 0, rd, 0) +
181181
arm_extract_bits(imm, 0, 11, 0, 11) +
182182
arm_extract_bits(imm, 12, 15, 16, 19);

src/globals.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ int insert_trie(trie_t *trie, char *name, int funcs_index)
109109
FUNC_TRIES[trie->next[fc]].index = 0;
110110
}
111111
trie = &FUNC_TRIES[trie->next[fc]];
112-
name = name + 1;
112+
name++;
113113
}
114114
}
115115

@@ -136,7 +136,7 @@ int find_trie(trie_t *trie, char *name)
136136
if (!trie->next[fc])
137137
return 0;
138138
trie = &FUNC_TRIES[trie->next[fc]];
139-
name = name + 1;
139+
name++;
140140
}
141141
}
142142

src/lexer.c

+47-6
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ typedef enum {
4040
T_minus, /* - */
4141
T_minuseq, /* -= */
4242
T_pluseq, /* += */
43+
T_asteriskeq, /* *= */
44+
T_divideeq, /* /= */
45+
T_modeq, /* %= */
46+
T_lshifteq, /* <<= */
47+
T_rshifteq, /* >>= */
48+
T_xoreq, /* ^= */
4349
T_oreq, /* |= */
4450
T_andeq, /* &= */
4551
T_eq, /* == */
@@ -246,6 +252,11 @@ token_t lex_token_internal(bool aliasing)
246252
return lex_token_internal(aliasing);
247253
}
248254

255+
if (next_char == '=') {
256+
read_char(true);
257+
return T_divideeq;
258+
}
259+
249260
return T_divide;
250261
}
251262

@@ -288,6 +299,12 @@ token_t lex_token_internal(bool aliasing)
288299
}
289300
if (next_char == '^') {
290301
read_char(true);
302+
303+
if (next_char == '=') {
304+
read_char(true);
305+
return T_xoreq;
306+
}
307+
291308
return T_bit_xor;
292309
}
293310
if (next_char == '~') {
@@ -359,14 +376,20 @@ token_t lex_token_internal(bool aliasing)
359376
}
360377
if (next_char == '*') {
361378
read_char(true);
379+
380+
if (next_char == '=') {
381+
read_char(true);
382+
return T_asteriskeq;
383+
}
384+
362385
return T_asterisk;
363386
}
364387
if (next_char == '&') {
365388
read_char(false);
366389
if (next_char == '&') {
367390
read_char(true);
368391
return T_log_and;
369-
};
392+
}
370393
if (next_char == '=') {
371394
read_char(true);
372395
return T_andeq;
@@ -379,7 +402,7 @@ token_t lex_token_internal(bool aliasing)
379402
if (next_char == '|') {
380403
read_char(true);
381404
return T_log_or;
382-
};
405+
}
383406
if (next_char == '=') {
384407
read_char(true);
385408
return T_oreq;
@@ -392,28 +415,46 @@ token_t lex_token_internal(bool aliasing)
392415
if (next_char == '=') {
393416
read_char(true);
394417
return T_le;
395-
};
418+
}
396419
if (next_char == '<') {
397420
read_char(true);
421+
422+
if (next_char == '=') {
423+
read_char(true);
424+
return T_lshifteq;
425+
}
426+
398427
return T_lshift;
399-
};
428+
}
400429
skip_whitespace();
401430
return T_lt;
402431
}
403432
if (next_char == '%') {
404433
read_char(true);
434+
435+
if (next_char == '=') {
436+
read_char(true);
437+
return T_modeq;
438+
}
439+
405440
return T_mod;
406441
}
407442
if (next_char == '>') {
408443
read_char(false);
409444
if (next_char == '=') {
410445
read_char(true);
411446
return T_ge;
412-
};
447+
}
413448
if (next_char == '>') {
414449
read_char(true);
450+
451+
if (next_char == '=') {
452+
read_char(true);
453+
return T_rshifteq;
454+
}
455+
415456
return T_rshift;
416-
};
457+
}
417458
skip_whitespace();
418459
return T_gt;
419460
}

src/parser.c

+23-11
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ int read_numeric_constant(char buffer[])
166166
i = 2;
167167
while (buffer[i]) {
168168
char c = buffer[i++];
169-
value = value << 4;
169+
value <<= 4;
170170
if (is_digit(c))
171171
value += c - '0';
172172
c |= 32; /* convert to lower case */
@@ -228,7 +228,7 @@ int read_constant_infix_expr(int precedence)
228228
case OP_add:
229229
break;
230230
case OP_sub:
231-
lhs = lhs * -1;
231+
lhs = -lhs;
232232
break;
233233
case OP_bit_not:
234234
lhs = ~lhs;
@@ -255,31 +255,31 @@ int read_constant_infix_expr(int precedence)
255255

256256
switch (op) {
257257
case OP_add:
258-
lhs = lhs + rhs;
258+
lhs += rhs;
259259
break;
260260
case OP_sub:
261-
lhs = lhs - rhs;
261+
lhs -= rhs;
262262
break;
263263
case OP_mul:
264-
lhs = lhs * rhs;
264+
lhs *= rhs;
265265
break;
266266
case OP_div:
267-
lhs = lhs / rhs;
267+
lhs /= rhs;
268268
break;
269269
case OP_bit_and:
270-
lhs = lhs & rhs;
270+
lhs &= rhs;
271271
break;
272272
case OP_bit_or:
273-
lhs = lhs | rhs;
273+
lhs |= rhs;
274274
break;
275275
case OP_bit_xor:
276-
lhs = lhs ^ rhs;
276+
lhs ^= rhs;
277277
break;
278278
case OP_lshift:
279-
lhs = lhs << rhs;
279+
lhs <<= rhs;
280280
break;
281281
case OP_rshift:
282-
lhs = lhs >> rhs;
282+
lhs >>= rhs;
283283
break;
284284
case OP_gt:
285285
lhs = lhs > rhs;
@@ -1870,6 +1870,18 @@ bool read_body_assignment(char *token,
18701870
op = OP_add;
18711871
} else if (lex_accept(T_minuseq)) {
18721872
op = OP_sub;
1873+
} else if (lex_accept(T_asteriskeq)) {
1874+
op = OP_mul;
1875+
} else if (lex_accept(T_divideeq)) {
1876+
op = OP_div;
1877+
} else if (lex_accept(T_modeq)) {
1878+
op = OP_mod;
1879+
} else if (lex_accept(T_lshifteq)) {
1880+
op = OP_lshift;
1881+
} else if (lex_accept(T_rshifteq)) {
1882+
op = OP_rshift;
1883+
} else if (lex_accept(T_xoreq)) {
1884+
op = OP_bit_xor;
18731885
} else if (lex_accept(T_oreq)) {
18741886
op = OP_bit_or;
18751887
} else if (lex_accept(T_andeq)) {

src/riscv.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -105,8 +105,8 @@ int rv_extract_bits(int imm, int i_start, int i_end, int d_start, int d_end)
105105
error("Invalid bit copy");
106106

107107
v = imm >> i_start;
108-
v = v & ((2 << (i_end - i_start)) - 1);
109-
v = v << d_start;
108+
v &= ((2 << (i_end - i_start)) - 1);
109+
v <<= d_start;
110110
return v;
111111
}
112112

tests/driver.sh

+6
Original file line numberDiff line numberDiff line change
@@ -450,6 +450,12 @@ expr 25 "0 ? 10 : 25"
450450
# compound assignemnt
451451
items 5 "int a; a = 2; a += 3; return a;"
452452
items 5 "int a; a = 10; a -= 5; return a;"
453+
items 4 "int a; a = 2; a *= 2; return a;"
454+
items 33 "int a; a = 100; a /= 3; return a;"
455+
items 1 "int a; a = 100; a %= 3; return a;"
456+
items 4 "int a; a = 2; a <<= 1; return a;"
457+
items 2 "int a; a = 4; a >>= 1; return a;"
458+
items 1 "int a; a = 1; a ^= 0; return a;"
453459
items 20 "int *p; int a[3]; a[0] = 10; a[1] = 20; a[2] = 30; p = a; p+=1; return p[0];"
454460

455461
# sizeof

tests/snapshots/fib-arm.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/fib-riscv.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/hello-arm.json

+1-1
Large diffs are not rendered by default.

tests/snapshots/hello-riscv.json

+1-1
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)