diff options
author | Jack Palevich <jackpal@google.com> | 2009-07-31 14:55:07 -0700 |
---|---|---|
committer | Jack Palevich <jackpal@google.com> | 2009-07-31 14:55:07 -0700 |
commit | 5b65909f93f7c35fc1e7aaf7dccc2198e30d17d1 (patch) | |
tree | fa2b27013ca172e6aff92bb27985db3816af4f31 /libacc | |
parent | aaac9284b407d236981cbe9be9b167c67cc905ba (diff) | |
download | system_core-5b65909f93f7c35fc1e7aaf7dccc2198e30d17d1.zip system_core-5b65909f93f7c35fc1e7aaf7dccc2198e30d17d1.tar.gz system_core-5b65909f93f7c35fc1e7aaf7dccc2198e30d17d1.tar.bz2 |
Clean up the way we handle postfix operators.
Function names are now treated just like any other variable.
Diffstat (limited to 'libacc')
-rw-r--r-- | libacc/acc.cpp | 136 |
1 files changed, 67 insertions, 69 deletions
diff --git a/libacc/acc.cpp b/libacc/acc.cpp index 327d3da..436f081 100644 --- a/libacc/acc.cpp +++ b/libacc/acc.cpp @@ -3823,9 +3823,8 @@ class Compiler : public ErrorSink { */ void unary() { tokenid_t t; - intptr_t n, a; + intptr_t a; t = 0; - n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */ if (acceptStringLiteral()) { // Nothing else to do. } else { @@ -3892,8 +3891,6 @@ class Compiler : public ErrorSink { pGen->setR0ExpressionType(ET_LVALUE); } } - // Else we fall through to the function call below, with - // t == 0 to trigger an indirect function call. Hack! } else if (t == '&') { VariableInfo* pVI = VI(tok); pGen->leaR0((int) pVI->pAddress, createPtrType(pVI->pType), @@ -3912,7 +3909,7 @@ class Compiler : public ErrorSink { // printf("Adding new global function %s\n", nameof(t)); } VariableInfo* pVI = VI(t); - n = (intptr_t) pVI->pAddress; + int n = (intptr_t) pVI->pAddress; /* forward reference: try our lookup function */ if (!n) { linkGlobal(t, tok == '('); @@ -3922,7 +3919,7 @@ class Compiler : public ErrorSink { } } if (tok != '(') { - /* variable */ + /* variable or function name */ if (!n) { linkGlobal(t, false); n = (intptr_t) pVI->pAddress; @@ -3930,83 +3927,84 @@ class Compiler : public ErrorSink { error("Undeclared variable %s\n", nameof(t)); } } - // load a variable - pGen->leaR0(n, createPtrType(pVI->pType), ET_LVALUE); - if (tokl == 11) { - // post inc / post dec - doIncDec(tokc == OP_INCREMENT, true); - next(); + } + // load a variable + Type* pVal = createPtrType(pVI->pType); + if (n) { + ExpressionType et = ET_LVALUE; + if (pVal->pHead->tag == TY_FUNC) { + et = ET_RVALUE; } + pGen->leaR0(n, pVal, et); + } else { + pVI->pForward = (void*) pGen->leaForward( + (int) pVI->pForward, pVal); } } } - /* function call */ - if (accept('(')) { - Type* pDecl = NULL; - VariableInfo* pVI = NULL; - if (n == 1) { // Indirect function call, push address of fn. + /* Now handle postfix operators */ + for(;;) { + if (tokl == 11) { + // post inc / post dec + doIncDec(tokc == OP_INCREMENT, true); + next(); + } else if (accept('(')) { + /* function call */ + Type* pDecl = NULL; + VariableInfo* pVI = NULL; Type* pFn = pGen->getR0Type(); assert(pFn->tag == TY_POINTER); assert(pFn->pHead->tag == TY_FUNC); pDecl = pFn->pHead; pGen->pushR0(); - } else { - pVI = VI(t); - pDecl = pVI->pType; - Type* pFn = createPtrType(pDecl); - if (n == 0) { - pVI->pForward = (void*) pGen->leaForward( - (int) pVI->pForward, pFn); - } else { - pGen->leaR0(n, pFn, ET_RVALUE); - } - pGen->pushR0(); - } - Type* pArgList = pDecl->pTail; - bool varArgs = pArgList == NULL; - /* push args and invert order */ - a = pGen->beginFunctionCallArguments(); - int l = 0; - int argCount = 0; - while (tok != ')' && tok != EOF) { - if (! varArgs && !pArgList) { - error("Unexpected argument."); - } - expr(); - pGen->forceR0RVal(); - Type* pTargetType; - if (pArgList) { - pTargetType = pArgList->pHead; - pArgList = pArgList->pTail; - } else { - // This is a ... function, just pass arguments in their - // natural type. - pTargetType = pGen->getR0Type(); - if (pTargetType->tag == TY_FLOAT) { - pTargetType = mkpDouble; + Type* pArgList = pDecl->pTail; + bool varArgs = pArgList == NULL; + /* push args and invert order */ + a = pGen->beginFunctionCallArguments(); + int l = 0; + int argCount = 0; + while (tok != ')' && tok != EOF) { + if (! varArgs && !pArgList) { + error("Unexpected argument."); } + expr(); + pGen->forceR0RVal(); + Type* pTargetType; + if (pArgList) { + pTargetType = pArgList->pHead; + pArgList = pArgList->pTail; + } else { + // This is a ... function, just pass arguments in their + // natural type. + pTargetType = pGen->getR0Type(); + if (pTargetType->tag == TY_FLOAT) { + pTargetType = mkpDouble; + } + } + if (pTargetType->tag == TY_VOID) { + error("Can't pass void value for argument %d", + argCount + 1); + } else { + l += pGen->storeR0ToArg(l, pTargetType); + } + if (accept(',')) { + // fine + } else if ( tok != ')') { + error("Expected ',' or ')'"); + } + argCount += 1; } - if (pTargetType->tag == TY_VOID) { - error("Can't pass void value for argument %d", - argCount + 1); - } else { - l += pGen->storeR0ToArg(l, pTargetType); - } - if (accept(',')) { - // fine - } else if ( tok != ')') { - error("Expected ',' or ')'"); + if (! varArgs && pArgList) { + error("Expected more argument(s). Saw %d", argCount); } - argCount += 1; - } - if (! varArgs && pArgList) { - error("Expected more argument(s). Saw %d", argCount); + pGen->endFunctionCallArguments(pDecl, a, l); + skip(')'); + pGen->callIndirect(l, pDecl); + pGen->adjustStackAfterCall(pDecl, l, true); + } else { + break; } - pGen->endFunctionCallArguments(pDecl, a, l); - skip(')'); - pGen->callIndirect(l, pDecl); - pGen->adjustStackAfterCall(pDecl, l, true); } } |