static expr *expr2(int critical) { expr *e, *f; e = expr3(critical); if (!e) return NULL; while (i == '&') { i = scan(scpriv, tokval); f = expr3(critical); if (!f) return NULL; if (!(is_simple(e) || is_just_unknown(e)) || !(is_simple(f) || is_just_unknown(f))) { nasm_error(ERR_NONFATAL, "`&' operator may only be applied to" " scalar values"); } if (is_just_unknown(e) || is_just_unknown(f)) e = unknown_expr(); else e = scalarvect(reloc_value(e) & reloc_value(f)); } return e; }
static Tree expr3(int k) { int k1; Tree p = unary(); for (k1 = prec[t]; k1 >= k; k1--) while (prec[t] == k1 && *cp != '=') { Tree r; Coordinate pt; int op = t; t = gettok(); pt = src; p = pointer(p); if (op == ANDAND || op == OROR) { r = pointer(expr3(k1)); if (events.points) apply(events.points, &pt, &r); } else r = pointer(expr3(k1 + 1)); p = (*optree[op])(oper[op], p, r); } return p; }
static Tree expr2(void) { Tree p = expr3(4); if (t == '?') { Tree l, r; Coordinate pts[2]; if (Aflag > 1 && isfunc(p->type)) warning("%s used in a conditional expression\n", funcname(p)); p = pointer(p); t = gettok(); pts[0] = src; l = pointer(expr(':')); pts[1] = src; r = pointer(expr2()); if (events.points) { apply(events.points, &pts[0], &l); apply(events.points, &pts[1], &r); } p = condtree(p, l, r); } return p; }
void test_expressions() { RPN::Context cxt; cxt.insert("a", new RPN::ArgumentNode(1, 3)); cxt.insert("b", new RPN::ArgumentNode(2, 3)); cxt.insert("c", new RPN::ArgumentNode(3, 3)); RPN::Expression fixed("13 + sin(0)", cxt); insist_equal(fixed.evaluate(), 13.0); RPN::Expression functor("a + b * c", cxt, 3); insist_equal(functor.evaluate(1, 2, 3), 7.0); cxt.insert("e", new RPN::ExpressionNode(&fixed)); cxt.insert("f", new RPN::ExpressionNode(&functor)); const RPN::Node* node = cxt.lookup("e"); insist_equal(node->isValue(), 1); insist_zero(node->arguments()); node = cxt.lookup("f"); insist_equal(node->isFunction(), 1); insist_equal(node->arguments(), 3); RPN::Expression expr1("2 * e + 5", cxt); insist_equal(expr1.evaluate(), 31.0); RPN::Expression expr2("f(1, 2, 3)", cxt); insist_equal(expr2.evaluate(), 7.0); RPN::Expression expr3("2 * f(3, e, 2) + 5", cxt); insist_equal(expr3.evaluate(), 63.0); }
int expr2(big_int *a) { big_int *b = NULL; int result = 0; b = big_int_create(1); if (b == NULL) { printf("error when creating [b]\n"); result = 1; goto done; } if (expr3(a)) { result = 2; goto done; } while (1) { switch ((int) curr_lex.token) { case AND1 : case '&' : match(curr_lex.token); if (expr3(b)) { result = 3; goto done; } if (big_int_and(a, b, 0, a)) { printf("error in big_int_and()\n"); result = 4; goto done; } continue; default : goto done; } } done: big_int_destroy(b); return result; }
static bool expr3 (int * pn) { if (* cur == '-' && (cur == text_start || strchr ("+-*/(", cur [-1]))) { cur ++; if (! expr3 (pn)) return false; * pn = - *pn; } else if (* cur == '(') { cur ++; if (! expr1 (pn)) return false; if (* cur != ')') return false; cur ++; } else if (isdigit (* cur)) { int n = 0; do { int d = * cur - '0'; int nn = n * 10 + d; // checking overflow if ((nn - d) / 10 != n) return false; n = nn; } while (isdigit (* ++ cur)); * pn = n; } else { return false; } return true; }
static bool expr2 (int * pn) { int op, n1, n2, n; if (! expr3 (& n1)) return false; op = * cur; if (op != '*' && op != '/') { * pn = n1; return true; } cur ++; if (! expr2 (& n2)) return false; if (op == '*') { n = n1 * n2; // checking overflow if (n2 != 0 && n / n2 != n1) return false; } else { if (n2 == 0) return false; n = n1 / n2; } * pn = n; return true; }
/* expr2 : ['-'] expr3; */ int expr2(ParserData *pd) { int currToken; double dblValue; currToken = pd->m_Token.Type; if ( pd->m_Token.Type == T_UMINUS ) { GetNextToken(pd->m_strExpr, &(pd->m_Token)); } if ( !expr3(pd) ) return 0; if ( currToken == T_UMINUS ) { dblValue = pd->m_stack[pd->m_top--]; dblValue *= -1; pd->m_stack[++pd->m_top] = dblValue; } return 1; }
PHPEntityBase::Ptr_t PHPCodeCompletion::DoGetPHPEntryUnderTheAtPos(IEditor* editor, int pos, bool forFunctionCalltip) { if(!PHPWorkspace::Get()->IsOpen()) return PHPEntityBase::Ptr_t(NULL); pos = editor->GetCtrl()->WordEndPosition(pos, true); // Get the expression under the caret wxString unsavedBuffer = editor->GetTextRange(0, pos); wxString filter; PHPEntityBase::Ptr_t resolved; // Parse the source file PHPSourceFile source(unsavedBuffer); source.SetFilename(editor->GetFileName()); source.SetParseFunctionBody(false); source.Parse(); PHPEntityBase::Ptr_t currentScope = source.CurrentScope(); if(currentScope && currentScope->Is(kEntityTypeClass)) { // we are trying to resolve a 'word' under the caret within the class // body but _not_ within a function body (i.e. it can only be // a definition of some kind) // try to construct an expression that will work int wordStart = editor->GetCtrl()->WordStartPosition(pos, true); wxString theWord = editor->GetTextRange(wordStart, pos); wxString theWordNoDollar = theWord; if(theWord.StartsWith("$")) { theWordNoDollar = theWord.Mid(1); } PHPExpression expr2(unsavedBuffer, "<?php $this->" + theWordNoDollar, forFunctionCalltip); resolved = expr2.Resolve(m_lookupTable, editor->GetFileName().GetFullPath()); filter = expr2.GetFilter(); if(!resolved) { // Maybe its a static member/function/const, try using static keyword PHPExpression expr3(unsavedBuffer, "<?php static::" + theWord, forFunctionCalltip); resolved = expr2.Resolve(m_lookupTable, editor->GetFileName().GetFullPath()); filter = expr2.GetFilter(); } } if(!resolved) { PHPExpression expr(unsavedBuffer, "", forFunctionCalltip); resolved = expr.Resolve(m_lookupTable, editor->GetFileName().GetFullPath()); filter = expr.GetFilter(); } if(resolved && !filter.IsEmpty()) { resolved = m_lookupTable.FindMemberOf(resolved->GetDbId(), filter); if(!resolved) { // Fallback to functions and constants PHPEntityBase::List_t children = m_lookupTable.FindGlobalFunctionAndConsts(PHPLookupTable::kLookupFlags_ExactMatch, filter); if(children.size() == 1) { resolved = *children.begin(); } } if(resolved && resolved->Is(kEntityTypeFunction)) { // for a function, we need to load its children (function arguments) resolved->SetChildren(m_lookupTable.LoadFunctionArguments(resolved->GetDbId())); } else if(resolved && resolved->Is(kEntityTypeFunctionAlias)) { // for a function alias, we need to load the actual functions' children (function arguments) PHPEntityBase::Ptr_t realFunc = resolved->Cast<PHPEntityFunctionAlias>()->GetFunc(); realFunc->SetChildren(m_lookupTable.LoadFunctionArguments(realFunc->GetDbId())); } } return resolved; }
void CheckCondition::checkIncorrectLogicOperator() { const bool printStyle = _settings->isEnabled("style"); const bool printWarning = _settings->isEnabled("warning"); if (!printWarning && !printStyle) return; const SymbolDatabase *symbolDatabase = _tokenizer->getSymbolDatabase(); const std::size_t functions = symbolDatabase->functionScopes.size(); for (std::size_t ii = 0; ii < functions; ++ii) { const Scope * scope = symbolDatabase->functionScopes[ii]; for (const Token* tok = scope->classStart->next(); tok != scope->classEnd; tok = tok->next()) { if (!Token::Match(tok, "%oror%|&&") || !tok->astOperand1() || !tok->astOperand2()) continue; // Opposite comparisons around || or && => always true or always false if ((tok->astOperand1()->isName() || tok->astOperand2()->isName()) && isOppositeCond(true, _tokenizer->isCPP(), tok->astOperand1(), tok->astOperand2(), _settings->library.functionpure)) { const bool alwaysTrue(tok->str() == "||"); incorrectLogicOperatorError(tok, tok->expressionString(), alwaysTrue, false); continue; } // 'A && (!A || B)' is equivalent with 'A && B' // 'A || (!A && B)' is equivalent with 'A || B' if (printStyle && ((tok->str() == "||" && tok->astOperand2()->str() == "&&") || (tok->str() == "&&" && tok->astOperand2()->str() == "||"))) { const Token* tok2 = tok->astOperand2()->astOperand1(); if (isOppositeCond(true, _tokenizer->isCPP(), tok->astOperand1(), tok2, _settings->library.functionpure)) { std::string expr1(tok->astOperand1()->expressionString()); std::string expr2(tok->astOperand2()->astOperand1()->expressionString()); std::string expr3(tok->astOperand2()->astOperand2()->expressionString()); if (expr1.length() + expr2.length() + expr3.length() > 50U) { if (expr1[0] == '!' && expr2[0] != '!') { expr1 = "!A"; expr2 = "A"; } else { expr1 = "A"; expr2 = "!A"; } expr3 = "B"; } const std::string cond1 = expr1 + " " + tok->str() + " (" + expr2 + " " + tok->astOperand2()->str() + " " + expr3 + ")"; const std::string cond2 = expr1 + " " + tok->str() + " " + expr3; redundantConditionError(tok, tok2->expressionString() + ". '" + cond1 + "' is equivalent to '" + cond2 + "'", false); continue; } } // Comparison #1 (LHS) const Token *comp1 = tok->astOperand1(); if (comp1 && comp1->str() == tok->str()) comp1 = comp1->astOperand2(); // Comparison #2 (RHS) const Token *comp2 = tok->astOperand2(); bool inconclusive = false; // Parse LHS bool not1; std::string op1, value1; const Token *expr1; if (!parseComparison(comp1, ¬1, &op1, &value1, &expr1, &inconclusive)) continue; // Parse RHS bool not2; std::string op2, value2; const Token *expr2; if (!parseComparison(comp2, ¬2, &op2, &value2, &expr2, &inconclusive)) continue; if (inconclusive && !_settings->inconclusive) continue; if (isSameExpression(_tokenizer->isCPP(), true, comp1, comp2, _settings->library.functionpure)) continue; // same expressions => only report that there are same expressions if (!isSameExpression(_tokenizer->isCPP(), true, expr1, expr2, _settings->library.functionpure)) continue; const bool isfloat = astIsFloat(expr1, true) || MathLib::isFloat(value1) || astIsFloat(expr2, true) || MathLib::isFloat(value2); // don't check floating point equality comparisons. that is bad // and deserves different warnings. if (isfloat && (op1 == "==" || op1 == "!=" || op2 == "==" || op2 == "!=")) continue; const double d1 = (isfloat) ? MathLib::toDoubleNumber(value1) : 0; const double d2 = (isfloat) ? MathLib::toDoubleNumber(value2) : 0; const MathLib::bigint i1 = (isfloat) ? 0 : MathLib::toLongNumber(value1); const MathLib::bigint i2 = (isfloat) ? 0 : MathLib::toLongNumber(value2); const bool useUnsignedInt = (std::numeric_limits<MathLib::bigint>::max()==i1)||(std::numeric_limits<MathLib::bigint>::max()==i2); const MathLib::biguint u1 = (useUnsignedInt) ? MathLib::toLongNumber(value1) : 0; const MathLib::biguint u2 = (useUnsignedInt) ? MathLib::toLongNumber(value2) : 0; // evaluate if expression is always true/false bool alwaysTrue = true, alwaysFalse = true; bool firstTrue = true, secondTrue = true; for (int test = 1; test <= 5; ++test) { // test: // 1 => testvalue is less than both value1 and value2 // 2 => testvalue is value1 // 3 => testvalue is between value1 and value2 // 4 => testvalue value2 // 5 => testvalue is larger than both value1 and value2 bool result1, result2; if (isfloat) { const double testvalue = getvalue<double>(test, d1, d2); result1 = checkFloatRelation(op1, testvalue, d1); result2 = checkFloatRelation(op2, testvalue, d2); } else if (useUnsignedInt) { const MathLib::biguint testvalue = getvalue<MathLib::biguint>(test, u1, u2); result1 = checkIntRelation(op1, testvalue, u1); result2 = checkIntRelation(op2, testvalue, u2); } else { const MathLib::bigint testvalue = getvalue<MathLib::bigint>(test, i1, i2); result1 = checkIntRelation(op1, testvalue, i1); result2 = checkIntRelation(op2, testvalue, i2); } if (not1) result1 = !result1; if (not2) result2 = !result2; if (tok->str() == "&&") { alwaysTrue &= (result1 && result2); alwaysFalse &= !(result1 && result2); } else { alwaysTrue &= (result1 || result2); alwaysFalse &= !(result1 || result2); } firstTrue &= !(!result1 && result2); secondTrue &= !(result1 && !result2); } const std::string cond1str = conditionString(not1, expr1, op1, value1); const std::string cond2str = conditionString(not2, expr2, op2, value2); if (printWarning && (alwaysTrue || alwaysFalse)) { const std::string text = cond1str + " " + tok->str() + " " + cond2str; incorrectLogicOperatorError(tok, text, alwaysTrue, inconclusive); } else if (printStyle && secondTrue) { const std::string text = "If '" + cond1str + "', the comparison '" + cond2str + "' is always " + (secondTrue ? "true" : "false") + "."; redundantConditionError(tok, text, inconclusive); } else if (printStyle && firstTrue) { //const std::string text = "The comparison " + cond1str + " is always " + // (firstTrue ? "true" : "false") + " when " + // cond2str + "."; const std::string text = "If '" + cond2str + "', the comparison '" + cond1str + "' is always " + (firstTrue ? "true" : "false") + "."; redundantConditionError(tok, text, inconclusive); } } } }