* Bug #15850 fixed: now unary plus calls overload for non supported types
[scilab.git] / scilab / modules / ast / includes / ast / deserializervisitor.hxx
1 /*
2  *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
3  *  Copyright (C) 2012-2013 - OCAMLPRO INRIA - Fabrice LE FESSANT
4  *  Copyright (C) 2014 - Scilab Enterprises - Antoine ELIAS
5  *
6  * Copyright (C) 2012 - 2016 - Scilab Enterprises
7  *
8  * This file is hereby licensed under the terms of the GNU GPL v2.0,
9  * pursuant to article 5.3.4 of the CeCILL v.2.1.
10  * This file was originally licensed under the terms of the CeCILL v2.1,
11  * and continues to be available under such terms.
12  * For more information, see the COPYING file which you should have received
13  * along with this program.
14  *
15  */
16 #ifndef __DESERIALIZER_HXX__
17 #define __DESERIALIZER_HXX__
18
19 #include <list>
20 #include <all.hxx>
21
22 namespace ast
23 {
24 class DeserializeVisitor
25 {
26 private :
27
28     unsigned char *initial_buf;
29     unsigned char *buf;
30
31
32     unsigned int get_uint8(void)
33     {
34         return *buf++;
35     }
36
37     unsigned int get_uint32(void)
38     {
39         unsigned int c0 = get_uint8();
40         unsigned int c1 = get_uint8();
41         unsigned int c2 = get_uint8();
42         unsigned int c3 = get_uint8();
43         return c0 + ((c1 + ((c2 + (c3 << 8)) << 8 )) << 8 );
44     }
45
46     unsigned long long get_uint64(void)
47     {
48         unsigned long long c0 = get_uint32();
49         unsigned long long c1 = get_uint32();
50         return c0 + (c1 << 32 );
51     }
52
53     int get_int32(void)
54     {
55         return (int)get_uint32();
56     }
57
58     bool get_bool(void)
59     {
60         return get_uint8() == 1;
61     }
62
63     Location get_location(void)
64     {
65         Location loc;
66         loc.first_line = get_uint32();
67         loc.first_column = get_uint32();
68         loc.last_line = get_uint32();
69         loc.last_column = get_uint32();
70         return loc;
71     }
72
73     exps_t* get_exps(void)
74     {
75         int nitems = get_uint32();
76         exps_t *list = new exps_t;
77         for (int i = 0; i < nitems; i++)
78         {
79             Exp* exp = get_exp();
80             list->push_back(exp);
81         }
82         return list;
83     }
84
85     exps_t* get_MatrixLines(void)
86     {
87         int nitems = get_uint32();
88         exps_t* list = new exps_t;
89         for (int i = 0; i < nitems; i++)
90         {
91             Location line_loc = get_location();
92             MatrixLineExp* line = new MatrixLineExp(line_loc, *get_exps());
93             list->push_back(line);
94         }
95         return list;
96     }
97
98     ast::exps_t* get_vars(void)
99     {
100         int nitems = get_uint32();
101         ast::exps_t* list = new ast::exps_t;
102         for (int i = 0; i < nitems; i++)
103         {
104             list->push_back(get_exp());
105         }
106         return list;
107     }
108
109     OpExp::Oper get_OpExp_Oper(void)
110     {
111         int code = get_uint8();
112         switch (code)
113         {
114             case 1 :
115                 return  OpExp::plus;
116             case 2 :
117                 return  OpExp::minus;
118             case 3 :
119                 return  OpExp::times;
120             case 4 :
121                 return  OpExp::rdivide;
122             case 5 :
123                 return  OpExp::ldivide;
124             case 6 :
125                 return  OpExp::power;
126
127             case 7 :
128                 return  OpExp::dottimes;
129             case 8 :
130                 return  OpExp::dotrdivide;
131             case 9 :
132                 return  OpExp::dotldivide;
133             case 10 :
134                 return  OpExp::dotpower;
135
136             case 11 :
137                 return  OpExp::krontimes;
138             case 12 :
139                 return  OpExp::kronrdivide;
140             case 13 :
141                 return  OpExp::kronldivide;
142
143             case 14 :
144                 return  OpExp::controltimes;
145             case 15 :
146                 return  OpExp::controlrdivide;
147             case 16 :
148                 return  OpExp::controlldivide;
149
150             case 17 :
151                 return  OpExp::eq;
152             case 18 :
153                 return  OpExp::ne;
154             case 19 :
155                 return  OpExp::lt;
156             case 20 :
157                 return  OpExp::le;
158             case 21 :
159                 return  OpExp::gt;
160             case 22 :
161                 return  OpExp::ge;
162
163             case 23 :
164                 return  OpExp::unaryMinus;
165
166             case 24 :
167                 return  OpExp::logicalAnd;
168             case 25 :
169                 return  OpExp::logicalOr;
170             case 26 :
171                 return  OpExp::logicalShortCutAnd;
172             case 27 :
173                 return  OpExp::logicalShortCutOr;
174
175             case 28 :
176                return  OpExp::unaryPlus;
177
178         }
179         std::cerr << "Unknown get_OpExp_Oper code " << code << std::endl;
180         exit(2);
181     }
182
183     TransposeExp::Kind get_TransposeExp_Kind(void)
184     {
185         int code = get_uint8();
186         switch (code)
187         {
188             case 1 :
189                 return TransposeExp::_Conjugate_;
190             case 2 :
191                 return TransposeExp::_NonConjugate_;
192         }
193         std::cerr << "Unknown get_TransposeExp_Kind code " << code << std::endl;
194         exit(2);
195     }
196
197     std::wstring* get_wstring(void)
198     {
199         unsigned int size = get_uint32();
200         char* ss = (char*)buf;
201         std::string s(ss, size / sizeof(char));
202         wchar_t* ws = to_wide_string(s.data());
203         std::wstring* w = new std::wstring(ws);
204         FREE(ws);
205         buf += size;
206         return w;
207     }
208
209     symbol::Symbol* get_Symbol(void)
210     {
211         std::wstring* s = get_wstring();
212         symbol::Symbol *sym = new symbol::Symbol(*s);
213         delete s;
214         return sym;
215     }
216
217     double get_double(void)
218     {
219         double d = *(double*)buf;
220         buf += 8;
221         return d;
222     }
223
224     VarDec* get_VarDec(Location & vardec_location)
225     {
226         symbol::Symbol *name = get_Symbol();
227         Exp *init = get_exp();
228         VarDec* vardec = new VarDec(vardec_location, *name, *init);
229         delete name;
230         return vardec;
231     }
232
233
234     Exp* get_exp(void)
235     {
236         Exp* exp;
237         int code = get_uint8();
238         size_t nodeNumber = get_uint64();
239         Location loc = get_location();
240         bool isVerbose = get_bool();
241
242         switch (code)
243         {
244             case 1:
245             {
246                 exps_t* l_body = get_exps();
247                 exp = new SeqExp(loc, *l_body);
248                 break;
249             }
250             case 2:
251             {
252                 std::wstring* s = get_wstring();
253                 exp = new StringExp(loc, *s);
254                 delete s;
255                 break;
256             }
257             case 3:
258             {
259                 std::wstring* s = get_wstring();
260                 exp = new CommentExp(loc, s);
261                 //delete s;
262                 break;
263             }
264             case 6:
265             {
266                 double d = get_double();
267                 exp = new DoubleExp(loc, d);
268                 break;
269             }
270             case 7:
271             {
272                 bool b = get_bool();
273                 exp = new BoolExp(loc, b);
274                 break;
275             }
276             case 8:
277             {
278                 exp = new NilExp(loc);
279                 break;
280             }
281             case 9:
282             {
283                 symbol::Symbol* sym = get_Symbol();
284                 exp = new SimpleVar(loc, *sym);
285                 delete sym;
286                 break;
287             }
288             case 10:
289             {
290                 exp = new ColonVar(loc);
291                 break;
292             }
293             case 11:
294             {
295                 exp = new DollarVar(loc);
296                 break;
297             }
298             case 12:
299             {
300                 exp = new ArrayListVar(loc, *get_vars());
301                 break;
302             }
303             case 13:
304             {
305                 Exp *head = get_exp();
306                 Exp *tail = get_exp();
307                 exp = new FieldExp(loc, *head, *tail);
308                 break;
309             }
310             case 14:
311             {
312                 bool hasElse = get_bool();
313                 Exp* test = get_exp();
314                 Exp* _then = get_exp();
315                 IfExp* ifexp;
316                 if (hasElse)
317                 {
318                     Exp* _else = get_exp();
319                     ifexp = new IfExp(loc, *test, *_then->getAs<SeqExp>(), *_else->getAs<SeqExp>());
320                 }
321                 else
322                 {
323                     ifexp = new IfExp(loc, *test, *_then);
324                 }
325                 exp = ifexp;
326                 break;
327             }
328             case 15:
329             {
330                 Location try_location = get_location();
331                 Location catch_location = get_location();
332                 exps_t* try_exps = get_exps();
333                 exps_t* catch_exps = get_exps();
334                 SeqExp *tryexp = new SeqExp(try_location, *try_exps);
335                 SeqExp *catchexp = new SeqExp(catch_location, *catch_exps);
336                 exp = new TryCatchExp(loc, *tryexp, *catchexp);
337                 break;
338             }
339             case 16:
340             {
341                 Exp* test = get_exp();
342                 Exp* body = get_exp();
343                 exp = new WhileExp(loc, *test, *body->getAs<SeqExp>());
344                 break;
345             }
346             case 17:
347             {
348                 Location vardec_location = get_location();
349                 VarDec* vardec = get_VarDec(vardec_location);
350                 Exp* body = get_exp();
351                 exp = new ForExp(loc, *vardec, *body->getAs<SeqExp>());
352                 break;
353             }
354             case 18:
355             {
356                 exp = new BreakExp(loc);
357                 break;
358             }
359             case 19:
360             {
361                 exp = new ContinueExp(loc);
362                 break;
363             }
364             case 20:
365             {
366                 bool is_global = get_bool();
367                 if ( is_global )
368                 {
369                     exp = new ReturnExp(loc);
370                 }
371                 else
372                 {
373                     Exp* returnExp_exp = get_exp();
374                     exp = new ReturnExp(loc, returnExp_exp);
375                 }
376                 break;
377             }
378             case 21:
379             {
380                 bool has_default = get_bool();
381                 SeqExp * default_case = NULL;
382                 if ( has_default )
383                 {
384                     Location default_case_location = get_location();
385                     exps_t* default_case_exps = get_exps();
386                     default_case = new SeqExp(default_case_location,
387                                               *default_case_exps);
388                 }
389                 Exp* select = get_exp();
390
391                 int nitems = get_uint32();
392                 exps_t* cases = new  exps_t;
393                 for (int i = 0; i < nitems; i++)
394                 {
395
396                     Location case_location = get_location();
397                     Location body_location = get_location();
398                     Exp* test = get_exp();
399                     exps_t* body_exps = get_exps();
400                     SeqExp *body = new SeqExp(body_location,  *body_exps);
401
402                     CaseExp* _case = new CaseExp(case_location, *test, *body);
403                     cases->push_back(_case);
404                 }
405
406
407                 if ( has_default )
408                 {
409                     exp = new SelectExp(loc, *select, *cases, *default_case);
410                 }
411                 else
412                 {
413                     exp = new SelectExp(loc, *select, *cases);
414                 }
415                 break;
416             }
417             /* SHOULD NEVER HAPPEN
418             case 22: {
419             exp = new CaseExp(*loc);
420             break;
421             }
422             */
423             case 23:
424             {
425                 ast::exps_t* lines = get_MatrixLines();
426                 exp = new CellExp(loc, *lines);
427                 break;
428             }
429             case 24:
430             {
431                 exps_t* exps = get_exps();
432                 exp = new ArrayListExp(loc, *exps);
433                 break;
434             }
435             case 25:
436             {
437                 exps_t* exps = get_exps();
438                 exp = new AssignListExp(loc, *exps);
439                 break;
440             }
441             case 26:
442             {
443                 Exp* notexp = get_exp();
444                 exp = new NotExp(loc, *notexp);
445                 break;
446             }
447             case 27:
448             {
449                 TransposeExp::Kind kind = get_TransposeExp_Kind();
450                 Exp* _exp = get_exp();
451                 exp = new TransposeExp(loc, *_exp, kind);
452                 break;
453             }
454             case 28:
455             {
456                 exp = get_VarDec(loc);
457                 break;
458             }
459             case 29:
460             {
461                 symbol::Symbol* name = get_Symbol();
462                 Location args_loc = get_location();
463                 Location returns_loc = get_location();
464                 Exp* body = get_exp();
465                 exps_t* args_list = get_vars();
466                 exps_t* returns_list = get_vars();
467                 ArrayListVar *args = new ArrayListVar(args_loc, *args_list);
468                 ArrayListVar *returns = new ArrayListVar(returns_loc, *returns_list);
469                 exp = new FunctionDec(loc, *name, *args, *returns, *body->getAs<SeqExp>());
470                 delete name;
471                 break;
472             }
473             case 30:
474             {
475                 Exp* _start = get_exp();
476                 Exp* _step = get_exp();
477                 Exp* _end = get_exp();
478                 exp = new ListExp(loc, *_start, *_step, *_end, true);
479                 break;
480             }
481             case 31:
482             {
483                 Exp* _left = get_exp();
484                 Exp* _right = get_exp();
485                 exp = new AssignExp(loc, *_left, *_right);
486                 break;
487             }
488             case 32:
489             {
490                 OpExp::Oper oper = get_OpExp_Oper();
491                 Exp *left = get_exp();
492                 Exp *right = get_exp();
493                 OpExp *_opexp  = new OpExp(loc, *left, oper, *right);
494                 exp = _opexp;
495                 break;
496             }
497             case 33:
498             {
499                 OpExp::Oper oper = get_OpExp_Oper();
500                 Exp *left = get_exp();
501                 Exp *right = get_exp();
502                 LogicalOpExp *_opexp  =
503                     new LogicalOpExp(loc, *left, oper, *right);
504                 exp = _opexp;
505                 break;
506             }
507             case 34:
508             {
509                 exps_t* lines = get_MatrixLines();
510                 exp = new MatrixExp(loc, *lines);
511                 break;
512             }
513             case 35:
514             {
515                 Exp* name = get_exp();
516                 exps_t* args = get_exps();
517                 exp = new CallExp(loc, *name, *args);
518                 break;
519             }
520             /* SHOULD NEVER HAPPEN
521             case 36: {
522             exp = new MatrixLineExp(*loc);
523             break;
524             }
525             */
526             case 37:
527             {
528                 Exp* name = get_exp();
529                 exps_t* args = get_exps();
530                 exp = new CellCallExp(loc, *name, *args);
531                 break;
532             }
533             default:
534                 std::cerr << "Unknown code " << code << std::endl;
535                 exit(2);
536         }
537
538         exp->setVerbose(isVerbose);
539         if (nodeNumber != 0)
540         {
541             exp->setNodeNumber(nodeNumber);
542         }
543
544         return exp;
545     }
546
547 public :
548     DeserializeVisitor(unsigned char* buffer) : initial_buf(buffer), buf(buffer) {};
549
550     Exp* deserialize()
551     {
552
553         // scilabVersion and size unused
554         // but get_uintxx used to deserialize macros
555         /*unsigned int size = */get_uint32();
556         // serialization version
557         /*unsigned char scilabVersion[4];
558         scilabVersion[0] = */
559         get_uint8();
560         /*scilabVersion[1] = */
561         get_uint8();
562         /*scilabVersion[2] = */
563         get_uint8();
564         /*scilabVersion[3] = */
565         get_uint8();
566
567         return get_exp();
568     }
569 };
570 }
571 #endif /* !__DESERIALIZER_HXX__  */