1 module TTSListener; 2 3 import RuleTranslatorBaseListener; 4 import RuleParser: RuleTranslatorParser; 5 import RuleWriter: RuleWriter; 6 import antlr.v4.runtime.ParserRuleContext; 7 import antlr.v4.runtime.tree.ErrorNode; 8 import antlr.v4.runtime.tree.TerminalNode; 9 import debugMixin; 10 import std.algorithm.iteration; 11 import std.array; 12 import std.container : SList; 13 import std.format; 14 import std.stdio; 15 import std.string; 16 17 /** 18 * This class provides an empty implementation of {@link RuleTranslatorListener}, 19 * which can be extended to create a listener which only needs to handle a subset 20 * of the available methods. 21 */ 22 public class TTSListener : RuleTranslatorBaseListener { 23 24 debug 25 { 26 __gshared short counter; 27 File debugInfo; 28 } 29 30 private auto stack = SList!(string[])(); 31 32 struct RuleSetting 33 { 34 string language; 35 string ruleName; 36 string className; 37 string baseName; 38 } 39 40 private RuleSetting ruleSetting; 41 42 struct LoopElement 43 { 44 string foreachType; 45 string foreachElementType; 46 ushort foreachIndex; // index must not start at 0 47 } 48 49 private auto loopStack = SList!(LoopElement)(); 50 51 private string foreachElementName; 52 53 private string dottedName; 54 55 private ushort indentLevel; 56 57 private bool funcdefFlag; 58 59 private bool trailerMode; 60 61 private bool ruleRequired = true; 62 63 private bool ruleExists; 64 65 public RuleWriter writer; 66 67 public string withPropertyName; 68 69 public string arguments; 70 71 string[] startText = [ 72 "\n", 73 "override string[] rule" ~ 74 "(${arguments})\n", 75 "{\n", 76 " output.clear;\n\n", 77 " with (${withPropertyName})\n", 78 " {\n" 79 ]; 80 81 string[] closingText = [ 82 "\n", 83 "static this()\n", 84 "{\n", 85 " auto inst = new ${class}();\n", 86 " inst.type = \"${rule}\";\n", 87 " inst.language = \"${language}\";\n", 88 " Repository.register(inst);\n", 89 "}\n" 90 ]; 91 92 /** 93 * {@inheritDoc} 94 * 95 * <p>The default implementation does nothing.</p> 96 */ 97 override public void enterFile_input(RuleTranslatorParser.File_inputContext ctx) { 98 debug { 99 debugInfo = File("/tmp/traceTTS", "w"); 100 } 101 mixin(DebugEnter); 102 writer.put("module "); 103 } 104 105 /** 106 * {@inheritDoc} 107 * 108 * <p>The default implementation does nothing.</p> 109 */ 110 override public void exitFile_input(RuleTranslatorParser.File_inputContext ctx) { 111 mixin(DebugExit); 112 writer.indentLevel = -- indentLevel; 113 writer.putnl("}"); 114 if (ruleExists) { 115 with (ruleSetting) { 116 closingText.each!((ref n) => n = n.replace("${class}", 117 className ? className : ruleName)); 118 closingText.each!((ref n) => n = n.replace("${rule}", ruleName)); 119 closingText.each!((ref n) => n = n.replace("${language}", language)); 120 } 121 writer.putnl("return output.data;"); 122 writer.indentLevel = -- indentLevel; 123 writer.putnl("}"); 124 writer.put(closingText); 125 writer.indentLevel = -- indentLevel; 126 writer.putnl("}"); 127 } 128 writer.print; 129 writer.clear; 130 } 131 132 /** 133 * {@inheritDoc} 134 * 135 * <p>The default implementation does nothing.</p> 136 */ 137 override public void exitRule_setting(RuleTranslatorParser.Rule_settingContext ctx) { 138 with (ruleSetting) { 139 if (language) 140 writer.putnl(format("%s.%s;\n", 141 language, 142 className ? className : ruleName 143 ) 144 ); 145 else 146 writer.putnl(format("%s;\n", 147 className ? className : ruleName 148 ) 149 ); 150 } 151 writer.putnl("import std.array;"); 152 writer.putnl("import std.conv;"); 153 writer.putnl("import std.datetime;"); 154 writer.putnl("import rule.Repository;"); 155 writer.putnl("import rule.GeneratedRule;\n"); 156 writer.putnl("auto iterate(R)(R range)"); 157 writer.putnl("{"); 158 writer.putnl(" import std.algorithm : map;"); 159 writer.putnl(" import std.range : enumerate;"); 160 writer.putnl(" import std.typecons : tuple;"); 161 writer.putnl(" import std.string;\n"); 162 163 writer.putnl(" return enumerate(range)"); 164 writer.putnl(" .map!(a => tuple!(\"value\", \"first\", 165 \"last\")(a.value, a.index == 0, 166 a.index + 1 == range.length));"); 167 writer.putnl("}"); 168 } 169 170 /** 171 * {@inheritDoc} 172 * 173 * <p>The default implementation does nothing.</p> 174 */ 175 override public void enterClass_name(RuleTranslatorParser.Class_nameContext ctx) { 176 ruleSetting.className = ctx.getText; 177 } 178 179 /** 180 * {@inheritDoc} 181 * 182 * <p>The default implementation does nothing.</p> 183 */ 184 override public void enterRule_name(RuleTranslatorParser.Rule_nameContext ctx) { 185 ruleSetting.ruleName = ctx.getText; 186 } 187 188 /** 189 * {@inheritDoc} 190 * 191 * <p>The default implementation does nothing.</p> 192 */ 193 override public void enterLanguage(RuleTranslatorParser.LanguageContext ctx) { 194 ruleSetting.language = ""; 195 } 196 /** 197 * {@inheritDoc} 198 * 199 * <p>The default implementation does nothing.</p> 200 */ 201 override public void exitLanguage(RuleTranslatorParser.LanguageContext ctx) { 202 ruleSetting.language = ctx.getText; 203 } 204 205 /** 206 * {@inheritDoc} 207 * 208 * <p>The default implementation does nothing.</p> 209 */ 210 override public void enterImport_stmt(RuleTranslatorParser.Import_stmtContext ctx) { 211 string app; 212 foreach (el; ctx.children[2..$]) 213 app ~= el.getText; 214 writer.putnl(format("import %s;", app)); 215 } 216 217 /** 218 * {@inheritDoc} 219 * 220 * <p>The default implementation does nothing.</p> 221 */ 222 override public void enterBase_rules(RuleTranslatorParser.Base_rulesContext ctx) { 223 ruleSetting.baseName = ctx.getText; 224 } 225 226 /** 227 * {@inheritDoc} 228 * 229 * <p>The default implementation does nothing.</p> 230 */ 231 override public void enterImport_stmts(RuleTranslatorParser.Import_stmtsContext ctx) { 232 mixin(DebugEnter); 233 ruleSetting.baseName = "GeneratedRule"; 234 } 235 236 /** 237 * {@inheritDoc} 238 * 239 * <p>The default implementation does nothing.</p> 240 */ 241 override public void exitImport_stmts(RuleTranslatorParser.Import_stmtsContext ctx) { 242 mixin(DebugExit); 243 if (! ruleSetting.className) 244 ruleSetting.className = ruleSetting.ruleName; 245 if (ruleSetting.baseName) 246 writer.putnl(format("\nclass %s : %s\n{", ruleSetting.className, ruleSetting.baseName)); 247 else 248 writer.putnl(format("\nclass %s : GeneratedRule\n{", ruleSetting.ruleName)); 249 writer.indentLevel = ++ indentLevel; 250 debug { 251 debugInfo.writefln("\truleSetting.className = %s", ruleSetting.className); 252 debugInfo.writefln("\truleSetting.ruleName = %s", ruleSetting.ruleName); 253 } 254 } 255 256 /** 257 * {@inheritDoc} 258 * 259 * <p>The default implementation does nothing.</p> 260 */ 261 override public void exitFunctionName(RuleTranslatorParser.FunctionNameContext ctx) { 262 mixin(DebugExit); 263 writer.put(ctx.getText); 264 debug 265 debugInfo.writefln("\tFunctionName = %s", ctx.getText); 266 } 267 /** 268 * {@inheritDoc} 269 * 270 * <p>The default implementation does nothing.</p> 271 */ 272 override public void enterStmt(RuleTranslatorParser.StmtContext ctx) { 273 mixin(DebugEnter); 274 debug { 275 debugInfo.writefln("\truleRequired = %s", ruleRequired); 276 debugInfo.writefln("\truleExits = %s", ruleExists); 277 } 278 if (ruleRequired) { 279 startText.each!((ref n) => n = n.replace("${withPropertyName}", withPropertyName)); 280 startText.each!((ref n) => n = n.replace("${arguments}", arguments)); 281 writer.put(startText); 282 writer.indentLevel = ++ indentLevel; 283 writer.indentLevel = ++ indentLevel; 284 ruleExists = true; 285 ruleRequired = false; 286 } 287 } 288 /** 289 * {@inheritDoc} 290 * 291 * <p>The default implementation does nothing.</p> 292 */ 293 override public void enterFuncdef(RuleTranslatorParser.FuncdefContext ctx) { 294 mixin(DebugEnter); 295 writer.putnl(""); 296 writer.put("void "); 297 funcdefFlag = true; 298 ruleRequired = false; 299 } 300 301 /** 302 * {@inheritDoc} 303 * 304 * <p>The default implementation does nothing.</p> 305 */ 306 override public void exitFuncdef(RuleTranslatorParser.FuncdefContext ctx) { 307 mixin(DebugExit); 308 writer.indentLevel = -- indentLevel; 309 writer.putnl("}"); 310 ruleRequired = true; 311 } 312 313 /** 314 * {@inheritDoc} 315 * 316 * <p>The default implementation does nothing.</p> 317 */ 318 override public void enterParameters(RuleTranslatorParser.ParametersContext ctx) { 319 mixin(DebugEnter); 320 if (funcdefFlag) 321 { 322 auto spl = splitter(ctx.getText[1..($-1)], ','); 323 writer.putnl('(' ~ spl.map!(a => "T_" ~ a).join(", ") ~ ')'); 324 writer.putnl(" (" ~ spl.map!(a => "T_" ~ a ~ ' ' ~ a).join(", ") ~ ')'); 325 writer.putnl("{"); 326 writer.indentLevel = ++ indentLevel; 327 funcdefFlag = false; 328 } 329 } 330 331 /** 332 * {@inheritDoc} 333 * 334 * <p>The default implementation does nothing.</p> 335 */ 336 override public void enterString_stmt(RuleTranslatorParser.String_stmtContext ctx) { 337 mixin(DebugEnter); 338 if (!stack.empty) { 339 stack.front ~= format("append(%s)", ctx.children[0].getText); 340 debug { 341 foreach (el; stack.opSlice) 342 debugInfo.writefln("\t%s", el); 343 } 344 } 345 } 346 347 /** 348 * {@inheritDoc} 349 * 350 * <p>The default implementation does nothing.</p> 351 */ 352 override public void exitVar_stmt(RuleTranslatorParser.Var_stmtContext ctx) { 353 mixin(DebugExit); 354 //mixin(DebugStack); 355 if (!stack.empty) { 356 stack.front = "append(" ~ dottedName ~ stack.front ~ ")"; 357 mixin(DebugStack); 358 } 359 } 360 361 /** 362 * When the name of the variable is equal to the foreach element, 363 * we need to append '.value' property 364 */ 365 override public void enterFirst_part_of_dotted_name(RuleTranslatorParser.First_part_of_dotted_nameContext ctx) { 366 dottedName = ctx.getText; 367 if (!loopStack.empty) { 368 import std.algorithm : map; 369 import std.algorithm: canFind; 370 if (array(map!(a => a.foreachElementType)(loopStack[])).canFind(ctx.getText)) { 371 dottedName ~= ".value"; 372 } 373 } 374 mixin(DebugEnter); 375 debug { 376 debugInfo.writefln("\tdottedName = %s", dottedName); 377 foreach (el; stack.opSlice) 378 debugInfo.writefln("\t%s", el); 379 } 380 } 381 /** 382 * {@inheritDoc} 383 * 384 * <p>The default implementation does nothing.</p> 385 */ 386 override public void enterDotted_name_part(RuleTranslatorParser.Dotted_name_partContext ctx) { 387 mixin(DebugEnter); 388 dottedName ~= "." ~ ctx.getText; 389 debug { 390 debugInfo.writefln("\tdottedName = %s", dottedName); 391 foreach (el; stack.opSlice) 392 debugInfo.writefln("\t%s", el); 393 } 394 } 395 396 /** 397 * {@inheritDoc} 398 * 399 * <p>The default implementation does nothing.</p> 400 */ 401 override public void enterIf_stmt(RuleTranslatorParser.If_stmtContext ctx) { 402 mixin(DebugEnter); 403 writer.put("if ("); 404 debug { 405 foreach (el; stack.opSlice) 406 debugInfo.writefln("\t%s", el); 407 } 408 } 409 /** 410 * {@inheritDoc} 411 * 412 * <p>The default implementation does nothing.</p> 413 */ 414 override public void exitIf_stmt(RuleTranslatorParser.If_stmtContext ctx) { 415 mixin(DebugExit); 416 writer.indentLevel = -- indentLevel; 417 writer.putnl("}"); 418 } 419 420 /** 421 * {@inheritDoc} 422 * 423 * <p>The default implementation does nothing.</p> 424 */ 425 override public void exitAtom_dotted_name(RuleTranslatorParser.Atom_dotted_nameContext ctx) { 426 mixin(DebugExit); 427 if (!stack.empty) { 428 stack.front ~= dottedName; 429 mixin(DebugStack); 430 } 431 } 432 433 /** 434 * {@inheritDoc} 435 * 436 * <p>The default implementation does nothing.</p> 437 */ 438 override public void enterFunct_name(RuleTranslatorParser.Funct_nameContext ctx) { 439 mixin(DebugEnter); 440 if (!stack.empty) { 441 stack.front ~= ctx.getText; 442 } 443 } 444 445 /** 446 */ 447 override public void enterCondition_only(RuleTranslatorParser.Condition_onlyContext ctx) { 448 mixin(DebugEnter); 449 string[] conditionBuf; 450 stack.insert(conditionBuf); 451 } 452 453 /** 454 */ 455 override public void exitCondition_only(RuleTranslatorParser.Condition_onlyContext ctx) { 456 mixin(DebugExit); 457 writer.put(stack.front.join); 458 writer.putnl(")"); 459 stack.removeFront; 460 writer.putnl("{"); 461 writer.indentLevel = ++ indentLevel; 462 mixin(DebugStack); 463 } 464 465 /** 466 */ 467 override public void enterCondition_with_value(RuleTranslatorParser.Condition_with_valueContext ctx) { 468 mixin(DebugEnter); 469 string[] conditionBuf; 470 stack.insert(conditionBuf); 471 mixin(DebugStack); 472 } 473 474 /** 475 */ 476 override public void exitCondition_with_value(RuleTranslatorParser.Condition_with_valueContext ctx) { 477 mixin(DebugEnter); 478 writer.put(stack.front.join); 479 writer.putnl(")"); 480 stack.removeFront; 481 writer.putnl("{"); 482 writer.indentLevel = ++ indentLevel; 483 mixin(DebugStack); 484 } 485 486 /** 487 */ 488 override public void enterCondition_without_value(RuleTranslatorParser.Condition_without_valueContext ctx) { 489 mixin(DebugEnter); 490 string[] conditionBuf; 491 stack.insert(conditionBuf); 492 mixin(DebugStack); 493 } 494 495 /** 496 */ 497 override public void exitCondition_without_value(RuleTranslatorParser.Condition_without_valueContext ctx) { 498 mixin(DebugExit); 499 writer.put(stack.front.join); 500 writer.putnl(")"); 501 stack.removeFront; 502 writer.putnl("{"); 503 writer.indentLevel = ++ indentLevel; 504 mixin(DebugStack); 505 } 506 507 /** 508 * {@inheritDoc} 509 * 510 * <p>The default implementation does nothing.</p> 511 */ 512 override public void enterNot(RuleTranslatorParser.NotContext ctx) { 513 mixin(DebugEnter); 514 stack.front ~= "!"; 515 mixin(DebugStack); 516 } 517 518 /** 519 * {@inheritDoc} 520 * 521 * <p>The default implementation does nothing.</p> 522 */ 523 override public void enterFunct_parameters(RuleTranslatorParser.Funct_parametersContext ctx) { 524 mixin(DebugEnter); 525 if (!stack.empty) { 526 string[] s; 527 stack.insert(s); 528 mixin(DebugStack); 529 } 530 } 531 /** 532 * {@inheritDoc} 533 * 534 * <p>The default implementation does nothing.</p> 535 */ 536 override public void exitFunct_parameters(RuleTranslatorParser.Funct_parametersContext ctx) { 537 mixin(DebugExit); 538 if (!stack.empty) { 539 auto x = stack.front.join(", "); 540 stack.removeFront; 541 stack.front ~= "(" ~ x ~ ")"; 542 mixin(DebugStack); 543 } 544 } 545 546 /** 547 * {@inheritDoc} 548 * 549 * <p>The default implementation does nothing.</p> 550 */ 551 override public void enterTfpdef_number(RuleTranslatorParser.Tfpdef_numberContext ctx) { 552 mixin(DebugEnter); 553 if (!stack.empty) { 554 stack.front ~= ctx.getText; 555 mixin(DebugStack); 556 } 557 } 558 559 /** 560 * {@inheritDoc} 561 * 562 * <p>The default implementation does nothing.</p> 563 */ 564 override public void exitTfpdef_name(RuleTranslatorParser.Tfpdef_nameContext ctx) { 565 mixin(DebugExit); 566 if (!stack.empty) { 567 stack.front ~= dottedName; 568 mixin(DebugStack); 569 } 570 } 571 572 /** 573 * {@inheritDoc} 574 * 575 * <p>The default implementation does nothing.</p> 576 */ 577 override public void enterTfpdef_string(RuleTranslatorParser.Tfpdef_stringContext ctx) { 578 mixin(DebugEnter); 579 if (!stack.empty) { 580 stack.front ~= ctx.getText; 581 mixin(DebugStack); 582 } 583 } 584 585 /** 586 * {@inheritDoc} 587 * 588 * <p>The default implementation does nothing.</p> 589 */ 590 override public void enterTfpdef_funct_stm(RuleTranslatorParser.Tfpdef_funct_stmContext ctx) { 591 mixin(DebugEnter); 592 if (!stack.empty) { 593 string[] s; 594 stack.insert(s); 595 mixin(DebugStack); 596 } 597 } 598 599 /** 600 * {@inheritDoc} 601 * 602 * <p>The default implementation does nothing.</p> 603 */ 604 override public void exitTfpdef_funct_stm(RuleTranslatorParser.Tfpdef_funct_stmContext ctx) { 605 mixin(DebugExit); 606 if (!stack.empty) { 607 auto x = stack.front.join; 608 stack.removeFront; 609 stack.front ~= x; 610 mixin(DebugStack); 611 } 612 } 613 614 /** 615 * {@inheritDoc} 616 * 617 * <p>The default implementation does nothing.</p> 618 */ 619 override public void enterElse_e(RuleTranslatorParser.Else_eContext ctx) { 620 mixin(DebugEnter); 621 writer.indentLevel = -- indentLevel; 622 writer.putnl("}"); 623 writer.putnl("else"); 624 writer.putnl("{"); 625 writer.indentLevel = ++ indentLevel; 626 mixin(DebugStack); 627 } 628 629 /** 630 * {@inheritDoc} 631 * 632 * <p>The default implementation does nothing.</p> 633 */ 634 override public void enterElif_e(RuleTranslatorParser.Elif_eContext ctx) { 635 mixin(DebugEnter); 636 writer.indentLevel = -- indentLevel; 637 writer.putnl("}"); 638 writer.put("else if ("); 639 mixin(DebugStack); 640 } 641 642 /** 643 * {@inheritDoc} 644 * 645 * <p>The default implementation does nothing.</p> 646 */ 647 override public void enterOr_e(RuleTranslatorParser.Or_eContext ctx) { 648 mixin(DebugEnter); 649 if (!stack.empty) { 650 stack.front ~= " || "; 651 } 652 } 653 654 /** 655 * {@inheritDoc} 656 * 657 * <p>The default implementation does nothing.</p> 658 */ 659 override public void enterAnd_e(RuleTranslatorParser.And_eContext ctx) { 660 mixin(DebugEnter); 661 if (!stack.empty) { 662 stack.front ~= " && "; 663 mixin(DebugStack); 664 } 665 } 666 667 /** 668 * {@inheritDoc} 669 * 670 * <p>The default implementation does nothing.</p> 671 */ 672 override public void enterLess_than(RuleTranslatorParser.Less_thanContext ctx) { 673 mixin(DebugEnter); 674 if (!stack.empty) { 675 stack.front ~= " < "; 676 mixin(DebugStack); 677 } 678 } 679 680 /** 681 * {@inheritDoc} 682 * 683 * <p>The default implementation does nothing.</p> 684 */ 685 override public void enterGreater_than(RuleTranslatorParser.Greater_thanContext ctx) { 686 mixin(DebugEnter); 687 if (!stack.empty) { 688 stack.front ~= " > "; 689 mixin(DebugStack); 690 } 691 } 692 693 /** 694 * {@inheritDoc} 695 * 696 * <p>The default implementation does nothing.</p> 697 */ 698 override public void enterGreater_equal(RuleTranslatorParser.Greater_equalContext ctx) { 699 mixin(DebugEnter); 700 if (!stack.empty) { 701 stack.front ~= " >= "; 702 mixin(DebugStack); 703 } 704 } 705 706 /** 707 * {@inheritDoc} 708 * 709 * <p>The default implementation does nothing.</p> 710 */ 711 override public void enterLess_equal(RuleTranslatorParser.Less_equalContext ctx) { 712 mixin(DebugEnter); 713 if (!stack.empty) { 714 stack.front ~= " <= "; 715 mixin(DebugStack); 716 } 717 } 718 719 /** 720 */ 721 override public void enterEquals(RuleTranslatorParser.EqualsContext ctx) { 722 mixin(DebugEnter); 723 if (!stack.empty) { 724 stack.front ~= " == "; 725 mixin(DebugStack); 726 } 727 } 728 729 /** 730 * {@inheritDoc} 731 * 732 * <p>The default implementation does nothing.</p> 733 */ 734 override public void enterR_equals(RuleTranslatorParser.R_equalsContext ctx) { 735 mixin(DebugEnter); 736 if (!stack.empty) { 737 stack.front ~= " == "; 738 mixin(DebugStack); 739 } 740 } 741 /** 742 * {@inheritDoc} 743 * 744 * <p>The default implementation does nothing.</p> 745 */ 746 override public void enterR_not_equal(RuleTranslatorParser.R_not_equalContext ctx) { 747 mixin(DebugEnter); 748 if (!stack.empty) { 749 stack.front ~= " != "; 750 mixin(DebugStack); 751 } 752 } 753 754 /** 755 * {@inheritDoc} 756 * 757 * <p>The default implementation does nothing.</p> 758 */ 759 override public void enterNot_equal(RuleTranslatorParser.Not_equalContext ctx) { 760 mixin(DebugEnter); 761 if (!stack.empty) { 762 stack.front ~= " != "; 763 mixin(DebugStack); 764 } 765 } 766 767 /** 768 * {@inheritDoc} 769 * 770 * <p>The default implementation does nothing.</p> 771 */ 772 override public void enterDot_e(RuleTranslatorParser.Dot_eContext ctx) { 773 mixin(DebugEnter); 774 if (!stack.empty) { 775 stack.front ~= "."; 776 mixin(DebugStack); 777 } 778 } 779 780 /** 781 * {@inheritDoc} 782 * 783 * <p>The default implementation does nothing.</p> 784 */ 785 override public void enterSmall_stmt(RuleTranslatorParser.Small_stmtContext ctx) { 786 mixin(DebugEnter); 787 string[] conditionBuf; 788 stack.insert(conditionBuf); 789 } 790 791 /** 792 * {@inheritDoc} 793 * 794 * <p>The default implementation does nothing.</p> 795 */ 796 override public void exitSmall_stmt(RuleTranslatorParser.Small_stmtContext ctx) { 797 mixin(DebugExit); 798 if (!stack.empty) { 799 writer.put(stack.front.join ~ ";\n"); 800 stack.removeFront; 801 mixin(DebugStack); 802 } 803 } 804 805 /** 806 * {@inheritDoc} 807 * 808 * <p>The default implementation does nothing.</p> 809 */ 810 override public void enterBlock_stmt(RuleTranslatorParser.Block_stmtContext ctx) { 811 mixin(DebugEnter); 812 string[] conditionBuf; 813 stack.insert(conditionBuf); 814 mixin(DebugStack); 815 } 816 /** 817 * {@inheritDoc} 818 * 819 * <p>The default implementation does nothing.</p> 820 */ 821 override public void exitBlock_stmt(RuleTranslatorParser.Block_stmtContext ctx) { 822 mixin(DebugExit); 823 if (!stack.empty) { 824 writer.putnl(stack.front.join); 825 stack.removeFront; 826 mixin(DebugStack); 827 } 828 } 829 /** 830 * {@inheritDoc} 831 * 832 * <p>The default implementation does nothing.</p> 833 */ 834 override public void enterNumber_e(RuleTranslatorParser.Number_eContext ctx) { 835 mixin(DebugEnter); 836 if (!stack.empty && !trailerMode) { 837 stack.front ~= ctx.getText; 838 mixin(DebugStack); 839 } 840 } 841 842 /** 843 * {@inheritDoc} 844 * 845 * <p>The default implementation does nothing.</p> 846 */ 847 override public void enterString_e(RuleTranslatorParser.String_eContext ctx) { 848 mixin(DebugEnter); 849 if (!stack.empty) { 850 stack.front ~= ctx.getText; 851 mixin(DebugStack); 852 } 853 } 854 855 /** 856 * {@inheritDoc} 857 * 858 * <p>The default implementation does nothing.</p> 859 */ 860 override public void enterAtom_funct_stmt(RuleTranslatorParser.Atom_funct_stmtContext ctx) { 861 mixin(DebugEnter); 862 if (!stack.empty) { 863 string[] s; 864 stack.insert(s); 865 mixin(DebugStack); 866 } 867 } 868 869 /** 870 * {@inheritDoc} 871 * 872 * <p>The default implementation does nothing.</p> 873 */ 874 override public void exitAtom_funct_stmt(RuleTranslatorParser.Atom_funct_stmtContext ctx) { 875 mixin(DebugExit); 876 if (!stack.empty) { 877 auto x = stack.front; 878 stack.removeFront; 879 stack.front ~= x; 880 mixin(DebugStack); 881 } 882 } 883 884 /** 885 * {@inheritDoc} 886 * 887 * <p>The default implementation does nothing.</p> 888 */ 889 override public void enterTrue_e(RuleTranslatorParser.True_eContext ctx) { 890 mixin(DebugEnter); 891 if (!stack.empty) { 892 stack.front ~= "true"; 893 mixin(DebugStack); 894 } 895 } 896 897 /** 898 * {@inheritDoc} 899 * 900 * <p>The default implementation does nothing.</p> 901 */ 902 override public void enterFalse_e(RuleTranslatorParser.False_eContext ctx) { 903 mixin(DebugEnter); 904 if (!stack.empty) { 905 stack.front ~= "false"; 906 mixin(DebugStack); 907 } 908 } 909 910 /** 911 * {@inheritDoc} 912 * 913 * <p>The default implementation does nothing.</p> 914 */ 915 override public void enterFor_stmt(RuleTranslatorParser.For_stmtContext ctx) { 916 mixin(DebugEnter); 917 LoopElement l; 918 loopStack.insert(l); 919 writer.put("foreach ("); 920 } 921 922 /** 923 * {@inheritDoc} 924 * 925 * <p>The default implementation does nothing.</p> 926 */ 927 override public void exitFor_stmt(RuleTranslatorParser.For_stmtContext ctx) { 928 mixin(DebugExit); 929 writer.indentLevel = -- indentLevel; 930 writer.putnl("}"); 931 mixin(DebugStack); 932 loopStack.removeFront; 933 } 934 935 /** 936 * {@inheritDoc} 937 * 938 * <p>The default implementation does nothing.</p> 939 */ 940 override public void enterFor_exprlist(RuleTranslatorParser.For_exprlistContext ctx) { 941 mixin(DebugEnter); 942 foreachElementName = ctx.getText; 943 } 944 945 /** 946 * {@inheritDoc} 947 * 948 * <p>The default implementation does nothing.</p> 949 */ 950 override public void enterFor_testlist(RuleTranslatorParser.For_testlistContext ctx) { 951 mixin(DebugEnter); 952 LoopElement l; 953 l.foreachElementType = foreachElementName; 954 l.foreachType = ctx.getText; 955 l.foreachIndex = 0; 956 loopStack.front = l; 957 mixin(DebugStack); 958 } 959 960 /** 961 * {@inheritDoc} 962 * 963 * <p>The default implementation does nothing.</p> 964 */ 965 override public void exitFor_testlist(RuleTranslatorParser.For_testlistContext ctx) 966 { 967 mixin(DebugExit); 968 writer.putnl(format("%s; %s.iterate)", 969 loopStack.front.foreachElementType, 970 loopStack.front.foreachType, 971 ) 972 ); 973 writer.putnl("{"); 974 writer.indentLevel = ++ indentLevel; 975 mixin(DebugStack); 976 } 977 978 /** 979 * {@inheritDoc} 980 * 981 * <p>The default implementation does nothing.</p> 982 */ 983 override public void enterFirst_e(RuleTranslatorParser.First_eContext ctx) { 984 mixin(DebugEnter); 985 if (!stack.empty) 986 stack.front ~= format("%s.first", 987 loopStack.front.foreachElementType, 988 ); 989 } 990 991 /** 992 * {@inheritDoc} 993 * 994 * <p>The default implementation does nothing.</p> 995 */ 996 override public void enterLast_e(RuleTranslatorParser.Last_eContext ctx) { 997 mixin(DebugEnter); 998 if (!stack.empty) 999 stack.front ~= format("%s.last", 1000 loopStack.front.foreachElementType); 1001 } 1002 1003 /** 1004 * {@inheritDoc} 1005 * 1006 * <p>The default implementation does nothing.</p> 1007 */ 1008 override public void enterTrailer(RuleTranslatorParser.TrailerContext ctx) { 1009 mixin(DebugEnter); 1010 trailerMode = true; 1011 } 1012 /** 1013 * {@inheritDoc} 1014 * 1015 * <p>The default implementation does nothing.</p> 1016 */ 1017 override public void exitTrailer(RuleTranslatorParser.TrailerContext ctx) { 1018 mixin(DebugExit); 1019 trailerMode = false; 1020 } 1021 1022 /** 1023 * {@inheritDoc} 1024 * 1025 * <p>The default implementation does nothing.</p> 1026 */ 1027 override public void enterFunct_stmt(RuleTranslatorParser.Funct_stmtContext ctx) { 1028 mixin(DebugEnter); 1029 debug { 1030 debugInfo.writefln("\tenterFunct_stmt funcdefFlag = %s", funcdefFlag); 1031 debugInfo.writefln("\tenterFunct_stmt ruleExists = %s", ruleExists); 1032 } 1033 } 1034 /** 1035 * {@inheritDoc} 1036 * 1037 * <p>The default implementation does nothing.</p> 1038 */ 1039 override public void exitFunct_stmt(RuleTranslatorParser.Funct_stmtContext ctx) { 1040 mixin(DebugExit); 1041 // if (! ruleExists) { 1042 // stack.front ~= ")"; 1043 // stack.front = "append(" ~ stack.front; 1044 // } 1045 debug { 1046 mixin(DebugStack); 1047 debugInfo.writefln("\texitFunct_stmt funcdefFlag = %s", funcdefFlag); 1048 debugInfo.writefln("\tenterFunct_stmt ruleExists = %s", ruleExists); 1049 } 1050 } 1051 }