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