AST Serialization :
[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
231         switch (code)
232         {
233             case 1:
234             {
235                 exps_t* l_body = get_exps();
236                 exp = new SeqExp(loc, *l_body);
237                 break;
238             }
239             case 2:
240             {
241                 std::wstring* s = get_wstring();
242                 exp = new StringExp(loc, *s);
243                 delete s;
244                 break;
245             }
246             case 3:
247             {
248                 std::wstring* s = get_wstring();
249                 exp = new CommentExp(loc, s);
250                 //delete s;
251                 break;
252             }
253             case 6:
254             {
255                 double d = get_double();
256                 exp = new DoubleExp(loc, d);
257                 break;
258             }
259             case 7:
260             {
261                 bool b = get_bool();
262                 exp = new BoolExp(loc, b);
263                 break;
264             }
265             case 8:
266             {
267                 exp = new NilExp(loc);
268                 break;
269             }
270             case 9:
271             {
272                 exp = new SimpleVar(loc, *get_Symbol());
273                 break;
274             }
275             case 10:
276             {
277                 exp = new ColonVar(loc);
278                 break;
279             }
280             case 11:
281             {
282                 exp = new DollarVar(loc);
283                 break;
284             }
285             case 12:
286             {
287                 exp = new ArrayListVar(loc, *get_vars());
288                 break;
289             }
290             case 13:
291             {
292                 Exp *head = get_exp();
293                 Exp *tail = get_exp();
294                 exp = new FieldExp(loc, *head, *tail);
295                 break;
296             }
297             case 14:
298             {
299                 bool hasElse = get_bool();
300                 Exp* test = get_exp();
301                 Exp* _then = get_exp();
302                 IfExp* ifexp;
303                 if ( hasElse )
304                 {
305                     Exp* _else = get_exp();
306                     ifexp = new IfExp(loc, *test, *_then, *_else);
307                 }
308                 else
309                 {
310                     ifexp = new IfExp(loc, *test, *_then);
311                 }
312                 exp = ifexp;
313                 break;
314             }
315             case 15:
316             {
317                 Location try_location = get_location();
318                 Location catch_location = get_location();
319                 exps_t* try_exps = get_exps();
320                 exps_t* catch_exps = get_exps();
321                 SeqExp *tryexp = new SeqExp(try_location, *try_exps);
322                 SeqExp *catchexp = new SeqExp(catch_location, *catch_exps);
323                 exp = new TryCatchExp(loc, *tryexp, *catchexp);
324                 break;
325             }
326             case 16:
327             {
328                 Exp* test = get_exp();
329                 Exp* body = get_exp();
330                 exp = new WhileExp(loc, *test, *body);
331                 break;
332             }
333             case 17:
334             {
335                 Location vardec_location = get_location();
336                 VarDec* vardec = get_VarDec(vardec_location);
337                 Exp* body = get_exp();
338                 exp = new ForExp(loc, *vardec, *body);
339                 break;
340             }
341             case 18:
342             {
343                 exp = new BreakExp(loc);
344                 break;
345             }
346             case 19:
347             {
348                 exp = new ContinueExp(loc);
349                 break;
350             }
351             case 20:
352             {
353                 bool is_global = get_bool();
354                 if ( is_global )
355                 {
356                     exp = new ReturnExp(loc);
357                 }
358                 else
359                 {
360                     Exp* returnExp_exp = get_exp();
361                     exp = new ReturnExp(loc, returnExp_exp);
362                 }
363                 break;
364             }
365             case 21:
366             {
367                 bool has_default = get_bool();
368                 SeqExp * default_case = NULL;
369                 if ( has_default )
370                 {
371                     Location default_case_location = get_location();
372                     exps_t* default_case_exps = get_exps();
373                     default_case = new SeqExp(default_case_location,
374                                               *default_case_exps);
375                 }
376                 Exp* select = get_exp();
377
378                 int nitems = get_uint32();
379                 exps_t* cases = new  exps_t;
380                 for (int i = 0; i < nitems; i++)
381                 {
382
383                     Location case_location = get_location();
384                     Location body_location = get_location();
385                     Exp* test = get_exp();
386                     exps_t* body_exps = get_exps();
387                     SeqExp *body = new SeqExp(body_location,  *body_exps);
388
389                     CaseExp* _case = new CaseExp(case_location, *test, *body);
390                     cases->push_back(_case);
391                 }
392
393
394                 if ( has_default )
395                 {
396                     exp = new SelectExp(loc, *select, *cases, *default_case);
397                 }
398                 else
399                 {
400                     exp = new SelectExp(loc, *select, *cases);
401                 }
402                 break;
403             }
404             /* SHOULD NEVER HAPPEN
405             case 22: {
406             exp = new CaseExp(*loc);
407             break;
408             }
409             */
410             case 23:
411             {
412                 ast::exps_t* lines = get_MatrixLines();
413                 exp = new CellExp(loc, *lines);
414                 break;
415             }
416             case 24:
417             {
418                 exps_t* exps = get_exps();
419                 exp = new ArrayListExp(loc, *exps);
420                 break;
421             }
422             case 25:
423             {
424                 exps_t* exps = get_exps();
425                 exp = new AssignListExp(loc, *exps);
426                 break;
427             }
428             case 26:
429             {
430                 Exp* notexp = get_exp();
431                 exp = new NotExp(loc, *notexp);
432                 break;
433             }
434             case 27:
435             {
436                 TransposeExp::Kind kind = get_TransposeExp_Kind();
437                 Exp* _exp = get_exp();
438                 exp = new TransposeExp(loc, *_exp, kind);
439                 break;
440             }
441             case 28:
442             {
443                 exp = get_VarDec(loc);
444                 break;
445             }
446             case 29:
447             {
448                 symbol::Symbol* name = get_Symbol();
449                 Location args_loc = get_location();
450                 Location returns_loc = get_location();
451                 Exp* body = get_exp();
452                 exps_t* args_list = get_vars();
453                 exps_t* returns_list = get_vars();
454                 ArrayListVar *args = new ArrayListVar(args_loc, *args_list);
455                 ArrayListVar *returns = new ArrayListVar(returns_loc, *returns_list);
456                 exp = new FunctionDec(loc, *name, *args, *returns, *body);
457                 break;
458             }
459             case 30:
460             {
461                 Exp* _start = get_exp();
462                 Exp* _step = get_exp();
463                 Exp* _end = get_exp();
464                 exp = new ListExp(loc, *_start, *_step, *_end);
465                 break;
466             }
467             case 31:
468             {
469                 Exp* _left = get_exp();
470                 Exp* _right = get_exp();
471                 exp = new AssignExp(loc, *_left, *_right);
472                 break;
473             }
474             case 32:
475             {
476                 OpExp::Oper oper = get_OpExp_Oper();
477                 Exp *left = get_exp();
478                 Exp *right = get_exp();
479                 OpExp *_opexp  = new OpExp(loc, *left, oper, *right);
480                 exp = _opexp;
481                 break;
482             }
483             case 33:
484             {
485                 OpExp::Oper oper = get_OpExp_Oper();
486                 Exp *left = get_exp();
487                 Exp *right = get_exp();
488                 LogicalOpExp *_opexp  =
489                     new LogicalOpExp(loc, *left, oper, *right);
490                 exp = _opexp;
491                 break;
492             }
493             case 34:
494             {
495                 exps_t* lines = get_MatrixLines();
496                 exp = new MatrixExp(loc, *lines);
497                 break;
498             }
499             case 35:
500             {
501                 Exp* name = get_exp();
502                 exps_t* args = get_exps();
503                 exp = new CallExp(loc, *name, *args);
504                 break;
505             }
506             /* SHOULD NEVER HAPPEN
507             case 36: {
508             exp = new MatrixLineExp(*loc);
509             break;
510             }
511             */
512             case 37:
513             {
514                 Exp* name = get_exp();
515                 exps_t* args = get_exps();
516                 exp = new CellCallExp(loc, *name, *args);
517                 break;
518             }
519             default:
520                 std::cerr << "Unknown code " << code << std::endl;
521                 exit(2);
522         }
523
524         exp->setVerbose(isVerbose);
525         if (nodeNumber != 0)
526         {
527             exp->setNodeNumber(nodeNumber);
528         }
529
530         return exp;
531     }
532
533 public :
534     DeserializeVisitor(unsigned char* buffer) : initial_buf(buffer), buf(buffer) {};
535
536     Exp* deserialize()
537     {
538
539         // scilabVersion and size unused
540         // but get_uintxx used to deserialize macros
541         /*unsigned int size = */get_uint32();
542         // serialization version
543         /*unsigned char scilabVersion[4];
544         scilabVersion[0] = */
545         get_uint8();
546         /*scilabVersion[1] = */
547         get_uint8();
548         /*scilabVersion[2] = */
549         get_uint8();
550         /*scilabVersion[3] = */
551         get_uint8();
552
553         return get_exp();
554     }
555 };
556 }
557 #endif /* !__DESERIALIZER_HXX__  */