From 5874fc5bb610763a0cce93a816c8014c7404e512 Mon Sep 17 00:00:00 2001 From: Lars Ljung Date: Fri, 8 Sep 2017 19:22:58 +0200 Subject: [PATCH 1/2] Handle constant folding for the shift operators --- simplecpp.cpp | 24 ++++++++++++++++++++++++ simplecpp.h | 1 + 2 files changed, 25 insertions(+) diff --git a/simplecpp.cpp b/simplecpp.cpp index 4149a3f8..cb9e0b88 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -589,6 +589,7 @@ void simplecpp::TokenList::constFold() constFoldUnaryNotPosNeg(tok); constFoldMulDivRem(tok); constFoldAddSub(tok); + constFoldShift(tok); constFoldComparison(tok); constFoldBitwise(tok); constFoldLogicalOp(tok); @@ -769,6 +770,29 @@ void simplecpp::TokenList::constFoldAddSub(Token *tok) } } +void simplecpp::TokenList::constFoldShift(Token *tok) +{ + for (; tok && tok->op != ')'; tok = tok->next) { + if (!tok->previous || !tok->previous->number) + continue; + if (!tok->next || !tok->next->number) + continue; + + long long result; + if (tok->str == "<<") + result = stringToLL(tok->previous->str) << stringToLL(tok->next->str); + else if (tok->str == ">>") + result = stringToLL(tok->previous->str) >> stringToLL(tok->next->str); + else + continue; + + tok = tok->previous; + tok->setstr(toString(result)); + deleteToken(tok->next); + deleteToken(tok->next); + } +} + static const std::string NOTEQ("not_eq"); void simplecpp::TokenList::constFoldComparison(Token *tok) { diff --git a/simplecpp.h b/simplecpp.h index 21fa5525..2e608d22 100644 --- a/simplecpp.h +++ b/simplecpp.h @@ -249,6 +249,7 @@ namespace simplecpp { void constFoldUnaryNotPosNeg(Token *tok); void constFoldMulDivRem(Token *tok); void constFoldAddSub(Token *tok); + void constFoldShift(Token *tok); void constFoldComparison(Token *tok); void constFoldBitwise(Token *tok); void constFoldLogicalOp(Token *tok); From a152704af23f54a6ffb045f4f4559c4767ce3a5f Mon Sep 17 00:00:00 2001 From: Lars Ljung Date: Wed, 13 Sep 2017 22:26:08 +0200 Subject: [PATCH 2/2] Support for bitwise not. --- run-tests.py | 1 - simplecpp.cpp | 13 ++++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/run-tests.py b/run-tests.py index 712ba5e6..7ad35dfd 100644 --- a/run-tests.py +++ b/run-tests.py @@ -69,7 +69,6 @@ def cleanup(out): # todo, high priority 'c99-6_10_3_4_p5.c', 'c99-6_10_3_4_p6.c', - 'cxx_compl.cpp', # if A compl B 'cxx_oper_keyword_ms_compat.cpp', 'expr_usual_conversions.c', # condition is true: 4U - 30 >= 0 'stdint.c', diff --git a/simplecpp.cpp b/simplecpp.cpp index e290421a..be3bf59b 100644 --- a/simplecpp.cpp +++ b/simplecpp.cpp @@ -699,6 +699,7 @@ void simplecpp::TokenList::combineOperators() } } +static const std::string COMPL("compl"); static const std::string NOT("not"); void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok) { @@ -706,10 +707,16 @@ void simplecpp::TokenList::constFoldUnaryNotPosNeg(simplecpp::Token *tok) // "not" might be ! if (isAlternativeUnaryOp(tok, NOT)) tok->op = '!'; + // "compl" might be ~ + else if (isAlternativeUnaryOp(tok, COMPL)) + tok->op = '~'; if (tok->op == '!' && tok->next && tok->next->number) { tok->setstr(tok->next->str == "0" ? "1" : "0"); deleteToken(tok->next); + } else if (tok->op == '~' && tok->next && tok->next->number) { + tok->setstr(toString(~stringToLL(tok->next->str))); + deleteToken(tok->next); } else { if (tok->previous && (tok->previous->number || tok->previous->name)) continue; @@ -1929,15 +1936,15 @@ static void simplifySizeof(simplecpp::TokenList &expr, const std::map altop(&altopData[0], &altopData[7]); +static const char * const altopData[] = {"and","or","bitand","bitor","compl","not","not_eq","xor"}; +static const std::set altop(&altopData[0], &altopData[8]); static void simplifyName(simplecpp::TokenList &expr) { for (simplecpp::Token *tok = expr.front(); tok; tok = tok->next) { if (tok->name) { if (altop.find(tok->str) != altop.end()) { bool alt; - if (tok->str == "not") { + if (tok->str == "not" || tok->str == "compl") { alt = isAlternativeUnaryOp(tok,tok->str); } else { alt = isAlternativeBinaryOp(tok,tok->str);