diff --git a/libacc/acc.cpp b/libacc/acc.cpp index a74f51deb..823849c7f 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -3188,6 +3188,7 @@ class Compiler : public ErrorSink { static const int TOK_NUM = 2; static const int TOK_NUM_FLOAT = 3; static const int TOK_NUM_DOUBLE = 4; + static const int TOK_OP_ASSIGNMENT = 5; // 3..255 are character and/or operators @@ -3626,6 +3627,13 @@ class Compiler : public ErrorSink { inp(); tok = TOK_DUMMY; /* dummy token for double tokens */ } + /* check for op=, valid for * / % + - << >> & ^ | */ + if (ch == '=' && + ((tokl >= 1 && tokl <= 3) + || tokl >=6 && tokl <= 8) ) { + inp(); + tok = TOK_OP_ASSIGNMENT; + } break; } opIndex++; @@ -3797,6 +3805,17 @@ class Compiler : public ErrorSink { expr(); pGen->forceR0RVal(); pGen->storeR0ToTOS(); + } else if (tok == TOK_OP_ASSIGNMENT) { + int t = tokc; + next(); + checkLVal(); + pGen->pushR0(); + pGen->forceR0RVal(); + pGen->pushR0(); + expr(); + pGen->forceR0RVal(); + pGen->genOp(t); + pGen->storeR0ToTOS(); } } diff --git a/libacc/tests/data/assignmentop.c b/libacc/tests/data/assignmentop.c new file mode 100644 index 000000000..10b463761 --- /dev/null +++ b/libacc/tests/data/assignmentop.c @@ -0,0 +1,66 @@ +// Test assignment operations + +void testAssignment() { + int a = 2; + a *= 5; + printf("2 *= 5 %d\n", a); + a = 20; + a /= 5; + printf("20 /= 5 %d\n", a); + a = 17; + a %= 5; + printf("17 %%= 5 %d\n", a); + a = 17; + a += 5; + printf("17 += 5 %d\n", a); + a = 17; + a-=5; + printf("17 -= 5 %d\n", a); + a = 17; + a<<=1; + printf("17<<= 1 %d\n", a); + a = 17; + a>>=1; + printf("17>>= 1 %d\n", a); + a = 17; + a&=1; + printf("17&= 1 %d\n", a); + a = 17; + a^=1; + printf("17^= 1 %d\n", a); + a = 16; + a^=1; + printf("16|= 1 %d\n", a); +} + +/* Can't use because int* f() is not parsed as a function decl. +int a; + +int* f() { + printf("f()\n"); + return &a; +} + +void testEval() { + a = 0; + printf("*f() = *f() + 10;"); + *f() = *f() + 10; + printf("a = %d\n", a); +} + +void testOpEval() { + a = 0; + printf("*f() += 10;"); + *f() += 10; + printf("a = %d\n", a); +} + +*/ +int main() { + testAssignment(); + /* + testEval(); + testOpEval(); + */ + return 0; +} diff --git a/libacc/tests/test.py b/libacc/tests/test.py index f9089be2a..239bb9b91 100644 --- a/libacc/tests/test.py +++ b/libacc/tests/test.py @@ -338,6 +338,20 @@ a = 0, *pa = 0 **ppa = 0 a = 2, *pa = 2 **ppa = 2 a = 0, *pa = 0 **ppa = 0 a = 2, *pa = 2 **ppa = 2 +""") + + def testassignmentop(self): + self.compileCheck(["-R", "data/assignmentop.c"], """Executing compiled code: +result: 0""", """2 *= 5 10 +20 /= 5 4 +17 %= 5 2 +17 += 5 22 +17 -= 5 12 +17<<= 1 34 +17>>= 1 8 +17&= 1 1 +17^= 1 16 +16|= 1 17 """) if __name__ == '__main__':