// File: /workspace/github_c_makefile_star2_O0/ohkimur[P]the-c-programming-language-2nd-edition-solutions/chapter_5/exercise_5_10/expr.c
// Function: main
int main(int argc, char *argv[])
{
  char Error = 0;

  for (size_t i = 1; i < argc; ++i)
  {
    float number = atof(argv[i]);

    if (number || strcmp(argv[i], "0") == 0)
    {
      push(number);
    }
    else if (strlen(argv[i]) == 1)
    {
      if (stack_pointer >= 2 && stack_pointer < STACK_SIZE)
      {
        float number2 = pop();
        float number1 = pop();

        char op = *argv[i];
        switch (op)
        {
        case '+':
          push(number1 + number2);
          break;

        case '-':
          push(number1 - number2);
          break;

        case '*': // This char might require to be escaped when passed as an argument.
          push(number1 * number2);
          break;

        case '/':
          if (number2 == 0)
          {
            Error = 4;
          }
          else
          {
            push(number1 / number2);
          }
          break;

        default:
          Error = 3;
          break;
        }
      }
      else
      {
        Error = 2;
      }
    }
    else
    {
      Error = 1;
    }
  }

  if (Error)
  {
    switch (Error)
    {
    case 1:
      printf("Error: arguments should be numbers or one of the following mathematical operations: '+', '-', '*', '/'.\n");
      break;

    case 2:
      printf("Error: too many or too few arguments.\n");
      break;

    case 3:
      printf("Error: invalid operation. use one of the following mathematical operations: '+', '-', '*', '/'.\n");
      break;

    case 4:
      printf("Error: division by zero (NaN).\n");
      break;

    default:
      break;
    }

    return EXIT_FAILURE;
  }

  printf("result: %.3f", pop());

  return EXIT_SUCCESS;
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x40, %rsp
movl $0x0, -0x4(%rbp)
movl %edi, -0x8(%rbp)
movq %rsi, -0x10(%rbp)
movb $0x0, -0x11(%rbp)
movq $0x1, -0x20(%rbp)
movq -0x20(%rbp), %rax
movslq -0x8(%rbp), %rcx
cmpq %rcx, %rax
jae 0x12fc
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x1030
cvtsd2ss %xmm0, %xmm0
movss %xmm0, -0x24(%rbp)
movss -0x24(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x11e9
jp 0x11e9
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
leaq 0xe4d(%rip), %rsi       # 0x202c
callq 0x1060
cmpl $0x0, %eax
jne 0x11f8
movss -0x24(%rbp), %xmm0
callq 0x13a0
jmp 0x12e9
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rdi
callq 0x1040
cmpq $0x1, %rax
jne 0x12e3
movzbl 0x2e46(%rip), %eax      # 0x4060
cmpl $0x2, %eax
jl 0x12dd
movzbl 0x2e36(%rip), %eax      # 0x4060
cmpl $0xf, %eax
jge 0x12dd
callq 0x1400
movss %xmm0, -0x28(%rbp)
callq 0x1400
movss %xmm0, -0x2c(%rbp)
movq -0x10(%rbp), %rax
movq -0x20(%rbp), %rcx
movq (%rax,%rcx,8), %rax
movb (%rax), %al
movb %al, -0x2d(%rbp)
movsbl -0x2d(%rbp), %eax
addl $-0x2a, %eax
movl %eax, %ecx
movq %rcx, -0x38(%rbp)
subl $0x5, %eax
ja 0x12d7
movq -0x38(%rbp), %rax
leaq 0xd9f(%rip), %rcx       # 0x2014
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movss -0x2c(%rbp), %xmm0
addss -0x28(%rbp), %xmm0
callq 0x13a0
jmp 0x12db
movss -0x2c(%rbp), %xmm0
subss -0x28(%rbp), %xmm0
callq 0x13a0
jmp 0x12db
movss -0x2c(%rbp), %xmm0
mulss -0x28(%rbp), %xmm0
callq 0x13a0
jmp 0x12db
movss -0x28(%rbp), %xmm0
xorps %xmm1, %xmm1
ucomiss %xmm1, %xmm0
jne 0x12c6
jp 0x12c6
movb $0x4, -0x11(%rbp)
jmp 0x12d5
movss -0x2c(%rbp), %xmm0
divss -0x28(%rbp), %xmm0
callq 0x13a0
jmp 0x12db
movb $0x3, -0x11(%rbp)
jmp 0x12e1
movb $0x2, -0x11(%rbp)
jmp 0x12e7
movb $0x1, -0x11(%rbp)
jmp 0x12e9
jmp 0x12eb
movq -0x20(%rbp), %rax
addq $0x1, %rax
movq %rax, -0x20(%rbp)
jmp 0x1192
cmpb $0x0, -0x11(%rbp)
je 0x1372
movsbl -0x11(%rbp), %eax
decl %eax
movl %eax, %ecx
movq %rcx, -0x40(%rbp)
subl $0x3, %eax
ja 0x1367
movq -0x40(%rbp), %rax
leaq 0xce6(%rip), %rcx       # 0x2004
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0xd00(%rip), %rdi       # 0x202e
movb $0x0, %al
callq 0x1050
jmp 0x1369
leaq 0xd59(%rip), %rdi       # 0x2097
movb $0x0, %al
callq 0x1050
jmp 0x1369
leaq 0xd70(%rip), %rdi       # 0x20be
movb $0x0, %al
callq 0x1050
jmp 0x1369
leaq 0xdc1(%rip), %rdi       # 0x211f
movb $0x0, %al
callq 0x1050
jmp 0x1369
jmp 0x1369
movl $0x1, -0x4(%rbp)
jmp 0x1390
callq 0x1400
cvtss2sd %xmm0, %xmm0
leaq 0xdbd(%rip), %rdi       # 0x213f
movb $0x1, %al
callq 0x1050
movl $0x0, -0x4(%rbp)
movl -0x4(%rbp), %eax
addq $0x40, %rsp
popq %rbp
retq
nopl (%rax)