diff options
author | Jack Palevich <jackpal@google.com> | 2009-07-31 14:34:34 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-07-31 14:34:34 -0700 |
commit | aaac9284b407d236981cbe9be9b167c67cc905ba (patch) | |
tree | ff735dd8552476d64df0ee22e3c205fec52fae76 | |
parent | 43aaee31b9cedc059213396f1e7aa420ace0c797 (diff) | |
download | system_core-aaac9284b407d236981cbe9be9b167c67cc905ba.zip system_core-aaac9284b407d236981cbe9be9b167c67cc905ba.tar.gz system_core-aaac9284b407d236981cbe9be9b167c67cc905ba.tar.bz2 |
Implement pre-increment / pre-decrement
-rw-r--r-- | libacc/acc.cpp | 62 | ||||
-rw-r--r-- | libacc/tests/data/inc.c | 4 | ||||
-rw-r--r-- | libacc/tests/test.py | 4 |
3 files changed, 43 insertions, 27 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp index da703a7..327d3da 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -3859,7 +3859,12 @@ class Compiler : public ErrorSink { } else { pGen->genUnaryOp(a); } - } else if (t == '(') { + } else if (c == 11) { + // pre increment / pre decrement + unary(); + doIncDec(a == OP_INCREMENT, 0); + } + else if (t == '(') { // It's either a cast or an expression Type* pCast = acceptCastTypeDeclaration(); if (pCast) { @@ -3926,35 +3931,11 @@ class Compiler : public ErrorSink { } } // load a variable + pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE); if (tokl == 11) { // post inc / post dec - pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE); - - pGen->pushR0(); - pGen->loadR0FromR0(); - pGen->over(); - int lit = 1; - if (tokc == OP_DECREMENT) { - lit = -1; - } - switch (pVI->pType->tag) { - case TY_INT: - case TY_CHAR: - case TY_POINTER: - pGen->pushR0(); - pGen->li(lit); - pGen->genOp(OP_PLUS); - break; - default: - error("++/-- illegal for this type."); - break; - } - - pGen->storeR0ToTOS(); - pGen->popR0(); + doIncDec(tokc == OP_INCREMENT, true); next(); - } else { - pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE); } } } @@ -4029,6 +4010,33 @@ class Compiler : public ErrorSink { } } + void doIncDec(int isInc, int isPost) { + // R0 already has the lval + checkLVal(); + int lit = isInc ? 1 : -1; + pGen->pushR0(); + pGen->loadR0FromR0(); + int tag = pGen->getR0Type()->tag; + if (!(tag == TY_INT || tag == TY_CHAR || tag == TY_POINTER)) { + error("++/-- illegal for this type. %d", tag); + } + if (isPost) { + pGen->over(); + pGen->pushR0(); + pGen->li(lit); + pGen->genOp(OP_PLUS); + pGen->storeR0ToTOS(); + pGen->popR0(); + } else { + pGen->pushR0(); + pGen->li(lit); + pGen->genOp(OP_PLUS); + pGen->over(); + pGen->storeR0ToTOS(); + pGen->popR0(); + } + } + /* Recursive descent parser for binary operations. */ void binaryOp(int level) { diff --git a/libacc/tests/data/inc.c b/libacc/tests/data/inc.c index eda3659..14c09d1 100644 --- a/libacc/tests/data/inc.c +++ b/libacc/tests/data/inc.c @@ -6,5 +6,9 @@ int main() { printf("%d\n", a++); printf("%d\n", a--); printf("%d\n", a--); + printf("%d\n", ++a); + printf("%d\n", ++a); + printf("%d\n", --a); + printf("%d\n", --a); return a; } diff --git a/libacc/tests/test.py b/libacc/tests/test.py index 5f9a71e..0249695 100644 --- a/libacc/tests/test.py +++ b/libacc/tests/test.py @@ -293,6 +293,10 @@ result: 0""", """0.002 0.1 10""") 1 2 1 +1 +2 +1 +0 result: 0 ""","""""") |