Added support for lambdas to AST
Fixed bug that return statement left an operand on the stack
This commit is contained in:
parent
7b36bbbba8
commit
a407b55945
|
@ -451,6 +451,7 @@ static void compileTerm(Token *& tok, std::stack<Token*> &op, unsigned int depth
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
} else if (tok->str() == "return") {
|
} else if (tok->str() == "return") {
|
||||||
compileUnaryOp(tok, compileExpression, op, depth);
|
compileUnaryOp(tok, compileExpression, op, depth);
|
||||||
|
op.pop();
|
||||||
} else if (tok->isName()) {
|
} else if (tok->isName()) {
|
||||||
while (tok->next() && tok->next()->isName())
|
while (tok->next() && tok->next()->isName())
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
@ -496,18 +497,36 @@ static void compilePrecedence2(Token *&tok, std::stack<Token*> &op, unsigned int
|
||||||
} else if (tok->str() == "." && tok->strAt(1) != "*") {
|
} else if (tok->str() == "." && tok->strAt(1) != "*") {
|
||||||
compileBinOp(tok, compileScope, op, depth);
|
compileBinOp(tok, compileScope, op, depth);
|
||||||
} else if (tok->str() == "[") {
|
} else if (tok->str() == "[") {
|
||||||
|
if (isPrefixUnary(tok) && tok->link()->strAt(1) == "(") { // Lambda
|
||||||
|
// What we do here:
|
||||||
|
// - Nest the round bracket under the square bracket.
|
||||||
|
// - Nest what follows the lambda (if anything) with the lambda opening [
|
||||||
|
// - Compile the content of the lambda function as separate tree
|
||||||
|
Token* squareBracket = tok;
|
||||||
|
Token* roundBracket = squareBracket->link()->next();
|
||||||
|
Token* curlyBracket = Token::findsimplematch(roundBracket->link()->next(), "{");
|
||||||
|
tok = curlyBracket->next();
|
||||||
|
compileExpression(tok, op, depth);
|
||||||
|
op.push(roundBracket);
|
||||||
|
compileUnaryOp(squareBracket, 0, op, depth);
|
||||||
|
tok = curlyBracket->link()->next();
|
||||||
|
//compilePrecedence2(tok, op, depth);
|
||||||
|
} else {
|
||||||
Token* tok2 = tok;
|
Token* tok2 = tok;
|
||||||
compileBinOp(tok, compileExpression, op, depth);
|
compileBinOp(tok, compileExpression, op, depth);
|
||||||
tok = tok2->link()->next();
|
tok = tok2->link()->next();
|
||||||
|
}
|
||||||
} else if (tok->str() == "(" && (!iscast(tok) || Token::Match(tok->previous(), "if|while|for|switch|catch"))) {
|
} else if (tok->str() == "(" && (!iscast(tok) || Token::Match(tok->previous(), "if|while|for|switch|catch"))) {
|
||||||
Token* tok2 = tok;
|
Token* tok2 = tok;
|
||||||
tok = tok->next();
|
tok = tok->next();
|
||||||
|
bool opPrevTopSquare = op.size() > 0 && op.top() && op.top()->str() == "[";
|
||||||
compileExpression(tok, op, depth);
|
compileExpression(tok, op, depth);
|
||||||
tok = tok2;
|
tok = tok2;
|
||||||
if ((tok->previous() && tok->previous()->isName() && !Token::Match(tok->previous(), "return|throw"))
|
if ((tok->previous() && tok->previous()->isName() && !Token::Match(tok->previous(), "return|throw"))
|
||||||
|| tok->strAt(-1) == "]"
|
|| tok->strAt(-1) == "]"
|
||||||
|| (tok->strAt(-1) == ">" && tok->linkAt(-1))
|
|| (tok->strAt(-1) == ">" && tok->linkAt(-1))
|
||||||
|| (tok->strAt(-1) == ")" && !iscast(tok->linkAt(-1)))) { // Don't treat brackets to clarify precedence as function calls
|
|| (tok->strAt(-1) == ")" && !iscast(tok->linkAt(-1))) // Don't treat brackets to clarify precedence as function calls
|
||||||
|
|| (tok->strAt(-1) == "}" && opPrevTopSquare)) {
|
||||||
if (tok->strAt(1) != ")")
|
if (tok->strAt(1) != ")")
|
||||||
compileBinOp(tok, 0, op, depth);
|
compileBinOp(tok, 0, op, depth);
|
||||||
else
|
else
|
||||||
|
|
|
@ -587,6 +587,7 @@ private:
|
||||||
TEST_CASE(astfunction);
|
TEST_CASE(astfunction);
|
||||||
TEST_CASE(asttemplate);
|
TEST_CASE(asttemplate);
|
||||||
TEST_CASE(astcast);
|
TEST_CASE(astcast);
|
||||||
|
TEST_CASE(astlambda);
|
||||||
|
|
||||||
TEST_CASE(startOfExecutableScope);
|
TEST_CASE(startOfExecutableScope);
|
||||||
}
|
}
|
||||||
|
@ -10605,6 +10606,15 @@ private:
|
||||||
ASSERT_EQUALS("ab-(=", testAst("a = ((int)-b)")); // Multiple subsequent unary operators (cast and -)
|
ASSERT_EQUALS("ab-(=", testAst("a = ((int)-b)")); // Multiple subsequent unary operators (cast and -)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void astlambda() const {
|
||||||
|
ASSERT_EQUALS("([(return 0return", testAst("return [](){ return 0; }();"));
|
||||||
|
ASSERT_EQUALS("([(return 0return", testAst("return []() -> int { return 0; }();"));
|
||||||
|
ASSERT_EQUALS("([(return 0return", testAst("return [something]() -> int { return 0; }();"));
|
||||||
|
ASSERT_EQUALS("([cd,(return 0return", testAst("return [](int a, int b) -> int { return 0; }(c, d);"));
|
||||||
|
|
||||||
|
ASSERT_EQUALS("x([= 0return", testAst("x = [](){return 0; };"));
|
||||||
|
}
|
||||||
|
|
||||||
void compileLimits() {
|
void compileLimits() {
|
||||||
const char raw_code[] = "#define PTR1 (* (* (* (* (* (* (* (* (* (*\n"
|
const char raw_code[] = "#define PTR1 (* (* (* (* (* (* (* (* (* (*\n"
|
||||||
"#define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1\n"
|
"#define PTR2 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1 PTR1\n"
|
||||||
|
|
Loading…
Reference in New Issue