Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
asttoscriptconverter.cpp
Go to the documentation of this file.
1/*
2 Copyright (C) 2019 Quaternion Risk Management Ltd
3 All rights reserved.
4
5 This file is part of ORE, a free-software/open-source library
6 for transparent pricing and risk analysis - http://opensourcerisk.org
7
8 ORE is free software: you can redistribute it and/or modify it
9 under the terms of the Modified BSD License. You should have received a
10 copy of the license along with this program.
11 The license is also available online at <http://opensourcerisk.org>
12
13 This program is distributed on the basis that it will form a useful
14 contribution to risk analytics and model standardisation, but WITHOUT
15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 FITNESS FOR A PARTICULAR PURPOSE. See the license for more details.
17*/
18
20
22
23#include <ql/errors.hpp>
24
25#include <sstream>
26
27namespace ore {
28namespace data {
29
30namespace {
31class ASTToScriptConverter : public AcyclicVisitor,
32 public Visitor<ASTNode>,
33 public Visitor<OperatorPlusNode>,
34 public Visitor<OperatorMinusNode>,
35 public Visitor<OperatorMultiplyNode>,
36 public Visitor<OperatorDivideNode>,
37 public Visitor<NegateNode>,
38 public Visitor<FunctionAbsNode>,
39 public Visitor<FunctionExpNode>,
40 public Visitor<FunctionLogNode>,
41 public Visitor<FunctionSqrtNode>,
42 public Visitor<FunctionNormalCdfNode>,
43 public Visitor<FunctionNormalPdfNode>,
44 public Visitor<FunctionMinNode>,
45 public Visitor<FunctionMaxNode>,
46 public Visitor<FunctionPowNode>,
47 public Visitor<FunctionBlackNode>,
48 public Visitor<FunctionDcfNode>,
49 public Visitor<FunctionDaysNode>,
50 public Visitor<FunctionPayNode>,
51 public Visitor<FunctionLogPayNode>,
52 public Visitor<FunctionNpvNode>,
53 public Visitor<FunctionNpvMemNode>,
54 public Visitor<HistFixingNode>,
55 public Visitor<FunctionDiscountNode>,
56 public Visitor<FunctionFwdCompNode>,
57 public Visitor<FunctionFwdAvgNode>,
58 public Visitor<FunctionAboveProbNode>,
59 public Visitor<FunctionBelowProbNode>,
60 public Visitor<FunctionDateIndexNode>,
61 public Visitor<SortNode>,
62 public Visitor<PermuteNode>,
63 public Visitor<ConstantNumberNode>,
64 public Visitor<VariableNode>,
65 public Visitor<SizeOpNode>,
66 public Visitor<VarEvaluationNode>,
67 public Visitor<AssignmentNode>,
68 public Visitor<RequireNode>,
69 public Visitor<DeclarationNumberNode>,
70 public Visitor<SequenceNode>,
71 public Visitor<ConditionEqNode>,
72 public Visitor<ConditionNeqNode>,
73 public Visitor<ConditionLtNode>,
74 public Visitor<ConditionLeqNode>,
75 public Visitor<ConditionGtNode>,
76 public Visitor<ConditionGeqNode>,
77 public Visitor<ConditionNotNode>,
78 public Visitor<ConditionAndNode>,
79 public Visitor<ConditionOrNode>,
80 public Visitor<IfThenElseNode>,
81 public Visitor<LoopNode> {
82public:
83 ASTToScriptConverter() : indent(0) {}
84
85 void visit(ASTNode& n) override { QL_FAIL("ASTToScriptConverter(): unknown node type"); }
86
87 void visit(OperatorPlusNode& n) override {
88 n.args[0]->accept(*this);
89 auto left = script;
90 n.args[1]->accept(*this);
91 auto right = script;
92 script = "(" + left + " + " + right + ")";
93 }
94
95 void visit(OperatorMinusNode& n) override {
96 n.args[0]->accept(*this);
97 auto left = script;
98 n.args[1]->accept(*this);
99 auto right = script;
100 script = "(" + left + " - (" + right + "))";
101 }
102
103 void visit(OperatorMultiplyNode& n) override {
104 n.args[0]->accept(*this);
105 auto left = script;
106 n.args[1]->accept(*this);
107 auto right = script;
108 script = "(" + left + " * " + right + ")";
109 }
110
111 void visit(OperatorDivideNode& n) override {
112 n.args[0]->accept(*this);
113 auto left = script;
114 n.args[1]->accept(*this);
115 auto right = script;
116 script = "(" + left + " / (" + right + "))";
117 }
118
119 void visit(NegateNode& n) override {
120 n.args[0]->accept(*this);
121 script = "-(" + script + ")";
122 }
123
124 void visit(FunctionAbsNode& n) override {
125 n.args[0]->accept(*this);
126 script = "abs(" + script + ")";
127 }
128
129 void visit(FunctionExpNode& n) override {
130 n.args[0]->accept(*this);
131 script = "exp(" + script + ")";
132 }
133
134 void visit(FunctionLogNode& n) override {
135 n.args[0]->accept(*this);
136 script = "ln(" + script + ")";
137 }
138
139 void visit(FunctionSqrtNode& n) override {
140 n.args[0]->accept(*this);
141 script = "sqrt(" + script + ")";
142 }
143
144 void visit(FunctionNormalCdfNode& n) override {
145 n.args[0]->accept(*this);
146 script = "normalCdf(" + script + ")";
147 }
148
149 void visit(FunctionNormalPdfNode& n) override {
150 n.args[0]->accept(*this);
151 script = "normalPdf(" + script + ")";
152 }
153
154 void visit(FunctionMinNode& n) override {
155 n.args[0]->accept(*this);
156 auto left = script;
157 n.args[1]->accept(*this);
158 auto right = script;
159 script = "min(" + left + ", " + right + ")";
160 }
161
162 void visit(FunctionMaxNode& n) override {
163 n.args[0]->accept(*this);
164 auto left = script;
165 n.args[1]->accept(*this);
166 auto right = script;
167 script = "max(" + left + ", " + right + ")";
168 }
169
170 void visit(FunctionPowNode& n) override {
171 n.args[0]->accept(*this);
172 auto left = script;
173 n.args[1]->accept(*this);
174 auto right = script;
175 script = "pow(" + left + ", " + right + ")";
176 }
177
178 void visit(FunctionBlackNode& n) override {
179 n.args[0]->accept(*this);
180 auto arg1 = script;
181 n.args[1]->accept(*this);
182 auto arg2 = script;
183 n.args[2]->accept(*this);
184 auto arg3 = script;
185 n.args[3]->accept(*this);
186 auto arg4 = script;
187 n.args[4]->accept(*this);
188 auto arg5 = script;
189 n.args[5]->accept(*this);
190 auto arg6 = script;
191 script = "black(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ", " + arg5 + ", " + arg6 + ")";
192 }
193
194 void visit(FunctionDcfNode& n) override {
195 n.args[0]->accept(*this);
196 auto arg1 = script;
197 n.args[1]->accept(*this);
198 auto arg2 = script;
199 n.args[2]->accept(*this);
200 auto arg3 = script;
201 script = "dcf(" + arg1 + ", " + arg2 + ", " + arg3 + ")";
202 }
203
204 void visit(FunctionDaysNode& n) override {
205 n.args[0]->accept(*this);
206 auto arg1 = script;
207 n.args[1]->accept(*this);
208 auto arg2 = script;
209 n.args[2]->accept(*this);
210 auto arg3 = script;
211 script = "days(" + arg1 + ", " + arg2 + ", " + arg3 + ")";
212 }
213
214 void visit(FunctionPayNode& n) override {
215 n.args[0]->accept(*this);
216 auto arg1 = script;
217 n.args[1]->accept(*this);
218 auto arg2 = script;
219 n.args[2]->accept(*this);
220 auto arg3 = script;
221 n.args[3]->accept(*this);
222 auto arg4 = script;
223 script = "PAY(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ")";
224 }
225
226 void visit(FunctionLogPayNode& n) override {
227 n.args[0]->accept(*this);
228 auto arg1 = script;
229 n.args[1]->accept(*this);
230 auto arg2 = script;
231 n.args[2]->accept(*this);
232 auto arg3 = script;
233 n.args[3]->accept(*this);
234 auto arg4 = script;
235 std::string arg5;
236 if (n.args[4]) {
237 n.args[4]->accept(*this);
238 arg5 = script;
239 }
240 std::string arg6;
241 if (n.args[5]) {
242 n.args[5]->accept(*this);
243 arg6 = script;
244 }
245 std::string arg7;
246 if (n.args[6]) {
247 n.args[6]->accept(*this);
248 arg7 = script;
249 }
250 script = "LOGPAY(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4;
251 if (!arg5.empty())
252 script += ", " + arg5;
253 if (!arg6.empty())
254 script += ", " + arg6;
255 if (!arg7.empty())
256 script += ", " + arg7;
257 script += ")";
258 }
259
260 void visit(FunctionNpvNode& n) override {
261 n.args[0]->accept(*this);
262 auto arg1 = script;
263 n.args[1]->accept(*this);
264 auto arg2 = script;
265 std::string arg3;
266 if (n.args[2]) {
267 n.args[2]->accept(*this);
268 arg3 = script;
269 }
270 std::string arg4;
271 if(n.args[3]) {
272 n.args[3]->accept(*this);
273 arg4 = script;
274 }
275 std::string arg5;
276 if(n.args[4]) {
277 n.args[4]->accept(*this);
278 arg5 = script;
279 }
280 script = "NPV(" + arg1 + ", " + arg2;
281 if (!arg3.empty())
282 script += ", " + arg3;
283 if (!arg4.empty())
284 script += ", " + arg4;
285 if (!arg5.empty())
286 script += ", " + arg5;
287 script += ")";
288 }
289
290 void visit(FunctionNpvMemNode& n) override {
291 n.args[0]->accept(*this);
292 auto arg1 = script;
293 n.args[1]->accept(*this);
294 auto arg2 = script;
295 n.args[2]->accept(*this);
296 auto arg3 = script;
297 std::string arg4;
298 if (n.args[3]) {
299 n.args[3]->accept(*this);
300 arg4 = script;
301 }
302 std::string arg5;
303 if (n.args[4]) {
304 n.args[4]->accept(*this);
305 arg5 = script;
306 }
307 std::string arg6;
308 if (n.args[5]) {
309 n.args[5]->accept(*this);
310 arg6 = script;
311 }
312 script = "NPVMEM(" + arg1 + ", " + arg2 + ", " + arg3;
313 if (!arg4.empty())
314 script += ", " + arg4;
315 if (!arg5.empty())
316 script += ", " + arg5;
317 if (!arg6.empty())
318 script += ", " + arg6;
319 script += ")";
320 }
321
322 void visit(HistFixingNode& n) override {
323 n.args[0]->accept(*this);
324 auto arg1 = script;
325 n.args[1]->accept(*this);
326 auto arg2 = script;
327 script = "HISTFIXING(" + arg1 + ", " + arg2 + ")";
328 }
329
330 void visit(FunctionDiscountNode& n) override {
331 n.args[0]->accept(*this);
332 auto arg1 = script;
333 n.args[1]->accept(*this);
334 auto arg2 = script;
335 n.args[2]->accept(*this);
336 auto arg3 = script;
337 script = "DISCOUNT(" + arg1 + ", " + arg2 + ", " + arg3 + ")";
338 }
339
340 void visit(FunctionFwdCompNode& n) override {
341 n.args[0]->accept(*this);
342 auto arg1 = script;
343 n.args[1]->accept(*this);
344 auto arg2 = script;
345 n.args[2]->accept(*this);
346 auto arg3 = script;
347 n.args[3]->accept(*this);
348 auto arg4 = script;
349 std::string arg5;
350 if (n.args[4]) {
351 n.args[4]->accept(*this);
352 arg5 = script;
353 }
354 std::string arg6;
355 if (n.args[5]) {
356 n.args[5]->accept(*this);
357 arg6 = script;
358 }
359 std::string arg7;
360 if (n.args[6]) {
361 n.args[6]->accept(*this);
362 arg7 = script;
363 }
364 std::string arg8;
365 if (n.args[7]) {
366 n.args[7]->accept(*this);
367 arg8 = script;
368 }
369 std::string arg9;
370 if (n.args[8]) {
371 n.args[8]->accept(*this);
372 arg9 = script;
373 }
374 std::string arg10;
375 if (n.args[9]) {
376 n.args[9]->accept(*this);
377 arg10 = script;
378 }
379 std::string arg11;
380 if (n.args[10]) {
381 n.args[10]->accept(*this);
382 arg11 = script;
383 }
384 std::string arg12;
385 if (n.args[11]) {
386 n.args[11]->accept(*this);
387 arg12 = script;
388 }
389 std::string arg13;
390 if (n.args[12]) {
391 n.args[12]->accept(*this);
392 arg13 = script;
393 }
394 std::string arg14;
395 if (n.args[13]) {
396 n.args[13]->accept(*this);
397 arg14 = script;
398 }
399 script = "FWDCOMP(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4;
400 if (arg5.empty())
401 script += ")";
402 else {
403 script += ", " + arg5;
404 if (arg6.empty())
405 script += ")";
406 else {
407 script += ", " + arg6;
408 if (arg7.empty())
409 script += ")";
410 else {
411 script += ", " + arg7;
412 if (arg8.empty())
413 script += ")";
414 else {
415 script += ", " + arg8;
416 if (arg9.empty())
417 script += ")";
418 else {
419 script += ", " + arg9;
420 if (arg10.empty())
421 script += ")";
422 else {
423 script += ", " + arg10;
424 if (arg11.empty())
425 script += ")";
426 else {
427 script += ", " + arg11;
428 if (arg12.empty())
429 script += ")";
430 else {
431 script += ", " + arg12;
432 if (arg13.empty())
433 script += ")";
434 else {
435 script += ", " + arg13;
436 if (arg14.empty())
437 script += ")";
438 else {
439 script += ", " + arg14 + ")";
440 }
441 }
442 }
443 }
444 }
445 }
446 }
447 }
448 }
449 }
450 }
451
452 void visit(FunctionFwdAvgNode& n) override {
453 n.args[0]->accept(*this);
454 auto arg1 = script;
455 n.args[1]->accept(*this);
456 auto arg2 = script;
457 n.args[2]->accept(*this);
458 auto arg3 = script;
459 n.args[3]->accept(*this);
460 auto arg4 = script;
461 std::string arg5;
462 if (n.args[4]) {
463 n.args[4]->accept(*this);
464 arg5 = script;
465 }
466 std::string arg6;
467 if (n.args[5]) {
468 n.args[5]->accept(*this);
469 arg6 = script;
470 }
471 std::string arg7;
472 if (n.args[6]) {
473 n.args[6]->accept(*this);
474 arg7 = script;
475 }
476 std::string arg8;
477 if (n.args[7]) {
478 n.args[7]->accept(*this);
479 arg8 = script;
480 }
481 std::string arg9;
482 if (n.args[8]) {
483 n.args[8]->accept(*this);
484 arg9 = script;
485 }
486 std::string arg10;
487 if (n.args[9]) {
488 n.args[9]->accept(*this);
489 arg10 = script;
490 }
491 std::string arg11;
492 if (n.args[10]) {
493 n.args[10]->accept(*this);
494 arg11 = script;
495 }
496 std::string arg12;
497 if (n.args[11]) {
498 n.args[11]->accept(*this);
499 arg12 = script;
500 }
501 std::string arg13;
502 if (n.args[12]) {
503 n.args[12]->accept(*this);
504 arg13 = script;
505 }
506 std::string arg14;
507 if (n.args[13]) {
508 n.args[13]->accept(*this);
509 arg14 = script;
510 }
511 script = "FWDAVG(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4;
512 if (arg5.empty())
513 script += ")";
514 else {
515 script += ", " + arg5;
516 if (arg6.empty())
517 script += ")";
518 else {
519 script += ", " + arg6;
520 if (arg7.empty())
521 script += ")";
522 else {
523 script += ", " + arg7;
524 if (arg8.empty())
525 script += ")";
526 else {
527 script += ", " + arg8;
528 if (arg9.empty())
529 script += ")";
530 else {
531 script += ", " + arg9;
532 if (arg10.empty())
533 script += ")";
534 else {
535 script += ", " + arg10;
536 if (arg11.empty())
537 script += ")";
538 else {
539 script += ", " + arg11;
540 if (arg12.empty())
541 script += ")";
542 else {
543 script += ", " + arg12;
544 if (arg13.empty())
545 script += ")";
546 else {
547 script += ", " + arg13;
548 if (arg14.empty())
549 script += ")";
550 else {
551 script += ", " + arg14 + ")";
552 }
553 }
554 }
555 }
556 }
557 }
558 }
559 }
560 }
561 }
562 }
563
564 void visit(FunctionAboveProbNode& n) override {
565 n.args[0]->accept(*this);
566 auto arg1 = script;
567 n.args[1]->accept(*this);
568 auto arg2 = script;
569 n.args[2]->accept(*this);
570 auto arg3 = script;
571 n.args[3]->accept(*this);
572 auto arg4 = script;
573 script = "ABOVEPROB(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ")";
574 }
575
576 void visit(FunctionBelowProbNode& n) override {
577 n.args[0]->accept(*this);
578 auto arg1 = script;
579 n.args[1]->accept(*this);
580 auto arg2 = script;
581 n.args[2]->accept(*this);
582 auto arg3 = script;
583 n.args[3]->accept(*this);
584 auto arg4 = script;
585 script = "BELOWPROB(" + arg1 + ", " + arg2 + ", " + arg3 + ", " + arg4 + ")";
586 }
587
588 void visit(FunctionDateIndexNode& n) override {
589 n.args[0]->accept(*this);
590 auto arg1 = script;
591 script = "DATEINDEX(" + arg1 + ", " + n.name + "," + n.op + ")";
592 }
593
594 void visit(SortNode& n) override {
595 auto v1 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[0]);
596 auto v2 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[1]);
597 auto v3 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[2]);
598 script = "SORT ( " + (v1 ? v1->name : "") + (v2 ? "," + v2->name : "") + (v3 ? "," + v3->name : "") + " )";
599 }
600
601 void visit(PermuteNode& n) override {
602 auto v1 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[0]);
603 auto v2 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[1]);
604 auto v3 = QuantLib::ext::dynamic_pointer_cast<VariableNode>(n.args[2]);
605 script = "PERMUTE ( " + (v1 ? v1->name : "") + (v2 ? "," + v2->name : "") + (v3 ? "," + v3->name : "") + " )";
606 }
607
608 void visit(ConstantNumberNode& n) override { script = std::to_string(n.value); }
609
610 void visit(VariableNode& n) override {
611 std::string arg1;
612 if (n.args[0]) {
613 n.args[0]->accept(*this);
614 arg1 = script;
615 }
616 script = n.name + (arg1.empty() ? "" : "[" + arg1 + "]");
617 }
618
619 void visit(SizeOpNode& n) override { script = "SIZE(" + n.name + ")"; }
620
621 void visit(VarEvaluationNode& n) override {
622 n.args[0]->accept(*this);
623 auto arg1 = script;
624 n.args[1]->accept(*this);
625 auto arg2 = script;
626 std::string arg3;
627 if (n.args[2]) {
628 n.args[2]->accept(*this);
629 arg3 = script;
630 }
631 script = arg1 + "(" + arg2 + (arg3.empty() ? ")" : ", " + arg3 + ")");
632 }
633
634 void visit(AssignmentNode& n) override {
635 n.args[0]->accept(*this);
636 auto arg1 = script;
637 n.args[1]->accept(*this);
638 auto arg2 = script;
639 script = std::string(indent, ' ') + arg1 + " = " + arg2;
640 }
641
642 void visit(RequireNode& n) override {
643 n.args[0]->accept(*this);
644 auto arg1 = script;
645 script = std::string(indent, ' ') + "REQUIRE " + arg1;
646 }
647
648 void visit(DeclarationNumberNode& n) override {
649 std::string tmp = "NUMBER ";
650 for (Size i = 0; i < n.args.size(); ++i) {
651 n.args[i]->accept(*this);
652 tmp += script + (i < n.args.size() - 1 ? ", " : "");
653 }
654 script = std::string(indent, ' ') + tmp;
655 }
656
657 void visit(SequenceNode& n) override {
658 std::string tmp;
659 for (Size i = 0; i < n.args.size(); ++i) {
660 n.args[i]->accept(*this);
661 tmp += script + ";\n";
662 }
663 script = tmp;
664 }
665
666 void visit(ConditionEqNode& n) override {
667 n.args[0]->accept(*this);
668 auto arg1 = script;
669 n.args[1]->accept(*this);
670 auto arg2 = script;
671 script = arg1 + " == " + arg2;
672 }
673
674 void visit(ConditionNeqNode& n) override {
675 n.args[0]->accept(*this);
676 auto arg1 = script;
677 n.args[1]->accept(*this);
678 auto arg2 = script;
679 script = arg1 + " != " + arg2;
680 }
681
682 void visit(ConditionLtNode& n) override {
683 n.args[0]->accept(*this);
684 auto arg1 = script;
685 n.args[1]->accept(*this);
686 auto arg2 = script;
687 script = arg1 + " < " + arg2;
688 }
689
690 void visit(ConditionLeqNode& n) override {
691 n.args[0]->accept(*this);
692 auto arg1 = script;
693 n.args[1]->accept(*this);
694 auto arg2 = script;
695 script = arg1 + " <= " + arg2;
696 }
697
698 void visit(ConditionGtNode& n) override {
699 n.args[0]->accept(*this);
700 auto arg1 = script;
701 n.args[1]->accept(*this);
702 auto arg2 = script;
703 script = arg1 + " > " + arg2;
704 }
705
706 void visit(ConditionGeqNode& n) override {
707 n.args[0]->accept(*this);
708 auto arg1 = script;
709 n.args[1]->accept(*this);
710 auto arg2 = script;
711 script = arg1 + " >= " + arg2;
712 }
713
714 void visit(ConditionNotNode& n) override {
715 n.args[0]->accept(*this);
716 auto arg1 = script;
717 script = "NOT(" + arg1 + ")";
718 }
719
720 void visit(ConditionAndNode& n) override {
721 n.args[0]->accept(*this);
722 auto arg1 = script;
723 n.args[1]->accept(*this);
724 auto arg2 = script;
725 script = "{" + arg1 + " AND " + arg2 + "}";
726 }
727
728 void visit(ConditionOrNode& n) override {
729 n.args[0]->accept(*this);
730 auto arg1 = script;
731 n.args[1]->accept(*this);
732 auto arg2 = script;
733 script = "{" + arg1 + " OR " + arg2 + "}";
734 }
735
736 void visit(IfThenElseNode& n) override {
737 n.args[0]->accept(*this);
738 auto arg1 = script;
739 indent += tabsize;
740 n.args[1]->accept(*this);
741 auto arg2 = script;
742 std::string arg3;
743 if (n.args[2]) {
744 n.args[2]->accept(*this);
745 arg3 = script;
746 }
747 indent -= tabsize;
748 script = std::string(indent, ' ') + "IF " + arg1 + " THEN\n" + arg2 + std::string(indent, ' ') +
749 (arg3.empty() ? "END" : "ELSE\n" + arg3 + std::string(indent, ' ') + "END");
750 }
751
752 void visit(LoopNode& n) override {
753 n.args[0]->accept(*this);
754 auto arg1 = script;
755 n.args[1]->accept(*this);
756 auto arg2 = script;
757 indent += tabsize;
758 n.args[2]->accept(*this);
759 auto arg3 = script;
760 n.args[3]->accept(*this);
761 auto arg4 = script;
762 indent -= tabsize;
763 script = std::string(indent, ' ') + "FOR " + n.name + " IN (" + arg1 + ", " + arg2 + ", " + arg3 + ") DO\n" +
764 arg4 + std::string(indent, ' ') + "END";
765 }
766
767 std::string script;
768 Size indent;
769 static constexpr Size tabsize = 2;
770};
771} // namespace
772
773std::string to_script(const ASTNodePtr root) {
774 ASTToScriptConverter p;
775 root->accept(p);
776 return p.script;
777}
778
779} // namespace data
780} // namespace ore
std::string script
Size indent
ast to script converter
@ data
Definition: log.hpp:77
std::string to_script(const ASTNodePtr root)
QuantLib::ext::shared_ptr< ASTNode > ASTNodePtr
Definition: ast.hpp:46
Serializable Credit Default Swap.
Definition: namespaces.docs:23
string conversion utilities