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