2 * Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3 * Copyright (C) 2015 - 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 "ConstantVisitor.hxx"
22 std::unordered_set<std::wstring> ConstantVisitor::constants = init();
24 void ConstantVisitor::visit(ast::SimpleVar & e)
26 bool isConstant = false;
29 const symbol::Symbol & sym = e.getSymbol();
30 const std::wstring & name = sym.getName();
31 if (constants.find(name) != constants.end() && symbol::Context::getInstance()->isOriginalSymbol(sym))
33 if (types::InternalType * pIT = symbol::Context::getInstance()->get(sym))
35 e.replace(pIT->getExp(e.getLocation()));
41 if (FunctionBlock * fblock = parent->getDM().topFunction())
43 ast::Exp * loop = parent->getCurrentLoop();
44 if (!fblock->getLoopAnalyzer().isAssigned(loop, sym))
46 // We propagate the constant only if we aren't in a loop which modifies the sym
47 Info & info = parent->getDM().read(sym, &e);
48 ConstantValue & constant = info.getConstant();
49 const ConstantValue::Kind kind = constant.getKind();
50 if (kind == ConstantValue::GVNVAL)
53 if (constant.getDblValue(val))
55 e.replace(new ast::DoubleExp(e.getLocation(), val));
59 else if (kind == ConstantValue::ITVAL)
61 types::InternalType * pIT = constant.getIT();
62 if (ast::Exp * exp = pIT->getExp(e.getLocation()))
73 setResult(isConstant);
76 void ConstantVisitor::visit(ast::OpExp & e)
78 e.getLeft().accept(*this);
79 const bool constL = getResult();
80 e.getRight().accept(*this);
81 const bool constR = getResult();
85 setResult(execAndReplace(e));
88 else if (constL || constR)
90 const ast::Exp::ExpType ty = e.getParent()->getType();
91 if (ty == ast::Exp::IFEXP || ty == ast::Exp::WHILEEXP)
93 ast::OpExp::Oper oper = e.getOper();
94 if (oper == ast::OpExp::Oper::logicalShortCutAnd || oper == ast::OpExp::Oper::logicalAnd)
98 e.getLeft().accept(exec);
99 if (exec.getResult()->isTrue())
101 e.replace(e.getRight().clone());
105 types::InternalType * b = new types::Bool(0);
106 e.replace(b->getExp(e.getLocation()));
113 e.getRight().accept(exec);
114 if (exec.getResult()->isTrue())
116 e.replace(e.getLeft().clone());
120 types::InternalType * b = new types::Bool(0);
121 e.replace(b->getExp(e.getLocation()));
127 else if (oper == ast::OpExp::Oper::logicalShortCutOr || oper == ast::OpExp::Oper::logicalOr)
131 e.getLeft().accept(exec);
132 if (exec.getResult()->isTrue())
134 types::InternalType * b = new types::Bool(1);
135 e.replace(b->getExp(e.getLocation()));
141 e.replace(e.getRight().clone());
146 e.getRight().accept(exec);
147 if (exec.getResult()->isTrue())
149 types::InternalType * b = new types::Bool(1);
150 e.replace(b->getExp(e.getLocation()));
156 e.replace(e.getLeft().clone());
166 void ConstantVisitor::visit(ast::LogicalOpExp & e)
168 visit(static_cast<ast::OpExp &>(e));
171 void ConstantVisitor::visit(ast::CallExp & e)
173 bool isConstant = false;
177 ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getName());
178 const symbol::Symbol & sym = var.getSymbol();
179 if (symbol::Context::getInstance()->isOriginalSymbol(sym))
181 const std::wstring & name = sym.getName();
182 ast::exps_t args = e.getArgs();
184 bool allConstant = true;
185 for (auto arg : args)
188 if (allConstant && !getResult())
194 if (allConstant && Checkers::isConst(name, args.size()))
198 if (parent && parent->getAnalyzer(sym)->analyze(*parent, lhs, e))
203 parent->getResult().getConstant().getDblValue(val);
204 e.replace(new ast::DoubleExp(e.getLocation(), val));
210 ast::exps_t * exps = new ast::exps_t();
212 std::vector<Result> & res = parent->getLHSContainer();
213 res.front().getConstant().getDblValue(val);
214 exps->push_back(new ast::DoubleExp(e.getLocation(), val));
215 res.back().getConstant().getDblValue(val);
216 exps->push_back(new ast::DoubleExp(e.getLocation(), val));
217 e.replace(new ast::ArrayListExp(e.getLocation(), *exps));
224 isConstant = execAndReplace(e);
228 if (parent && args.size() == 1)
230 if (name == L"type" || name == L"inttype")
232 if (parent->getAnalyzer(sym)->analyze(*parent, 1, e))
235 parent->getResult().getConstant().getDblValue(val);
236 e.replace(new ast::DoubleExp(e.getLocation(), val));
240 else if (name == L"typeof")
242 if (parent->getAnalyzer(sym)->analyze(*parent, 1, e))
245 if (parent->getResult().getConstant().getStrValue(wstr))
247 e.replace(new ast::StringExp(e.getLocation(), wstr));
252 else if (name == L"isreal" || name == L"isscalar")
254 if (parent->getAnalyzer(sym)->analyze(*parent, 1, e))
257 parent->getResult().getConstant().getBoolValue(val);
258 e.replace(new ast::BoolExp(e.getLocation(), val));
266 setResult(isConstant);
269 void ConstantVisitor::visit(ast::MatrixExp & e)
271 const ast::exps_t & lines = e.getLines();
274 setResult(execAndReplace(e));
278 for (auto line : lines)
280 const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
281 for (auto column : columns)
283 column->accept(*this);
290 setResult(execAndReplace(e));
294 void ConstantVisitor::visit(ast::NotExp & e)
296 e.getExp().accept(*this);
299 setResult(execAndReplace(e));
307 void ConstantVisitor::visit(ast::TransposeExp & e)
309 e.getExp().accept(*this);
312 setResult(execAndReplace(e));
320 void ConstantVisitor::visit(ast::CellExp & e)
322 visit(static_cast<ast::MatrixExp &>(e));
325 void ConstantVisitor::visit(ast::ListExp & e)
327 e.getStart().accept(*this);
328 const bool startConst = getResult();
329 e.getStep().accept(*this);
330 const bool stepConst = getResult();
331 e.getEnd().accept(*this);
332 const bool endConst = getResult();
334 if (startConst && stepConst && endConst)
336 setResult(execAndReplace(e));
344 void ConstantVisitor::visit(ast::IfExp & e)
348 void ConstantVisitor::visit(ast::DollarVar & e)
353 void ConstantVisitor::visit(ast::ColonVar & e)
358 void ConstantVisitor::visit(ast::ArrayListVar & e)
362 void ConstantVisitor::visit(ast::DoubleExp & e)
367 void ConstantVisitor::visit(ast::BoolExp & e)
372 void ConstantVisitor::visit(ast::StringExp & e)
377 void ConstantVisitor::visit(ast::CommentExp & e)
382 void ConstantVisitor::visit(ast::NilExp & e)
387 void ConstantVisitor::visit(ast::CellCallExp & e)
392 void ConstantVisitor::visit(ast::AssignExp & e)
396 void ConstantVisitor::visit(ast::WhileExp & e)
400 void ConstantVisitor::visit(ast::ForExp & e)
404 void ConstantVisitor::visit(ast::BreakExp & e)
409 void ConstantVisitor::visit(ast::ContinueExp & e)
414 void ConstantVisitor::visit(ast::TryCatchExp & e)
418 void ConstantVisitor::visit(ast::SelectExp & e)
422 void ConstantVisitor::visit(ast::CaseExp & e)
426 void ConstantVisitor::visit(ast::ReturnExp & e)
430 void ConstantVisitor::visit(ast::FieldExp & e)
434 void ConstantVisitor::visit(ast::MatrixLineExp & e)
438 void ConstantVisitor::visit(ast::SeqExp & e)
442 void ConstantVisitor::visit(ast::ArrayListExp & e)
446 void ConstantVisitor::visit(ast::AssignListExp & e)
450 void ConstantVisitor::visit(ast::VarDec & e)
454 void ConstantVisitor::visit(ast::FunctionDec & e)
458 void ConstantVisitor::visit(ast::OptimizedExp & e)
462 void ConstantVisitor::visit(ast::MemfillExp & e)
466 void ConstantVisitor::visit(ast::DAXPYExp & e)
470 void ConstantVisitor::visit(ast::IntSelectExp & e)
474 void ConstantVisitor::visit(ast::StringSelectExp & e)
478 std::unordered_set<std::wstring> ConstantVisitor::init()
480 std::unordered_set<std::wstring> _constants;
481 _constants.emplace(L"%pi");
482 _constants.emplace(L"%eps");
483 _constants.emplace(L"%e");
484 _constants.emplace(L"%i");
485 _constants.emplace(L"%nan");
486 _constants.emplace(L"%inf");
487 _constants.emplace(L"%t");
488 _constants.emplace(L"%f");
489 _constants.emplace(L"%T");
490 _constants.emplace(L"%F");
491 _constants.emplace(L"SCI");
492 _constants.emplace(L"WSCI");
493 _constants.emplace(L"SCIHOME");
494 _constants.emplace(L"TMPDIR");