Skip to content

Commit

Permalink
Support all assignment operators
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
ChAoSUnItY committed Jan 17, 2025
1 parent fefe803 commit 3f745d1
Show file tree
Hide file tree
Showing 7 changed files with 90 additions and 31 deletions.
12 changes: 6 additions & 6 deletions lib/c.c
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ void __str_base10(char *pb, int val)
q += (q >> 4);
q += (q >> 8);
q += (q >> 16);
q = q >> 3;
q >>= 3;
r = val - (((q << 2) + q) << 1);
t = ((r + 6) >> 4);
q += t;
r = r - (((t << 2) + t) << 1);
r -= (((t << 2) + t) << 1);

pb[i] += r;
val = q;
Expand All @@ -181,7 +181,7 @@ void __str_base8(char *pb, int val)
for (int i = 0; i < times; i++) {
v = val & 0x7;
pb[c] = '0' + v;
val = val >> 3;
val >>= 3;
c--;
}
v = val & 0x3;
Expand All @@ -202,7 +202,7 @@ void __str_base16(char *pb, int val)
abort();
break;
}
val = val >> 4;
val >>= 4;
c--;
}
}
Expand Down Expand Up @@ -315,7 +315,7 @@ void printf(char *str, ...)
w = str[si] - '0';
si++;
while (str[si] >= '0' && str[si] <= '9') {
w = w * 10;
w *= 10;
w += str[si] - '0';
si++;
}
Expand Down Expand Up @@ -382,7 +382,7 @@ void sprintf(char *buffer, char *str, ...)
w = str[si] - '0';
si++;
if (str[si] >= '0' && str[si] <= '9') {
w = w * 10;
w *= 10;
w += str[si] - '0';
si++;
}
Expand Down
8 changes: 4 additions & 4 deletions src/arm.c
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,8 @@ int arm_extract_bits(int imm, int i_start, int i_end, int d_start, int d_end)
error("Invalid bit copy");

int v = imm >> i_start;
v = v & ((2 << (i_end - i_start)) - 1);
v = v << d_start;
v &= ((2 << (i_end - i_start)) - 1);
v <<= d_start;
return v;
}

Expand All @@ -136,7 +136,7 @@ int __mov(arm_cond_t cond, int io, int opcode, int s, int rn, int rd, int op2)
shift = 16; /* full rotation */
while ((op2 & 3) == 0) {
/* we can shift by two bits */
op2 = op2 >> 2;
op2 >>= 2;
shift -= 1;
}
if (op2 > 255)
Expand Down Expand Up @@ -176,7 +176,7 @@ int __movw(arm_cond_t cond, arm_reg rd, int imm)

int __movt(arm_cond_t cond, arm_reg rd, int imm)
{
imm = imm >> 16;
imm >>= 16;
return arm_encode(cond, 52, 0, rd, 0) +
arm_extract_bits(imm, 0, 11, 0, 11) +
arm_extract_bits(imm, 12, 15, 16, 19);
Expand Down
4 changes: 2 additions & 2 deletions src/globals.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ int insert_trie(trie_t *trie, char *name, int funcs_index)
FUNC_TRIES[trie->next[fc]].index = 0;
}
trie = &FUNC_TRIES[trie->next[fc]];
name = name + 1;
name++;
}
}

Expand All @@ -136,7 +136,7 @@ int find_trie(trie_t *trie, char *name)
if (!trie->next[fc])
return 0;
trie = &FUNC_TRIES[trie->next[fc]];
name = name + 1;
name++;
}
}

Expand Down
53 changes: 47 additions & 6 deletions src/lexer.c
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ typedef enum {
T_minus, /* - */
T_minuseq, /* -= */
T_pluseq, /* += */
T_asteriskeq, /* *= */
T_divideeq, /* /= */
T_modeq, /* %= */
T_lshifteq, /* <<= */
T_rshifteq, /* >>= */
T_xoreq, /* ^= */
T_oreq, /* |= */
T_andeq, /* &= */
T_eq, /* == */
Expand Down Expand Up @@ -246,6 +252,11 @@ token_t lex_token_internal(bool aliasing)
return lex_token_internal(aliasing);
}

if (next_char == '=') {
read_char(true);
return T_divideeq;
}

return T_divide;
}

