// File: /workspace/github_c_makefile_star2_O2/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
movq %rsi, %rbx
movslq %edi, %r15
pushq $0x1
popq %r12
xorl %ebp, %ebp
leaq 0xe92(%rip), %r13       # 0x201c
cmpq %r15, %r12
jae 0x124a
movq (%rbx,%r12,8), %r14
movq %r14, %rdi
callq 0x1040
cvtsd2ss %xmm0, %xmm1
ucomiss 0xe5a(%rip), %xmm1      # 0x2004
jne 0x11ae
jnp 0x11bf
movaps %xmm1, %xmm0
callq 0x12b2
movl %ebp, %ecx
incq %r12
movl %ecx, %ebp
jmp 0x118a
cmpb $0x30, (%r14)
jne 0x11cc
cmpb $0x0, 0x1(%r14)
je 0x11ae
movq %r14, %rdi
callq 0x1050
movb $0x1, %cl
cmpq $0x1, %rax
jne 0x11b8
movb 0x2e7e(%rip), %al       # 0x4060
addb $-0x2, %al
movb $0x2, %cl
cmpb $0xc, %al
ja 0x11b8
callq 0x12e3
movss %xmm0, 0x4(%rsp)
callq 0x12e3
movq (%rbx,%r12,8), %rax
movzbl (%rax), %eax
movb $0x3, %cl
addl $-0x2a, %eax
cmpl $0x5, %eax
ja 0x11b8
movslq (%r13,%rax,4), %rax
addq %r13, %rax
movss 0x4(%rsp), %xmm1
jmpq *%rax
mulss %xmm0, %xmm1
jmp 0x11ae
subss %xmm1, %xmm0
jmp 0x1242
addss %xmm0, %xmm1
jmp 0x11ae
movb $0x4, %cl
ucomiss 0xdce(%rip), %xmm1      # 0x2004
jne 0x123e
jnp 0x11b8
divss %xmm1, %xmm0
movaps %xmm0, %xmm1
jmp 0x11ae
movzbl %bpl, %eax
leaq 0xdb3(%rip), %rcx       # 0x2008
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
callq 0x12e3
cvtss2sd %xmm0, %xmm0
leaq 0xdc6(%rip), %rdi       # 0x2034
movb $0x1, %al
callq 0x1060
xorl %eax, %eax
jmp 0x12a3
leaq 0xdc1(%rip), %rdi       # 0x2041
jmp 0x129b
leaq 0xe37(%rip), %rdi       # 0x20c0
jmp 0x129b
leaq 0xdce(%rip), %rdi       # 0x2060
jmp 0x129b
leaq 0xe4b(%rip), %rdi       # 0x20e6
callq 0x1030
pushq $0x1
popq %rax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq