// File: /workspace/github_c_makefile_star2_O1/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 0x1342
movq %rsi, %rbx
movslq %edi, %rbp
movl $0x1, %r12d
xorl %r14d, %r14d
leaq 0x2eca(%rip), %r15      # 0x4070
movq (%rbx,%r12,8), %r13
movq %r13, %rdi
callq 0x1040
cvtsd2ss %xmm0, %xmm0
ucomiss 0xe47(%rip), %xmm0      # 0x2004
jne 0x11c1
jnp 0x11e8
movzbl 0x2e98(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x1322
leaq 0x1(%rax), %rcx
movb %cl, 0x2e84(%rip)       # 0x4060
movss %xmm0, 0x4(%r15,%rax,4)
jmp 0x132e
movq %r13, %rdi
leaq 0xe42(%rip), %rsi       # 0x2034
movss %xmm0, 0x4(%rsp)
callq 0x1070
movss 0x4(%rsp), %xmm0
testl %eax, %eax
je 0x11c1
movq %r13, %rdi
callq 0x1050
movb $0x1, %cl
cmpq $0x1, %rax
jne 0x1331
movzbl 0x2e3e(%rip), %eax      # 0x4060
leal -0x2(%rax), %edx
movb $0x2, %cl
cmpb $0xc, %dl
ja 0x1331
testq %rax, %rax
je 0x1246
leal -0x1(%rax), %ecx
movb %cl, 0x2e22(%rip)       # 0x4060
movss (%r15,%rax,4), %xmm1
jmp 0x1255
leaq 0xf1d(%rip), %rdi       # 0x216a
callq 0x1030
xorps %xmm1, %xmm1
movzbl 0x2e04(%rip), %eax      # 0x4060
testq %rax, %rax
je 0x1272
leal -0x1(%rax), %ecx
movb %cl, 0x2df6(%rip)       # 0x4060
movss (%r15,%rax,4), %xmm0
jmp 0x128d
leaq 0xef1(%rip), %rdi       # 0x216a
movss %xmm1, 0x4(%rsp)
callq 0x1030
movss 0x4(%rsp), %xmm1
xorps %xmm0, %xmm0
movq (%rbx,%r12,8), %rax
movzbl (%rax), %eax
movb $0x3, %cl
addl $-0x2a, %eax
cmpl $0x5, %eax
ja 0x1331
leaq 0xd5f(%rip), %rdx       # 0x2008
movslq (%rdx,%rax,4), %rax
addq %rdx, %rax
jmpq *%rax
movzbl 0x2da7(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x1322
mulss %xmm0, %xmm1
jmp 0x12ec
movzbl 0x2d94(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x1322
subss %xmm1, %xmm0
jmp 0x11d2
movzbl 0x2d7e(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x1322
addss %xmm0, %xmm1
leaq 0x1(%rax), %rcx
movb %cl, 0x2d6a(%rip)       # 0x4060
movss %xmm1, 0x4(%r15,%rax,4)
jmp 0x132e
movb $0x4, %cl
ucomiss 0xcfc(%rip), %xmm1      # 0x2004
jne 0x130c
jnp 0x1331
movzbl 0x2d4d(%rip), %eax      # 0x4060
cmpq $0xe, %rax
ja 0x1322
divss %xmm1, %xmm0
jmp 0x11d2
leaq 0xe27(%rip), %rdi       # 0x2150
callq 0x1030
movl %r14d, %ecx
incq %r12
movl %ecx, %r14d
cmpq %r12, %rbp
jne 0x11a6
jmp 0x1344
xorl %ecx, %ecx
movzbl %cl, %eax
leaq 0xcd2(%rip), %rcx       # 0x2020
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
movzbl 0x2d02(%rip), %eax      # 0x4060
testq %rax, %rax
je 0x13b8
leal -0x1(%rax), %ecx
movb %cl, 0x2cf4(%rip)       # 0x4060
leaq 0x2cfd(%rip), %rcx      # 0x4070
xorps %xmm0, %xmm0
cvtss2sd (%rcx,%rax,4), %xmm0
jmp 0x13c7
leaq 0xcbf(%rip), %rdi       # 0x2043
jmp 0x139f
leaq 0xd35(%rip), %rdi       # 0x20c2
jmp 0x139f
leaq 0xccc(%rip), %rdi       # 0x2062
jmp 0x139f
leaq 0xd49(%rip), %rdi       # 0x20e8
callq 0x1030
movl $0x1, %eax
addq $0x8, %rsp
popq %rbx
popq %r12
popq %r13
popq %r14
popq %r15
popq %rbp
retq
leaq 0xdab(%rip), %rdi       # 0x216a
callq 0x1030
xorps %xmm0, %xmm0
leaq 0xc68(%rip), %rdi       # 0x2036
movb $0x1, %al
callq 0x1060
xorl %eax, %eax
jmp 0x13a9