License Header change: Removed the LICENSE_END before beta
[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         std::cerr << "Unknown get_OpExp_Oper code " << code << std::endl;
176         exit(2);
177     }
178
179     TransposeExp::Kind get_TransposeExp_Kind(void)
180     {
181         int code = get_uint8();
182         switch (code)
183         {
184             case 1 :
185                 return TransposeExp::_Conjugate_;
186             case 2 :
187                 return TransposeExp::_NonConjugate_;
188         }
189         std::cerr << "Unknown get_TransposeExp_Kind code " << code << std::endl;
190         exit(2);
191     }
192
193     std::wstring* get_wstring(void)
194     {
195         unsigned int size = get_uint32();
196         char* ss = (char*)buf;
197         std::string s(ss, size / sizeof(char));
198         wchar_t* ws = to_wide_string(s.data());
199         std::wstring* w = new std::wstring(ws);
200         FREE(ws);
201         buf += size;
202         return w;
203     }
204
205     symbol::Symbol* get_Symbol(void)
206     {
207         std::wstring* s = get_wstring();
208         symbol::Symbol *sym = new symbol::Symbol(*s);
209         delete s;
210         return sym;
211     }
212
213     double get_double(void)
214     {
215         double d = *(double*)buf;
216         buf += 8;
217         return d;
218     }
219
220     VarDec* get_VarDec(Location & vardec_location)
221     {
222         symbol::Symbol *name = get_Symbol();
223         Exp *init = get_exp();
224         VarDec* vardec = new VarDec(vardec_location, *name, *init);
225         delete name;
226         return vardec;
227     }
228
229
230     Exp* get_exp(void)
231     {
232         Exp* exp;
233         int code = get_uint8();
234         size_t nodeNumber = get_uint64();
235         Location loc = get_location();
236         bool isVerbose = get_bool();
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                 symbol::Symbol* sym = get_Symbol();
280                 exp = new SimpleVar(loc, *sym);
281                 delete sym;
282                 break;
283             }
284             case 10:
285             {
286                 exp = new ColonVar(loc);
287                 break;
288             }
289             case 11:
290             {
291                 exp = new DollarVar(loc);
292                 break;
293             }
294             case 12:
295             {
296                 exp = new ArrayListVar(loc, *get_vars());
297                 break;
298             }
299             case 13:
300             {
301                 Exp *head = get_exp();
302                 Exp *tail = get_exp();
303                 exp = new FieldExp(loc, *head, *tail);
304                 break;
305             }
306             case 14:
307             {
308                 bool hasElse = get_bool();
309                 Exp* test = get_exp();
310                 Exp* _then = get_exp();
311                 IfExp* ifexp;
312                 if ( hasElse )
313                 {
314                     Exp* _else = get_exp();
315                     ifexp = new IfExp(loc, *test, *_then->getAs<SeqExp>(), *_else->getAs<SeqExp>());
316                 }
317                 else
318                 {
319                     ifexp = new IfExp(loc, *test, *_then);
320                 }
321                 exp = ifexp;
322                 break;
323             }
324             case 15:
325             {
326                 Location try_location = get_location();
327                 Location catch_location = get_location();
328                 exps_t* try_exps = get_exps();
329                 exps_t* catch_exps = get_exps();
330                 SeqExp *tryexp = new SeqExp(try_location, *try_exps);
331                 SeqExp *catchexp = new SeqExp(catch_location, *catch_exps);
332                 exp = new TryCatchExp(loc, *tryexp, *catchexp);
333                 break;
334             }
335             case 16:
336             {
337                 Exp* test = get_exp();
338                 Exp* body = get_exp();
339                 exp = new WhileExp(loc, *test, *body->getAs<SeqExp>());
340                 break;
341             }
342             case 17:
343             {
344                 Location vardec_location = get_location();
345                 VarDec* vardec = get_VarDec(vardec_location);
346                 Exp* body = get_exp();
347                 exp = new ForExp(loc, *vardec, *body->getAs<SeqExp>());
348                 break;
349             }
350             case 18:
351             {
352                 exp = new BreakExp(loc);
353                 break;
354             }
355             case 19:
356             {
357                 exp = new ContinueExp(loc);
358                 break;
359             }
360             case 20:
361             {
362                 bool is_global = get_bool();
363                 if ( is_global )
364                 {
365                     exp = new ReturnExp(loc);
366                 }
367                 else
368                 {
369                     Exp* returnExp_exp = get_exp();
370                     exp = new ReturnExp(loc, returnExp_exp);
371                 }
372                 break;
373             }
374             case 21:
375             {
376                 bool has_default = get_bool();
377                 SeqExp * default_case = NULL;
378                 if ( has_default )
379                 {
380                     Location default_case_location = get_location();
381                     exps_t* default_case_exps = get_exps();
382                     default_case = new SeqExp(default_case_location,
383                                               *default_case_exps);
384                 }
385                 Exp* select = get_exp();
386
387                 int nitems = get_uint32();
388                 exps_t* cases = new  exps_t;
389                 for (int i = 0; i < nitems; i++)
390                 {
391
392                     Location case_location = get_location();
393                     Location body_location = get_location();
394                     Exp* test = get_exp();
395                     exps_t* body_exps = get_exps();
396                     SeqExp *body = new SeqExp(body_location,  *body_exps);
397
398                     CaseExp* _case = new CaseExp(case_location, *test, *body);
399                     cases->push_back(_case);
400                 }
401
402
403                 if ( has_default )
404                 {
405                     exp = new SelectExp(loc, *select, *cases, *default_case);
406                 }
407                 else
408                 {
409                     exp = new SelectExp(loc, *select, *cases);
410                 }
411                 break;
412             }
413             /* SHOULD NEVER HAPPEN
414             case 22: {
415             exp = new CaseExp(*loc);
416             break;
417             }
418             */
419             case 23:
420             {
421                 ast::exps_t* lines = get_MatrixLines();
422                 exp = new CellExp(loc, *lines);
423                 break;
424             }
425             case 24:
426             {
427                 exps_t* exps = get_exps();
428                 exp = new ArrayListExp(loc, *exps);
429                 break;
430             }
431             case 25:
432             {
433                 exps_t* exps = get_exps();
434                 exp = new AssignListExp(loc, *exps);
435                 break;
436             }
437             case 26:
438             {
439                 Exp* notexp = get_exp();
440                 exp = new NotExp(loc, *notexp);
441                 break;
442             }
443             case 27:
444             {
445                 TransposeExp::Kind kind = get_TransposeExp_Kind();
446                 Exp* _exp = get_exp();
447                 exp = new TransposeExp(loc, *_exp, kind);
448                 break;
449             }
450             case 28:
451             {
452                 exp = get_VarDec(loc);
453                 break;
454             }
455             case 29:
456             {
457                 symbol::Symbol* name = get_Symbol();
458                 Location args_loc = get_location();
459                 Location returns_loc = get_location();
460                 Exp* body = get_exp();
461                 exps_t* args_list = get_vars();
462                 exps_t* returns_list = get_vars();
463                 ArrayListVar *args = new ArrayListVar(args_loc, *args_list);
464                 ArrayListVar *returns = new ArrayListVar(returns_loc, *returns_list);
465                 exp = new FunctionDec(loc, *name, *args, *returns, *body->getAs<SeqExp>());
466                 delete name;
467                 break;
468             }
469             case 30:
470             {
471                 Exp* _start = get_exp();
472                 Exp* _step = get_exp();
473                 Exp* _end = get_exp();
474                 exp = new ListExp(loc, *_start, *_step, *_end);
475                 break;
476             }
477             case 31:
478             {
479                 Exp* _left = get_exp();
480                 Exp* _right = get_exp();
481                 exp = new AssignExp(loc, *_left, *_right);
482                 break;
483             }
484             case 32:
485             {
486                 OpExp::Oper oper = get_OpExp_Oper();
487                 Exp *left = get_exp();
488                 Exp *right = get_exp();
489                 OpExp *_opexp  = new OpExp(loc, *left, oper, *right);
490                 exp = _opexp;
491                 break;
492             }
493             case 33:
494             {
495                 OpExp::Oper oper = get_OpExp_Oper();
496                 Exp *left = get_exp();
497                 Exp *right = get_exp();
498                 LogicalOpExp *_opexp  =
499                     new LogicalOpExp(loc, *left, oper, *right);
500                 exp = _opexp;
501                 break;
502             }
503             case 34:
504             {
505                 exps_t* lines = get_MatrixLines();
506                 exp = new MatrixExp(loc, *lines);
507                 break;
508             }
509             case 35:
510             {
511                 Exp* name = get_exp();
512                 exps_t* args = get_exps();
513                 exp = new CallExp(loc, *name, *args);
514                 break;
515             }
516             /* SHOULD NEVER HAPPEN
517             case 36: {
518             exp = new MatrixLineExp(*loc);
519             break;
520             }
521             */
522             case 37:
523             {
524                 Exp* name = get_exp();
525                 exps_t* args = get_exps();
526                 exp = new CellCallExp(loc, *name, *args);
527                 break;
528             }
529             default:
530                 std::cerr << "Unknown code " << code << std::endl;
531                 exit(2);
532         }
533
534         exp->setVerbose(isVerbose);
535         if (nodeNumber != 0)
536         {
537             exp->setNodeNumber(nodeNumber);
538         }
539
540         return exp;
541     }
542
543 public :
544     DeserializeVisitor(unsigned char* buffer) : initial_buf(buffer), buf(buffer) {};
545
546     Exp* deserialize()
547     {
548
549         // scilabVersion and size unused
550         // but get_uintxx used to deserialize macros
551         /*unsigned int size = */get_uint32();
552         // serialization version
553         /*unsigned char scilabVersion[4];
554         scilabVersion[0] = */
555         get_uint8();
556         /*scilabVersion[1] = */
557         get_uint8();
558         /*scilabVersion[2] = */
559         get_uint8();
560         /*scilabVersion[3] = */
561         get_uint8();
562
563         return get_exp();
564     }
565 };
566 }
567 #endif /* !__DESERIALIZER_HXX__  */