License Header change: Removed the LICENSE_END before beta
[scilab.git] / scilab / modules / ast / src / cpp / analysis / ArgnAnalyzer.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 #include "analyzers/ArgnAnalyzer.hxx"
18 #include "tools.hxx"
19 #include "double.hxx"
20
21 namespace analysis
22 {
23 bool ArgnAnalyzer::analyze(AnalysisVisitor & visitor, const unsigned int lhs, ast::CallExp & e)
24 {
25     if (lhs > 2)
26     {
27         return false;
28     }
29
30     TIType type(visitor.getGVN(), TIType::DOUBLE);
31     FunctionBlock * fblock = visitor.getDM().topFunction();
32     if (!fblock)
33     {
34         if (lhs == 1)
35         {
36             Result & res = e.getDecorator().setResult(type);
37             res.getConstant() = new types::Double(0);
38             e.getDecorator().setCall(L"argn");
39             visitor.setResult(res);
40             return true;
41         }
42         return false;
43     }
44
45
46     enum Kind
47     {
48         LHS, RHS, LHSRHS, DUNNO
49     } kind = DUNNO;
50     const ast::exps_t args = e.getArgs();
51     switch (args.size())
52     {
53         case 0:
54         {
55             if (lhs == 1)
56             {
57                 kind = LHS;
58             }
59             else if (lhs == 2)
60             {
61                 kind = LHSRHS;
62             }
63             break;
64         }
65         case 1:
66         {
67             ast::Exp * first = args.front();
68             if (first && first->isDoubleExp())
69             {
70                 const double arg1 = static_cast<ast::DoubleExp *>(first)->getValue();
71                 if (arg1 == 0)
72                 {
73                     if (lhs == 1)
74                     {
75                         kind = LHS;
76                     }
77                     else if (lhs == 2)
78                     {
79                         kind = LHSRHS;
80                     }
81                 }
82                 else if (arg1 == 1)
83                 {
84                     kind = LHS;
85                 }
86                 else if (arg1 == 2)
87                 {
88                     kind = RHS;
89                 }
90                 else
91                 {
92                     return false;
93                 }
94             }
95             else
96             {
97                 return false;
98             }
99             break;
100         }
101         default:
102             return false;
103     }
104
105     switch (kind)
106     {
107         case LHS:
108         case RHS:
109         {
110             const int64_t val = kind == LHS ? fblock->getLHS() : fblock->getRHS();
111             Result & res = e.getDecorator().setResult(type);
112             res.getConstant() = visitor.getGVN().getValue(val);
113             e.getDecorator().setCall(L"argn");
114             visitor.setResult(res);
115             break;
116         }
117         case LHSRHS:
118         {
119             std::vector<Result> & mlhs = visitor.getLHSContainer();
120             mlhs.clear();
121             mlhs.reserve(2);
122
123             const int64_t flhs = fblock->getLHS();
124             const int64_t frhs = fblock->getRHS();
125             mlhs.emplace_back(type);
126             mlhs.back().getConstant() = visitor.getGVN().getValue(flhs);
127             mlhs.emplace_back(type);
128             mlhs.back().getConstant() = visitor.getGVN().getValue(frhs);
129
130             e.getDecorator().setCall(L"argn");
131             break;
132         }
133         default:
134             return false;
135     }
136
137     return true;
138 }
139 }