bool IsscalarAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
    {
        if (lhs != 1)
        {
            return false;
        }

        const ast::exps_t args = e.getArgs();
        if (args.size() != 1)
        {
            return false;
        }

	ast::Exp * first = args.front();
	first->accept(visitor);
	Result & R1 = visitor.getResult();
	TIType & type1 = R1.getType();

	if (!type1.ismatrix())
	{
	    return false;
	}
	
	if (type1.isscalar())
	{
	    TIType type(visitor.getGVN(), TIType::BOOLEAN);
	    Result & res = e.getDecorator().setResult(type);
	    res.getConstant() = new types::Bool(1);
	    e.getDecorator().setCall(L"isscalar");
	    visitor.setResult(res);
	    return true;
	}

	return false;
    }
void DeprecatedChecker::__Mfprintf::preCheckNode(const ast::Exp & e, SLintContext & context, SLintResult & result)
{
    const ast::CallExp & ce = static_cast<const ast::CallExp &>(e);
    const ast::exps_t args = ce.getArgs();
    if (args.size() != 0)
    {
        const ast::Exp & first = *args.front();
        if (first.isDoubleExp() && static_cast<const ast::DoubleExp &>(first).getValue() == -1)
        {
            result.report(context, e.getLocation(), *this, _("mfprintf(-1, ...) is deprecated."));
        }
    }
}
bool IconvertAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
{
    if (lhs != 1)
    {
        return false;
    }

    const ast::exps_t args = e.getArgs();
    if (args.size() != 2)
    {
        return false;
    }

    ast::Exp * first = args.front();
    ast::Exp * second = args.back();

    first->accept(visitor);
    Result R1 = visitor.getResult();
    TIType & type1 = R1.getType();
    if (!type1.ismatrix())
    {
        return false;
    }
    second->accept(visitor);
    Result & R2 = visitor.getResult();

    double val;
    unsigned char ival;

    if (R2.getConstant().getDblValue(val) && tools::asInteger<unsigned char>(val, ival))
    {
        TIType::Type type;

        switch (ival)
        {
            case 0:
                type = TIType::DOUBLE;
                break;
            case 1:
                type = TIType::INT8;
                break;
            case 2:
                type = TIType::INT16;
                break;
            case 4:
                type = TIType::INT32;
                break;
            case 8:
                type = TIType::INT64;
                break;
            case 11:
                type = TIType::UINT8;
                break;
            case 12:
                type = TIType::UINT16;
                break;
            case 14:
                type = TIType::UINT32;
                break;
            case 18:
                type = TIType::UINT64;
                break;
            default:
                return false;
        }

        TIType typ(visitor.getGVN(), type, type1.rows, type1.cols);
        Result & res = e.getDecorator().setResult(typ);
        e.getDecorator().setCall(L"iconvert");
        visitor.setResult(res);
        return true;
    }

    return false;
}
Exemple #4
0
void AnalysisVisitor::visit(ast::IfExp & e)
{
    logger.log(L"IfExp", e.getLocation());
    ast::Exp * shortcutExp = nullptr;

    // we apply the ConstantVisitor
    e.getTest().accept(cv);
    ast::Exp & test = e.getTest();

    if (cv.getResult() && test.isConstExp())
    {
        e.accept(cv);
        // we have a constant !
        ast::ConstExp & ce = static_cast<ast::ConstExp &>(test);
        types::InternalType * pIT = ce.getConstant();
        if (!pIT)
        {
            test.accept(cv.getExec());
            pIT = ce.getConstant();
        }
        if (pIT)
        {
            const bool result = pIT->isTrue();
            if (result)
            {
                shortcutExp = &e.getThen();
                e.getExps()[1] = nullptr;
            }
            else
            {
                shortcutExp = &e.getElse();
                e.getExps()[2] = nullptr;
            }
        }
    }
    else
    {
        ast::Exp * val = nullptr;
        bool isEq;
        if (test.isOpExp())
        {
            ast::OpExp & oe = static_cast<ast::OpExp &>(test);
            isEq = oe.getOper() == ast::OpExp::eq;
            if (isEq || oe.getOper() == ast::OpExp::ne)
            {
                if (oe.getLeft().isDoubleExp())
                {
                    ast::DoubleExp & de = static_cast<ast::DoubleExp &>(oe.getLeft());
                    if (types::InternalType * pIT = de.getConstant())
                    {
                        if (pIT->isDouble())
                        {
                            types::Double * pDbl = static_cast<types::Double *>(pIT);
                            if (pDbl->isEmpty())
                            {
                                val = &oe.getRight();
                            }
                        }
                    }
                }
                else if (oe.getRight().isDoubleExp())
                {
                    ast::DoubleExp & de = static_cast<ast::DoubleExp &>(oe.getRight());
                    if (types::InternalType * pIT = de.getConstant())
                    {
                        if (pIT->isDouble())
                        {
                            types::Double * pDbl = static_cast<types::Double *>(pIT);
                            if (pDbl->isEmpty())
                            {
                                val = &oe.getLeft();
                            }
                        }
                    }
                }
            }
        }
        else
        {
            ast::CallExp * ce = nullptr;
            if (test.isNotExp())
            {
                ast::NotExp & ne = static_cast<ast::NotExp &>(test);
                if (ne.getExp().isCallExp())
                {
                    ce = &static_cast<ast::CallExp &>(ne.getExp());
                    isEq = false;
                }
            }
            else if (test.isCallExp())
            {
                ce = &static_cast<ast::CallExp &>(test);
                isEq = true;
            }

            if (ce && ce->getName().isSimpleVar())
            {
                ast::SimpleVar & var = static_cast<ast::SimpleVar &>(ce->getName());
                const symbol::Symbol & sym = var.getSymbol();
                const std::wstring & name = sym.getName();
                if (name == L"isempty" && getCM().checkGlobalConstant(sym))
                {
                    const ast::exps_t args = ce->getArgs();
                    if (args.size() == 1)
                    {
                        val = args.front();
                    }
                }
            }
        }

        if (val)
        {
            // test is something like val == [], isempty(val), val ~= [], ~isempty(val)
            val->accept(*this);
            Result & res = getResult();
            TIType & ty = res.getType();
            if ((ty.ismatrix() && ty.isscalar()) || (getCM().check(ConstraintManager::STRICT_POSITIVE, ty.rows.getValue()) || getCM().check(ConstraintManager::STRICT_POSITIVE, ty.cols.getValue())))
            {
                if (isEq)
                {
                    shortcutExp = &e.getElse();
                    e.getExps()[2] = nullptr;
                }
                else
                {
                    shortcutExp = &e.getThen();
                    e.getExps()[1] = nullptr;
                }
            }
        }
    }

    if (shortcutExp)
    {
        e.replace(shortcutExp);
        shortcutExp->accept(*this);
    }
    else
    {
        dm.addBlock(Block::EXCLUSIVE, &e);
        e.getTest().accept(*this);
        dm.releaseTmp(getResult().getTempId());
        dm.addBlock(Block::NORMAL, &e.getThen());
        e.getThen().accept(*this);
        dm.finalizeBlock();
        dm.addBlock(Block::NORMAL, e.hasElse() ? &e.getElse() : nullptr);
        if (e.hasElse())
        {
            e.getElse().accept(*this);
        }
        dm.finalizeBlock();
        dm.finalizeBlock();
    }
}
bool AnalysisVisitor::analyzeIndices(TIType & type, ast::CallExp & ce)
{
    const ast::exps_t args = ce.getArgs();
    const unsigned int size = args.size();

    if (size >= 3)
    {
        // Not handle yet...
        // TODO
        return false;
    }

    if (size == 0)
    {
        Result & res = ce.getDecorator().setResult(type);
        setResult(res);
        return true;
    }

    SymbolicDimension first, second;
    bool safe, ret;

    argIndices.emplace(static_cast<ast::SimpleVar &>(ce.getName()), size, 1);
    if (size == 1)
    {
        // when there is one argument, a(?) is equivalent to A(?,1)
        // where A = matrix(a, r_a * c_a, 1)

        SymbolicDimension rows(type.rows);
        second = SymbolicDimension(getGVN(), 1);
        if (type.cols != 1)
        {
            rows *= type.cols;
        }
        ret = getDimension(rows, *args.front(), safe, first);
    }
    else
    {
        bool _safe;
        ret = getDimension(type.rows, *args.front(), _safe, first);
        if (ret)
        {
            argIndices.top().getIndex() = 2;
            ret = getDimension(type.cols, *args.back(), safe, second);
            safe = safe && _safe;
        }
        else
        {
            safe = _safe;
        }
    }
    argIndices.pop();

    if (ret)
    {
        TIType typ(getGVN(), type.type, first, second);
        Result & _res = ce.getDecorator().setResult(typ);
        setResult(_res);
        ce.getDecorator().safe = safe;
    }

    return ret;
}