// File: mikeakohn[P]drumsplusplus/build/../src/Song.cxx
// Function: Song::parse_song(Tokens*)
int Song::parse_song(Tokens *tokens)
{
  int token_type;
  char token[1024];
  int repeat;
  int x;

  token_type = tokens->get(token);

  if (strcmp(token, "{") != 0)
  {
    if (token_type == TOKEN_ALPHA)
    {
      song_info.set_song_name(token);

      token_type = tokens->get(token);

      if (strcmp(token, "{") != 0)
      {
        print_error(tokens, "{", token);
        return -1;
      }
    }
      else
    {
      printf("Error: Expecting song name or '{' but got '%s' at %s:%d.\n",
        token, tokens->get_filename(), tokens->get_line());
      return -1;
    }
  }

  midi_file->write_header(&song_info);
  midi_file->write_bpm(&song_info);

  while(1)
  {
    token_type = tokens->get(token);

    if (strcmp(token, "}") == 0)
    {
      break;
    }

    if (strcmp(token, "play") == 0)
    {
      token_type = tokens->get(token);

      if (strcmp(token, ":") != 0)
      {
        print_error(tokens, ":", token);
        return -1;
      }

      while(1)
      {
        repeat = 1;

        token_type = tokens->get(token);

        if (token_type == TOKEN_NUMBER)
        {
          repeat = atoi(token);
          token_type = tokens->get(token);
        }

        std::string section_name = token;

        if (sections.find(section_name) != sections.end())
        {
          for (x = 0; x < repeat; x++)
          {
            play_section(section_name);
          }
        }
          else
        {
          if (patterns.find(token) == patterns.end())
          {
            printf("Error:  Undefined pattern '%s' at %s:%d.\n",
              token, tokens->get_filename(), tokens->get_line());
            return -1;
          }

          std::string pattern_name = token;

          for (x = 0; x < repeat; x++)
          {
            play_pattern(pattern_name);
          }
        }

        token_type = tokens->get(token);

        if (strcmp(token, ";") == 0)
        {
          break;
        }
          else
        if (strcmp(token, ",") != 0)
        {
          print_error(tokens, ",", token);
          return -1;
        }
      }
    }
  }

  midi_file->write_footer();

  return 0;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x550, %rsp            # imm = 0x550
movq %rdi, -0x10(%rbp)
movq %rsi, -0x18(%rbp)
movq -0x10(%rbp), %rax
movq %rax, -0x4e0(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x9230(%rip), %rsi      # 0x1079f
callq 0x2320
cmpl $0x0, %eax
je 0x7640
cmpl $0x1, -0x1c(%rbp)
jne 0x75ed
movq -0x4e0(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x9410
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x91e8(%rip), %rsi      # 0x1079f
callq 0x2320
cmpl $0x0, %eax
je 0x75eb
movq -0x4e0(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x420(%rbp), %rcx
leaq 0x91c5(%rip), %rdx      # 0x1079f
callq 0x7e10
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7b9a
jmp 0x763e
leaq -0x420(%rbp), %rax
movq %rax, -0x4f0(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2f40
movq %rax, -0x4e8(%rbp)
movq -0x18(%rbp), %rdi
callq 0x89f0
movq -0x4f0(%rbp), %rsi
movq -0x4e8(%rbp), %rdx
movl %eax, %ecx
leaq 0x92aa(%rip), %rdi      # 0x108d5
movb $0x0, %al
callq 0x2060
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7b9a
jmp 0x7640
movq -0x4e0(%rbp), %rsi
movq 0x38(%rsi), %rdi
callq 0x3030
movq -0x4e0(%rbp), %rsi
movq 0x38(%rsi), %rdi
callq 0x34e0
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x9120(%rip), %rsi      # 0x107a1
callq 0x2320
cmpl $0x0, %eax
jne 0x7690
jmp 0x7b83
leaq -0x420(%rbp), %rdi
leaq 0x9207(%rip), %rsi      # 0x108a5
callq 0x2320
cmpl $0x0, %eax
jne 0x7b7e
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x8f90(%rip), %rsi      # 0x1065d
callq 0x2320
cmpl $0x0, %eax
je 0x7701
movq -0x4e0(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq -0x420(%rbp), %rcx
leaq 0x8f6d(%rip), %rdx      # 0x1065d
callq 0x7e10
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
jmp 0x7b9a
jmp 0x7703
movl $0x1, -0x424(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
cmpl $0x2, -0x1c(%rbp)
jne 0x774b
leaq -0x420(%rbp), %rdi
callq 0x2380
movl %eax, -0x424(%rbp)
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x1c(%rbp)
leaq -0x449(%rbp), %rdi
movq %rdi, -0x4f8(%rbp)
callq 0x23d0
movq -0x4f8(%rbp), %rdx
leaq -0x448(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x8f10
jmp 0x777a
leaq -0x449(%rbp), %rdi
callq 0x2260
movq -0x4e0(%rbp), %rdi
addq $0x48, %rdi
leaq -0x448(%rbp), %rsi
callq 0x9440
movq %rax, -0x500(%rbp)
jmp 0x77a6
movq -0x4e0(%rbp), %rdi
movq -0x500(%rbp), %rax
movq %rax, -0x468(%rbp)
addq $0x48, %rdi
callq 0x8e30
movq %rax, -0x470(%rbp)
leaq -0x468(%rbp), %rdi
leaq -0x470(%rbp), %rsi
callq 0x8e00
testb $0x1, %al
jne 0x77e4
jmp 0x7863
movl $0x0, -0x428(%rbp)
movl -0x428(%rbp), %eax
cmpl -0x424(%rbp), %eax
jge 0x785e
movq -0x4e0(%rbp), %rdi
leaq -0x448(%rbp), %rsi
callq 0x8400
jmp 0x7811
jmp 0x7813
movl -0x428(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x428(%rbp)
jmp 0x77ee
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
leaq -0x449(%rbp), %rdi
callq 0x2260
jmp 0x7ba6
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
jmp 0x7b6e
jmp 0x7aa0
movq -0x4e0(%rbp), %rax
addq $0x78, %rax
movq %rax, -0x510(%rbp)
leaq -0x499(%rbp), %rdi
movq %rdi, -0x508(%rbp)
callq 0x23d0
movq -0x508(%rbp), %rdx
leaq -0x498(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x8f10
jmp 0x78a4
movq -0x510(%rbp), %rdi
leaq -0x498(%rbp), %rsi
callq 0x90d0
movq %rax, -0x518(%rbp)
jmp 0x78c0
movq -0x4e0(%rbp), %rdi
movq -0x518(%rbp), %rax
movq %rax, -0x478(%rbp)
addq $0x78, %rdi
callq 0x9100
movq %rax, -0x4a8(%rbp)
leaq -0x478(%rbp), %rdi
leaq -0x4a8(%rbp), %rsi
callq 0x91d0
movb %al, -0x519(%rbp)
leaq -0x498(%rbp), %rdi
callq 0x2150
leaq -0x499(%rbp), %rdi
callq 0x2260
movb -0x519(%rbp), %al
testb $0x1, %al
jne 0x7925
jmp 0x79d3
leaq -0x420(%rbp), %rax
movq %rax, -0x530(%rbp)
movq -0x18(%rbp), %rdi
callq 0x2f40
movq %rax, -0x528(%rbp)
jmp 0x7945
movq -0x18(%rbp), %rdi
callq 0x89f0
movl %eax, -0x534(%rbp)
jmp 0x7956
movl -0x534(%rbp), %ecx
movq -0x528(%rbp), %rdx
movq -0x530(%rbp), %rsi
leaq 0x8f9e(%rip), %rdi      # 0x1090f
xorl %eax, %eax
callq 0x2060
jmp 0x797a
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x4ac(%rbp)
jmp 0x7b3c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
jmp 0x79c2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
leaq -0x498(%rbp), %rdi
callq 0x2150
leaq -0x499(%rbp), %rdi
callq 0x2260
jmp 0x7b6e
leaq -0x4d1(%rbp), %rdi
movq %rdi, -0x540(%rbp)
callq 0x23d0
movq -0x540(%rbp), %rdx
leaq -0x4d0(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x8f10
jmp 0x7a02
leaq -0x4d1(%rbp), %rdi
callq 0x2260
movl $0x0, -0x428(%rbp)
movl -0x428(%rbp), %eax
cmpl -0x424(%rbp), %eax
jge 0x7a94
movq -0x4e0(%rbp), %rdi
leaq -0x4d0(%rbp), %rsi
callq 0x85c0
jmp 0x7a3b
jmp 0x7a3d
movl -0x428(%rbp), %eax
addl $0x1, %eax
movl %eax, -0x428(%rbp)
jmp 0x7a18
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
leaq -0x4d1(%rbp), %rdi
callq 0x2260
jmp 0x7b6e
movq %rax, %rcx
movl %edx, %eax
movq %rcx, -0x458(%rbp)
movl %eax, -0x45c(%rbp)
leaq -0x4d0(%rbp), %rdi
callq 0x2150
jmp 0x7b6e
leaq -0x4d0(%rbp), %rdi
callq 0x2150
movq -0x18(%rbp), %rdi
leaq -0x420(%rbp), %rsi
callq 0x2b10
movl %eax, -0x544(%rbp)
jmp 0x7ab8
movl -0x544(%rbp), %eax
movl %eax, -0x1c(%rbp)
leaq -0x420(%rbp), %rdi
leaq 0x8af9(%rip), %rsi      # 0x105c8
callq 0x2320
cmpl $0x0, %eax
jne 0x7ae5
movl $0x5, -0x4ac(%rbp)
jmp 0x7b3c
leaq -0x420(%rbp), %rdi
leaq 0x8de0(%rip), %rsi      # 0x108d3
callq 0x2320
cmpl $0x0, %eax
je 0x7b30
movq -0x4e0(%rbp), %rdi
movq -0x18(%rbp), %rsi
leaq 0x8dc4(%rip), %rdx      # 0x108d3
leaq -0x420(%rbp), %rcx
callq 0x7e10
jmp 0x7b1d
movl $0xffffffff, -0x4(%rbp) # imm = 0xFFFFFFFF
movl $0x1, -0x4ac(%rbp)
jmp 0x7b3c
jmp 0x7b32
movl $0x0, -0x4ac(%rbp)
leaq -0x448(%rbp), %rdi
callq 0x2150
movl -0x4ac(%rbp), %eax
movl %eax, -0x548(%rbp)
testl %eax, %eax
je 0x7b69
jmp 0x7b5a
movl -0x548(%rbp), %eax
subl $0x1, %eax
je 0x7b9a
jmp 0x7b67
jmp 0x7b7c
jmp 0x7703
leaq -0x448(%rbp), %rdi
callq 0x2150
jmp 0x7ba6
jmp 0x7b7e
jmp 0x7660
movq -0x4e0(%rbp), %rax
movq 0x38(%rax), %rdi
callq 0x3430
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x550, %rsp            # imm = 0x550
popq %rbp
retq
movq -0x458(%rbp), %rdi
callq 0x23c0
nopw %cs:(%rax,%rax)