6b1e3537ef38d4ecde85f640dddcd7632e7f2259
[scilab.git] / scilab / modules / ast / src / cpp / analysis / VisitMatrixExp.cpp
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2014 - 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 #include "tools.hxx"
15
16 namespace analysis
17 {
18 void AnalysisVisitor::visit(ast::MatrixExp & e)
19 {
20     logger.log(L"MatrixExp", e.getLocation());
21     const ast::exps_t & lines = e.getLines();
22     if (lines.empty())
23     {
24         // empty matrix
25         TIType type(getGVN(), TIType::EMPTY);
26         e.getDecorator().res = Result(type);
27         setResult(e.getDecorator().res);
28         return;
29     }
30
31     GVN::Value * totalColsRef = nullptr;
32     GVN::Value * totalRows = getGVN().getValue(0.);
33     TIType::Type baseType = TIType::UNKNOWN;
34     bool baseTypeSet = false;
35     bool checkDims = true;
36
37     for (auto line : lines)
38     {
39         const ast::exps_t & columns = static_cast<ast::MatrixLineExp *>(line)->getColumns();
40         if (!columns.empty())
41         {
42             GVN::Value * totalCols = nullptr;
43             GVN::Value * rows = nullptr;
44             for (auto e : columns)
45             {
46                 e->accept(*this);
47                 Result & res = getResult();
48                 TIType & type = res.getType();
49                 if (type.type != TIType::EMPTY && type.rows != 0 && type.cols != 0)
50                 {
51                     if (!baseTypeSet)
52                     {
53                         baseTypeSet = true;
54                         baseType = type.type;
55                     }
56                     else
57                     {
58                         switch (baseType)
59                         {
60                             case TIType::DOUBLE:
61                                 switch (type.type)
62                                 {
63                                     case TIType::COMPLEX:
64                                         baseType = TIType::COMPLEX;
65                                         break;
66                                     case TIType::DOUBLE:
67                                     case TIType::BOOLEAN:
68                                         break;
69                                     default:
70                                         baseType = TIType::UNKNOWN;
71                                 }
72                                 break;
73                             case TIType::COMPLEX:
74                                 switch (type.type)
75                                 {
76                                     case TIType::DOUBLE:
77                                     case TIType::COMPLEX:
78                                     case TIType::BOOLEAN:
79                                         break;
80                                     default:
81                                         baseType = TIType::UNKNOWN;
82                                 }
83                                 break;
84                             case TIType::BOOLEAN:
85                                 switch (type.type)
86                                 {
87                                     case TIType::DOUBLE:
88                                     case TIType::COMPLEX:
89                                         baseType = type.type;
90                                         break;
91                                     case TIType::BOOLEAN:
92                                         break;
93                                     default:
94                                         baseType = TIType::UNKNOWN;
95                                 }
96                                 break;
97                             default:
98                                 if (baseType != type.type)
99                                 {
100                                     baseType = TIType::UNKNOWN;
101                                 }
102                         }
103                     }
104
105                     if (checkDims)
106                     {
107                         if (!rows)
108                         {
109                             rows = type.rows.getValue();
110                         }
111                         else
112                         {
113                             if (!getCM().check(ConstraintManager::EQUAL, rows, type.rows.getValue()))
114                             {
115                                 checkDims = false;
116                             }
117                         }
118                         if (!totalCols)
119                         {
120                             totalCols = type.cols.getValue();
121                         }
122                         else
123                         {
124                             totalCols = getGVN().getValue(OpValue::Kind::PLUS, *totalCols, *type.cols.getValue());
125                         }
126                     }
127                 }
128             }
129
130             if (checkDims && totalCols)
131             {
132                 if (!totalColsRef)
133                 {
134                     totalColsRef = totalCols;
135                 }
136                 else
137                 {
138                     if (!getCM().check(ConstraintManager::EQUAL, totalCols, totalColsRef))
139                     {
140                         checkDims = false;
141                     }
142                 }
143
144                 if (rows)
145                 {
146                     totalRows = getGVN().getValue(OpValue::Kind::PLUS, *totalRows, *rows);
147                 }
148             }
149         }
150     }
151
152     if (checkDims)
153     {
154         if (!totalRows || !totalColsRef || totalRows->poly->isConstant(0) || totalColsRef->poly->isConstant(0))
155         {
156             TIType type(getGVN(), TIType::EMPTY);
157             e.getDecorator().res = Result(type);
158         }
159         else
160         {
161             TIType type(getGVN(), baseType, SymbolicDimension(getGVN(), totalRows), SymbolicDimension(getGVN(), totalColsRef));
162             e.getDecorator().res = Result(type);
163         }
164     }
165     else
166     {
167         TIType type(getGVN(), baseType, false);
168         e.getDecorator().res = Result(type);
169     }
170
171     setResult(e.getDecorator().res);
172 }
173 }