2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2014 - Scilab Enterprises - Calixte DENIZET
5 * Copyright (C) 2012 - 2016 - Scilab Enterprises
7 * This file is hereby licensed under the terms of the GNU GPL v2.0,
8 * pursuant to article 5.3.4 of the CeCILL v.2.1.
9 * This file was originally licensed under the terms of the CeCILL v2.1,
10 * and continues to be available under such terms.
11 * For more information, see the COPYING file which you should have received
12 * along with this program.
16 #include "AnalysisVisitor.hxx"
17 #include "analyzers/SizeAnalyzer.hxx"
18 #include "call/SizeCall.hxx"
24 bool SizeAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
31 const ast::exps_t args = e.getArgs();
32 SizeCall::Kind kind = SizeCall::DUNNO;
34 const std::size_t size = args.size();
35 if (size == 0 || size >= 3)
40 ast::Exp * first = *args.begin();
45 first->accept(visitor);
46 Result & res = visitor.getResult();
47 if (!res.getType().ismatrix())
49 visitor.getDM().releaseTmp(res.getTempId(), first);
58 kind = SizeCall::BOTH;
67 ast::Exp * second = *std::next(args.begin());
68 if (second && lhs == 1)
70 if (second->isStringExp())
72 const std::wstring & arg2 = static_cast<ast::StringExp *>(second)->getValue();
77 else if (arg2 == L"c")
81 else if (arg2 == L"*")
87 visitor.getDM().releaseTmp(res.getTempId(), first);
91 else if (second->isDoubleExp())
93 const double arg2 = static_cast<ast::DoubleExp *>(second)->getValue();
104 // TODO: we should handle hypermatrix
105 kind = SizeCall::ONE;
109 visitor.getDM().releaseTmp(res.getTempId(), first);
116 visitor.getDM().releaseTmp(res.getTempId(), first);
122 visitor.getDM().releaseTmp(res.getTempId(), first);
126 TIType type(visitor.getGVN(), TIType::DOUBLE);
132 SymbolicDimension & rows = res.getType().rows;
133 Result & _res = e.getDecorator().setResult(type);
134 _res.getConstant() = rows.getValue();
135 e.getDecorator().setCall(new SizeCall(SizeCall::R));
136 visitor.setResult(_res);
141 SymbolicDimension & cols = res.getType().cols;
142 Result & _res = e.getDecorator().setResult(type);
143 _res.getConstant() = cols.getValue();
144 e.getDecorator().setCall(new SizeCall(SizeCall::C));
145 visitor.setResult(_res);
150 SymbolicDimension & rows = res.getType().rows;
151 SymbolicDimension & cols = res.getType().cols;
152 SymbolicDimension prod = rows * cols;
154 Result & _res = e.getDecorator().setResult(type);
155 _res.getConstant() = prod.getValue();
156 e.getDecorator().setCall(new SizeCall(SizeCall::RC));
157 visitor.setResult(_res);
163 if (kind == SizeCall::BOTH)
165 TIType _type(visitor.getGVN(), TIType::DOUBLE, 1, 2);
166 Result & _res = e.getDecorator().setResult(_type);
169 SymbolicDimension & rows = res.getType().rows;
170 SymbolicDimension & cols = res.getType().cols;
171 std::vector<Result> & mlhs = visitor.getLHSContainer();
174 mlhs.emplace_back(type);
175 mlhs.back().getConstant() = rows.getValue();
176 mlhs.emplace_back(type);
177 mlhs.back().getConstant() = cols.getValue();
179 e.getDecorator().setCall(new SizeCall(kind));
184 Result & _res = e.getDecorator().setResult(type);
185 _res.getConstant() = new types::Double(1);
186 e.getDecorator().setCall(new SizeCall(SizeCall::ONE));
187 visitor.setResult(_res);