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