Clean up expression code.
Concatenate adjacent string literals.
diff --git a/libacc/acc.cpp b/libacc/acc.cpp
index 0d26a5c..5731f31 100644
--- a/libacc/acc.cpp
+++ b/libacc/acc.cpp
@@ -1854,6 +1854,11 @@
Vector<Mark> mLevelStack;
};
+ struct Value {
+ Type* pType;
+ bool mLValue; // This is the L-value (true means the lvalue)
+ };
+
int ch; // Current input character, or EOF
tokenid_t tok; // token
intptr_t tokc; // token extra info
@@ -1875,10 +1880,14 @@
SymbolStack mGlobals;
SymbolStack mLocals;
+ // Prebuilt types, makes things slightly faster.
Type* mkpInt;
Type* mkpChar;
Type* mkpVoid;
+ // Track what's on the expression stack
+ Vector<Value> mValueStack;
+
InputStream* file;
CodeBuf codeBuf;
@@ -1995,10 +2004,18 @@
}
}
+ bool isSymbol(tokenid_t t) {
+ return t >= TOK_SYMBOL &&
+ ((size_t) (t-TOK_SYMBOL)) < mTokenTable.size();
+ }
+
+ bool isSymbolOrKeyword(tokenid_t t) {
+ return t >= TOK_KEYWORD &&
+ ((size_t) (t-TOK_SYMBOL)) < mTokenTable.size();
+ }
+
VariableInfo* VI(tokenid_t t) {
- if ( t < TOK_SYMBOL || ((size_t) (t-TOK_SYMBOL)) >= mTokenTable.size()) {
- internalError();
- }
+ assert(isSymbol(t));
VariableInfo* pV = mTokenTable[t].mpVariableInfo;
if (pV && pV->tok != t) {
internalError();
@@ -2010,7 +2027,8 @@
return t >= TOK_SYMBOL && VI(t) != 0;
}
- inline const char* nameof(tokenid_t t) {
+ const char* nameof(tokenid_t t) {
+ assert(isSymbolOrKeyword(t));
return mTokenTable[t].pText;
}
@@ -2324,37 +2342,48 @@
return false;
}
- /* l is one if '=' parsing wanted (quick hack) */
- void unary(intptr_t l) {
- intptr_t n, t, a;
- int c;
- String tString;
- t = 0;
- n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */
- if (tok == '\"') {
+ bool acceptStringLiteral() {
+ if (tok == '"') {
pGen->li((int) glo);
- while (ch != '\"' && ch != EOF) {
- *allocGlobalSpace(1) = getq();
+ // This while loop merges multiple adjacent string constants.
+ while (tok == '"') {
+ while (ch != '"' && ch != EOF) {
+ *allocGlobalSpace(1) = getq();
+ }
+ if (ch != '"') {
+ error("Unterminated string constant.");
+ }
+ inp();
+ next();
}
- if (ch != '\"') {
- error("Unterminated string constant.");
- }
+ /* Null terminate */
*glo = 0;
/* align heap */
allocGlobalSpace((char*) (((intptr_t) glo + 4) & -4) - glo);
- inp();
- next();
+
+ return true;
+ }
+ return false;
+ }
+ /* Parse and evaluate a unary expression.
+ * allowAssignment is true if '=' parsing wanted (quick hack)
+ */
+ void unary(bool allowAssignment) {
+ intptr_t n, t, a;
+ t = 0;
+ n = 1; /* type of expression 0 = forward, 1 = value, other = lvalue */
+ if (acceptStringLiteral()) {
+ // Nothing else to do.
} else {
- c = tokl;
+ int c = tokl;
a = tokc;
t = tok;
- tString = mTokenString;
next();
if (t == TOK_NUM) {
pGen->li(a);
} else if (c == 2) {
/* -, +, !, ~ */
- unary(0);
+ unary(false);
pGen->clearR1();
if (t == '!')
pGen->gcmp(a);
@@ -2378,7 +2407,7 @@
t = 0;
}
skip(')');
- unary(0);
+ unary(false);
if (tok == '=') {
next();
pGen->pushR0();
@@ -2393,7 +2422,7 @@
next();
} else if (t == EOF ) {
error("Unexpected EOF.");
- } else if (!checkSymbol(t, &tString)) {
+ } else if (!checkSymbol(t)) {
// Don't have to do anything special here, the error
// message was printed by checkSymbol() above.
} else {
@@ -2405,11 +2434,10 @@
n = (intptr_t) VI(t)->pAddress;
/* forward reference: try dlsym */
if (!n) {
- n = (intptr_t) dlsym(RTLD_DEFAULT,
- tString.getUnwrapped());
+ n = (intptr_t) dlsym(RTLD_DEFAULT, nameof(t));
VI(t)->pAddress = (void*) n;
}
- if ((tok == '=') & l) {
+ if ((tok == '=') & allowAssignment) {
/* assignment */
next();
expr();
@@ -2417,7 +2445,7 @@
} else if (tok != '(') {
/* variable */
if (!n) {
- error("Undefined variable %s", tString.getUnwrapped());
+ error("Undefined variable %s", nameof(t));
}
pGen->loadR0(n, tokl == 11, tokc);
if (tokl == 11) {
@@ -2435,7 +2463,7 @@
/* push args and invert order */
a = pGen->beginFunctionCallArguments();
next();
- l = 0;
+ int l = 0;
while (tok != ')' && tok != EOF) {
expr();
pGen->storeR0ToArg(l);
@@ -2458,28 +2486,30 @@
}
}
- void sum(int l) {
+ /* Recursive descent parser for binary operations.
+ */
+ void binaryOp(int level) {
intptr_t t, n, a;
t = 0;
- if (l-- == 1)
- unary(1);
+ if (level-- == 1)
+ unary(true);
else {
- sum(l);
+ binaryOp(level);
a = 0;
- while (l == tokl) {
+ while (level == tokl) {
n = tok;
t = tokc;
next();
- if (l > 8) {
+ if (level > 8) {
a = pGen->gtst(t == OP_LOGICAL_OR, a); /* && and || output code generation */
- sum(l);
+ binaryOp(level);
} else {
pGen->pushR0();
- sum(l);
+ binaryOp(level);
pGen->popR1();
- if ((l == 4) | (l == 5)) {
+ if ((level == 4) | (level == 5)) {
pGen->gcmp(t);
} else {
pGen->genOp(t);
@@ -2487,7 +2517,7 @@
}
}
/* && and || output code generation */
- if (a && l > 8) {
+ if (a && level > 8) {
a = pGen->gtst(t == OP_LOGICAL_OR, a);
pGen->li(t != OP_LOGICAL_OR);
pGen->gjmp(5); /* jmp $ + 5 (sizeof li, FIXME for ARM) */
@@ -2498,7 +2528,7 @@
}
void expr() {
- sum(11);
+ binaryOp(11);
}
int test_expr() {
@@ -2809,7 +2839,7 @@
}
bool checkSymbol() {
- return checkSymbol(tok, &mTokenString);
+ return checkSymbol(tok);
}
void decodeToken(String& buffer, tokenid_t token) {
@@ -2830,7 +2860,7 @@
}
}
- bool checkSymbol(tokenid_t token, String* pText) {
+ bool checkSymbol(tokenid_t token) {
bool result = token >= TOK_SYMBOL;
if (!result) {
String temp;