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
6 * Copyright (C) 2012 - 2016 - Scilab Enterprises
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.
17 #ifndef __SERIALIZER_HXX__
18 #define __SERIALIZER_HXX__
20 #include "dummyvisitor.hxx"
21 #include "deserializervisitor.hxx"
23 #include "charEncoding.h"
26 #define FAGMENT_SIZE 65536
30 class SerializeVisitor : public DummyVisitor
40 unsigned char* get_buf(void)
43 set_uint32(0, buflen);
49 /** @{ Set the file header without modifying the file size. */
53 set_byte(4, (unsigned char)SCI_VERSION_MAJOR);
54 set_byte(5, (unsigned char)SCI_VERSION_MINOR);
55 set_byte(6, (unsigned char)SCI_VERSION_MAINTENANCE);
56 set_byte(7, (unsigned char)0);
59 void set_uint32(unsigned int pos, unsigned int n)
61 buf[pos++] = (n & 0xff);
63 buf[pos++] = (n & 0xff);
65 buf[pos++] = (n & 0xff);
67 buf[pos++] = (n & 0xff);
70 void set_byte(unsigned int pos, unsigned char n)
77 void add_location(const Location& loc)
81 add_uint32(loc.first_line);
82 add_uint32(loc.first_column);
83 add_uint32(loc.last_line);
84 add_uint32(loc.last_column);
94 void add_ast(unsigned int code, const Exp& e)
99 add_uint64(e.getNodeNumber());
103 add_uint64((unsigned long long)0);
106 add_location(e.getLocation());
107 add_uint8(e.isVerbose());
110 /** @{ Low-level append to the buffer functions */
112 /* ensure that we have [size] bytes in the buffer */
115 if (bufsize - buflen < size)
117 bufsize = 2 * bufsize + size + FAGMENT_SIZE;
118 unsigned char *newbuf = (unsigned char*) malloc(bufsize * sizeof(unsigned char));
119 // std::cerr << "malloc " << (void*) newbuf << " " << bufsize << " " << (void*) buf << " " << buflen << std::endl;
122 // std::cerr << "memcpy " << (void*) newbuf << " " << bufsize << " " << (void*) buf << " " << buflen << std::endl;
123 memcpy(newbuf, buf, buflen);
127 // std::cerr << "free " << (void*) newbuf << " " << bufsize << " " << (void*) buf << " " << buflen << std::endl;
132 buflen = 8; /* Header length. Header = final size of buf (4 bytes) + scilab version (4 bytes)*/
137 // std::cerr << "need " << size << " " << bufsize << " " << (void*) buf << " " << buflen << std::endl;
140 void add_byte(unsigned char n)
145 void add_uint8(unsigned char n)
151 void add_uint32(unsigned int n)
155 add_byte((n >>= 8) & 0xff);
156 add_byte((n >>= 8) & 0xff);
157 add_byte((n >>= 8) & 0xff);
160 void add_uint64(unsigned long long n)
164 add_byte((n >>= 8) & 0xff);
165 add_byte((n >>= 8) & 0xff);
166 add_byte((n >>= 8) & 0xff);
167 add_byte((n >>= 8) & 0xff);
168 add_byte((n >>= 8) & 0xff);
169 add_byte((n >>= 8) & 0xff);
170 add_byte((n >>= 8) & 0xff);
173 void add_double(double d)
176 *(double*)(buf + buflen) = d;
180 void add_wstring(const std::wstring &w)
182 char *c_str = wide_string_to_UTF8(w.c_str());
183 int size = strlen(c_str);
184 int final_size = size * sizeof(char);
185 add_uint32(final_size);
187 memcpy(buf + buflen, c_str, final_size);
189 buflen += final_size;
194 void add_exps(const exps_t& exps)
196 add_uint32((unsigned int)exps.size());
197 if (exps.size() != 0)
199 for (auto exp : exps)
201 exp->getOriginal()->accept(*this);
206 void add_vars(const ArrayListVar& var)
208 exps_t vars = var.getVars();
209 add_uint32((unsigned int)vars.size());
210 for (exps_t::const_iterator it = vars.begin (), itEnd = vars.end(); it != itEnd; ++it)
212 (*it)->getOriginal()->accept(*this);
216 void add_Symbol(const symbol::Symbol& e)
218 add_wstring(e.getName());
221 void add_exp(const Exp* e)
223 e->getOriginal()->accept(*this);
226 void add_exp(const Exp& e)
228 e.getOriginal()->accept(*this);
231 void add_OpExp_Oper(const OpExp::Oper oper)
255 case OpExp::dottimes:
258 case OpExp::dotrdivide:
261 case OpExp::dotldivide:
264 case OpExp::dotpower:
268 case OpExp::krontimes:
271 case OpExp::kronrdivide:
274 case OpExp::kronldivide:
278 case OpExp::controltimes:
281 case OpExp::controlrdivide:
284 case OpExp::controlldivide:
307 case OpExp::unaryMinus:
311 case OpExp::logicalAnd:
314 case OpExp::logicalOr:
317 case OpExp::logicalShortCutAnd:
320 case OpExp::logicalShortCutOr:
324 case OpExp::unaryPlus:
331 void add_TransposeExp_Kind(const TransposeExp::Kind kind)
336 case TransposeExp::_Conjugate_ :
339 case TransposeExp::_NonConjugate_:
346 void add_bool(bool b)
351 void add_varDec(const VarDec& varDec)
353 add_Symbol(varDec.getSymbol());
354 add_exp(varDec.getInit());
357 void add_MatrixLines(const exps_t* lines)
359 add_uint32((unsigned int)lines->size());
360 for (exps_t::const_iterator it = lines->begin(), itEnd = lines->end(); it != itEnd ; ++it)
362 add_location((*it)->getLocation());
363 add_exps((*it)->getAs<MatrixLineExp>()->getColumns());
367 virtual void visit (const SeqExp &e) /* done */
370 add_exps(e.getExps());
372 void visit(const StringExp& e) /* done */
375 add_wstring(e.getValue());
377 void visit(const CommentExp& e) /* done */
380 add_wstring(e.getComment());
382 void visit(const DoubleExp& e) /* done */
385 add_double(e.getValue());
387 void visit(const BoolExp& e) /* done */
390 add_bool(e.getValue());
392 void visit(const NilExp& e) /* done */
396 void visit(const SimpleVar& e) /* done */
399 add_Symbol(e.getSymbol());
401 void visit(const ColonVar& e) /* done */
405 void visit(const DollarVar& e) /* done */
409 void visit(const ArrayListVar& e) /* done */
414 void visit(const FieldExp& e) /* done */
417 add_exp(e.getHead());
418 add_exp(e.getTail());
420 void visit(const IfExp& e) /* done */
423 bool hasElse = e.hasElse();
425 add_exp(& e.getTest());
426 add_exp(& e.getThen());
429 add_exp(& e.getElse());
432 void visit(const TryCatchExp& e) /* done */
435 add_location(e.getTry().getLocation());
436 add_location(e.getCatch().getLocation());
437 add_exps(e.getTry().getAs<SeqExp>()->getExps());
438 add_exps(e.getCatch().getAs<SeqExp>()->getExps());
440 void visit(const WhileExp& e) /* done */
443 add_exp(& e.getTest());
444 add_exp(& e.getBody());
446 void visit(const ForExp& e) /* done */
449 add_location(e.getVardec().getLocation());
450 add_varDec(*e.getAs<ForExp>()->getVardec().getAs<VarDec>());
451 add_exp(&e.getBody());
453 void visit(const BreakExp& e) /* done */
457 void visit(const ContinueExp& e) /* done */
461 void visit(const ReturnExp& e) /* done */
464 bool is_global = e.isGlobal();
466 if (!is_global) /* otherwise exp is NULL */
468 add_exp(& e.getExp());
471 void visit(const SelectExp& e)
474 Exp *default_case = e.getDefaultCase();
475 add_bool(e.hasDefault());
478 add_location(default_case->getLocation());
479 add_exps(default_case->getAs<SeqExp>()->getExps());
481 add_exp(e.getSelect());
483 exps_t cases = e.getCases();
484 add_uint32((unsigned int)cases.size());
486 for (auto exp : cases)
488 const CaseExp *ce = exp->getAs<CaseExp>();
489 add_location(ce->getLocation());
490 add_location(ce->getBody()->getLocation());
491 add_exp(ce->getTest());
492 add_exps(ce->getBody()->getAs<SeqExp>()->getExps());
495 void visit(const CellExp& e) /* done */
498 add_MatrixLines(& e.getLines());
500 void visit(const ArrayListExp& e) /* done */
503 add_exps(e.getExps());
505 void visit(const AssignListExp& e) /* done */
508 add_exps(e.getExps());
510 void visit(const NotExp& e) /* done */
515 void visit(const TransposeExp& e) /* done */
518 add_TransposeExp_Kind(e.getConjugate());
521 void visit(const VarDec& e)
526 void visit(const FunctionDec& e) /* done */
529 add_Symbol(e.getSymbol());
530 add_location(e.getArgs().getLocation());
531 add_location(e.getReturns().getLocation());
532 add_exp(e.getBody());
533 add_vars(*e.getArgs().getAs<ArrayListVar>());
534 add_vars(*e.getReturns().getAs<ArrayListVar>());
536 void visit(const ListExp& e) /* done */
539 add_exp(e.getStart());
540 add_exp(e.getStep());
543 void visit(const AssignExp& e)
546 add_exp(e.getLeftExp());
547 add_exp(e.getRightExp());
549 void visit(const OpExp& e) /* done */
552 add_OpExp_Oper(e.getOper());
553 e.getLeft().getOriginal()->accept(*this);
554 e.getRight().getOriginal()->accept(*this);
556 void visit(const LogicalOpExp& e) /* done */
559 add_OpExp_Oper(e.getOper());
560 e.getLeft().getOriginal()->accept(*this);
561 e.getRight().getOriginal()->accept(*this);
563 void visit(const MatrixExp& e) /* done */
566 add_MatrixLines(& e.getLines());
568 void visit(const CallExp& e) /* done */
571 add_exp(e.getName());
572 ast::exps_t args = e.getArgs();
575 void visit(const MatrixLineExp& e) /* SHOULD NEVER HAPPEN */
579 void visit(const CellCallExp& e) /* done */
582 add_exp(e.getName());
583 ast::exps_t args = e.getArgs();
588 void visit(const OptimizedExp& e)
590 e.getOriginal()->accept(*this);
593 void visit(const MemfillExp& e)
595 e.getOriginal()->accept(*this);
598 void visit(const DAXPYExp& e)
600 e.getOriginal()->accept(*this);
603 void visit(const IntSelectExp& e)
605 e.getOriginal()->accept(*this);
608 void visit(const StringSelectExp& e)
610 e.getOriginal()->accept(*this);
614 SerializeVisitor(Exp* _ast) : ast(_ast), buf(NULL), buflen(0), bufsize(0), saveNodeNumber(true), saveLocation(true) {}
620 SerializeVisitor* clone()
622 return new SerializeVisitor(ast);
625 unsigned char* serialize(bool _saveNodeNumber = true, bool _saveLocation = true)
627 saveNodeNumber = _saveNodeNumber;
628 saveLocation = _saveLocation;
629 ast->getOriginal()->accept(*this);
635 #endif /* !__SERIALIZER_HXX__ */