// File: /workspace/github_c_makefile_star2_O0/ejunjsh[P]mycc/expr.c
// Function: prefix
static struct ASTnode *prefix(int ptp) {
  struct ASTnode *tree;
  switch (Token.token) {
  case T_AMPER:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 保证是标识符
    if (tree->op != A_IDENT)
      fatal("& operator must be followed by an identifier");

    // 防止'&'用在数组上
    if (tree->sym->stype == S_ARRAY)
      fatal("& operator cannot be performed on an array");

    // 改变操作为A_ADDR，类型改成指向原来类型的指针
    tree->op = A_ADDR;
    tree->type = pointer_to(tree->type);
    break;
  case T_STAR:
    // 获取下个token，然后解析它
    // 递归执行
    // 标记为右值
    scan(&Token);
    tree = prefix(ptp);
    tree->rvalue= 1;

    // 保证树的类型是指针
    if (!ptrtype(tree->type))
      fatal("* operator must be followed by an expression of pointer type");

    // 创建A_DEREF节点
    tree =
      mkastunary(A_DEREF, value_at(tree->type), tree->ctype, tree, NULL, 0);
    break;
  case T_MINUS:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 创建A_NEGATE节点
    // 标记为右值
    // 由于字符类型是无符号的，所以在这里要转成整型
    tree->rvalue = 1;
    if (tree->type == P_CHAR)
      tree->type = P_INT;
    tree = mkastunary(A_NEGATE, tree->type, tree->ctype, tree, NULL, 0);
    break;
  case T_INVERT:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 创建A_INVERT节点
    // 标记为右值
    tree->rvalue = 1;
    tree = mkastunary(A_INVERT, tree->type, tree->ctype, tree, NULL, 0);
    break;
  case T_LOGNOT:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 创建A_LOGNOT节点
    // 标记为右值
    tree->rvalue = 1;
    tree = mkastunary(A_LOGNOT, tree->type, tree->ctype, tree, NULL, 0);
    break;
  case T_INC:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 保证是标识符
    if (tree->op != A_IDENT)
      fatal("++ operator must be followed by an identifier");

    // 创建A_PREINC节点
    tree = mkastunary(A_PREINC, tree->type, tree->ctype, tree, NULL, 0);
    break;
  case T_DEC:
    // 获取下个token，然后解析它
    // 递归执行
    scan(&Token);
    tree = prefix(ptp);

    // 保证是标识符
    if (tree->op != A_IDENT)
      fatal("-- operator must be followed by an identifier");

    // 创建A_PREDEC节点
    tree = mkastunary(A_PREDEC, tree->type, tree->ctype, tree, NULL, 0);
    break;
  default:
    tree = postfix(ptp);
  }
  return (tree);
}

// Assembly:
pushq %rbp
movq %rsp, %rbp
subq $0x20, %rsp
movl %edi, -0x4(%rbp)
leaq 0xc94e(%rip), %rax      # 0x12530
movl (%rax), %eax
addl $-0xc, %eax
movl %eax, %ecx
movq %rcx, -0x18(%rbp)
subl $0x11, %eax
ja 0x5ea6
movq -0x18(%rbp), %rax
leaq 0x718f(%rip), %rcx      # 0xcd90
movslq (%rcx,%rax,4), %rax
addq %rcx, %rax
jmpq *%rax
leaq 0xc91f(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1c, 0x4(%rax)
je 0x5c38
leaq 0x72a3(%rip), %rdi      # 0xced6
callq 0x8110
movq -0x10(%rbp), %rax
movq 0x38(%rax), %rax
cmpl $0x2, 0x20(%rax)
jne 0x5c52
leaq 0x72b6(%rip), %rdi      # 0xcf03
callq 0x8110
movq -0x10(%rbp), %rax
movl $0x25, 0x4(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edi
callq 0xb740
movl %eax, %ecx
movq -0x10(%rbp), %rax
movl %ecx, 0x8(%rax)
jmp 0x5eb2
leaq 0xc8b2(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edi
callq 0xb720
cmpl $0x0, %eax
jne 0x5cb7
leaq 0x727c(%rip), %rdi      # 0xcf2e
callq 0x8110
movq -0x10(%rbp), %rax
movl 0x8(%rax), %edi
callq 0xb780
movl %eax, %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x24, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
leaq 0xc83d(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x10(%rbp), %rax
cmpl $0x20, 0x8(%rax)
jne 0x5d24
movq -0x10(%rbp), %rax
movl $0x30, 0x8(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x2b, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
leaq 0xc7d7(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x2c, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
leaq 0xc786(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
movl $0x1, 0x18(%rax)
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x2d, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
leaq 0xc735(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1c, 0x4(%rax)
je 0x5e22
leaq 0x714e(%rip), %rdi      # 0xcf6b
callq 0x8110
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x27, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
leaq 0xc6dc(%rip), %rdi      # 0x12530
callq 0x84c0
movl -0x4(%rbp), %edi
callq 0x5bd0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
cmpl $0x1c, 0x4(%rax)
je 0x5e7b
leaq 0x7123(%rip), %rdi      # 0xcf99
callq 0x8110
movq -0x10(%rbp), %rax
movl 0x8(%rax), %esi
movq -0x10(%rbp), %rax
movq 0x10(%rax), %rdx
movq -0x10(%rbp), %rcx
movl $0x28, %edi
xorl %eax, %eax
movl %eax, %r8d
xorl %r9d, %r9d
callq 0xada0
movq %rax, -0x10(%rbp)
jmp 0x5eb2
movl -0x4(%rbp), %edi
callq 0x5fb0
movq %rax, -0x10(%rbp)
movq -0x10(%rbp), %rax
addq $0x20, %rsp
popq %rbp
retq
nopl (%rax)