Merge remote-tracking branch 'origin/master' into jit
[scilab.git] / scilab / modules / ast / src / cpp / analysis / VisitAssignExp.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2015 - Scilab Enterprises - Calixte DENIZET
4  *
5  *  This file must be used under the terms of the CeCILL.
6  *  This source file is licensed as described in the file COPYING, which
7  *  you should have received as part of this distribution.  The terms
8  *  are also available at
9  *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
10  *
11  */
12
13 #include "AnalysisVisitor.hxx"
14
15 namespace analysis
16 {
17
18 void AnalysisVisitor::visit(ast::AssignExp & e)
19 {
20     logger.log(L"AssignExp", e.getLocation());
21     if (e.getLeftExp().isSimpleVar()) // A = ...
22     {
23         ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getLeftExp());
24         const symbol::Symbol & sym = var.getSymbol();
25
26         if (e.getRightExp().isSimpleVar())
27         {
28             // We have A = B (so the data associated to b is shared with a)
29             const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
30             Info & info = getSymInfo(symR);
31             const TIType & Rtype = info.getType();
32             Result & resL = e.getLeftExp().getDecorator().setResult(Rtype);
33             resL.setConstant(info.getConstant());
34             resL.setRange(info.getRange());
35             Result & resR = e.getRightExp().getDecorator().setResult(Rtype);
36             resR.setConstant(info.getConstant());
37             resR.setRange(info.getRange());
38             getDM().share(sym, symR, Rtype, resR.isAnInt(), &e);
39         }
40         else
41         {
42             // apply the ConstantVisitor
43             cv.setLHS(1);
44             e.getRightExp().accept(cv);
45
46             if (e.getRightExp().isCallExp()) // A = foo(...)
47             {
48                 if (e.getRightExp().isCallExp())
49                 {
50                     visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
51                 }
52                 else
53                 {
54                     e.getRightExp().accept(*this);
55                 }
56             }
57             else // A = 1 + 2
58             {
59                 e.getRightExp().accept(*this);
60             }
61
62             Result & RR = getResult();
63             var.getDecorator().res = RR;
64             Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
65             info.getConstant() = RR.getConstant();
66             e.getDecorator().safe = true;
67
68             // Don't remove temp: because the value is transfered to LHS
69             getDM().releaseTmp(RR.getTempId(), nullptr);//&e.getRightExp());
70         }
71     }
72     else if (e.getLeftExp().isCallExp()) // A(12) = ...
73     {
74         // apply the ConstantVisitor
75         cv.setLHS(1);
76         e.getRightExp().accept(cv);
77
78         ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
79         if (ce.getName().isSimpleVar())
80         {
81             const symbol::Symbol & symL = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
82             e.getRightExp().accept(*this);
83             Result & RR = e.getRightExp().getDecorator().getResult();
84             ce.getDecorator().res = RR;
85             Info & info = getDM().write(symL, RR.getType(), &ce.getName());
86             ce.getName().getDecorator().setResult(info.type);
87             if (analyzeIndices(info.type, ce))
88             {
89                 e.getDecorator().safe = (RR.getType() == getResult().getType());
90             }
91             getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
92         }
93     }
94     else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
95     {
96         ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
97         if (e.getRightExp().isCallExp())
98         {
99             const ast::exps_t & exps = ale.getExps();
100             visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ exps.size());
101             std::vector<Result>::iterator j = multipleLHS.begin();
102             for (const auto exp : exps)
103             {
104                 // TODO: handle fields...
105                 if (exp->isSimpleVar() && j != multipleLHS.end())
106                 {
107                     ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
108                     const symbol::Symbol & sym = var.getSymbol();
109                     Info & info = getDM().define(sym, j->getType(), j->isAnInt(), exp);
110                     info.setConstant(j->getConstant());
111                     var.getDecorator().res = *j;
112                     ++j;
113                 }
114             }
115         }
116     }
117 }
118 }