Ejemplo n.º 1
0
    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;
    }
bool PolymorphicMacroCache::getCompleteIn(MacroDef & macrodef, AnalysisVisitor & visitor, const std::vector<TIType> & in, std::vector<TIType> & completeIn)
{
    for (const auto & ty : in)
    {
        if (ty.type == TIType::UNKNOWN)
        {
            return false;
        }
    }

    const tools::SymbolOrdSet & globals = macrodef.getGlobals();
    completeIn.reserve(in.size() + globals.size());
    for (const auto & ty : in)
    {
        completeIn.emplace_back(ty);
    }

    const std::vector<symbol::Symbol> & declaredIn = macrodef.getIn();
    const unsigned int size = declaredIn.size();
    DataManager & dm = visitor.getDM();

    if (in.size() < size)
    {
        // we have less rhs than declared rhs:
        // function foo(x,y,z)...endfunction
        // called with foo(x) so y and z are globals
        for (unsigned int i = in.size(); i < size; ++i)
        {
            completeIn.emplace_back(dm.getType(declaredIn[i]));
        }
    }

    for (const auto & sym : globals)
    {
        TIType ty = dm.getType(sym, /* global */ true);
        completeIn.emplace_back(ty);
        if (ty.type == TIType::UNKNOWN)
        {
            return false;
        }
    }

    return true;
}
Ejemplo n.º 3
0
    bool MatrixAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
    {
        if (lhs > 1)
        {
            return false;
        }

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

	if (size == 2)
	{
	    return analyze2Args(visitor, args, e);
	}
	
        ast::Exp * first = args[0];
        ast::Exp * second = args[1];
        ast::Exp * third = args[2];

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

        second->accept(visitor);
        Result R2 = visitor.getResult();
        third->accept(visitor);
        Result & R3 = visitor.getResult();

        double val;
        SymbolicDimension rows;
        SymbolicDimension cols;

        if (R2.getConstant().getDblValue(val))
        {
            const int nrows = tools::cast<int>(val);
            if (nrows <= 0)
            {
                return false;
            }
            else
            {
                rows = SymbolicDimension(visitor.getGVN(), nrows);
            }
        }
        else if (GVN::Value * gvnValue = R2.getConstant().getGVNValue())
        {
            if (gvnValue->poly->isConstant() && gvnValue->poly->constant <= 0)
            {
                return false;
            }
            rows.setValue(gvnValue);
            rows.setGVN(&visitor.getGVN());
        }
        else
        {
            return false;
        }

        if (R3.getConstant().getDblValue(val))
        {
            const int ncols = tools::cast<int>(val);
            if (ncols <= 0)
            {
                return false;
            }
            else
            {
                cols = SymbolicDimension(visitor.getGVN(), ncols);
            }
        }
        else if (GVN::Value * gvnValue = R3.getConstant().getGVNValue())
        {
            if (gvnValue->poly->isConstant() && gvnValue->poly->constant <= 0)
            {
                return false;
            }
            cols.setValue(gvnValue);
            cols.setGVN(&visitor.getGVN());
        }
        else
        {
            return false;
        }

        const TIType & type = R1.getType();
        SymbolicDimension prod1 = type.rows * type.cols;
        SymbolicDimension prod2 = rows * cols;
        bool res = visitor.getCM().check(ConstraintManager::EQUAL, prod1.getValue(), prod2.getValue());
        if (res)
        {
            res = visitor.getCM().check(ConstraintManager::POSITIVE, rows.getValue());
            if (!res)
            {
                return false;
            }
        }
        else
        {
            return false;
        }

        TIType resT(visitor.getGVN(), R1.getType().type, rows, cols);
	int tempId;
	if (R1.getTempId() != -1)
	{
	    tempId = R1.getTempId();
	}
	else
	{
	    tempId = visitor.getDM().getTmpId(resT, false);
	}
        Result & _res = e.getDecorator().setResult(Result(resT, tempId));
        visitor.setResult(_res);
        return true;
    }
