Advertisement
Guest User

Untitled

a guest
Apr 4th, 2020
177
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 12.59 KB | None | 0 0
  1. package nl.saxion.cos;
  2.  
  3. import org.antlr.v4.runtime.tree.ParseTreeProperty;
  4.  
  5. public class CodeGenerator extends MusicLangBaseVisitor<Void> {
  6.     private JasminBytecode jasminCode;
  7.  
  8.     public JasminBytecode getJasminCode() {
  9.         return jasminCode;
  10.     }
  11.  
  12.     private ParseTreeProperty<DataType> types;
  13.     private ParseTreeProperty<Symbol> symbols;
  14.  
  15.     private int unique = 0;
  16.  
  17.     private String nextLabel() {
  18.         return "L" + ++unique;
  19.     }
  20.  
  21.     private String ifLabel = "";
  22.     private String doneLabel = "";
  23.     private boolean isLast = false;
  24.  
  25.  
  26.     public CodeGenerator(JasminBytecode jasminCode, ParseTreeProperty<DataType> types,
  27.                          ParseTreeProperty<Symbol> symbols) {
  28.         this.jasminCode = jasminCode;
  29.         this.types = types;
  30.         this.symbols = symbols;
  31.     }
  32.  
  33.     private int localStorageCounter = 0;
  34.  
  35.     private int getNextIndex() {
  36.         return ++localStorageCounter;
  37.     }
  38.  
  39.     @Override
  40.     public Void visitProgram(MusicLangParser.ProgramContext ctx) {
  41.  
  42.         for (MusicLangParser.FunctionContext f : ctx.function()) {
  43.             visit(f);
  44.         }
  45.         jasminCode.add(".method public static main([Ljava/lang/String;)V");
  46.         jasminCode.add(".limit stack 99");
  47.         jasminCode.add(".limit locals 99");
  48.         jasminCode.add("");
  49.  
  50.         visit(ctx.main_method);
  51.  
  52.         jasminCode.add("return");
  53.         jasminCode.add(".end method");
  54.         return null;
  55.     }
  56.  
  57.     @Override
  58.     public Void visitFunction(MusicLangParser.FunctionContext ctx) {
  59.         String returnType = ";";
  60.         if (ctx.type() != null) {
  61.             returnType = "I";
  62.         } else {
  63.             returnType = "V";
  64.         }
  65.         String paramTypes = "";
  66. //        for (MusicLangParser.ParametersContext param : ctx.parameters()) {
  67. //            if (param.type().getText().equals("number")) {
  68. //                paramTypes += "I";
  69. //            }
  70. //        }
  71.  
  72.         if (ctx.parameters() != null) {
  73.             for (MusicLangParser.TypeContext t : ctx.parameters().type()) {
  74.                 if (t.getText().equals("number")) {
  75.                     paramTypes += "I";
  76.                 }
  77.             }
  78.         }
  79.  
  80.  
  81.         jasminCode.add(".method public static " + ctx.IDENTIFIER() + "(" + paramTypes + ")" + returnType);
  82.         jasminCode.add(".limit stack 99");
  83.         jasminCode.add(".limit locals 99");
  84.         jasminCode.add("");
  85.  
  86.  
  87.         if (!ctx.statement().isEmpty()) {
  88.             for (MusicLangParser.StatementContext stat : ctx.statement()) {
  89.                 visit(stat);
  90.             }
  91.         }
  92.  
  93.         if (returnType.equals("I")) {
  94.             returnType = "i";
  95.         } else {
  96.             returnType = "";
  97.         }
  98.  
  99.         if (ctx.expression() != null) {
  100.             visit(ctx.expression());
  101.         }
  102.  
  103.         jasminCode.add(returnType + "return");
  104.         jasminCode.add(".end method");
  105.  
  106.         return null;
  107.     }
  108.  
  109.  
  110.     @Override
  111.     public Void visitDclNum(MusicLangParser.DclNumContext ctx) {
  112.  
  113.         visit(ctx.num_decl());
  114.  
  115.         return null;
  116.     }
  117.  
  118.     @Override
  119.     public Void visitDclSound(MusicLangParser.DclSoundContext ctx) {
  120.  
  121.         visit(ctx.sound_decl());
  122.  
  123.         return null;
  124.     }
  125.  
  126.     @Override
  127.     public Void visitSound_decl(MusicLangParser.Sound_declContext ctx) {
  128.  
  129.  
  130. //        jasminCode.add("    ldc  \"" + ctx.SOUND_VALUE().getText() + "\"");
  131. //        jasminCode.add("    astore " + getNextIndex());
  132.         String soundAsString = ctx.SOUND_VALUE().getText();
  133.         int soundAsNum = soundToNumber(soundAsString);
  134.         jasminCode.add("    ldc  " + soundAsNum);
  135.         jasminCode.add("    istore " + getNextIndex());
  136.         return null;
  137.     }
  138.  
  139.     @Override
  140.     public Void visitNum_decl(MusicLangParser.Num_declContext ctx) {
  141.  
  142.         if (ctx.INT_VALUE() != null) {
  143.             jasminCode.add("    ldc " + ctx.INT_VALUE().getText());
  144.         } else if (ctx.scan_num() != null) {
  145.             visit(ctx.scan_num());
  146.         }
  147.  
  148.         jasminCode.add("    istore " + getNextIndex());
  149.         return null;
  150.     }
  151.  
  152.     @Override
  153.     public Void visitDclNote(MusicLangParser.DclNoteContext ctx) {
  154.         visit(ctx.note_decl());
  155.         return null;
  156.     }
  157.  
  158.     @Override
  159.     public Void visitNote_decl(MusicLangParser.Note_declContext ctx) {
  160.         jasminCode.add("    new nl/saxion/cos/Note");
  161.         jasminCode.add("    dup");
  162.  
  163.  
  164.         jasminCode.add("    ldc  \"" + ctx.SOUND_VALUE().getText() + "\"");
  165.  
  166.         jasminCode.add("    ldc " + ctx.INT_VALUE().getText());
  167.  
  168.  
  169.         jasminCode.add("   invokenonvirtual nl/saxion/cos/Note/<init>(Ljava/lang/String;I)V");
  170.  
  171.         jasminCode.add("    astore " + getNextIndex());
  172.  
  173.         return null;
  174.     }
  175.  
  176.     @Override
  177.     public Void visitPlay(MusicLangParser.PlayContext ctx) {
  178.         jasminCode.add("getstatic java/lang/System/out Ljava/io/PrintStream;");
  179.         MusicLangParser.ExpressionContext expression = ctx.expression();
  180.         visit(expression);
  181.         System.out.println("type of expresiion " + types.get(expression));
  182.  
  183.         if (types.get(expression) == DataType.NUM) {
  184.             jasminCode.add("invokevirtual java/io/PrintStream/println(I)V");
  185.         } else if (types.get(expression) == DataType.SOUND) {
  186.             jasminCode.add("invokevirtual java/io/PrintStream/println(Ljava/lang/String;)V");
  187.         }
  188.  
  189.         return null;
  190.     }
  191.  
  192.     @Override
  193.     public Void visitScan_num(MusicLangParser.Scan_numContext ctx) {
  194.  
  195.         jasminCode.add("    new java/util/Scanner");
  196.         jasminCode.add("    dup");
  197.         jasminCode.add("    getstatic java/lang/System/in Ljava/io/InputStream;");
  198.         jasminCode.add("    invokenonvirtual  java/util/Scanner/<init>(Ljava/io/InputStream;)V");
  199.         int index = getNextIndex();
  200.         jasminCode.add("    astore " + index);
  201.         jasminCode.add("    aload " + index);
  202.         jasminCode.add("    invokevirtual java/util/Scanner/nextInt()I");
  203.  
  204.         return null;
  205.     }
  206.  
  207.     @Override
  208.     public Void visitRepeat(MusicLangParser.RepeatContext ctx) {
  209.         if (ctx.INT_VALUE() != null) {
  210.             jasminCode.add("    ldc 0");
  211.             int index = getNextIndex();
  212.             jasminCode.add("    istore " + index);
  213.             jasminCode.add("    iload " + index);
  214.             jasminCode.add("    ldc " + ctx.INT_VALUE().getText());
  215.             String loopLabel = nextLabel();
  216.             jasminCode.add(loopLabel + ":");
  217.             String outLabel = nextLabel();
  218.             jasminCode.add("    if_icmpge " + outLabel);
  219.             visit(ctx.repeat_body);
  220.             jasminCode.add("    iinc " + index + " " + 1);
  221.             jasminCode.add("    goto " + loopLabel);
  222.             jasminCode.add(outLabel + ":");
  223.         }
  224.  
  225.         return null;
  226.     }
  227.  
  228.     @Override
  229.     public Void visitExNegate(MusicLangParser.ExNegateContext ctx) {
  230.         visit(ctx.expression());
  231.         jasminCode.add("ineg");
  232.         return null;
  233.     }
  234.  
  235.     @Override
  236.     public Void visitExIdentifier(MusicLangParser.ExIdentifierContext ctx) {
  237.         Symbol symbol = symbols.get(ctx);
  238. //        String instruction = symbol.getType() != DataType.NUM ? "iload" : "aload";
  239.         String instruction = "  iload";
  240.         jasminCode.add(instruction + " " + symbol.getLocalSlot());
  241.         return null;
  242.     }
  243.  
  244.  
  245.     @Override
  246.     public Void visitExMulOp(MusicLangParser.ExMulOpContext ctx) {
  247.         visit(ctx.left);
  248.         visit(ctx.right);
  249.         jasminCode.add("    imul");
  250.         return null;
  251.     }
  252.  
  253.     @Override
  254.     public Void visitExSoundLiteral(MusicLangParser.ExSoundLiteralContext ctx) {
  255.  
  256.         //jasminCode.add("    ldc  \"" + ctx.SOUND_VALUE().getText() + "\"");
  257.         String soundAsString = ctx.SOUND_VALUE().getText();
  258.         int soundAsNum = soundToNumber(soundAsString);
  259.         jasminCode.add("    ldc  " + soundAsNum);
  260.         return null;
  261.     }
  262.  
  263.     @Override
  264.     public Void visitExAddOp(MusicLangParser.ExAddOpContext ctx) {
  265.         visit(ctx.left);
  266.         visit(ctx.right);
  267.         if (ctx.op.getText().equals(ctx.PLUS_SIGN().getText())) {
  268.             jasminCode.add("    iadd");
  269.         } else {
  270.             jasminCode.add("    isub");
  271.         }
  272.         return null;
  273.     }
  274.  
  275.     @Override
  276.     public Void visitExIntLiteral(MusicLangParser.ExIntLiteralContext ctx) {
  277.         jasminCode.add("    ldc  " + ctx.INT_VALUE().getText());
  278.         return null;
  279.     }
  280.  
  281.     @Override
  282.     public Void visitExParentheses(MusicLangParser.ExParenthesesContext ctx) {
  283.         visit(ctx.expression());
  284.         return null;
  285.     }
  286.  
  287.  
  288.     @Override
  289.     public Void visitIf_statement(MusicLangParser.If_statementContext ctx) {
  290.         System.out.println("par - " + ctx.parent.getText());
  291.  
  292.         if (ctx.else_statement() != null) {
  293.             isLast = false;
  294.             visit(ctx.if_else_body());
  295.             if (doneLabel.equals("")) {
  296.                 doneLabel = nextLabel();
  297.             }
  298.             jasminCode.add("    goto " + doneLabel);
  299.             jasminCode.add("    " + ifLabel + ":");
  300.             System.out.println("done1 - " + doneLabel);
  301.  
  302.  
  303.             if (ctx.else_statement().if_statement() == null) {
  304.                 System.out.println("this is else statement");
  305.  
  306.                 visit(ctx.else_statement());
  307.                 jasminCode.add("    " + doneLabel + ":");
  308.                 System.out.println("done2 - " + doneLabel);
  309.                 ifLabel = "";
  310.                 doneLabel = "";
  311.  
  312.             } else {
  313.                 System.out.println("this is else if statement");
  314.  
  315.                 visit(ctx.else_statement());
  316.  
  317.  
  318.             }
  319.         } else {
  320.             isLast = true;
  321.             if (doneLabel.equals("")) {
  322.                 doneLabel = nextLabel();
  323.             }
  324.             visit(ctx.if_else_body());
  325.             System.out.println(ctx.parent);
  326.             System.out.println(ctx.children);
  327.             if (!jasminCode.getLines().contains(doneLabel)) {
  328.                 jasminCode.add("    " + doneLabel + ":");
  329.  
  330.                 System.out.println("done3 - " + doneLabel);
  331.  
  332.                 ifLabel = "";
  333.                 doneLabel = "";
  334.             }
  335.  
  336.         }
  337.  
  338.  
  339.         return null;
  340.     }
  341.  
  342.     @Override
  343.     public Void visitIf_else_body(MusicLangParser.If_else_bodyContext ctx) {
  344.         visit(ctx.my_boolean());
  345.         for (MusicLangParser.StatementContext s : ctx.statement()) {
  346.             visit(s);
  347.         }
  348.  
  349.         return null;
  350.     }
  351.  
  352.     @Override
  353.     public Void visitElse_statement(MusicLangParser.Else_statementContext ctx) {
  354.         return super.visitElse_statement(ctx);
  355.     }
  356.  
  357.     @Override
  358.     public Void visitMy_boolean(MusicLangParser.My_booleanContext ctx) {
  359.         MusicLangParser.ExpressionContext left = ctx.left;
  360.         MusicLangParser.ExpressionContext right = ctx.right;
  361.         visit(left);
  362.         visit(right);
  363.         String operator = reverseComparison(ctx.BOOLEAN_OPERATOR().getText());
  364.  
  365.         if (isLast) {
  366.             jasminCode.add("    if_icmp" + operator + " " + doneLabel);
  367.  
  368.         } else {
  369.             System.out.println(ctx.left.getText());
  370.  
  371.             ifLabel = nextLabel();
  372.             jasminCode.add("    if_icmp" + operator + " " + ifLabel);
  373.         }
  374.  
  375.         return null;
  376.     }
  377.  
  378.     private String reverseComparison(String text) {
  379.         switch (text) {
  380.             case "<":
  381.                 return "ge";
  382.             case "<=":
  383.                 return "gt";
  384.             case ">":
  385.                 return "le";
  386.             case ">=":
  387.                 return "lt";
  388.             case "==":
  389.                 return "ne";
  390.             case "!=":
  391.                 return "eq";
  392.             default:
  393.                 return null;
  394.         }
  395.     }
  396.  
  397.     private int soundToNumber(String sound) {
  398.         switch (sound) {
  399.             case "C":
  400.             case "B#":
  401.                 return 0;
  402.             case "C#":
  403.             case "Db":
  404.                 return 1;
  405.             case "Cb":
  406.             case "B":
  407.                 return 11;
  408.             case "D":
  409.                 return 2;
  410.             case "D#":
  411.             case "Eb":
  412.                 return 3;
  413.             case "E":
  414.             case "Fb":
  415.                 return 4;
  416.             case "E#":
  417.             case "F":
  418.                 return 5;
  419.             case "F#":
  420.             case "Gb":
  421.                 return 6;
  422.             case "G":
  423.                 return 7;
  424.             case "G#":
  425.             case "Ab":
  426.                 return 8;
  427.             case "A":
  428.                 return 9;
  429.             case "A#":
  430.             case "Bb":
  431.                 return 10;
  432.  
  433.             default:
  434.                 return -1;
  435.         }
  436.     }
  437. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement