fc67b8f59cf2ac717d6e1ea06936ed382330bfa2
[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  * Copyright (C) 2012 - 2016 - Scilab Enterprises
6  *
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.
13  *
14  */
15
16 #include "AnalysisVisitor.hxx"
17
18 namespace analysis
19 {
20
21 void AnalysisVisitor::visit(ast::AssignExp & e)
22 {
23     logger.log(L"AssignExp", e.getLocation());
24     if (e.getLeftExp().isSimpleVar()) // A = ...
25     {
26         ast::SimpleVar & var = static_cast<ast::SimpleVar &>(e.getLeftExp());
27         const symbol::Symbol & sym = var.getSymbol();
28
29         if (e.getRightExp().isSimpleVar())
30         {
31             // We have A = B (so the data associated to b is shared with a)
32             const symbol::Symbol & symR = static_cast<ast::SimpleVar &>(e.getRightExp()).getSymbol();
33             Info & info = getSymInfo(symR);
34             const TIType & Rtype = info.getType();
35             Result & resL = e.getLeftExp().getDecorator().setResult(Rtype);
36             resL.setConstant(info.getConstant());
37             resL.setRange(info.getRange());
38             Result & resR = e.getRightExp().getDecorator().setResult(Rtype);
39             resR.setConstant(info.getConstant());
40             resR.setRange(info.getRange());
41             getDM().share(sym, symR, Rtype, resR.isAnInt(), &e);
42         }
43         else
44         {
45             // apply the ConstantVisitor
46             cv.setLHS(1);
47             e.getRightExp().accept(cv);
48
49             if (e.getRightExp().isCallExp()) // A = foo(...)
50             {
51                 if (e.getRightExp().isCallExp())
52                 {
53                     visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ 1);
54                 }
55                 else
56                 {
57                     e.getRightExp().accept(*this);
58                 }
59             }
60             else // A = 1 + 2
61             {
62                 e.getRightExp().accept(*this);
63             }
64
65             Result & RR = getResult();
66             var.getDecorator().res = RR;
67             Info & info = getDM().define(sym, RR.getType(), RR.isAnInt(), &e);
68             info.getConstant() = RR.getConstant();
69             e.getDecorator().safe = true;
70
71             // Don't remove temp: because the value is transfered to LHS
72             getDM().releaseTmp(RR.getTempId(), nullptr);//&e.getRightExp());
73         }
74     }
75     else if (e.getLeftExp().isCallExp()) // A(12) = ...
76     {
77         // apply the ConstantVisitor
78         cv.setLHS(1);
79         e.getRightExp().accept(cv);
80
81         ast::CallExp & ce = static_cast<ast::CallExp &>(e.getLeftExp());
82         if (ce.getName().isSimpleVar())
83         {
84             const symbol::Symbol & symL = static_cast<ast::SimpleVar &>(ce.getName()).getSymbol();
85             e.getRightExp().accept(*this);
86             Result & RR = e.getRightExp().getDecorator().getResult();
87             ce.getDecorator().res = RR;
88             Info & info = getDM().write(symL, RR.getType(), &ce.getName());
89             ce.getName().getDecorator().setResult(info.type);
90             if (analyzeIndices(info.type, ce))
91             {
92                 e.getDecorator().safe = (RR.getType() == getResult().getType());
93             }
94             getDM().releaseTmp(RR.getTempId(), &e.getRightExp());
95         }
96     }
97     else if (e.getLeftExp().isAssignListExp()) // [A, B] = ...
98     {
99         ast::AssignListExp & ale = static_cast<ast::AssignListExp &>(e.getLeftExp());
100         if (e.getRightExp().isCallExp())
101         {
102             const ast::exps_t & exps = ale.getExps();
103             visit(static_cast<ast::CallExp &>(e.getRightExp()), /* LHS */ exps.size());
104             std::vector<Result>::iterator j = multipleLHS.begin();
105             for (const auto exp : exps)
106             {
107                 // TODO: handle fields...
108                 if (exp->isSimpleVar() && j != multipleLHS.end())
109                 {
110                     ast::SimpleVar & var = *static_cast<ast::SimpleVar *>(exp);
111                     const symbol::Symbol & sym = var.getSymbol();
112                     Info & info = getDM().define(sym, j->getType(), j->isAnInt(), exp);
113                     info.setConstant(j->getConstant());
114                     var.getDecorator().res = *j;
115                     ++j;
116                 }
117             }
118         }
119     }
120 }
121 }