Expand Down Expand Up @@ -288,6 +299,12 @@ token_t lex_token_internal(bool aliasing)
}
if (next_char == '^') {
read_char(true);

if (next_char == '=') {
read_char(true);
return T_xoreq;
}

return T_bit_xor;
}
if (next_char == '~') {
Expand Down Expand Up @@ -359,14 +376,20 @@ token_t lex_token_internal(bool aliasing)
}
if (next_char == '*') {
read_char(true);

if (next_char == '=') {
read_char(true);
return T_asteriskeq;
}

return T_asterisk;
}
if (next_char == '&') {
read_char(false);
if (next_char == '&') {
read_char(true);
return T_log_and;
};
}
if (next_char == '=') {
read_char(true);
return T_andeq;
Expand All @@ -379,7 +402,7 @@ token_t lex_token_internal(bool aliasing)
if (next_char == '|') {
read_char(true);
return T_log_or;
};
}
if (next_char == '=') {
read_char(true);
return T_oreq;
Expand All @@ -392,28 +415,46 @@ token_t lex_token_internal(bool aliasing)
if (next_char == '=') {
read_char(true);
return T_le;
};
}
if (next_char == '<') {
read_char(true);

if (next_char == '=') {
read_char(true);
return T_lshifteq;
}

return T_lshift;
};
}
skip_whitespace();
return T_lt;
}
if (next_char == '%') {
read_char(true);

if (next_char == '=') {
read_char(true);
return T_modeq;
}

return T_mod;
}
if (next_char == '>') {
read_char(false);
if (next_char == '=') {
read_char(true);
return T_ge;
};
}
if (next_char == '>') {
read_char(true);

if (next_char == '=') {
read_char(true);
return T_rshifteq;
}

return T_rshift;
};
}
skip_whitespace();
return T_gt;
}
Expand Down
34 changes: 23 additions & 11 deletions src/parser.c
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ int read_numeric_constant(char buffer[])
i = 2;
while (buffer[i]) {
char c = buffer[i++];
value = value << 4;
value <<= 4;
if (is_digit(c))
value += c - '0';
c |= 32; /* convert to lower case */
Expand Down Expand Up @@ -228,7 +228,7 @@ int read_constant_infix_expr(int precedence)
case OP_add:
break;
case OP_sub:
lhs = lhs * -1;
lhs = -lhs;
break;
case OP_bit_not:
lhs = ~lhs;
Expand All @@ -255,31 +255,31 @@ int read_constant_infix_expr(int precedence)

switch (op) {
case OP_add:
lhs = lhs + rhs;
lhs += rhs;
break;
case OP_sub:
lhs = lhs - rhs;
lhs -= rhs;
break;
case OP_mul:
lhs = lhs * rhs;
lhs *= rhs;
break;
case OP_div:
lhs = lhs / rhs;
lhs /= rhs;
break;
case OP_bit_and:
lhs = lhs & rhs;
lhs &= rhs;
break;
case OP_bit_or:
lhs = lhs | rhs;
lhs |= rhs;
break;
case OP_bit_xor:
lhs = lhs ^ rhs;
lhs ^= rhs;
break;
case OP_lshift:
lhs = lhs << rhs;
lhs <<= rhs;
break;
case OP_rshift:
lhs = lhs >> rhs;
lhs >>= rhs;
break;
case OP_gt:
lhs = lhs > rhs;
Expand Down Expand Up @@ -1870,6 +1870,18 @@ bool read_body_assignment(char *token,
op = OP_add;
} else if (lex_accept(T_minuseq)) {
op = OP_sub;
} else if (lex_accept(T_asteriskeq)) {
op = OP_mul;
} else if (lex_accept(T_divideeq)) {
op = OP_div;
} else if (lex_accept(T_modeq)) {
op = OP_mod;
} else if (lex_accept(T_lshifteq)) {
op = OP_lshift;
} else if (lex_accept(T_rshifteq)) {
op = OP_rshift;
} else if (lex_accept(T_xoreq)) {
op = OP_bit_xor;
} else if (lex_accept(T_oreq)) {
op = OP_bit_or;
} else if (lex_accept(T_andeq)) {
Expand Down
4 changes: 2 additions & 2 deletions src/riscv.c
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,8 @@ int rv_extract_bits(int imm, int i_start, int i_end, int d_start, int d_end)
error("Invalid bit copy");

v = imm >> i_start;
v = v & ((2 << (i_end - i_start)) - 1);
v = v << d_start;
v &= ((2 << (i_end - i_start)) - 1);
v <<= d_start;
return v;
}

Expand Down
6 changes: 6 additions & 0 deletions tests/driver.sh
Original file line number Diff line number Diff line change
Expand Up @@ -450,6 +450,12 @@ expr 25 "0 ? 10 : 25"
# compound assignemnt
items 5 "int a; a = 2; a += 3; return a;"
items 5 "int a; a = 10; a -= 5; return a;"
items 4 "int a; a = 2; a *= 2; return a;"
items 33 "int a; a = 100; a /= 3; return a;"
items 1 "int a; a = 100; a %= 3; return a;"
items 4 "int a; a = 2; a <<= 1; return a;"
items 2 "int a; a = 4; a >>= 1; return a;"
items 1 "int a; a = 1; a ^= 0; return a;"
items 20 "int *p; int a[3]; a[0] = 10; a[1] = 20; a[2] = 30; p = a; p+=1; return p[0];"

# sizeof
Expand Down

0 comments on commit 3f745d1

Please sign in to comment.