Upgrade to 1.46.0
[platform/upstream/nghttp2.git] / third-party / mruby / oss-fuzz / proto_to_ruby.cpp
1 #include "proto_to_ruby.h"
2
3 using namespace ruby_fuzzer;
4
5 std::string protoConverter::removeSpecial(const std::string &x)
6 {
7         std::string tmp(x);
8         if (!tmp.empty())
9                 tmp.erase(std::remove_if(tmp.begin(), tmp.end(),
10                                          [](char c) { return !(std::isalpha(c) || std::isdigit(c)); } ), tmp.end());
11         return tmp;
12 }
13
14 void protoConverter::visit(ArrType const& x)
15 {
16         if (x.elements_size() > 0) {
17                 int i = x.elements_size();
18                 m_output << "[";
19                 for (auto &e : x.elements()) {
20                         i--;
21                         if (i == 0) {
22                                 visit(e);
23                         } else {
24                                 visit(e);
25                                 m_output << ", ";
26                         }
27                 }
28                 m_output << "]";
29         } else {
30                 m_output << "[1]";
31         }
32 }
33
34 void protoConverter::visit(Array const& x)
35 {
36         switch (x.arr_func()) {
37                 case Array::FLATTEN:
38                         visit(x.arr_arg());
39                         m_output << ".flatten";
40                         break;
41                 case Array::COMPACT:
42                         visit(x.arr_arg());
43                         m_output << ".compact";
44                         break;
45                 case Array::FETCH:
46                         visit(x.arr_arg());
47                         m_output << ".fetch";
48                         break;
49                 case Array::FILL:
50                         visit(x.arr_arg());
51                         m_output << ".fill";
52                         break;
53                 case Array::ROTATE:
54                         visit(x.arr_arg());
55                         m_output << ".rotate";
56                         break;
57                 case Array::ROTATE_E:
58                         visit(x.arr_arg());
59                         m_output << ".rotate!";
60                         break;
61                 case Array::DELETEIF:
62                         visit(x.arr_arg());
63                         m_output << ".delete_if";
64                         break;
65                 case Array::INSERT:
66                         visit(x.arr_arg());
67                         m_output << ".insert";
68                         break;
69                 case Array::BSEARCH:
70                         visit(x.arr_arg());
71                         m_output << ".bsearch";
72                         break;
73                 case Array::KEEPIF:
74                         visit(x.arr_arg());
75                         m_output << ".keep_if";
76                         break;
77                 case Array::SELECT:
78                         visit(x.arr_arg());
79                         m_output << ".select";
80                         break;
81                 case Array::VALUES_AT:
82                         visit(x.arr_arg());
83                         m_output << ".values_at";
84                         break;
85                 case Array::BLOCK:
86                         visit(x.arr_arg());
87                         m_output << ".index";
88                         break;
89                 case Array::DIG:
90                         visit(x.arr_arg());
91                         m_output << ".dig";
92                         break;
93                 case Array::SLICE:
94                         visit(x.arr_arg());
95                         m_output << ".slice";
96                         break;
97                 case Array::PERM:
98                         visit(x.arr_arg());
99                         m_output << ".permutation";
100                         break;
101                 case Array::COMB:
102                         visit(x.arr_arg());
103                         m_output << ".combination";
104                         break;
105                 case Array::ASSOC:
106                         visit(x.arr_arg());
107                         m_output << ".assoc";
108                         break;
109                 case Array::RASSOC:
110                         visit(x.arr_arg());
111                         m_output << ".rassoc";
112                         break;
113         }
114         m_output << "(";
115         visit(x.val_arg());
116         m_output << ")";
117 }
118
119 void protoConverter::visit(AssignmentStatement const& x)
120 {
121         m_output << "var_" << m_numLiveVars << " = ";
122         visit(x.rvalue());
123         m_numVarsPerScope.top()++;
124         m_numLiveVars++;
125         m_output << "\n";
126 }
127
128 void protoConverter::visit(BinaryOp const& x)
129 {
130         m_output << "(";
131         visit(x.left());
132         switch (x.op()) {
133                 case BinaryOp::ADD: m_output << " + "; break;
134                 case BinaryOp::SUB: m_output << " - "; break;
135                 case BinaryOp::MUL: m_output << " * "; break;
136                 case BinaryOp::DIV: m_output << " / "; break;
137                 case BinaryOp::MOD: m_output << " % "; break;
138                 case BinaryOp::XOR: m_output << " ^ "; break;
139                 case BinaryOp::AND: m_output << " and "; break;
140                 case BinaryOp::OR: m_output << " or "; break;
141                 case BinaryOp::EQ: m_output << " == "; break;
142                 case BinaryOp::NE: m_output << " != "; break;
143                 case BinaryOp::LE: m_output << " <= "; break;
144                 case BinaryOp::GE: m_output << " >= "; break;
145                 case BinaryOp::LT: m_output << " < "; break;
146                 case BinaryOp::GT: m_output << " > "; break;
147                 case BinaryOp::RS: m_output << " >> "; break;
148         }
149         visit(x.right());
150         m_output << ")";
151 }
152
153 void protoConverter::visit(BuiltinFuncs const& x)
154 {
155         switch (x.bifunc_oneof_case()) {
156                 case BuiltinFuncs::kOs:
157                         visit(x.os());
158                         break;
159                 case BuiltinFuncs::kTime:
160                         visit(x.time());
161                         break;
162                 case BuiltinFuncs::kArr:
163                         visit(x.arr());
164                         break;
165                 case BuiltinFuncs::kMops:
166                         visit(x.mops());
167                         break;
168                 case BuiltinFuncs::BIFUNC_ONEOF_NOT_SET:
169                         m_output << "1";
170                         break;
171         }
172         m_output << "\n";
173 }
174
175 void protoConverter::visit(Const const& x)
176 {
177         switch (x.const_oneof_case()) {
178                 case Const::kIntLit:
179                         m_output << "(" << (x.int_lit() % 13) << ")";
180                         break;
181                 case Const::kBoolVal:
182                         m_output << "(" << x.bool_val() << ")";
183                         break;
184                 case Const::CONST_ONEOF_NOT_SET:
185                         m_output << "1";
186                         break;
187         }
188 }
189
190 void protoConverter::visit(Function const& x)
191 {
192         m_output << "def foo()\nvar_0 = 1\n";
193         visit(x.statements());
194         m_output << "end\n";
195         m_output << "foo\n";
196 }
197
198 void protoConverter::visit(HashType const& x)
199 {
200         if (x.keyval_size() > 0) {
201                 int i = x.keyval_size();
202                 m_output << "{";
203                 for (auto &e : x.keyval()) {
204                         i--;
205                         if (i == 0) {
206                                 visit(e);
207                         }
208                         else {
209                                 visit(e);
210                                 m_output << ", ";
211                         }
212                 }
213                 m_output << "}";
214         }
215 }
216
217 void protoConverter::visit(IfElse const& x)
218 {
219         m_output << "if ";
220         visit(x.cond());
221         m_output << "\n";
222         visit(x.if_body());
223         m_output << "\nelse\n";
224         visit(x.else_body());
225         m_output << "\nend\n";
226 }
227
228 void protoConverter::visit(KVPair const& x)
229 {
230         m_output << "\"" << removeSpecial(x.key()) << "\"";
231         m_output << " => ";
232         m_output << "\"" << removeSpecial(x.val()) << "\"";
233 }
234
235 void protoConverter::visit(MathConst const& x)
236 {
237         switch (x.math_const()) {
238                 case MathConst::PI:
239                         m_output << "Math::PI";
240                         break;
241                 case MathConst::E:
242                         m_output << "Math::E";
243                         break;
244         }
245 }
246
247 void protoConverter::visit(MathOps const& x)
248 {
249         switch (x.math_op()) {
250                 case MathOps::CBRT:
251                         m_output << "Math.cbrt(";
252                         visit(x.math_arg());
253                         m_output << ")";
254                         break;
255                 case MathOps::COS:
256                         m_output << "Math.cos(";
257                         visit(x.math_arg());
258                         m_output << ")";
259                         break;
260                 case MathOps::ERF:
261                         m_output << "Math.erf(";
262                         visit(x.math_arg());
263                         m_output << ")";
264                         break;
265                 case MathOps::ERFC:
266                         m_output << "Math.erfc(";
267                         visit(x.math_arg());
268                         m_output << ")";
269                         break;
270                 case MathOps::LOG:
271                         m_output << "Math.log(";
272                         visit(x.math_arg());
273                         m_output << ")";
274                         break;
275                 case MathOps::LOG10:
276                         m_output << "Math.log10(";
277                         visit(x.math_arg());
278                         m_output << ")";
279                         break;
280                 case MathOps::LOG2:
281                         m_output << "Math.log2(";
282                         visit(x.math_arg());
283                         m_output << ")";
284                         break;
285                 case MathOps::SIN:
286                         m_output << "Math.sin(";
287                         visit(x.math_arg());
288                         m_output << ")";
289                         break;
290                 case MathOps::SQRT:
291                         m_output << "Math.sqrt(";
292                         visit(x.math_arg());
293                         m_output << ")";
294                         break;
295                 case MathOps::TAN:
296                         m_output << "Math.tan(";
297                         visit(x.math_arg());
298                         m_output << ")";
299                         break;
300         }
301 }
302
303 void protoConverter::visit(MathType const& x)
304 {
305         switch (x.math_arg_oneof_case()) {
306                 case MathType::kMathRval:
307                         visit(x.math_rval());
308                         break;
309                 case MathType::kMathConst:
310                         visit(x.math_const());
311                         break;
312                 case MathType::MATH_ARG_ONEOF_NOT_SET:
313                         m_output << "1";
314                         break;
315         }
316 }
317
318 void protoConverter::visit(ObjectSpace const& x)
319 {
320         switch (x.os_func()) {
321                 case ObjectSpace::COUNT:
322                         m_output << "ObjectSpace.count_objects";
323                         break;
324         }
325         m_output << "(";
326         visit(x.os_arg());
327         m_output << ")" << "\n";
328 }
329
330 void protoConverter::visit(Rvalue const& x)
331 {
332         switch (x.rvalue_oneof_case()) {
333                 case Rvalue::kVarref:
334                         visit(x.varref());
335                         break;
336                 case Rvalue::kCons:
337                         visit(x.cons());
338                         break;
339                 case Rvalue::kBinop:
340                         visit(x.binop());
341                         break;
342                 case Rvalue::RVALUE_ONEOF_NOT_SET:
343                         m_output << "1";
344                         break;
345         }
346 }
347
348 void protoConverter::visit(Statement const& x)
349 {
350         switch (x.stmt_oneof_case()) {
351                 case Statement::kAssignment:
352                         visit(x.assignment());
353                         break;
354                 case Statement::kIfelse:
355                         visit(x.ifelse());
356                         break;
357                 case Statement::kTernaryStmt:
358                         visit(x.ternary_stmt());
359                         break;
360                 case Statement::kBuiltins:
361                         visit(x.builtins());
362                         break;
363                 case Statement::kBlockstmt:
364                         visit(x.blockstmt());
365                         break;
366                 case Statement::STMT_ONEOF_NOT_SET:
367                         break;
368         }
369         m_output << "\n";
370 }
371
372 void protoConverter::visit(StatementSeq const& x)
373 {
374         if (x.statements_size() > 0) {
375                 m_numVarsPerScope.push(0);
376                 m_output << "@scope ||= begin\n";
377                 for (auto &st : x.statements())
378                         visit(st);
379                 m_output << "end\n";
380                 m_numLiveVars -= m_numVarsPerScope.top();
381                 m_numVarsPerScope.pop();
382         }
383 }
384
385 void protoConverter::visit(StringExtNoArg const& x)
386 {
387         m_output << "\"" << removeSpecial(x.str_arg()) << "\"";
388         switch (x.str_op()) {
389                 case StringExtNoArg::DUMP:
390                         m_output << ".dump";
391                         break;
392                 case StringExtNoArg::STRIP:
393                         m_output << ".strip";
394                         break;
395                 case StringExtNoArg::LSTRIP:
396                         m_output << ".lstrip";
397                         break;
398                 case StringExtNoArg::RSTRIP:
399                         m_output << ".rstrip";
400                         break;
401                 case StringExtNoArg::STRIPE:
402                         m_output << ".strip!";
403                         break;
404                 case StringExtNoArg::LSTRIPE:
405                         m_output << ".lstrip!";
406                         break;
407                 case StringExtNoArg::RSTRIPE:
408                         m_output << ".rstrip!";
409                         break;
410                 case StringExtNoArg::SWAPCASE:
411                         m_output << ".swapcase";
412                         break;
413                 case StringExtNoArg::SWAPCASEE:
414                         m_output << ".swapcase!";
415                         break;
416                 case StringExtNoArg::SQUEEZE:
417                         m_output << ".squeeze";
418                         break;
419         }
420 }
421
422 void protoConverter::visit(Ternary const& x)
423 {
424         m_output << "(";
425         visit(x.tern_cond());
426         m_output << " ? ";
427         visit(x.t_branch());
428         m_output << " : ";
429         visit(x.f_branch());
430         m_output << ")\n";
431 }
432
433 void protoConverter::visit(Time const& x)
434 {
435         switch (x.t_func()) {
436                 case Time::AT:
437                         m_output << "Time.at";
438                         break;
439                 case Time::GM:
440                         m_output << "Time.gm";
441                         break;
442         }
443         m_output << "(" << (x.t_arg()% 13) << ")" << "\n";
444 }
445
446 void protoConverter::visit(VarRef const& x)
447 {
448         m_output << "var_" << (static_cast<uint32_t>(x.varnum()) % m_numLiveVars);
449 }
450
451 std::string protoConverter::FunctionToString(Function const& input)
452 {
453         visit(input);
454         return m_output.str();
455 }