import org.objectweb.asm.ClassWriter;
import org.objectweb.asm.Label;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import java.io.*;

class GenCode implements Visitor<Void>{
  Writer out;
  @Override public Void visit(Tree.Prog prog){
    try{
      out = new FileWriter("Module.s");
      out.write(".globl  f\n");
      out.write(".type   f, @function\n");
      out.write("f:\n");
      out.write("        pushq   %rbp\n");
      out.write("        movq    %rsp, %rbp\n");
      prog.expr.welcome(this);      
      out.write("        popq    %rax\n");
      out.write("        popq    %rbp\n");
      out.write("        ret\n");
      out.close();
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;
  }
  @Override public Void visit(Tree.MultExpr e){
    try{
    e.op1.welcome(this);
    e.op2.welcome(this);
    out.write("        popq    %rax\n");
    out.write("        popq    %rdx\n");
    out.write("        imull   %rdx, %rax\n");
    out.write("        pushq   %rax\n");
    }catch(Exception ex){
    }

    return null;
  }
  @Override public Void visit(Tree.AddExpr e){
    try{

    e.op1.welcome(this);
    e.op2.welcome(this);
    out.write("        popq    %rax\n");
    out.write("        popq    %rdx\n");
    out.write("        addl   %rdx, %rax\n");
    out.write("        pushq   %rax\n");
    }catch(Exception ex){
    }

    return null;
  }

  @Override public Void visit(Tree.IntLit e){
    try{
      out.write("	 pushq    $"+e.n+"\n");
    }catch(Exception ex){
    }
    return null;
  }

  public static void main(String[] args) throws Exception{
    LParser parser = new LParser(System.in);
    var gj = new GenCode();
    System.out.println(parser.expression().welcome(gj));

  }
}