Ejemplo n.º 4
0
    bool MatrixAnalyzer::analyze2Args(AnalysisVisitor & visitor, const ast::exps_t & args, ast::CallExp & e)
    {
        ast::Exp * first = args[0];
        ast::Exp * second = args[1];

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

        SymbolicDimension rows;
        SymbolicDimension cols;
	bool hasRC = false;
	
	if (second->isCallExp())
	{
	    ast::CallExp & ce = static_cast<ast::CallExp &>(*second);
	    if (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"size" && visitor.getCM().checkGlobalConstant(sym))
		{
		    const ast::exps_t size_args = ce.getArgs();
		    if (size_args.size() == 1)
		    {
			ast::Exp * e = size_args[0];
			e->accept(visitor);
			Result & res = visitor.getResult();
			if (res.getType().ismatrix())
			{
			    rows = res.getType().rows;
			    cols = res.getType().cols;
			    hasRC = true;
			}
		    }
		}
	    }
	}

	if (hasRC)
	{
	    const TIType & type = R1.getType();
	    SymbolicDimension prod1 = type.rows * type.cols;
	    SymbolicDimension prod2 = rows * cols;
	    bool res = visitor.getCM().check(ConstraintManager::EQUAL, prod1.getValue(), prod2.getValue());
	    if (res)
	    {
		TIType resT(visitor.getGVN(), R1.getType().type, rows, cols);
		int tempId;
		if (R1.getTempId() != -1)
		{
		    tempId = R1.getTempId();
		}
		else
		{
		    tempId = visitor.getDM().getTmpId(resT, false);
		}
		Result & _res = e.getDecorator().setResult(Result(resT, tempId));
		visitor.setResult(_res);

		return true;
	    }
	}

	return false;
    }
bool SymbolicList::get(AnalysisVisitor & visitor, ast::ListExp & le, SymbolicList & sl)
{
    le.getStart().accept(visitor);
    Result Rstart = visitor.getResult();
    le.getEnd().accept(visitor);
    Result Rend = visitor.getResult();
    le.getStep().accept(visitor);
    Result & Rstep = visitor.getResult();

    double start, step, end;
    if (Rstart.getConstant().getDblValue(start) && Rstep.getConstant().getDblValue(step) && Rend.getConstant().getDblValue(end))
    {
        if (tools::isAnInt(start) && tools::isAnInt(step) && tools::isAnInt(end))
        {
            sl = SymbolicList(start, step, end);
            return true;
        }
        return false;
    }

    GVN::Value * gvnStart, * gvnStep, * gvnEnd;
    if (Rstart.getConstant().getDblValue(start))
    {
        int64_t _start;
        if (tools::asInteger(start, _start))
        {
            gvnStart = visitor.getGVN().getValue(_start);
        }
        else
        {
            return false;
        }
    }
    else if (GVN::Value * v = Rstart.getConstant().getGVNValue())
    {
        gvnStart = v;
    }
    else
    {
        return false;
    }

    if (Rstep.getConstant().getDblValue(step))
    {
        int64_t _step;
        if (tools::asInteger(step, _step))
        {
            gvnStep = visitor.getGVN().getValue(_step);
        }
        else
        {
            return false;
        }
    }
    else if (GVN::Value * v = Rstep.getConstant().getGVNValue())
    {
        gvnStep = v;
    }
    else
    {
        return false;
    }

    if (Rend.getConstant().getDblValue(end))
    {
        int64_t _end;
        if (tools::asInteger(end, _end))
        {
            gvnEnd = visitor.getGVN().getValue(_end);
        }
        else
        {
            return false;
        }
    }
    else if (GVN::Value * v = Rend.getConstant().getGVNValue())
    {
        gvnEnd = v;
    }
    else
    {
        return false;
    }

    sl = SymbolicList(gvnStart, gvnStep, gvnEnd);

    return true;
}
Ejemplo n.º 6
0
std::vector<TIType> Block::addCall(AnalysisVisitor & visitor, const unsigned int lhs, const symbol::Symbol & sym, std::vector<TIType> & in, ast::CallExp * callexp)
{
    tools::SymbolMap<Info>::iterator it;
    Block * block = getDefBlock(sym, it, false);
    types::InternalType * pIT = nullptr;
    std::vector<TIType> out(lhs, TIType(visitor.getGVN()));
    TIType type;

    if (block)
    {
        type = it->second.type;
    }
    else
    {
        type = DataManager::getSymInScilabContext(getGVN(), sym, pIT);
    }

    switch (type.type)
    {
        case TIType::FUNCTION:
        {
            if (lhs > 0)
            {
                TIType ty = Checkers::check(getGVN(), sym.getName(), in);
                if (ty.type != TIType::UNKNOWN && ty.hasInvalidDims())
                {
                    out[0] = ty.asUnknownMatrix();
                }
                else
                {
                    out[0] = ty;
                }
            }
            break;
        }
        case TIType::MACRO:
        {
            if (pIT)
            {
                visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
            }
            else
            {
                if (it->second.exp && it->second.exp->isFunctionDec())
                {
                    DeclaredMacroDef macrodef(static_cast<ast::FunctionDec *>(it->second.exp));
                    visitor.getPMC().getOutTypes(visitor, &macrodef, in, out);
                }
                else
                {
                    DataManager::getSymInScilabContext(getGVN(), sym, pIT);
                    visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::Macro *>(pIT)), in, out);
                }
            }
            break;
        }
        case TIType::MACROFILE:
        {
            DataManager::getSymInScilabContext(getGVN(), sym, pIT);
            visitor.getPMC().getOutTypes(visitor, dm->getMacroDef(static_cast<types::MacroFile *>(pIT)->getMacro()), in, out);
            break;
        }
        default:
        {
        }
    }

    return out;
}
bool MemInitAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
{
    const ast::exps_t args = e.getArgs();
    if (args.size() == 2)
    {
        ast::Exp * first = *args.begin();
        ast::Exp * second = *std::next(args.begin());

        first->accept(visitor);
        Result R1 = visitor.getResult();
        visitor.getDM().releaseTmp(R1.getTempId(), first);
        second->accept(visitor);
        Result & R2 = visitor.getResult();
        visitor.getDM().releaseTmp(R2.getTempId(), second);
        double val;
        SymbolicDimension rows, cols;
        bool empty = false;

        if (R1.getConstant().getDblValue(val))
        {
            const int nrows = tools::cast<int>(val);
            if (nrows <= 0)
            {
                empty = true;
            }
            else
            {
                rows = SymbolicDimension(visitor.getGVN(), nrows);
            }
        }
        else if (GVN::Value * gvnValue = R1.getConstant().getGVNValue())
        {
            rows.setValue(gvnValue);
            rows.setGVN(&visitor.getGVN());
        }
        else
        {
            return false;
        }

        if (!empty)
        {
            if (R2.getConstant().getDblValue(val))
            {
                const int ncols = tools::cast<int>(val);
                if (ncols <= 0)
                {
                    empty = true;
                }
                else
                {
                    cols = SymbolicDimension(visitor.getGVN(), ncols);
                }
            }
            else if (GVN::Value * gvnValue = R2.getConstant().getGVNValue())
            {
                cols.setValue(gvnValue);
                cols.setGVN(&visitor.getGVN());
            }
            else
            {
                return false;
            }
        }

        if (empty)
        {
            e.getDecorator().setResult(TIType(visitor.getGVN(), TIType::EMPTY));
        }
        else
        {
            bool res = visitor.getCM().check(ConstraintManager::POSITIVE, rows.getValue());
            if (res)
            {
                res = visitor.getCM().check(ConstraintManager::POSITIVE, cols.getValue());
                if (!res)
                {
                    return false;
                }
            }
            else
            {
                return false;
            }
            TIType resT(visitor.getGVN(), TIType::DOUBLE, rows, cols);
            e.getDecorator().setResult(Result(resT, visitor.getDM().getTmpId(resT, false)));
        }
        visitor.setResult(e.getDecorator().res);

        return true;
    }

    return false;
}
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;
}
const bool PolymorphicMacroCache::getOutTypes(AnalysisVisitor & visitor, MacroDef * macrodef, std::vector<TIType> & in, std::vector<TIType> & out)
{

    // TODO: handle varargin
    if (in.size() > macrodef->getRhs())
    {
        return false;
    }

    std::vector<TIType> completeIn;
    if (!PolymorphicMacroCache::getCompleteIn(*macrodef, visitor, in, completeIn))
    {
        return false;
    }

    MacroSignature signature(*macrodef, out.size(), completeIn);
    MacroSignMap::iterator i = signatures.find(signature);
    if (i == signatures.end())
    {
        i = signatures.emplace(signature, 0).first;
    }

    CompleteMacroSignature & cms = i->second;
    std::vector<GVN::Value *> values;
    std::vector<const MultivariatePolynomial *> polys;
    for (auto & t : completeIn)
    {
        if (t.isscalar())
        {
            GVN::Value * v = t.rows.getValue();
            values.emplace_back(v);
            polys.emplace_back(v->poly);
        }
        else
        {
            GVN::Value * v = t.rows.getValue();
            values.emplace_back(v);
            polys.emplace_back(v->poly);
            v = t.cols.getValue();
            values.emplace_back(v);
            polys.emplace_back(v->poly);
        }
    }

    const MacroOut * mout = cms.getOutTypes(visitor, signature, macrodef, visitor.getDM(), in.size(), completeIn, values);
    if (mout)
    {
        std::vector<TIType>::iterator i = out.begin();
        for (const auto & t : mout->tuple.types)
        {
            *i = t;
            GVN::Value * Rv = getValue(t.rows.getValue(), visitor, polys, mout->maxVarId);
            GVN::Value * Cv = getValue(t.cols.getValue(), visitor, polys, mout->maxVarId);
            i->rows.setValue(Rv);
            i->cols.setValue(Cv);
            i->invalidScalar();
            ++i;
        }

        //out.assign(mout->tuple.types.begin(), mout->tuple.types.end());
        return true;
    }
    else
    {
        return false;
    }
}
Ejemplo n.º 10
0
bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
{
    if (lhs > 2)
    {
        return false;
    }

    const ast::exps_t args = e.getArgs();
    enum Kind
    {
        ROWS, COLS, ROWSTIMESCOLS, ROWSCOLS, ONE, BOTH, DUNNO
    } kind = DUNNO;
    const std::size_t size = args.size();
    if (size == 0 || size >= 3)
    {
        return false;
    }

    ast::Exp * first = *args.begin();
    if (!first)
    {
        return false;
    }
    first->accept(visitor);
    Result & res = visitor.getResult();
    if (!res.getType().ismatrix())
    {
        visitor.getDM().releaseTmp(res.getTempId(), first);
        return false;
    }

    switch (size)
    {
        case 1:
            if (lhs == 1)
            {
                kind = BOTH;
            }
            else if (lhs == 2)
            {
                kind = ROWSCOLS;
            }
            break;
        case 2:
        {
            ast::Exp * second = *std::next(args.begin());
            if (second && lhs == 1)
            {
                if (second->isStringExp())
                {
                    const std::wstring & arg2 = static_cast<ast::StringExp *>(second)->getValue();
                    if (arg2 == L"r")
                    {
                        kind = ROWS;
                    }
                    else if (arg2 == L"c")
                    {
                        kind = COLS;
                    }
                    else if (arg2 == L"*")
                    {
                        kind = ROWSTIMESCOLS;
                    }
                    else
                    {
                        visitor.getDM().releaseTmp(res.getTempId(), first);
                        return false;
                    }
                }
                else if (second->isDoubleExp())
                {
                    const double arg2 = static_cast<ast::DoubleExp *>(second)->getValue();
                    if (arg2 == 1)
                    {
                        kind = ROWS;
                    }
                    else if (arg2 == 2)
                    {
                        kind = COLS;
                    }
                    else if (arg2 >= 3)
                    {
                        // TODO: we should handle hypermatrix
                        kind = ONE;
                    }
                    else
                    {
                        visitor.getDM().releaseTmp(res.getTempId(), first);
                        return false;
                    }
                }
            }
            else
            {
                visitor.getDM().releaseTmp(res.getTempId(), first);
                return false;
            }
            break;
        }
        default:
            visitor.getDM().releaseTmp(res.getTempId(), first);
            return false;
    }

    TIType type(visitor.getGVN(), TIType::DOUBLE);

    switch (kind)
    {
        case ROWS:
        {
            SymbolicDimension & rows = res.getType().rows;
            Result & _res = e.getDecorator().setResult(type);
            _res.getConstant() = rows.getValue();
            e.getDecorator().setCall(new SizeCall(SizeCall::R));
            visitor.setResult(_res);
            break;
        }
        case COLS:
        {
            SymbolicDimension & cols = res.getType().cols;
            Result & _res = e.getDecorator().setResult(type);
            _res.getConstant() = cols.getValue();
            e.getDecorator().setCall(new SizeCall(SizeCall::C));
            visitor.setResult(_res);
            break;
        }
        case ROWSTIMESCOLS:
        {
            SymbolicDimension & rows = res.getType().rows;
            SymbolicDimension & cols = res.getType().cols;
            SymbolicDimension prod = rows * cols;
            Result & _res = e.getDecorator().setResult(type);
            _res.getConstant() = prod.getValue();
            e.getDecorator().setCall(new SizeCall(SizeCall::RC));
            visitor.setResult(_res);
            break;
        }
        case ROWSCOLS:
        {
            SymbolicDimension & rows = res.getType().rows;
            SymbolicDimension & cols = res.getType().cols;
            std::vector<Result> & mlhs = visitor.getLHSContainer();
            mlhs.clear();
            mlhs.reserve(2);
            mlhs.emplace_back(type);
            mlhs.back().getConstant() = rows.getValue();
            mlhs.emplace_back(type);
            mlhs.back().getConstant() = cols.getValue();

            e.getDecorator().setCall(new SizeCall(SizeCall::R_C));
            break;
        }
        case ONE:
        {
            Result & _res = e.getDecorator().setResult(type);
            _res.getConstant() = new types::Double(1);
            e.getDecorator().setCall(new SizeCall(SizeCall::ONE));
            visitor.setResult(_res);
            break;
        }
        case BOTH:
        {
            TIType _type(visitor.getGVN(), TIType::DOUBLE, 1, 2);
            Result & _res = e.getDecorator().setResult(_type);
            e.getDecorator().setCall(new SizeCall(SizeCall::BOTH));
            visitor.setResult(_res);
            break;
        }
        default:
            return false;
    }

    return true;
}