Ejemplo n.º 1
0
Archivo: eval.c Proyecto: AxFab/nasm
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;
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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, &not1, &op1, &value1, &expr1, &inconclusive))
                continue;

            // Parse RHS
            bool not2;
            std::string op2, value2;
            const Token *expr2;
            if (!parseComparison(comp2, &not2, &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);
            }
        }
    }
}