// File: /workspace/github_c_makefile_star2_O3/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
pushq %r15
pushq %r14
pushq %r13
pushq %r12
pushq %rbx
pushq %rax
cmpl $0x2, %edi
jb 0x12e5
movq %rsi, %rbx
movslq %edi, %r12
movl $0x1, %r13d
xorl %ecx, %ecx
leaq 0x2edb(%rip), %rbp      # 0x4070
movl %ecx, %r14d
movq (%rbx,%r13,8), %r15
movq %r15, %rdi
callq 0x1040
cvtsd2ss %xmm0, %xmm0
ucomiss 0xe55(%rip), %xmm0      # 0x2004
jne 0x11b3
jnp 0x11d9
movzbl 0x2ea6(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x12b7
leaq 0x1(%rax), %rcx
movb %cl, 0x2e92(%rip)       # 0x4060
movss %xmm0, 0x4(%rbp,%rax,4)
jmp 0x12c3
cmpb $0x30, (%r15)
jne 0x11e6
cmpb $0x0, 0x1(%r15)
je 0x11b3
movq %r15, %rdi
callq 0x1050
movb $0x1, %cl
cmpq $0x1, %rax
jne 0x12c6
movzbl 0x2e5f(%rip), %eax      # 0x4060
leal -0x2(%rax), %edx
movb $0x2, %cl
cmpb $0xc, %dl
ja 0x12c6
movss (%rbp,%rax,4), %xmm0
movb %dl, 0x2e45(%rip)       # 0x4060
movzbl (%r15), %edx
movb $0x3, %cl
addl $-0x2a, %edx
cmpl $0x5, %edx
ja 0x12c6
decb %al
movzbl %al, %eax
movss (%rbp,%rax,4), %xmm1
leaq 0xdc9(%rip), %rsi       # 0x2008
movslq (%rsi,%rdx,4), %rax
addq %rsi, %rax
jmpq *%rax
movzbl 0x2e11(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x12b7
mulss %xmm1, %xmm0
jmp 0x11c4
movzbl 0x2dfb(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x12b7
subss %xmm0, %xmm1
jmp 0x12a5
movzbl 0x2de8(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x12b7
addss %xmm1, %xmm0
jmp 0x11c4
movb $0x4, %cl
ucomiss 0xd74(%rip), %xmm0      # 0x2004
jne 0x1294
jnp 0x12c6
movzbl 0x2dc5(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x12b7
divss %xmm0, %xmm1
leaq 0x1(%rax), %rcx
movb %cl, 0x2db1(%rip)       # 0x4060
movss %xmm1, 0x4(%rbp,%rax,4)
jmp 0x12c3
leaq 0xe90(%rip), %rdi       # 0x214e
callq 0x1030
movl %r14d, %ecx
incq %r13
cmpq %r13, %r12
jne 0x1195
movzbl %cl, %eax
leaq 0xd44(%rip), %rcx       # 0x2020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x2d74(%rip), %eax      # 0x4060
testq %rax, %rax
je 0x130b
leal -0x1(%rax), %ecx
movb %cl, 0x2d66(%rip)       # 0x4060
leaq 0x2d6f(%rip), %rcx      # 0x4070
xorps %xmm0, %xmm0
cvtss2sd (%rcx,%rax,4), %xmm0
jmp 0x131a
leaq 0xe56(%rip), %rdi       # 0x2168
callq 0x1030
xorps %xmm0, %xmm0
leaq 0xd13(%rip), %rdi       # 0x2034
movb $0x1, %al
callq 0x1060
xorl %eax, %eax
jmp 0x1358
leaq 0xd0e(%rip), %rdi       # 0x2041
jmp 0x134e
leaq 0xd84(%rip), %rdi       # 0x20c0
jmp 0x134e
leaq 0xd1b(%rip), %rdi       # 0x2060
jmp 0x134e
leaq 0xd98(%rip), %rdi       # 0x20e6
callq 0x1030
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq